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