1 //===- unittest/Tooling/SourceCodeTest.cpp --------------------------------===// 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 #include "clang/Tooling/Transformer/SourceCode.h" 10 #include "TestVisitor.h" 11 #include "clang/Basic/Diagnostic.h" 12 #include "clang/Basic/SourceLocation.h" 13 #include "clang/Lex/Lexer.h" 14 #include "llvm/Testing/Support/Annotations.h" 15 #include "llvm/Testing/Support/Error.h" 16 #include "llvm/Testing/Support/SupportHelpers.h" 17 #include <gmock/gmock.h> 18 #include <gtest/gtest.h> 19 20 using namespace clang; 21 22 using llvm::Failed; 23 using llvm::Succeeded; 24 using llvm::ValueIs; 25 using tooling::getAssociatedRange; 26 using tooling::getExtendedRange; 27 using tooling::getExtendedText; 28 using tooling::getRangeForEdit; 29 using tooling::getText; 30 using tooling::maybeExtendRange; 31 using tooling::validateEditRange; 32 33 namespace { 34 35 struct IntLitVisitor : TestVisitor<IntLitVisitor> { 36 bool VisitIntegerLiteral(IntegerLiteral *Expr) { 37 OnIntLit(Expr, Context); 38 return true; 39 } 40 41 std::function<void(IntegerLiteral *, ASTContext *Context)> OnIntLit; 42 }; 43 44 struct CallsVisitor : TestVisitor<CallsVisitor> { 45 bool VisitCallExpr(CallExpr *Expr) { 46 OnCall(Expr, Context); 47 return true; 48 } 49 50 std::function<void(CallExpr *, ASTContext *Context)> OnCall; 51 }; 52 53 // Equality matcher for `clang::CharSourceRange`, which lacks `operator==`. 54 MATCHER_P(EqualsRange, R, "") { 55 return arg.isTokenRange() == R.isTokenRange() && 56 arg.getBegin() == R.getBegin() && arg.getEnd() == R.getEnd(); 57 } 58 59 MATCHER_P2(EqualsAnnotatedRange, Context, R, "") { 60 if (arg.getBegin().isMacroID()) { 61 *result_listener << "which starts in a macro"; 62 return false; 63 } 64 if (arg.getEnd().isMacroID()) { 65 *result_listener << "which ends in a macro"; 66 return false; 67 } 68 69 CharSourceRange Range = Lexer::getAsCharRange( 70 arg, Context->getSourceManager(), Context->getLangOpts()); 71 unsigned Begin = Context->getSourceManager().getFileOffset(Range.getBegin()); 72 unsigned End = Context->getSourceManager().getFileOffset(Range.getEnd()); 73 74 *result_listener << "which is a " << (arg.isTokenRange() ? "Token" : "Char") 75 << " range [" << Begin << "," << End << ")"; 76 return Begin == R.Begin && End == R.End; 77 } 78 79 static ::testing::Matcher<CharSourceRange> AsRange(const SourceManager &SM, 80 llvm::Annotations::Range R) { 81 return EqualsRange(CharSourceRange::getCharRange( 82 SM.getLocForStartOfFile(SM.getMainFileID()).getLocWithOffset(R.Begin), 83 SM.getLocForStartOfFile(SM.getMainFileID()).getLocWithOffset(R.End))); 84 } 85 86 // Base class for visitors that expect a single match corresponding to a 87 // specific annotated range. 88 template <typename T> class AnnotatedCodeVisitor : public TestVisitor<T> { 89 protected: 90 int MatchCount = 0; 91 llvm::Annotations Code; 92 93 public: 94 AnnotatedCodeVisitor() : Code("$r[[]]") {} 95 // Helper for tests of `getAssociatedRange`. 96 bool VisitDeclHelper(Decl *Decl) { 97 // Only consider explicit declarations. 98 if (Decl->isImplicit()) 99 return true; 100 101 ++MatchCount; 102 EXPECT_THAT(getAssociatedRange(*Decl, *this->Context), 103 EqualsAnnotatedRange(this->Context, Code.range("r"))) 104 << Code.code(); 105 return true; 106 } 107 108 bool runOverAnnotated(llvm::StringRef AnnotatedCode, 109 std::vector<std::string> Args = {}) { 110 Code = llvm::Annotations(AnnotatedCode); 111 MatchCount = 0; 112 Args.push_back("-std=c++11"); 113 Args.push_back("-fno-delayed-template-parsing"); 114 bool result = tooling::runToolOnCodeWithArgs(this->CreateTestAction(), 115 Code.code(), Args); 116 EXPECT_EQ(MatchCount, 1) << AnnotatedCode; 117 return result; 118 } 119 }; 120 121 TEST(SourceCodeTest, getText) { 122 CallsVisitor Visitor; 123 124 Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) { 125 EXPECT_EQ("foo(x, y)", getText(*CE, *Context)); 126 }; 127 Visitor.runOver("void foo(int x, int y) { foo(x, y); }"); 128 129 Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) { 130 EXPECT_EQ("APPLY(foo, x, y)", getText(*CE, *Context)); 131 }; 132 Visitor.runOver("#define APPLY(f, x, y) f(x, y)\n" 133 "void foo(int x, int y) { APPLY(foo, x, y); }"); 134 } 135 136 TEST(SourceCodeTest, getTextWithMacro) { 137 CallsVisitor Visitor; 138 139 Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) { 140 EXPECT_EQ("F OO", getText(*CE, *Context)); 141 Expr *P0 = CE->getArg(0); 142 Expr *P1 = CE->getArg(1); 143 EXPECT_EQ("", getText(*P0, *Context)); 144 EXPECT_EQ("", getText(*P1, *Context)); 145 }; 146 Visitor.runOver("#define F foo(\n" 147 "#define OO x, y)\n" 148 "void foo(int x, int y) { F OO ; }"); 149 150 Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) { 151 EXPECT_EQ("", getText(*CE, *Context)); 152 Expr *P0 = CE->getArg(0); 153 Expr *P1 = CE->getArg(1); 154 EXPECT_EQ("x", getText(*P0, *Context)); 155 EXPECT_EQ("y", getText(*P1, *Context)); 156 }; 157 Visitor.runOver("#define FOO(x, y) (void)x; (void)y; foo(x, y);\n" 158 "void foo(int x, int y) { FOO(x,y) }"); 159 } 160 161 TEST(SourceCodeTest, getExtendedText) { 162 CallsVisitor Visitor; 163 164 Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) { 165 EXPECT_EQ("foo(x, y);", 166 getExtendedText(*CE, tok::TokenKind::semi, *Context)); 167 168 Expr *P0 = CE->getArg(0); 169 Expr *P1 = CE->getArg(1); 170 EXPECT_EQ("x", getExtendedText(*P0, tok::TokenKind::semi, *Context)); 171 EXPECT_EQ("x,", getExtendedText(*P0, tok::TokenKind::comma, *Context)); 172 EXPECT_EQ("y", getExtendedText(*P1, tok::TokenKind::semi, *Context)); 173 }; 174 Visitor.runOver("void foo(int x, int y) { foo(x, y); }"); 175 Visitor.runOver("void foo(int x, int y) { if (true) foo(x, y); }"); 176 Visitor.runOver("int foo(int x, int y) { if (true) return 3 + foo(x, y); }"); 177 Visitor.runOver("void foo(int x, int y) { for (foo(x, y);;) ++x; }"); 178 Visitor.runOver( 179 "bool foo(int x, int y) { for (;foo(x, y);) x = 1; return true; }"); 180 181 Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) { 182 EXPECT_EQ("foo()", getExtendedText(*CE, tok::TokenKind::semi, *Context)); 183 }; 184 Visitor.runOver("bool foo() { if (foo()) return true; return false; }"); 185 Visitor.runOver("void foo() { int x; for (;; foo()) ++x; }"); 186 Visitor.runOver("int foo() { return foo() + 3; }"); 187 } 188 189 TEST(SourceCodeTest, maybeExtendRange_TokenRange) { 190 struct ExtendTokenRangeVisitor 191 : AnnotatedCodeVisitor<ExtendTokenRangeVisitor> { 192 bool VisitCallExpr(CallExpr *CE) { 193 ++MatchCount; 194 EXPECT_THAT(getExtendedRange(*CE, tok::TokenKind::semi, *Context), 195 EqualsAnnotatedRange(Context, Code.range("r"))); 196 return true; 197 } 198 }; 199 200 ExtendTokenRangeVisitor Visitor; 201 // Extends to include semicolon. 202 Visitor.runOverAnnotated("void f(int x, int y) { $r[[f(x, y);]] }"); 203 // Does not extend to include semicolon. 204 Visitor.runOverAnnotated( 205 "int f(int x, int y) { if (0) return $r[[f(x, y)]] + 3; }"); 206 } 207 208 TEST(SourceCodeTest, maybeExtendRange_CharRange) { 209 struct ExtendCharRangeVisitor : AnnotatedCodeVisitor<ExtendCharRangeVisitor> { 210 bool VisitCallExpr(CallExpr *CE) { 211 ++MatchCount; 212 CharSourceRange Call = Lexer::getAsCharRange(CE->getSourceRange(), 213 Context->getSourceManager(), 214 Context->getLangOpts()); 215 EXPECT_THAT(maybeExtendRange(Call, tok::TokenKind::semi, *Context), 216 EqualsAnnotatedRange(Context, Code.range("r"))); 217 return true; 218 } 219 }; 220 ExtendCharRangeVisitor Visitor; 221 // Extends to include semicolon. 222 Visitor.runOverAnnotated("void f(int x, int y) { $r[[f(x, y);]] }"); 223 // Does not extend to include semicolon. 224 Visitor.runOverAnnotated( 225 "int f(int x, int y) { if (0) return $r[[f(x, y)]] + 3; }"); 226 } 227 228 TEST(SourceCodeTest, getAssociatedRange) { 229 struct VarDeclsVisitor : AnnotatedCodeVisitor<VarDeclsVisitor> { 230 bool VisitVarDecl(VarDecl *Decl) { return VisitDeclHelper(Decl); } 231 }; 232 VarDeclsVisitor Visitor; 233 234 // Includes semicolon. 235 Visitor.runOverAnnotated("$r[[int x = 4;]]"); 236 237 // Includes newline and semicolon. 238 Visitor.runOverAnnotated("$r[[int x = 4;\n]]"); 239 240 // Includes trailing comments. 241 Visitor.runOverAnnotated("$r[[int x = 4; // Comment\n]]"); 242 Visitor.runOverAnnotated("$r[[int x = 4; /* Comment */\n]]"); 243 244 // Does *not* include trailing comments when another entity appears between 245 // the decl and the comment. 246 Visitor.runOverAnnotated("$r[[int x = 4;]] class C {}; // Comment\n"); 247 248 // Includes attributes. 249 Visitor.runOverAnnotated(R"cpp( 250 #define ATTR __attribute__((deprecated("message"))) 251 $r[[ATTR 252 int x;]])cpp"); 253 254 // Includes attributes and comments together. 255 Visitor.runOverAnnotated(R"cpp( 256 #define ATTR __attribute__((deprecated("message"))) 257 $r[[ATTR 258 // Commment. 259 int x;]])cpp"); 260 } 261 262 TEST(SourceCodeTest, getAssociatedRangeClasses) { 263 struct RecordDeclsVisitor : AnnotatedCodeVisitor<RecordDeclsVisitor> { 264 bool VisitRecordDecl(RecordDecl *Decl) { return VisitDeclHelper(Decl); } 265 }; 266 RecordDeclsVisitor Visitor; 267 268 Visitor.runOverAnnotated("$r[[class A;]]"); 269 Visitor.runOverAnnotated("$r[[class A {};]]"); 270 271 // Includes leading template annotation. 272 Visitor.runOverAnnotated("$r[[template <typename T> class A;]]"); 273 Visitor.runOverAnnotated("$r[[template <typename T> class A {};]]"); 274 } 275 276 TEST(SourceCodeTest, getAssociatedRangeClassTemplateSpecializations) { 277 struct CXXRecordDeclsVisitor : AnnotatedCodeVisitor<CXXRecordDeclsVisitor> { 278 bool VisitCXXRecordDecl(CXXRecordDecl *Decl) { 279 return Decl->getTemplateSpecializationKind() != 280 TSK_ExplicitSpecialization || 281 VisitDeclHelper(Decl); 282 } 283 }; 284 CXXRecordDeclsVisitor Visitor; 285 286 Visitor.runOverAnnotated(R"cpp( 287 template <typename T> class A{}; 288 $r[[template <> class A<int>;]])cpp"); 289 Visitor.runOverAnnotated(R"cpp( 290 template <typename T> class A{}; 291 $r[[template <> class A<int> {};]])cpp"); 292 } 293 294 TEST(SourceCodeTest, getAssociatedRangeFunctions) { 295 struct FunctionDeclsVisitor : AnnotatedCodeVisitor<FunctionDeclsVisitor> { 296 bool VisitFunctionDecl(FunctionDecl *Decl) { return VisitDeclHelper(Decl); } 297 }; 298 FunctionDeclsVisitor Visitor; 299 300 Visitor.runOverAnnotated("$r[[int f();]]"); 301 Visitor.runOverAnnotated("$r[[int f() { return 0; }]]"); 302 // Includes leading template annotation. 303 Visitor.runOverAnnotated("$r[[template <typename T> int f();]]"); 304 Visitor.runOverAnnotated("$r[[template <typename T> int f() { return 0; }]]"); 305 } 306 307 TEST(SourceCodeTest, getAssociatedRangeMemberTemplates) { 308 struct CXXMethodDeclsVisitor : AnnotatedCodeVisitor<CXXMethodDeclsVisitor> { 309 bool VisitCXXMethodDecl(CXXMethodDecl *Decl) { 310 // Only consider the definition of the template. 311 return !Decl->doesThisDeclarationHaveABody() || VisitDeclHelper(Decl); 312 } 313 }; 314 CXXMethodDeclsVisitor Visitor; 315 316 Visitor.runOverAnnotated(R"cpp( 317 template <typename C> 318 struct A { template <typename T> int member(T v); }; 319 320 $r[[template <typename C> 321 template <typename T> 322 int A<C>::member(T v) { return 0; }]])cpp"); 323 } 324 325 TEST(SourceCodeTest, getAssociatedRangeWithComments) { 326 struct VarDeclsVisitor : AnnotatedCodeVisitor<VarDeclsVisitor> { 327 bool VisitVarDecl(VarDecl *Decl) { return VisitDeclHelper(Decl); } 328 }; 329 330 VarDeclsVisitor Visitor; 331 auto Visit = [&](llvm::StringRef AnnotatedCode) { 332 Visitor.runOverAnnotated(AnnotatedCode, {"-fparse-all-comments"}); 333 }; 334 335 // Includes leading comments. 336 Visit("$r[[// Comment.\nint x = 4;]]"); 337 Visit("$r[[// Comment.\nint x = 4;\n]]"); 338 Visit("$r[[/* Comment.*/\nint x = 4;\n]]"); 339 // ... even if separated by (extra) horizontal whitespace. 340 Visit("$r[[/* Comment.*/ \nint x = 4;\n]]"); 341 342 // Includes comments even in the presence of trailing whitespace. 343 Visit("$r[[// Comment.\nint x = 4;]] "); 344 345 // Includes comments when the declaration is followed by the beginning or end 346 // of a compound statement. 347 Visit(R"cpp( 348 void foo() { 349 $r[[/* C */ 350 int x = 4; 351 ]]};)cpp"); 352 Visit(R"cpp( 353 void foo() { 354 $r[[/* C */ 355 int x = 4; 356 ]]{ class Foo {}; } 357 })cpp"); 358 359 // Includes comments inside macros (when decl is in the same macro). 360 Visit(R"cpp( 361 #define DECL /* Comment */ int x 362 $r[[DECL;]])cpp"); 363 364 // Does not include comments when only the decl or the comment come from a 365 // macro. 366 // FIXME: Change code to allow this. 367 Visit(R"cpp( 368 #define DECL int x 369 // Comment 370 $r[[DECL;]])cpp"); 371 Visit(R"cpp( 372 #define COMMENT /* Comment */ 373 COMMENT 374 $r[[int x;]])cpp"); 375 376 // Includes multi-line comments. 377 Visit(R"cpp( 378 $r[[/* multi 379 * line 380 * comment 381 */ 382 int x;]])cpp"); 383 Visit(R"cpp( 384 $r[[// multi 385 // line 386 // comment 387 int x;]])cpp"); 388 389 // Does not include comments separated by multiple empty lines. 390 Visit("// Comment.\n\n\n$r[[int x = 4;\n]]"); 391 Visit("/* Comment.*/\n\n\n$r[[int x = 4;\n]]"); 392 393 // Does not include comments before a *series* of declarations. 394 Visit(R"cpp( 395 // Comment. 396 $r[[int x = 4; 397 ]]class foo {};)cpp"); 398 399 // Does not include IfThisThenThat comments 400 Visit("// LINT.IfChange.\n$r[[int x = 4;]]"); 401 Visit("// LINT.ThenChange.\n$r[[int x = 4;]]"); 402 403 // Includes attributes. 404 Visit(R"cpp( 405 #define ATTR __attribute__((deprecated("message"))) 406 $r[[ATTR 407 int x;]])cpp"); 408 409 // Includes attributes and comments together. 410 Visit(R"cpp( 411 #define ATTR __attribute__((deprecated("message"))) 412 $r[[ATTR 413 // Commment. 414 int x;]])cpp"); 415 } 416 417 TEST(SourceCodeTest, getAssociatedRangeInvalidForPartialExpansions) { 418 struct FailingVarDeclsVisitor : TestVisitor<FailingVarDeclsVisitor> { 419 FailingVarDeclsVisitor() {} 420 bool VisitVarDecl(VarDecl *Decl) { 421 EXPECT_TRUE(getAssociatedRange(*Decl, *Context).isInvalid()); 422 return true; 423 } 424 }; 425 426 FailingVarDeclsVisitor Visitor; 427 // Should fail because it only includes a part of the expansion. 428 std::string Code = R"cpp( 429 #define DECL class foo { }; int x 430 DECL;)cpp"; 431 Visitor.runOver(Code); 432 } 433 434 TEST(SourceCodeTest, EditRangeWithMacroExpansionsShouldSucceed) { 435 // The call expression, whose range we are extracting, includes two macro 436 // expansions. 437 llvm::Annotations Code(R"cpp( 438 #define M(a) a * 13 439 int foo(int x, int y); 440 int a = $r[[foo(M(1), M(2))]]; 441 )cpp"); 442 443 CallsVisitor Visitor; 444 445 Visitor.OnCall = [&Code](CallExpr *CE, ASTContext *Context) { 446 auto Range = CharSourceRange::getTokenRange(CE->getSourceRange()); 447 EXPECT_THAT(getRangeForEdit(Range, *Context), 448 ValueIs(AsRange(Context->getSourceManager(), Code.range("r")))); 449 }; 450 Visitor.runOver(Code.code()); 451 } 452 453 TEST(SourceCodeTest, EditWholeMacroExpansionShouldSucceed) { 454 llvm::Annotations Code(R"cpp( 455 #define FOO 10 456 int a = $r[[FOO]]; 457 )cpp"); 458 459 IntLitVisitor Visitor; 460 Visitor.OnIntLit = [&Code](IntegerLiteral *Expr, ASTContext *Context) { 461 auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange()); 462 EXPECT_THAT(getRangeForEdit(Range, *Context), 463 ValueIs(AsRange(Context->getSourceManager(), Code.range("r")))); 464 }; 465 Visitor.runOver(Code.code()); 466 } 467 468 TEST(SourceCodeTest, EditPartialMacroExpansionShouldFail) { 469 std::string Code = R"cpp( 470 #define BAR 10+ 471 int c = BAR 3.0; 472 )cpp"; 473 474 IntLitVisitor Visitor; 475 Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) { 476 auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange()); 477 EXPECT_FALSE(getRangeForEdit(Range, *Context)); 478 }; 479 Visitor.runOver(Code); 480 } 481 482 TEST(SourceCodeTest, EditWholeMacroArgShouldSucceed) { 483 llvm::Annotations Code(R"cpp( 484 #define FOO(a) a + 7.0; 485 int a = FOO($r[[10]]); 486 )cpp"); 487 488 IntLitVisitor Visitor; 489 Visitor.OnIntLit = [&Code](IntegerLiteral *Expr, ASTContext *Context) { 490 auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange()); 491 EXPECT_THAT(getRangeForEdit(Range, *Context), 492 ValueIs(AsRange(Context->getSourceManager(), Code.range("r")))); 493 }; 494 Visitor.runOver(Code.code()); 495 } 496 497 TEST(SourceCodeTest, EditPartialMacroArgShouldSucceed) { 498 llvm::Annotations Code(R"cpp( 499 #define FOO(a) a + 7.0; 500 int a = FOO($r[[10]] + 10.0); 501 )cpp"); 502 503 IntLitVisitor Visitor; 504 Visitor.OnIntLit = [&Code](IntegerLiteral *Expr, ASTContext *Context) { 505 auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange()); 506 EXPECT_THAT(getRangeForEdit(Range, *Context), 507 ValueIs(AsRange(Context->getSourceManager(), Code.range("r")))); 508 }; 509 Visitor.runOver(Code.code()); 510 } 511 512 TEST(SourceCodeTest, EditRangeWithMacroExpansionsIsValid) { 513 // The call expression, whose range we are extracting, includes two macro 514 // expansions. 515 llvm::StringRef Code = R"cpp( 516 #define M(a) a * 13 517 int foo(int x, int y); 518 int a = foo(M(1), M(2)); 519 )cpp"; 520 521 CallsVisitor Visitor; 522 523 Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) { 524 auto Range = CharSourceRange::getTokenRange(CE->getSourceRange()); 525 EXPECT_THAT_ERROR(validateEditRange(Range, Context->getSourceManager()), 526 Succeeded()); 527 }; 528 Visitor.runOver(Code); 529 } 530 531 TEST(SourceCodeTest, SpellingRangeOfMacroArgIsValid) { 532 llvm::StringRef Code = R"cpp( 533 #define FOO(a) a + 7.0; 534 int a = FOO(10); 535 )cpp"; 536 537 IntLitVisitor Visitor; 538 Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) { 539 SourceLocation ArgLoc = 540 Context->getSourceManager().getSpellingLoc(Expr->getBeginLoc()); 541 // The integer literal is a single token. 542 auto ArgRange = CharSourceRange::getTokenRange(ArgLoc); 543 EXPECT_THAT_ERROR(validateEditRange(ArgRange, Context->getSourceManager()), 544 Succeeded()); 545 }; 546 Visitor.runOver(Code); 547 } 548 549 TEST(SourceCodeTest, InvalidEditRangeIsInvalid) { 550 llvm::StringRef Code = "int c = 10;"; 551 552 // We use the visitor just to get a valid context. 553 IntLitVisitor Visitor; 554 Visitor.OnIntLit = [](IntegerLiteral *, ASTContext *Context) { 555 CharSourceRange Invalid; 556 EXPECT_THAT_ERROR(validateEditRange(Invalid, Context->getSourceManager()), 557 Failed()); 558 }; 559 Visitor.runOver(Code); 560 } 561 562 TEST(SourceCodeTest, InvertedEditRangeIsInvalid) { 563 llvm::StringRef Code = R"cpp( 564 int foo(int x); 565 int a = foo(2); 566 )cpp"; 567 568 CallsVisitor Visitor; 569 Visitor.OnCall = [](CallExpr *Expr, ASTContext *Context) { 570 auto InvertedRange = CharSourceRange::getTokenRange( 571 SourceRange(Expr->getEndLoc(), Expr->getBeginLoc())); 572 EXPECT_THAT_ERROR( 573 validateEditRange(InvertedRange, Context->getSourceManager()), 574 Failed()); 575 }; 576 Visitor.runOver(Code); 577 } 578 579 TEST(SourceCodeTest, MacroArgIsInvalid) { 580 llvm::StringRef Code = R"cpp( 581 #define FOO(a) a + 7.0; 582 int a = FOO(10); 583 )cpp"; 584 585 IntLitVisitor Visitor; 586 Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) { 587 auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange()); 588 EXPECT_THAT_ERROR(validateEditRange(Range, Context->getSourceManager()), 589 Failed()); 590 }; 591 Visitor.runOver(Code); 592 } 593 594 TEST(SourceCodeTest, EditWholeMacroExpansionIsInvalid) { 595 llvm::StringRef Code = R"cpp( 596 #define FOO 10 597 int a = FOO; 598 )cpp"; 599 600 IntLitVisitor Visitor; 601 Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) { 602 auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange()); 603 EXPECT_THAT_ERROR(validateEditRange(Range, Context->getSourceManager()), 604 Failed()); 605 606 }; 607 Visitor.runOver(Code); 608 } 609 610 TEST(SourceCodeTest, EditPartialMacroExpansionIsInvalid) { 611 llvm::StringRef Code = R"cpp( 612 #define BAR 10+ 613 int c = BAR 3.0; 614 )cpp"; 615 616 IntLitVisitor Visitor; 617 Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) { 618 auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange()); 619 EXPECT_THAT_ERROR(validateEditRange(Range, Context->getSourceManager()), 620 Failed()); 621 }; 622 Visitor.runOver(Code); 623 } 624 625 TEST(SourceCodeTest, GetCallReturnType_Dependent) { 626 llvm::Annotations Code{R"cpp( 627 template<class T, class F> 628 void templ(const T& t, F f) {} 629 630 template<class T, class F> 631 void templ1(const T& t, F f) { 632 $test1[[f(t)]]; 633 } 634 635 int f_overload(int) { return 1; } 636 int f_overload(double) { return 2; } 637 638 void f1() { 639 int i = 0; 640 templ(i, [](const auto &p) { 641 $test2[[f_overload(p)]]; 642 }); 643 } 644 645 struct A { 646 void f_overload(int); 647 void f_overload(double); 648 }; 649 650 void f2() { 651 int i = 0; 652 templ(i, [](const auto &p) { 653 A a; 654 $test3[[a.f_overload(p)]]; 655 }); 656 } 657 )cpp"}; 658 659 llvm::Annotations::Range R1 = Code.range("test1"); 660 llvm::Annotations::Range R2 = Code.range("test2"); 661 llvm::Annotations::Range R3 = Code.range("test3"); 662 663 CallsVisitor Visitor; 664 Visitor.OnCall = [&R1, &R2, &R3](CallExpr *Expr, ASTContext *Context) { 665 unsigned Begin = Context->getSourceManager().getFileOffset( 666 Expr->getSourceRange().getBegin()); 667 unsigned End = Context->getSourceManager().getFileOffset( 668 Expr->getSourceRange().getEnd()); 669 llvm::Annotations::Range R{Begin, End + 1}; 670 671 QualType CalleeType = Expr->getCallee()->getType(); 672 if (R == R1) { 673 ASSERT_TRUE(CalleeType->isDependentType()); 674 EXPECT_EQ(Expr->getCallReturnType(*Context), Context->DependentTy); 675 } else if (R == R2) { 676 ASSERT_FALSE(CalleeType->isDependentType()); 677 ASSERT_TRUE(CalleeType->isSpecificPlaceholderType(BuiltinType::Overload)); 678 ASSERT_TRUE(isa<UnresolvedLookupExpr>(Expr->getCallee())); 679 EXPECT_EQ(Expr->getCallReturnType(*Context), Context->DependentTy); 680 } else if (R == R3) { 681 ASSERT_FALSE(CalleeType->isDependentType()); 682 ASSERT_TRUE( 683 CalleeType->isSpecificPlaceholderType(BuiltinType::BoundMember)); 684 ASSERT_TRUE(isa<UnresolvedMemberExpr>(Expr->getCallee())); 685 EXPECT_EQ(Expr->getCallReturnType(*Context), Context->DependentTy); 686 } 687 }; 688 Visitor.runOver(Code.code(), CallsVisitor::Lang_CXX14); 689 } 690 691 } // end anonymous namespace 692