1 | //===- unittest/AST/SourceLocationTest.cpp - AST source loc unit tests ----===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file contains tests for SourceLocation and SourceRange fields |
10 | // in AST nodes. |
11 | // |
12 | // FIXME: In the long-term, when we test more than source locations, we may |
13 | // want to have a unit test file for an AST node (or group of related nodes), |
14 | // rather than a unit test file for source locations for all AST nodes. |
15 | // |
16 | //===----------------------------------------------------------------------===// |
17 | |
18 | #include "MatchVerifier.h" |
19 | #include "clang/AST/ASTConcept.h" |
20 | #include "clang/AST/ASTContext.h" |
21 | #include "clang/AST/ASTFwd.h" |
22 | #include "clang/AST/DeclTemplate.h" |
23 | #include "clang/AST/ExprConcepts.h" |
24 | #include "clang/ASTMatchers/ASTMatchFinder.h" |
25 | #include "clang/ASTMatchers/ASTMatchers.h" |
26 | #include "clang/Tooling/Tooling.h" |
27 | #include "llvm/Testing/Annotations/Annotations.h" |
28 | #include "gtest/gtest.h" |
29 | |
30 | using namespace clang; |
31 | using namespace clang::ast_matchers; |
32 | |
33 | namespace { |
34 | |
35 | // FIXME: Pull the *Verifier tests into their own test file. |
36 | |
37 | TEST(MatchVerifier, ParseError) { |
38 | LocationVerifier<VarDecl> Verifier; |
39 | Verifier.expectLocation(Line: 1, Column: 1); |
40 | EXPECT_FALSE(Verifier.match("int i" , varDecl())); |
41 | } |
42 | |
43 | TEST(MatchVerifier, NoMatch) { |
44 | LocationVerifier<VarDecl> Verifier; |
45 | Verifier.expectLocation(Line: 1, Column: 1); |
46 | EXPECT_FALSE(Verifier.match("int i;" , recordDecl())); |
47 | } |
48 | |
49 | TEST(MatchVerifier, WrongType) { |
50 | LocationVerifier<RecordDecl> Verifier; |
51 | Verifier.expectLocation(Line: 1, Column: 1); |
52 | EXPECT_FALSE(Verifier.match("int i;" , varDecl())); |
53 | } |
54 | |
55 | TEST(LocationVerifier, WrongLocation) { |
56 | LocationVerifier<VarDecl> Verifier; |
57 | Verifier.expectLocation(Line: 1, Column: 1); |
58 | EXPECT_FALSE(Verifier.match("int i;" , varDecl())); |
59 | } |
60 | |
61 | TEST(RangeVerifier, WrongRange) { |
62 | RangeVerifier<VarDecl> Verifier; |
63 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 1); |
64 | EXPECT_FALSE(Verifier.match("int i;" , varDecl())); |
65 | } |
66 | |
67 | class WhileParenLocationVerifier : public MatchVerifier<WhileStmt> { |
68 | unsigned ExpectLParenLine = 0, ExpectLParenColumn = 0; |
69 | unsigned ExpectRParenLine = 0, ExpectRParenColumn = 0; |
70 | |
71 | public: |
72 | void expectLocations(unsigned LParenLine, unsigned LParenColumn, |
73 | unsigned RParenLine, unsigned RParenColumn) { |
74 | ExpectLParenLine = LParenLine; |
75 | ExpectLParenColumn = LParenColumn; |
76 | ExpectRParenLine = RParenLine; |
77 | ExpectRParenColumn = RParenColumn; |
78 | } |
79 | |
80 | protected: |
81 | void verify(const MatchFinder::MatchResult &Result, |
82 | const WhileStmt &Node) override { |
83 | SourceLocation LParenLoc = Node.getLParenLoc(); |
84 | SourceLocation RParenLoc = Node.getRParenLoc(); |
85 | unsigned LParenLine = |
86 | Result.SourceManager->getSpellingLineNumber(Loc: LParenLoc); |
87 | unsigned LParenColumn = |
88 | Result.SourceManager->getSpellingColumnNumber(Loc: LParenLoc); |
89 | unsigned RParenLine = |
90 | Result.SourceManager->getSpellingLineNumber(Loc: RParenLoc); |
91 | unsigned RParenColumn = |
92 | Result.SourceManager->getSpellingColumnNumber(Loc: RParenLoc); |
93 | |
94 | if (LParenLine != ExpectLParenLine || LParenColumn != ExpectLParenColumn || |
95 | RParenLine != ExpectRParenLine || RParenColumn != ExpectRParenColumn) { |
96 | std::string MsgStr; |
97 | llvm::raw_string_ostream Msg(MsgStr); |
98 | Msg << "Expected LParen Location <" << ExpectLParenLine << ":" |
99 | << ExpectLParenColumn << ">, found <" ; |
100 | LParenLoc.print(OS&: Msg, SM: *Result.SourceManager); |
101 | Msg << ">\n" ; |
102 | |
103 | Msg << "Expected RParen Location <" << ExpectRParenLine << ":" |
104 | << ExpectRParenColumn << ">, found <" ; |
105 | RParenLoc.print(OS&: Msg, SM: *Result.SourceManager); |
106 | Msg << ">" ; |
107 | |
108 | this->setFailure(Msg.str()); |
109 | } |
110 | } |
111 | }; |
112 | |
113 | TEST(LocationVerifier, WhileParenLoc) { |
114 | WhileParenLocationVerifier Verifier; |
115 | Verifier.expectLocations(LParenLine: 1, LParenColumn: 17, RParenLine: 1, RParenColumn: 38); |
116 | EXPECT_TRUE(Verifier.match("void f() { while(true/*some comment*/) {} }" , |
117 | whileStmt())); |
118 | } |
119 | |
120 | class LabelDeclRangeVerifier : public RangeVerifier<LabelStmt> { |
121 | protected: |
122 | SourceRange getRange(const LabelStmt &Node) override { |
123 | return Node.getDecl()->getSourceRange(); |
124 | } |
125 | }; |
126 | |
127 | TEST(LabelDecl, Range) { |
128 | LabelDeclRangeVerifier Verifier; |
129 | Verifier.expectRange(BeginLine: 1, BeginColumn: 12, EndLine: 1, EndColumn: 12); |
130 | EXPECT_TRUE(Verifier.match("void f() { l: return; }" , labelStmt())); |
131 | } |
132 | |
133 | TEST(LabelStmt, Range) { |
134 | RangeVerifier<LabelStmt> Verifier; |
135 | Verifier.expectRange(BeginLine: 1, BeginColumn: 12, EndLine: 1, EndColumn: 15); |
136 | EXPECT_TRUE(Verifier.match("void f() { l: return; }" , labelStmt())); |
137 | } |
138 | |
139 | TEST(ParmVarDecl, KNRLocation) { |
140 | LocationVerifier<ParmVarDecl> Verifier; |
141 | Verifier.expectLocation(Line: 1, Column: 8); |
142 | EXPECT_TRUE(Verifier.match("void f(i) {}" , varDecl(), Lang_C89)); |
143 | |
144 | Verifier.expectLocation(Line: 1, Column: 15); |
145 | EXPECT_TRUE(Verifier.match("void f(i) int i; {}" , varDecl(), Lang_C99)); |
146 | } |
147 | |
148 | TEST(ParmVarDecl, KNRRange) { |
149 | RangeVerifier<ParmVarDecl> Verifier; |
150 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 8); |
151 | EXPECT_TRUE(Verifier.match("void f(i) {}" , varDecl(), Lang_C89)); |
152 | |
153 | Verifier.expectRange(BeginLine: 1, BeginColumn: 11, EndLine: 1, EndColumn: 15); |
154 | EXPECT_TRUE(Verifier.match("void f(i) int i; {}" , varDecl(), Lang_C99)); |
155 | } |
156 | |
157 | TEST(CXXNewExpr, ArrayRange) { |
158 | RangeVerifier<CXXNewExpr> Verifier; |
159 | Verifier.expectRange(BeginLine: 1, BeginColumn: 12, EndLine: 1, EndColumn: 22); |
160 | EXPECT_TRUE(Verifier.match("void f() { new int[10]; }" , cxxNewExpr())); |
161 | } |
162 | |
163 | TEST(CXXNewExpr, ParenRange) { |
164 | RangeVerifier<CXXNewExpr> Verifier; |
165 | Verifier.expectRange(BeginLine: 1, BeginColumn: 12, EndLine: 1, EndColumn: 20); |
166 | EXPECT_TRUE(Verifier.match("void f() { new int(); }" , cxxNewExpr())); |
167 | } |
168 | |
169 | TEST(MemberExpr, ImplicitMemberRange) { |
170 | RangeVerifier<MemberExpr> Verifier; |
171 | Verifier.expectRange(BeginLine: 2, BeginColumn: 30, EndLine: 2, EndColumn: 30); |
172 | EXPECT_TRUE(Verifier.match("struct S { operator int() const; };\n" |
173 | "int foo(const S& s) { return s; }" , |
174 | memberExpr())); |
175 | } |
176 | |
177 | class MemberExprArrowLocVerifier : public RangeVerifier<MemberExpr> { |
178 | protected: |
179 | SourceRange getRange(const MemberExpr &Node) override { |
180 | return Node.getOperatorLoc(); |
181 | } |
182 | }; |
183 | |
184 | TEST(MemberExpr, ArrowRange) { |
185 | MemberExprArrowLocVerifier Verifier; |
186 | Verifier.expectRange(BeginLine: 2, BeginColumn: 19, EndLine: 2, EndColumn: 19); |
187 | EXPECT_TRUE(Verifier.match("struct S { int x; };\n" |
188 | "void foo(S *s) { s->x = 0; }" , |
189 | memberExpr())); |
190 | } |
191 | |
192 | TEST(MemberExpr, MacroArrowRange) { |
193 | MemberExprArrowLocVerifier Verifier; |
194 | Verifier.expectRange(BeginLine: 1, BeginColumn: 24, EndLine: 1, EndColumn: 24); |
195 | EXPECT_TRUE(Verifier.match("#define MEMBER(a, b) (a->b)\n" |
196 | "struct S { int x; };\n" |
197 | "void foo(S *s) { MEMBER(s, x) = 0; }" , |
198 | memberExpr())); |
199 | } |
200 | |
201 | TEST(MemberExpr, ImplicitArrowRange) { |
202 | MemberExprArrowLocVerifier Verifier; |
203 | Verifier.expectRange(BeginLine: 0, BeginColumn: 0, EndLine: 0, EndColumn: 0); |
204 | EXPECT_TRUE(Verifier.match("struct S { int x; void Test(); };\n" |
205 | "void S::Test() { x = 1; }" , |
206 | memberExpr())); |
207 | } |
208 | |
209 | TEST(VarDecl, VMTypeFixedVarDeclRange) { |
210 | RangeVerifier<VarDecl> Verifier; |
211 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 23); |
212 | EXPECT_TRUE(Verifier.match("int a[(int)(void*)1234];" , |
213 | varDecl(), Lang_C89)); |
214 | } |
215 | |
216 | TEST(TypeLoc, IntRange) { |
217 | RangeVerifier<TypeLoc> Verifier; |
218 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 1); |
219 | EXPECT_TRUE(Verifier.match("int a;" , typeLoc())); |
220 | } |
221 | |
222 | TEST(TypeLoc, LongRange) { |
223 | RangeVerifier<TypeLoc> Verifier; |
224 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 1); |
225 | EXPECT_TRUE(Verifier.match("long a;" , typeLoc())); |
226 | } |
227 | |
228 | TEST(TypeLoc, DecltypeTypeLocRange) { |
229 | llvm::Annotations Code(R"( |
230 | $full1[[decltype(1)]] a; |
231 | struct A {struct B{};} var; |
232 | $full2[[decltype(var)]]::B c; |
233 | )" ); |
234 | auto AST = tooling::buildASTFromCodeWithArgs(Code: Code.code(), /*Args=*/{}); |
235 | ASTContext &Ctx = AST->getASTContext(); |
236 | const auto &SM = Ctx.getSourceManager(); |
237 | |
238 | auto MatchedLocs = clang::ast_matchers::match( |
239 | Matcher: typeLoc(loc(InnerMatcher: decltypeType())).bind(ID: "target" ), Context&: Ctx); |
240 | ASSERT_EQ(MatchedLocs.size(), 2u); |
241 | auto verify = [&](SourceRange ActualRange, |
242 | const llvm::Annotations::Range &Expected) { |
243 | auto ActualCharRange = |
244 | Lexer::getAsCharRange(Range: ActualRange, SM, LangOpts: Ctx.getLangOpts()); |
245 | EXPECT_EQ(SM.getFileOffset(ActualCharRange.getBegin()), Expected.Begin); |
246 | EXPECT_EQ(SM.getFileOffset(ActualCharRange.getEnd()), Expected.End); |
247 | }; |
248 | const auto *Target1 = MatchedLocs[0].getNodeAs<DecltypeTypeLoc>(ID: "target" ); |
249 | verify(Target1->getSourceRange(), Code.range(Name: "full1" )); |
250 | |
251 | const auto *Target2 = MatchedLocs[1].getNodeAs<DecltypeTypeLoc>(ID: "target" ); |
252 | verify(Target2->getSourceRange(), Code.range(Name: "full2" )); |
253 | } |
254 | |
255 | TEST(TypeLoc, AutoTypeLocRange) { |
256 | RangeVerifier<TypeLoc> Verifier; |
257 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 14); |
258 | EXPECT_TRUE(Verifier.match("decltype(auto) a = 1;" , typeLoc(loc(autoType())), |
259 | Lang_CXX14)); |
260 | |
261 | const char *Code = |
262 | R"cpp(template <typename T> concept C = true; |
263 | C auto abc(); |
264 | )cpp" ; |
265 | // Should include "C auto" tokens. |
266 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 3); // token range. |
267 | EXPECT_TRUE(Verifier.match(Code, typeLoc(loc(autoType())), Lang_CXX20)); |
268 | } |
269 | |
270 | TEST(TypeLoc, LongDoubleRange) { |
271 | RangeVerifier<TypeLoc> Verifier; |
272 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 6); |
273 | EXPECT_TRUE(Verifier.match("long double a;" , typeLoc())); |
274 | } |
275 | |
276 | TEST(TypeLoc, DoubleLongRange) { |
277 | RangeVerifier<TypeLoc> Verifier; |
278 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 8); |
279 | EXPECT_TRUE(Verifier.match("double long a;" , typeLoc())); |
280 | } |
281 | |
282 | TEST(TypeLoc, LongIntRange) { |
283 | RangeVerifier<TypeLoc> Verifier; |
284 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 6); |
285 | EXPECT_TRUE(Verifier.match("long int a;" , typeLoc())); |
286 | } |
287 | |
288 | TEST(TypeLoc, IntLongRange) { |
289 | RangeVerifier<TypeLoc> Verifier; |
290 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 5); |
291 | EXPECT_TRUE(Verifier.match("int long a;" , typeLoc())); |
292 | } |
293 | |
294 | TEST(TypeLoc, UnsignedIntRange) { |
295 | RangeVerifier<TypeLoc> Verifier; |
296 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 10); |
297 | EXPECT_TRUE(Verifier.match("unsigned int a;" , typeLoc())); |
298 | } |
299 | |
300 | TEST(TypeLoc, IntUnsignedRange) { |
301 | RangeVerifier<TypeLoc> Verifier; |
302 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 5); |
303 | EXPECT_TRUE(Verifier.match("int unsigned a;" , typeLoc())); |
304 | } |
305 | |
306 | TEST(TypeLoc, LongLongRange) { |
307 | RangeVerifier<TypeLoc> Verifier; |
308 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 6); |
309 | EXPECT_TRUE(Verifier.match("long long a;" , typeLoc())); |
310 | } |
311 | |
312 | TEST(TypeLoc, UnsignedLongLongRange) { |
313 | RangeVerifier<TypeLoc> Verifier; |
314 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 15); |
315 | EXPECT_TRUE(Verifier.match("unsigned long long a;" , typeLoc())); |
316 | } |
317 | |
318 | TEST(TypeLoc, LongUnsignedLongRange) { |
319 | RangeVerifier<TypeLoc> Verifier; |
320 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 15); |
321 | EXPECT_TRUE(Verifier.match("long unsigned long a;" , typeLoc())); |
322 | } |
323 | |
324 | TEST(TypeLoc, LongLongUnsignedRange) { |
325 | RangeVerifier<TypeLoc> Verifier; |
326 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 11); |
327 | EXPECT_TRUE(Verifier.match("long long unsigned a;" , typeLoc())); |
328 | } |
329 | |
330 | TEST(TypeLoc, ConstLongLongRange) { |
331 | RangeVerifier<TypeLoc> Verifier; |
332 | Verifier.expectRange(BeginLine: 1, BeginColumn: 7, EndLine: 1, EndColumn: 12); |
333 | EXPECT_TRUE(Verifier.match("const long long a = 0;" , typeLoc())); |
334 | } |
335 | |
336 | TEST(TypeLoc, LongConstLongRange) { |
337 | RangeVerifier<TypeLoc> Verifier; |
338 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 12); |
339 | EXPECT_TRUE(Verifier.match("long const long a = 0;" , typeLoc())); |
340 | } |
341 | |
342 | TEST(TypeLoc, LongLongConstRange) { |
343 | RangeVerifier<TypeLoc> Verifier; |
344 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 6); |
345 | EXPECT_TRUE(Verifier.match("long long const a = 0;" , typeLoc())); |
346 | } |
347 | |
348 | TEST(CXXConstructorDecl, NoRetFunTypeLocRange) { |
349 | RangeVerifier<CXXConstructorDecl> Verifier; |
350 | Verifier.expectRange(BeginLine: 1, BeginColumn: 11, EndLine: 1, EndColumn: 13); |
351 | EXPECT_TRUE(Verifier.match("class C { C(); };" , functionDecl())); |
352 | } |
353 | |
354 | TEST(CXXConstructorDecl, DefaultedCtorLocRange) { |
355 | RangeVerifier<CXXConstructorDecl> Verifier; |
356 | Verifier.expectRange(BeginLine: 1, BeginColumn: 11, EndLine: 1, EndColumn: 23); |
357 | EXPECT_TRUE(Verifier.match("class C { C() = default; };" , functionDecl())); |
358 | } |
359 | |
360 | TEST(CXXConstructorDecl, DeletedCtorLocRange) { |
361 | RangeVerifier<CXXConstructorDecl> Verifier; |
362 | Verifier.expectRange(BeginLine: 1, BeginColumn: 11, EndLine: 1, EndColumn: 22); |
363 | EXPECT_TRUE(Verifier.match("class C { C() = delete; };" , functionDecl())); |
364 | } |
365 | |
366 | TEST(CompoundLiteralExpr, CompoundVectorLiteralRange) { |
367 | RangeVerifier<CompoundLiteralExpr> Verifier; |
368 | Verifier.expectRange(BeginLine: 2, BeginColumn: 11, EndLine: 2, EndColumn: 22); |
369 | EXPECT_TRUE(Verifier.match( |
370 | "typedef int int2 __attribute__((ext_vector_type(2)));\n" |
371 | "int2 i2 = (int2){1, 2};" , compoundLiteralExpr())); |
372 | } |
373 | |
374 | TEST(CompoundLiteralExpr, ParensCompoundVectorLiteralRange) { |
375 | RangeVerifier<CompoundLiteralExpr> Verifier; |
376 | Verifier.expectRange(BeginLine: 2, BeginColumn: 20, EndLine: 2, EndColumn: 31); |
377 | EXPECT_TRUE( |
378 | Verifier.match("typedef int int2 __attribute__((ext_vector_type(2)));\n" |
379 | "constant int2 i2 = (int2)(1, 2);" , |
380 | compoundLiteralExpr(), Lang_OpenCL)); |
381 | } |
382 | |
383 | TEST(InitListExpr, VectorLiteralListBraceRange) { |
384 | RangeVerifier<InitListExpr> Verifier; |
385 | Verifier.expectRange(BeginLine: 2, BeginColumn: 17, EndLine: 2, EndColumn: 22); |
386 | EXPECT_TRUE(Verifier.match( |
387 | "typedef int int2 __attribute__((ext_vector_type(2)));\n" |
388 | "int2 i2 = (int2){1, 2};" , initListExpr())); |
389 | } |
390 | |
391 | TEST(InitListExpr, VectorLiteralInitListParens) { |
392 | RangeVerifier<InitListExpr> Verifier; |
393 | Verifier.expectRange(BeginLine: 2, BeginColumn: 26, EndLine: 2, EndColumn: 31); |
394 | EXPECT_TRUE(Verifier.match( |
395 | "typedef int int2 __attribute__((ext_vector_type(2)));\n" |
396 | "constant int2 i2 = (int2)(1, 2);" , initListExpr(), Lang_OpenCL)); |
397 | } |
398 | |
399 | class TemplateAngleBracketLocRangeVerifier : public RangeVerifier<TypeLoc> { |
400 | protected: |
401 | SourceRange getRange(const TypeLoc &Node) override { |
402 | TemplateSpecializationTypeLoc T = |
403 | Node.getUnqualifiedLoc().castAs<TemplateSpecializationTypeLoc>(); |
404 | assert(!T.isNull()); |
405 | return SourceRange(T.getLAngleLoc(), T.getRAngleLoc()); |
406 | } |
407 | }; |
408 | |
409 | TEST(TemplateSpecializationTypeLoc, AngleBracketLocations) { |
410 | TemplateAngleBracketLocRangeVerifier Verifier; |
411 | Verifier.expectRange(BeginLine: 2, BeginColumn: 8, EndLine: 2, EndColumn: 10); |
412 | EXPECT_TRUE(Verifier.match( |
413 | "template<typename T> struct A {}; struct B{}; void f(\n" |
414 | "const A<B>&);" , |
415 | loc(templateSpecializationType()))); |
416 | } |
417 | |
418 | TEST(CXXNewExpr, TypeParenRange) { |
419 | RangeVerifier<CXXNewExpr> Verifier; |
420 | Verifier.expectRange(BeginLine: 1, BeginColumn: 10, EndLine: 1, EndColumn: 18); |
421 | EXPECT_TRUE(Verifier.match("int* a = new (int);" , cxxNewExpr())); |
422 | } |
423 | |
424 | class UnaryTransformTypeLocParensRangeVerifier : public RangeVerifier<TypeLoc> { |
425 | protected: |
426 | SourceRange getRange(const TypeLoc &Node) override { |
427 | UnaryTransformTypeLoc T = |
428 | Node.getUnqualifiedLoc().castAs<UnaryTransformTypeLoc>(); |
429 | assert(!T.isNull()); |
430 | return SourceRange(T.getLParenLoc(), T.getRParenLoc()); |
431 | } |
432 | }; |
433 | |
434 | TEST(UnaryTransformTypeLoc, ParensRange) { |
435 | UnaryTransformTypeLocParensRangeVerifier Verifier; |
436 | Verifier.expectRange(BeginLine: 3, BeginColumn: 26, EndLine: 3, EndColumn: 28); |
437 | EXPECT_TRUE(Verifier.match( |
438 | "template <typename T>\n" |
439 | "struct S {\n" |
440 | "typedef __underlying_type(T) type;\n" |
441 | "};" , |
442 | loc(unaryTransformType()))); |
443 | } |
444 | |
445 | TEST(PointerTypeLoc, StarLoc) { |
446 | llvm::Annotations Example(R"c( |
447 | int $star^*var; |
448 | )c" ); |
449 | |
450 | auto AST = tooling::buildASTFromCode(Code: Example.code()); |
451 | SourceManager &SM = AST->getSourceManager(); |
452 | auto &Ctx = AST->getASTContext(); |
453 | |
454 | auto *VD = selectFirst<VarDecl>(BoundTo: "vd" , Results: match(Matcher: varDecl(hasName(Name: "var" )).bind(ID: "vd" ), Context&: Ctx)); |
455 | ASSERT_NE(VD, nullptr); |
456 | |
457 | auto TL = |
458 | VD->getTypeSourceInfo()->getTypeLoc().castAs<PointerTypeLoc>(); |
459 | ASSERT_EQ(SM.getFileOffset(TL.getStarLoc()), Example.point("star" )); |
460 | } |
461 | |
462 | TEST(PointerTypeLoc, StarLocBehindSugar) { |
463 | llvm::Annotations Example(R"c( |
464 | #define NODEREF __attribute__((noderef)) |
465 | char $1st^* NODEREF _Nonnull $2nd^* var; |
466 | )c" ); |
467 | |
468 | auto AST = tooling::buildASTFromCode(Code: Example.code()); |
469 | SourceManager &SM = AST->getSourceManager(); |
470 | auto &Ctx = AST->getASTContext(); |
471 | |
472 | auto *VD = selectFirst<VarDecl>(BoundTo: "vd" , Results: match(Matcher: varDecl(hasName(Name: "var" )).bind(ID: "vd" ), Context&: Ctx)); |
473 | ASSERT_NE(VD, nullptr); |
474 | |
475 | auto TL = VD->getTypeSourceInfo()->getTypeLoc().castAs<PointerTypeLoc>(); |
476 | EXPECT_EQ(SM.getFileOffset(TL.getStarLoc()), Example.point("2nd" )); |
477 | |
478 | // Cast intermediate TypeLoc to make sure the structure matches expectations. |
479 | auto InnerPtrTL = TL.getPointeeLoc().castAs<AttributedTypeLoc>() |
480 | .getNextTypeLoc().castAs<MacroQualifiedTypeLoc>() |
481 | .getNextTypeLoc().castAs<AttributedTypeLoc>() |
482 | .getNextTypeLoc().castAs<PointerTypeLoc>(); |
483 | EXPECT_EQ(SM.getFileOffset(InnerPtrTL.getStarLoc()), Example.point("1st" )); |
484 | } |
485 | |
486 | TEST(CXXFunctionalCastExpr, SourceRange) { |
487 | RangeVerifier<CXXFunctionalCastExpr> Verifier; |
488 | Verifier.expectRange(BeginLine: 2, BeginColumn: 10, EndLine: 2, EndColumn: 14); |
489 | EXPECT_TRUE(Verifier.match( |
490 | "int foo() {\n" |
491 | " return int{};\n" |
492 | "}" , |
493 | cxxFunctionalCastExpr(), Lang_CXX11)); |
494 | } |
495 | |
496 | TEST(CXXConstructExpr, SourceRange) { |
497 | RangeVerifier<CXXConstructExpr> Verifier; |
498 | Verifier.expectRange(BeginLine: 3, BeginColumn: 14, EndLine: 3, EndColumn: 19); |
499 | EXPECT_TRUE(Verifier.match( |
500 | "struct A { A(int, int); };\n" |
501 | "void f(A a);\n" |
502 | "void g() { f({0, 0}); }" , |
503 | cxxConstructExpr(), Lang_CXX11)); |
504 | } |
505 | |
506 | TEST(CXXTemporaryObjectExpr, SourceRange) { |
507 | RangeVerifier<CXXTemporaryObjectExpr> Verifier; |
508 | Verifier.expectRange(BeginLine: 2, BeginColumn: 6, EndLine: 2, EndColumn: 12); |
509 | EXPECT_TRUE(Verifier.match( |
510 | "struct A { A(int, int); };\n" |
511 | "A a( A{0, 0} );" , |
512 | cxxTemporaryObjectExpr(), Lang_CXX11)); |
513 | } |
514 | |
515 | TEST(CXXUnresolvedConstructExpr, SourceRange) { |
516 | RangeVerifier<CXXUnresolvedConstructExpr> Verifier; |
517 | Verifier.expectRange(BeginLine: 3, BeginColumn: 10, EndLine: 3, EndColumn: 12); |
518 | std::vector<std::string> Args; |
519 | Args.push_back(x: "-fno-delayed-template-parsing" ); |
520 | EXPECT_TRUE(Verifier.match( |
521 | "template <typename U>\n" |
522 | "U foo() {\n" |
523 | " return U{};\n" |
524 | "}" , |
525 | cxxUnresolvedConstructExpr(), Args, Lang_CXX11)); |
526 | } |
527 | |
528 | TEST(UsingDecl, SourceRange) { |
529 | RangeVerifier<UsingDecl> Verifier; |
530 | Verifier.expectRange(BeginLine: 2, BeginColumn: 22, EndLine: 2, EndColumn: 25); |
531 | EXPECT_TRUE(Verifier.match( |
532 | "class B { protected: int i; };\n" |
533 | "class D : public B { B::i; };" , |
534 | usingDecl())); |
535 | } |
536 | |
537 | TEST(UnresolvedUsingValueDecl, SourceRange) { |
538 | RangeVerifier<UnresolvedUsingValueDecl> Verifier; |
539 | Verifier.expectRange(BeginLine: 3, BeginColumn: 3, EndLine: 3, EndColumn: 6); |
540 | EXPECT_TRUE(Verifier.match( |
541 | "template <typename B>\n" |
542 | "class D : public B {\n" |
543 | " B::i;\n" |
544 | "};" , |
545 | unresolvedUsingValueDecl())); |
546 | } |
547 | |
548 | TEST(FriendDecl, FriendNonMemberFunctionLocation) { |
549 | LocationVerifier<FriendDecl> Verifier; |
550 | Verifier.expectLocation(Line: 2, Column: 13); |
551 | EXPECT_TRUE(Verifier.match("struct A {\n" |
552 | "friend void f();\n" |
553 | "};\n" , |
554 | friendDecl())); |
555 | } |
556 | |
557 | TEST(FriendDecl, FriendNonMemberFunctionRange) { |
558 | RangeVerifier<FriendDecl> Verifier; |
559 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 15); |
560 | EXPECT_TRUE(Verifier.match("struct A {\n" |
561 | "friend void f();\n" |
562 | "};\n" , |
563 | friendDecl())); |
564 | } |
565 | |
566 | TEST(FriendDecl, FriendNonMemberFunctionDefinitionLocation) { |
567 | LocationVerifier<FriendDecl> Verifier; |
568 | Verifier.expectLocation(Line: 2, Column: 12); |
569 | EXPECT_TRUE(Verifier.match("struct A {\n" |
570 | "friend int f() { return 0; }\n" |
571 | "};\n" , |
572 | friendDecl())); |
573 | } |
574 | |
575 | TEST(FriendDecl, FriendNonMemberFunctionDefinitionRange) { |
576 | RangeVerifier<FriendDecl> Verifier; |
577 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 28); |
578 | EXPECT_TRUE(Verifier.match("struct A {\n" |
579 | "friend int f() { return 0; }\n" |
580 | "};\n" , |
581 | friendDecl())); |
582 | } |
583 | |
584 | TEST(FriendDecl, FriendElaboratedTypeLocation) { |
585 | LocationVerifier<FriendDecl> Verifier; |
586 | Verifier.expectLocation(Line: 2, Column: 8); |
587 | EXPECT_TRUE(Verifier.match("struct A {\n" |
588 | "friend class B;\n" |
589 | "};\n" , |
590 | friendDecl())); |
591 | } |
592 | |
593 | TEST(FriendDecl, FriendElaboratedTypeRange) { |
594 | RangeVerifier<FriendDecl> Verifier; |
595 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 14); |
596 | EXPECT_TRUE(Verifier.match("struct A {\n" |
597 | "friend class B;\n" |
598 | "};\n" , |
599 | friendDecl())); |
600 | } |
601 | |
602 | TEST(FriendDecl, FriendSimpleTypeLocation) { |
603 | LocationVerifier<FriendDecl> Verifier; |
604 | Verifier.expectLocation(Line: 3, Column: 8); |
605 | EXPECT_TRUE(Verifier.match("class B;\n" |
606 | "struct A {\n" |
607 | "friend B;\n" |
608 | "};\n" , |
609 | friendDecl(), Lang_CXX11)); |
610 | } |
611 | |
612 | TEST(FriendDecl, FriendSimpleTypeRange) { |
613 | RangeVerifier<FriendDecl> Verifier; |
614 | Verifier.expectRange(BeginLine: 3, BeginColumn: 1, EndLine: 3, EndColumn: 8); |
615 | EXPECT_TRUE(Verifier.match("class B;\n" |
616 | "struct A {\n" |
617 | "friend B;\n" |
618 | "};\n" , |
619 | friendDecl(), Lang_CXX11)); |
620 | } |
621 | |
622 | TEST(FriendDecl, FriendTemplateParameterLocation) { |
623 | LocationVerifier<FriendDecl> Verifier; |
624 | Verifier.expectLocation(Line: 3, Column: 8); |
625 | EXPECT_TRUE(Verifier.match("template <typename T>\n" |
626 | "struct A {\n" |
627 | "friend T;\n" |
628 | "};\n" , |
629 | friendDecl(), Lang_CXX11)); |
630 | } |
631 | |
632 | TEST(FriendDecl, FriendTemplateParameterRange) { |
633 | RangeVerifier<FriendDecl> Verifier; |
634 | Verifier.expectRange(BeginLine: 3, BeginColumn: 1, EndLine: 3, EndColumn: 8); |
635 | EXPECT_TRUE(Verifier.match("template <typename T>\n" |
636 | "struct A {\n" |
637 | "friend T;\n" |
638 | "};\n" , |
639 | friendDecl(), Lang_CXX11)); |
640 | } |
641 | |
642 | TEST(FriendDecl, FriendDecltypeLocation) { |
643 | LocationVerifier<FriendDecl> Verifier; |
644 | Verifier.expectLocation(Line: 4, Column: 8); |
645 | EXPECT_TRUE(Verifier.match("struct A;\n" |
646 | "A foo();\n" |
647 | "struct A {\n" |
648 | "friend decltype(foo());\n" |
649 | "};\n" , |
650 | friendDecl(), Lang_CXX11)); |
651 | } |
652 | |
653 | TEST(FriendDecl, FriendDecltypeRange) { |
654 | RangeVerifier<FriendDecl> Verifier; |
655 | Verifier.expectRange(BeginLine: 4, BeginColumn: 1, EndLine: 4, EndColumn: 22); |
656 | EXPECT_TRUE(Verifier.match("struct A;\n" |
657 | "A foo();\n" |
658 | "struct A {\n" |
659 | "friend decltype(foo());\n" |
660 | "};\n" , |
661 | friendDecl(), Lang_CXX11)); |
662 | } |
663 | |
664 | TEST(FriendDecl, FriendConstructorDestructorLocation) { |
665 | const std::string Code = "struct B {\n" |
666 | "B();\n" |
667 | "~B();\n" |
668 | "};\n" |
669 | "struct A {\n" |
670 | "friend B::B(), B::~B();\n" |
671 | "};\n" ; |
672 | LocationVerifier<FriendDecl> ConstructorVerifier; |
673 | ConstructorVerifier.expectLocation(Line: 6, Column: 11); |
674 | EXPECT_TRUE(ConstructorVerifier.match( |
675 | Code, friendDecl(has(cxxConstructorDecl(ofClass(hasName("B" ))))))); |
676 | LocationVerifier<FriendDecl> DestructorVerifier; |
677 | DestructorVerifier.expectLocation(Line: 6, Column: 19); |
678 | EXPECT_TRUE(DestructorVerifier.match( |
679 | Code, friendDecl(has(cxxDestructorDecl(ofClass(hasName("B" ))))))); |
680 | } |
681 | |
682 | TEST(FriendDecl, FriendConstructorDestructorRange) { |
683 | const std::string Code = "struct B {\n" |
684 | "B();\n" |
685 | "~B();\n" |
686 | "};\n" |
687 | "struct A {\n" |
688 | "friend B::B(), B::~B();\n" |
689 | "};\n" ; |
690 | RangeVerifier<FriendDecl> ConstructorVerifier; |
691 | ConstructorVerifier.expectRange(BeginLine: 6, BeginColumn: 1, EndLine: 6, EndColumn: 13); |
692 | EXPECT_TRUE(ConstructorVerifier.match( |
693 | Code, friendDecl(has(cxxConstructorDecl(ofClass(hasName("B" ))))))); |
694 | RangeVerifier<FriendDecl> DestructorVerifier; |
695 | DestructorVerifier.expectRange(BeginLine: 6, BeginColumn: 1, EndLine: 6, EndColumn: 22); |
696 | EXPECT_TRUE(DestructorVerifier.match( |
697 | Code, friendDecl(has(cxxDestructorDecl(ofClass(hasName("B" ))))))); |
698 | } |
699 | |
700 | TEST(FriendDecl, FriendTemplateFunctionLocation) { |
701 | LocationVerifier<FriendDecl> Verifier; |
702 | Verifier.expectLocation(Line: 3, Column: 13); |
703 | EXPECT_TRUE(Verifier.match("struct A {\n" |
704 | "template <typename T>\n" |
705 | "friend void f();\n" |
706 | "};\n" , |
707 | friendDecl())); |
708 | } |
709 | |
710 | TEST(FriendDecl, FriendTemplateFunctionRange) { |
711 | RangeVerifier<FriendDecl> Verifier; |
712 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 3, EndColumn: 15); |
713 | EXPECT_TRUE(Verifier.match("struct A {\n" |
714 | "template <typename T>\n" |
715 | "friend void f();\n" |
716 | "};\n" , |
717 | friendDecl())); |
718 | } |
719 | |
720 | TEST(FriendDecl, FriendTemplateClassLocation) { |
721 | LocationVerifier<FriendDecl> Verifier; |
722 | Verifier.expectLocation(Line: 3, Column: 14); |
723 | EXPECT_TRUE(Verifier.match("struct A {\n" |
724 | "template <typename T>\n" |
725 | "friend class B;\n" |
726 | "};\n" , |
727 | friendDecl())); |
728 | } |
729 | |
730 | TEST(FriendDecl, FriendTemplateClassRange) { |
731 | RangeVerifier<FriendDecl> Verifier; |
732 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 3, EndColumn: 14); |
733 | EXPECT_TRUE(Verifier.match("struct A {\n" |
734 | "template <typename T>\n" |
735 | "friend class B;\n" |
736 | "};\n" , |
737 | friendDecl())); |
738 | } |
739 | |
740 | TEST(FriendDecl, FriendInlineFunctionLocation) { |
741 | LocationVerifier<FriendDecl> Verifier; |
742 | Verifier.expectLocation(Line: 2, Column: 19); |
743 | EXPECT_TRUE(Verifier.match("struct A {\n" |
744 | "int inline friend f() { return 0; }" |
745 | "};\n" , |
746 | friendDecl())); |
747 | } |
748 | |
749 | TEST(FriendDecl, FriendInlineFunctionRange) { |
750 | RangeVerifier<FriendDecl> Verifier; |
751 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 35); |
752 | EXPECT_TRUE(Verifier.match("struct A {\n" |
753 | "int inline friend f() { return 0; }" |
754 | "};\n" , |
755 | friendDecl(), Lang_CXX11)); |
756 | } |
757 | |
758 | TEST(FriendDecl, InstantiationSourceRange) { |
759 | RangeVerifier<FriendDecl> Verifier; |
760 | Verifier.expectRange(BeginLine: 4, BeginColumn: 3, EndLine: 4, EndColumn: 35); |
761 | EXPECT_TRUE(Verifier.match( |
762 | "template <typename T> class S;\n" |
763 | "template<class T> void operator+(S<T> x);\n" |
764 | "template<class T> struct S {\n" |
765 | " friend void operator+<>(S<T> src);\n" |
766 | "};\n" |
767 | "void test(S<double> s) { +s; }" , |
768 | friendDecl(hasParent(cxxRecordDecl(isTemplateInstantiation()))))); |
769 | } |
770 | |
771 | TEST(ObjCMessageExpr, ParenExprRange) { |
772 | RangeVerifier<ParenExpr> Verifier; |
773 | Verifier.expectRange(BeginLine: 5, BeginColumn: 25, EndLine: 5, EndColumn: 27); |
774 | EXPECT_TRUE(Verifier.match("struct A { int a; };\n" |
775 | "@interface B {}\n" |
776 | "+ (void) f1: (A)arg;\n" |
777 | "@end\n" |
778 | "void f2() { A a; [B f1: (a)]; }\n" , |
779 | traverse(TK_AsIs, parenExpr()), Lang_OBJCXX)); |
780 | } |
781 | |
782 | TEST(FunctionDecl, FunctionDeclWithThrowSpecification) { |
783 | RangeVerifier<FunctionDecl> Verifier; |
784 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 16); |
785 | EXPECT_TRUE(Verifier.match( |
786 | "void f() throw();\n" , |
787 | functionDecl())); |
788 | } |
789 | |
790 | TEST(FunctionDecl, FunctionDeclWithNoExceptSpecification) { |
791 | RangeVerifier<FunctionDecl> Verifier; |
792 | Verifier.expectRange(BeginLine: 1, BeginColumn: 1, EndLine: 1, EndColumn: 24); |
793 | EXPECT_TRUE(Verifier.match("void f() noexcept(false);\n" , functionDecl(), |
794 | Lang_CXX11)); |
795 | } |
796 | |
797 | class FunctionDeclParametersRangeVerifier : public RangeVerifier<FunctionDecl> { |
798 | protected: |
799 | SourceRange getRange(const FunctionDecl &Function) override { |
800 | return Function.getParametersSourceRange(); |
801 | } |
802 | }; |
803 | |
804 | TEST(FunctionDeclParameters, FunctionDeclOnlyVariadic) { |
805 | FunctionDeclParametersRangeVerifier Verifier; |
806 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 8); |
807 | EXPECT_TRUE(Verifier.match("void f(...);\n" , functionDecl())); |
808 | } |
809 | |
810 | TEST(FunctionDeclParameters, FunctionDeclVariadic) { |
811 | FunctionDeclParametersRangeVerifier Verifier; |
812 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 15); |
813 | EXPECT_TRUE(Verifier.match("void f(int a, ...);\n" , functionDecl())); |
814 | } |
815 | |
816 | TEST(FunctionDeclParameters, FunctionDeclMacroVariadic) { |
817 | FunctionDeclParametersRangeVerifier Verifier; |
818 | Verifier.expectRange(BeginLine: 2, BeginColumn: 8, EndLine: 1, EndColumn: 18); |
819 | EXPECT_TRUE(Verifier.match("#define VARIADIC ...\n" |
820 | "void f(int a, VARIADIC);\n" , |
821 | functionDecl())); |
822 | } |
823 | |
824 | TEST(FunctionDeclParameters, FunctionDeclMacroParams) { |
825 | FunctionDeclParametersRangeVerifier Verifier; |
826 | Verifier.expectRange(BeginLine: 1, BeginColumn: 16, EndLine: 2, EndColumn: 20); |
827 | EXPECT_TRUE(Verifier.match("#define PARAMS int a, int b\n" |
828 | "void f(PARAMS, int c);" , |
829 | functionDecl())); |
830 | } |
831 | |
832 | TEST(FunctionDeclParameters, FunctionDeclSingleParameter) { |
833 | FunctionDeclParametersRangeVerifier Verifier; |
834 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 12); |
835 | EXPECT_TRUE(Verifier.match("void f(int a);\n" , functionDecl())); |
836 | } |
837 | |
838 | TEST(FunctionDeclParameters, MemberFunctionDecl) { |
839 | FunctionDeclParametersRangeVerifier Verifier; |
840 | Verifier.expectRange(BeginLine: 2, BeginColumn: 8, EndLine: 2, EndColumn: 12); |
841 | EXPECT_TRUE(Verifier.match("class A{\n" |
842 | "void f(int a);\n" |
843 | "};" , |
844 | functionDecl())); |
845 | } |
846 | |
847 | TEST(FunctionDeclParameters, MemberFunctionDeclVariadic) { |
848 | FunctionDeclParametersRangeVerifier Verifier; |
849 | Verifier.expectRange(BeginLine: 2, BeginColumn: 8, EndLine: 2, EndColumn: 15); |
850 | EXPECT_TRUE(Verifier.match("class A{\n" |
851 | "void f(int a, ...);\n" |
852 | "};" , |
853 | functionDecl())); |
854 | } |
855 | |
856 | TEST(FunctionDeclParameters, StaticFunctionDecl) { |
857 | FunctionDeclParametersRangeVerifier Verifier; |
858 | Verifier.expectRange(BeginLine: 2, BeginColumn: 15, EndLine: 2, EndColumn: 19); |
859 | EXPECT_TRUE(Verifier.match("class A{\n" |
860 | "static void f(int a);\n" |
861 | "};" , |
862 | functionDecl())); |
863 | } |
864 | |
865 | TEST(FunctionDeclParameters, FunctionDeclMultipleParameters) { |
866 | FunctionDeclParametersRangeVerifier Verifier; |
867 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 28); |
868 | EXPECT_TRUE( |
869 | Verifier.match("void f(int a, int b, char *c);\n" , functionDecl())); |
870 | } |
871 | |
872 | TEST(FunctionDeclParameters, FunctionDeclWithDefaultValue) { |
873 | FunctionDeclParametersRangeVerifier Verifier; |
874 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 16); |
875 | EXPECT_TRUE(Verifier.match("void f(int a = 5);\n" , functionDecl())); |
876 | } |
877 | |
878 | TEST(FunctionDeclParameters, FunctionDeclWithVolatile) { |
879 | FunctionDeclParametersRangeVerifier Verifier; |
880 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 22); |
881 | EXPECT_TRUE(Verifier.match("void f(volatile int *i);" , functionDecl())); |
882 | } |
883 | |
884 | TEST(FunctionDeclParameters, FunctionDeclWithConstParam) { |
885 | FunctionDeclParametersRangeVerifier Verifier; |
886 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 19); |
887 | EXPECT_TRUE(Verifier.match("void f(const int *i);" , functionDecl())); |
888 | } |
889 | |
890 | TEST(FunctionDeclParameters, FunctionDeclWithConstVolatileParam) { |
891 | FunctionDeclParametersRangeVerifier Verifier; |
892 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 28); |
893 | EXPECT_TRUE(Verifier.match("void f(const volatile int *i);" , functionDecl())); |
894 | } |
895 | |
896 | TEST(FunctionDeclParameters, FunctionDeclWithParamAttribute) { |
897 | FunctionDeclParametersRangeVerifier Verifier; |
898 | Verifier.expectRange(BeginLine: 1, BeginColumn: 8, EndLine: 1, EndColumn: 36); |
899 | EXPECT_TRUE(Verifier.match("void f(__attribute__((unused)) int a) {}" , |
900 | functionDecl())); |
901 | } |
902 | |
903 | TEST(CXXMethodDecl, CXXMethodDeclWithThrowSpecification) { |
904 | RangeVerifier<FunctionDecl> Verifier; |
905 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 16); |
906 | EXPECT_TRUE(Verifier.match( |
907 | "class A {\n" |
908 | "void f() throw();\n" |
909 | "};\n" , |
910 | functionDecl())); |
911 | } |
912 | |
913 | TEST(CXXMethodDecl, CXXMethodDeclWithNoExceptSpecification) { |
914 | RangeVerifier<FunctionDecl> Verifier; |
915 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 24); |
916 | EXPECT_TRUE(Verifier.match("class A {\n" |
917 | "void f() noexcept(false);\n" |
918 | "};\n" , |
919 | functionDecl(), Lang_CXX11)); |
920 | } |
921 | |
922 | class ExceptionSpecRangeVerifier : public RangeVerifier<TypeLoc> { |
923 | protected: |
924 | SourceRange getRange(const TypeLoc &Node) override { |
925 | auto T = |
926 | Node.getUnqualifiedLoc().castAs<FunctionProtoTypeLoc>(); |
927 | assert(!T.isNull()); |
928 | return T.getExceptionSpecRange(); |
929 | } |
930 | }; |
931 | |
932 | class ParmVarExceptionSpecRangeVerifier : public RangeVerifier<ParmVarDecl> { |
933 | protected: |
934 | SourceRange getRange(const ParmVarDecl &Node) override { |
935 | if (const TypeSourceInfo *TSI = Node.getTypeSourceInfo()) { |
936 | TypeLoc TL = TSI->getTypeLoc(); |
937 | if (TL.getType()->isPointerType()) { |
938 | TL = TL.getNextTypeLoc().IgnoreParens(); |
939 | if (auto FPTL = TL.getAs<FunctionProtoTypeLoc>()) { |
940 | return FPTL.getExceptionSpecRange(); |
941 | } |
942 | } |
943 | } |
944 | return SourceRange(); |
945 | } |
946 | }; |
947 | |
948 | TEST(FunctionDecl, ExceptionSpecifications) { |
949 | ExceptionSpecRangeVerifier Verifier; |
950 | |
951 | Verifier.expectRange(BeginLine: 1, BeginColumn: 10, EndLine: 1, EndColumn: 16); |
952 | EXPECT_TRUE(Verifier.match("void f() throw();\n" , loc(functionType()))); |
953 | |
954 | Verifier.expectRange(BeginLine: 1, BeginColumn: 10, EndLine: 1, EndColumn: 34); |
955 | EXPECT_TRUE(Verifier.match("void f() throw(void(void) throw());\n" , |
956 | loc(functionType()))); |
957 | |
958 | Verifier.expectRange(BeginLine: 1, BeginColumn: 10, EndLine: 1, EndColumn: 19); |
959 | std::vector<std::string> Args; |
960 | Args.push_back(x: "-fms-extensions" ); |
961 | EXPECT_TRUE(Verifier.match("void f() throw(...);\n" , loc(functionType()), |
962 | Args, Lang_CXX03)); |
963 | |
964 | Verifier.expectRange(BeginLine: 1, BeginColumn: 10, EndLine: 1, EndColumn: 10); |
965 | EXPECT_TRUE( |
966 | Verifier.match("void f() noexcept;\n" , loc(functionType()), Lang_CXX11)); |
967 | |
968 | Verifier.expectRange(BeginLine: 1, BeginColumn: 10, EndLine: 1, EndColumn: 24); |
969 | EXPECT_TRUE(Verifier.match("void f() noexcept(false);\n" , loc(functionType()), |
970 | Lang_CXX11)); |
971 | |
972 | Verifier.expectRange(BeginLine: 1, BeginColumn: 10, EndLine: 1, EndColumn: 32); |
973 | EXPECT_TRUE(Verifier.match("void f() noexcept(noexcept(1+1));\n" , |
974 | loc(functionType()), Lang_CXX11)); |
975 | |
976 | ParmVarExceptionSpecRangeVerifier Verifier2; |
977 | Verifier2.expectRange(BeginLine: 1, BeginColumn: 25, EndLine: 1, EndColumn: 31); |
978 | EXPECT_TRUE(Verifier2.match("void g(void (*fp)(void) throw());\n" , |
979 | parmVarDecl(hasType(pointerType(pointee( |
980 | parenType(innerType(functionType())))))))); |
981 | |
982 | Verifier2.expectRange(BeginLine: 1, BeginColumn: 25, EndLine: 1, EndColumn: 38); |
983 | EXPECT_TRUE(Verifier2.match("void g(void (*fp)(void) noexcept(true));\n" , |
984 | parmVarDecl(hasType(pointerType(pointee( |
985 | parenType(innerType(functionType())))))), |
986 | Lang_CXX11)); |
987 | } |
988 | |
989 | TEST(Decl, MemberPointerStarLoc) { |
990 | llvm::Annotations Example(R"cpp( |
991 | struct X {}; |
992 | int X::$star^* a; |
993 | )cpp" ); |
994 | |
995 | auto AST = tooling::buildASTFromCode(Code: Example.code()); |
996 | SourceManager &SM = AST->getSourceManager(); |
997 | auto &Ctx = AST->getASTContext(); |
998 | |
999 | auto *VD = selectFirst<VarDecl>(BoundTo: "vd" , Results: match(Matcher: varDecl().bind(ID: "vd" ), Context&: Ctx)); |
1000 | ASSERT_TRUE(VD != nullptr); |
1001 | |
1002 | auto TL = |
1003 | VD->getTypeSourceInfo()->getTypeLoc().castAs<MemberPointerTypeLoc>(); |
1004 | ASSERT_EQ(SM.getFileOffset(TL.getStarLoc()), Example.point("star" )); |
1005 | } |
1006 | |
1007 | class AutoTypeLocConceptReferenceRangeVerifier |
1008 | : public RangeVerifier<AutoTypeLoc> { |
1009 | protected: |
1010 | SourceRange getRange(const AutoTypeLoc &Node) override { |
1011 | if (const ConceptReference *ConceptRef = Node.getConceptReference()) { |
1012 | return ConceptRef->getSourceRange(); |
1013 | } |
1014 | return SourceRange(); |
1015 | } |
1016 | }; |
1017 | |
1018 | TEST(LocationVerifier, AutoTypeLocConceptReference) { |
1019 | AutoTypeLocConceptReferenceRangeVerifier Verifier; |
1020 | |
1021 | const char *Code = |
1022 | R"cpp(template <typename T> concept CCC = true; |
1023 | CCC auto abc(); |
1024 | )cpp" ; |
1025 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 1); |
1026 | EXPECT_TRUE(Verifier.match(Code, typeLoc(loc(autoType())), Lang_CXX20)); |
1027 | |
1028 | const char *Code2 = |
1029 | R"cpp(template <typename T, int> concept CCC = true; |
1030 | CCC<10> auto abc(); |
1031 | )cpp" ; |
1032 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 7); |
1033 | EXPECT_TRUE(Verifier.match(Code2, typeLoc(loc(autoType())), Lang_CXX20)); |
1034 | |
1035 | const char *Code3 = |
1036 | R"cpp(namespace NS { |
1037 | template <typename T, int> concept CCC = true; |
1038 | } |
1039 | NS::CCC<10> auto abc(); |
1040 | )cpp" ; |
1041 | Verifier.expectRange(BeginLine: 4, BeginColumn: 1, EndLine: 4, EndColumn: 11); |
1042 | EXPECT_TRUE(Verifier.match(Code3, typeLoc(loc(autoType())), Lang_CXX20)); |
1043 | |
1044 | const char *Code4 = |
1045 | R"cpp(template <typename T> concept CCC = true; |
1046 | CCC<> auto abc(); |
1047 | )cpp" ; |
1048 | Verifier.expectRange(BeginLine: 2, BeginColumn: 1, EndLine: 2, EndColumn: 5); |
1049 | EXPECT_TRUE(Verifier.match(Code4, typeLoc(loc(autoType())), Lang_CXX20)); |
1050 | } |
1051 | |
1052 | class TemplateTypeParmDeclConceptReferenceRangeVerifier |
1053 | : public RangeVerifier<TemplateTypeParmDecl> { |
1054 | protected: |
1055 | SourceRange getRange(const TemplateTypeParmDecl &Node) override { |
1056 | if (const TypeConstraint *TC = Node.getTypeConstraint()) { |
1057 | if (const ConceptReference *ConceptRef = TC->getConceptReference()) { |
1058 | return ConceptRef->getSourceRange(); |
1059 | } |
1060 | } |
1061 | return SourceRange(); |
1062 | } |
1063 | }; |
1064 | |
1065 | TEST(LocationVerifier, TemplateTypeParmDeclConceptReference) { |
1066 | TemplateTypeParmDeclConceptReferenceRangeVerifier Verifier; |
1067 | |
1068 | const char *Code = |
1069 | R"cpp(template <typename S> concept CCC = true; |
1070 | template <CCC T> void print(T object); |
1071 | )cpp" ; |
1072 | Verifier.expectRange(BeginLine: 2, BeginColumn: 11, EndLine: 2, EndColumn: 11); |
1073 | EXPECT_TRUE(Verifier.match(Code, templateTypeParmDecl(), Lang_CXX20)); |
1074 | |
1075 | const char *Code2 = |
1076 | R"cpp(template <typename S, typename T> concept CCC = true; |
1077 | template <CCC<int> T> void print(T object); |
1078 | )cpp" ; |
1079 | Verifier.expectRange(BeginLine: 2, BeginColumn: 11, EndLine: 2, EndColumn: 18); |
1080 | EXPECT_TRUE(Verifier.match(Code2, templateTypeParmDecl(), Lang_CXX20)); |
1081 | |
1082 | const char *Code3 = |
1083 | R"cpp(namespace X { |
1084 | template <typename S, typename T> concept CCC = true; |
1085 | } |
1086 | template <X::CCC<int> T> void print(T object); |
1087 | )cpp" ; |
1088 | Verifier.expectRange(BeginLine: 4, BeginColumn: 11, EndLine: 4, EndColumn: 21); |
1089 | EXPECT_TRUE(Verifier.match(Code3, templateTypeParmDecl(), Lang_CXX20)); |
1090 | } |
1091 | |
1092 | class ConceptSpecializationExprConceptReferenceRangeVerifier |
1093 | : public RangeVerifier<VarTemplateDecl> { |
1094 | protected: |
1095 | SourceRange getRange(const VarTemplateDecl &Node) override { |
1096 | assert(Node.hasAssociatedConstraints()); |
1097 | SmallVector<const Expr *, 3> ACs; |
1098 | Node.getAssociatedConstraints(ACs); |
1099 | for (const Expr *Constraint : ACs) { |
1100 | if (const ConceptSpecializationExpr *CSConstraint = |
1101 | dyn_cast<ConceptSpecializationExpr>(Val: Constraint)) { |
1102 | return CSConstraint->getConceptReference()->getSourceRange(); |
1103 | } |
1104 | } |
1105 | return SourceRange(); |
1106 | } |
1107 | }; |
1108 | |
1109 | const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl> |
1110 | varTemplateDecl; |
1111 | |
1112 | TEST(LocationVerifier, ConceptSpecializationExprConceptReference) { |
1113 | ConceptSpecializationExprConceptReferenceRangeVerifier Verifier; |
1114 | |
1115 | const char *Code = |
1116 | R"cpp(template <int X> concept CCC = true; |
1117 | template <int X> requires CCC<X> int z = X; |
1118 | )cpp" ; |
1119 | Verifier.expectRange(BeginLine: 2, BeginColumn: 27, EndLine: 2, EndColumn: 32); |
1120 | EXPECT_TRUE(Verifier.match(Code, varTemplateDecl(hasName("z" )), Lang_CXX20)); |
1121 | |
1122 | const char *Code2 = |
1123 | R"cpp(namespace NS { |
1124 | template <int X> concept CCC = true; |
1125 | } |
1126 | template <int X> requires NS::CCC<X> int z = X; |
1127 | )cpp" ; |
1128 | Verifier.expectRange(BeginLine: 4, BeginColumn: 27, EndLine: 4, EndColumn: 36); |
1129 | EXPECT_TRUE(Verifier.match(Code2, varTemplateDecl(hasName("z" )), Lang_CXX20)); |
1130 | } |
1131 | |
1132 | } // end namespace |
1133 | |