| 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(MsgStr); |
| 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<AssociatedConstraint, 3> ACs; |
| 1098 | Node.getAssociatedConstraints(ACs); |
| 1099 | for (const AssociatedConstraint &AC : ACs) { |
| 1100 | if (const ConceptSpecializationExpr *CSConstraint = |
| 1101 | dyn_cast<ConceptSpecializationExpr>(Val: AC.ConstraintExpr)) { |
| 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 | |