1 //===- unittest/AST/ASTImporterTest.cpp - AST node import test ------------===// 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 // Tests for the correct import of AST nodes from one AST context to another. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/ASTMatchers/ASTMatchers.h" 14 #include "llvm/ADT/StringMap.h" 15 #include "llvm/Support/SmallVectorMemoryBuffer.h" 16 17 #include "clang/AST/DeclContextInternals.h" 18 #include "gtest/gtest.h" 19 20 #include "ASTImporterFixtures.h" 21 22 namespace clang { 23 namespace ast_matchers { 24 25 using internal::Matcher; 26 using internal::BindableMatcher; 27 using llvm::StringMap; 28 29 static const RecordDecl *getRecordDeclOfFriend(FriendDecl *FD) { 30 QualType Ty = FD->getFriendType()->getType().getCanonicalType(); 31 return cast<RecordType>(Ty)->getDecl(); 32 } 33 34 struct ImportExpr : TestImportBase {}; 35 struct ImportType : TestImportBase {}; 36 struct ImportDecl : TestImportBase {}; 37 struct ImportFixedPointExpr : ImportExpr {}; 38 39 struct CanonicalRedeclChain : ASTImporterOptionSpecificTestBase {}; 40 41 TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers) { 42 Decl *FromTU = getTuDecl("void f();", Lang_CXX03); 43 auto Pattern = functionDecl(hasName("f")); 44 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 45 46 auto Redecls = getCanonicalForwardRedeclChain(D0); 47 ASSERT_EQ(Redecls.size(), 1u); 48 EXPECT_EQ(D0, Redecls[0]); 49 } 50 51 TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers2) { 52 Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03); 53 auto Pattern = functionDecl(hasName("f")); 54 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 55 auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 56 FunctionDecl *D1 = D2->getPreviousDecl(); 57 58 auto Redecls = getCanonicalForwardRedeclChain(D0); 59 ASSERT_EQ(Redecls.size(), 3u); 60 EXPECT_EQ(D0, Redecls[0]); 61 EXPECT_EQ(D1, Redecls[1]); 62 EXPECT_EQ(D2, Redecls[2]); 63 } 64 65 TEST_P(CanonicalRedeclChain, ShouldBeSameForAllDeclInTheChain) { 66 Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03); 67 auto Pattern = functionDecl(hasName("f")); 68 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 69 auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 70 FunctionDecl *D1 = D2->getPreviousDecl(); 71 72 auto RedeclsD0 = getCanonicalForwardRedeclChain(D0); 73 auto RedeclsD1 = getCanonicalForwardRedeclChain(D1); 74 auto RedeclsD2 = getCanonicalForwardRedeclChain(D2); 75 76 EXPECT_THAT(RedeclsD0, ::testing::ContainerEq(RedeclsD1)); 77 EXPECT_THAT(RedeclsD1, ::testing::ContainerEq(RedeclsD2)); 78 } 79 80 namespace { 81 struct RedirectingImporter : public ASTImporter { 82 using ASTImporter::ASTImporter; 83 84 protected: 85 llvm::Expected<Decl *> ImportImpl(Decl *FromD) override { 86 auto *ND = dyn_cast<NamedDecl>(FromD); 87 if (!ND || ND->getName() != "shouldNotBeImported") 88 return ASTImporter::ImportImpl(FromD); 89 for (Decl *D : getToContext().getTranslationUnitDecl()->decls()) { 90 if (auto *ND = dyn_cast<NamedDecl>(D)) 91 if (ND->getName() == "realDecl") { 92 RegisterImportedDecl(FromD, ND); 93 return ND; 94 } 95 } 96 return ASTImporter::ImportImpl(FromD); 97 } 98 }; 99 100 } // namespace 101 102 struct RedirectingImporterTest : ASTImporterOptionSpecificTestBase { 103 RedirectingImporterTest() { 104 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 105 ASTContext &FromContext, FileManager &FromFileManager, 106 bool MinimalImport, 107 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 108 return new RedirectingImporter(ToContext, ToFileManager, FromContext, 109 FromFileManager, MinimalImport, 110 SharedState); 111 }; 112 } 113 }; 114 115 // Test that an ASTImporter subclass can intercept an import call. 116 TEST_P(RedirectingImporterTest, InterceptImport) { 117 Decl *From, *To; 118 std::tie(From, To) = 119 getImportedDecl("class shouldNotBeImported {};", Lang_CXX03, 120 "class realDecl {};", Lang_CXX03, "shouldNotBeImported"); 121 auto *Imported = cast<CXXRecordDecl>(To); 122 EXPECT_EQ(Imported->getQualifiedNameAsString(), "realDecl"); 123 124 // Make sure our importer prevented the importing of the decl. 125 auto *ToTU = Imported->getTranslationUnitDecl(); 126 auto Pattern = functionDecl(hasName("shouldNotBeImported")); 127 unsigned count = 128 DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern); 129 EXPECT_EQ(0U, count); 130 } 131 132 // Test that when we indirectly import a declaration the custom ASTImporter 133 // is still intercepting the import. 134 TEST_P(RedirectingImporterTest, InterceptIndirectImport) { 135 Decl *From, *To; 136 std::tie(From, To) = 137 getImportedDecl("class shouldNotBeImported {};" 138 "class F { shouldNotBeImported f; };", 139 Lang_CXX03, "class realDecl {};", Lang_CXX03, "F"); 140 141 // Make sure our ASTImporter prevented the importing of the decl. 142 auto *ToTU = To->getTranslationUnitDecl(); 143 auto Pattern = functionDecl(hasName("shouldNotBeImported")); 144 unsigned count = 145 DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern); 146 EXPECT_EQ(0U, count); 147 } 148 149 struct ImportPath : ASTImporterOptionSpecificTestBase { 150 Decl *FromTU; 151 FunctionDecl *D0, *D1, *D2; 152 ImportPath() { 153 FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03); 154 auto Pattern = functionDecl(hasName("f")); 155 D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 156 D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 157 D1 = D2->getPreviousDecl(); 158 } 159 }; 160 161 TEST_P(ImportPath, Push) { 162 ASTImporter::ImportPathTy path; 163 path.push(D0); 164 EXPECT_FALSE(path.hasCycleAtBack()); 165 } 166 167 TEST_P(ImportPath, SmallCycle) { 168 ASTImporter::ImportPathTy path; 169 path.push(D0); 170 path.push(D0); 171 EXPECT_TRUE(path.hasCycleAtBack()); 172 path.pop(); 173 EXPECT_FALSE(path.hasCycleAtBack()); 174 path.push(D0); 175 EXPECT_TRUE(path.hasCycleAtBack()); 176 } 177 178 TEST_P(ImportPath, GetSmallCycle) { 179 ASTImporter::ImportPathTy path; 180 path.push(D0); 181 path.push(D0); 182 EXPECT_TRUE(path.hasCycleAtBack()); 183 std::array<Decl* ,2> Res; 184 int i = 0; 185 for (Decl *Di : path.getCycleAtBack()) { 186 Res[i++] = Di; 187 } 188 ASSERT_EQ(i, 2); 189 EXPECT_EQ(Res[0], D0); 190 EXPECT_EQ(Res[1], D0); 191 } 192 193 TEST_P(ImportPath, GetCycle) { 194 ASTImporter::ImportPathTy path; 195 path.push(D0); 196 path.push(D1); 197 path.push(D2); 198 path.push(D0); 199 EXPECT_TRUE(path.hasCycleAtBack()); 200 std::array<Decl* ,4> Res; 201 int i = 0; 202 for (Decl *Di : path.getCycleAtBack()) { 203 Res[i++] = Di; 204 } 205 ASSERT_EQ(i, 4); 206 EXPECT_EQ(Res[0], D0); 207 EXPECT_EQ(Res[1], D2); 208 EXPECT_EQ(Res[2], D1); 209 EXPECT_EQ(Res[3], D0); 210 } 211 212 TEST_P(ImportPath, CycleAfterCycle) { 213 ASTImporter::ImportPathTy path; 214 path.push(D0); 215 path.push(D1); 216 path.push(D0); 217 path.push(D1); 218 path.push(D2); 219 path.push(D0); 220 EXPECT_TRUE(path.hasCycleAtBack()); 221 std::array<Decl* ,4> Res; 222 int i = 0; 223 for (Decl *Di : path.getCycleAtBack()) { 224 Res[i++] = Di; 225 } 226 ASSERT_EQ(i, 4); 227 EXPECT_EQ(Res[0], D0); 228 EXPECT_EQ(Res[1], D2); 229 EXPECT_EQ(Res[2], D1); 230 EXPECT_EQ(Res[3], D0); 231 232 path.pop(); 233 path.pop(); 234 path.pop(); 235 EXPECT_TRUE(path.hasCycleAtBack()); 236 i = 0; 237 for (Decl *Di : path.getCycleAtBack()) { 238 Res[i++] = Di; 239 } 240 ASSERT_EQ(i, 3); 241 EXPECT_EQ(Res[0], D0); 242 EXPECT_EQ(Res[1], D1); 243 EXPECT_EQ(Res[2], D0); 244 245 path.pop(); 246 EXPECT_FALSE(path.hasCycleAtBack()); 247 } 248 249 const internal::VariadicDynCastAllOfMatcher<Stmt, SourceLocExpr> sourceLocExpr; 250 251 AST_MATCHER_P(SourceLocExpr, hasBuiltinStr, StringRef, Str) { 252 return Node.getBuiltinStr() == Str; 253 } 254 255 TEST_P(ImportExpr, ImportSourceLocExpr) { 256 MatchVerifier<Decl> Verifier; 257 testImport("void declToImport() { (void)__builtin_FILE(); }", Lang_CXX03, "", 258 Lang_CXX03, Verifier, 259 functionDecl(hasDescendant( 260 sourceLocExpr(hasBuiltinStr("__builtin_FILE"))))); 261 testImport("void declToImport() { (void)__builtin_COLUMN(); }", Lang_CXX03, 262 "", Lang_CXX03, Verifier, 263 functionDecl(hasDescendant( 264 sourceLocExpr(hasBuiltinStr("__builtin_COLUMN"))))); 265 } 266 267 TEST_P(ImportExpr, ImportStringLiteral) { 268 MatchVerifier<Decl> Verifier; 269 testImport("void declToImport() { (void)\"foo\"; }", Lang_CXX03, "", 270 Lang_CXX03, Verifier, 271 functionDecl(hasDescendant( 272 stringLiteral(hasType(asString("const char [4]")))))); 273 testImport("void declToImport() { (void)L\"foo\"; }", Lang_CXX03, "", 274 Lang_CXX03, Verifier, 275 functionDecl(hasDescendant( 276 stringLiteral(hasType(asString("const wchar_t [4]")))))); 277 testImport("void declToImport() { (void) \"foo\" \"bar\"; }", Lang_CXX03, "", 278 Lang_CXX03, Verifier, 279 functionDecl(hasDescendant( 280 stringLiteral(hasType(asString("const char [7]")))))); 281 } 282 283 TEST_P(ImportExpr, ImportChooseExpr) { 284 MatchVerifier<Decl> Verifier; 285 286 // This case tests C code that is not condition-dependent and has a true 287 // condition. 288 testImport("void declToImport() { (void)__builtin_choose_expr(1, 2, 3); }", 289 Lang_C99, "", Lang_C99, Verifier, 290 functionDecl(hasDescendant(chooseExpr()))); 291 } 292 293 TEST_P(ImportExpr, ImportGNUNullExpr) { 294 MatchVerifier<Decl> Verifier; 295 testImport("void declToImport() { (void)__null; }", Lang_CXX03, "", 296 Lang_CXX03, Verifier, 297 functionDecl(hasDescendant(gnuNullExpr(hasType(isInteger()))))); 298 } 299 300 TEST_P(ImportExpr, ImportGenericSelectionExpr) { 301 MatchVerifier<Decl> Verifier; 302 303 testImport( 304 "void declToImport() { int x; (void)_Generic(x, int: 0, float: 1); }", 305 Lang_C99, "", Lang_C99, Verifier, 306 functionDecl(hasDescendant(genericSelectionExpr()))); 307 } 308 309 TEST_P(ImportExpr, ImportCXXNullPtrLiteralExpr) { 310 MatchVerifier<Decl> Verifier; 311 testImport( 312 "void declToImport() { (void)nullptr; }", 313 Lang_CXX11, "", Lang_CXX11, Verifier, 314 functionDecl(hasDescendant(cxxNullPtrLiteralExpr()))); 315 } 316 317 318 TEST_P(ImportExpr, ImportFloatinglLiteralExpr) { 319 MatchVerifier<Decl> Verifier; 320 testImport("void declToImport() { (void)1.0; }", Lang_C99, "", Lang_C99, 321 Verifier, 322 functionDecl(hasDescendant( 323 floatLiteral(equals(1.0), hasType(asString("double")))))); 324 testImport("void declToImport() { (void)1.0e-5f; }", Lang_C99, "", Lang_C99, 325 Verifier, 326 functionDecl(hasDescendant( 327 floatLiteral(equals(1.0e-5f), hasType(asString("float")))))); 328 } 329 330 TEST_P(ImportFixedPointExpr, ImportFixedPointerLiteralExpr) { 331 MatchVerifier<Decl> Verifier; 332 testImport("void declToImport() { (void)1.0k; }", Lang_C99, "", Lang_C99, 333 Verifier, functionDecl(hasDescendant(fixedPointLiteral()))); 334 testImport("void declToImport() { (void)0.75r; }", Lang_C99, "", Lang_C99, 335 Verifier, functionDecl(hasDescendant(fixedPointLiteral()))); 336 } 337 338 TEST_P(ImportExpr, ImportImaginaryLiteralExpr) { 339 MatchVerifier<Decl> Verifier; 340 testImport( 341 "void declToImport() { (void)1.0i; }", 342 Lang_CXX14, "", Lang_CXX14, Verifier, 343 functionDecl(hasDescendant(imaginaryLiteral()))); 344 } 345 346 TEST_P(ImportExpr, ImportCompoundLiteralExpr) { 347 MatchVerifier<Decl> Verifier; 348 testImport("void declToImport() {" 349 " struct s { int x; long y; unsigned z; }; " 350 " (void)(struct s){ 42, 0L, 1U }; }", 351 Lang_CXX03, "", Lang_CXX03, Verifier, 352 functionDecl(hasDescendant(compoundLiteralExpr( 353 hasType(asString("struct s")), 354 has(initListExpr( 355 hasType(asString("struct s")), 356 has(integerLiteral(equals(42), hasType(asString("int")))), 357 has(integerLiteral(equals(0), hasType(asString("long")))), 358 has(integerLiteral( 359 equals(1), hasType(asString("unsigned int")))))))))); 360 } 361 362 TEST_P(ImportExpr, ImportCXXThisExpr) { 363 MatchVerifier<Decl> Verifier; 364 testImport("class declToImport { void f() { (void)this; } };", Lang_CXX03, "", 365 Lang_CXX03, Verifier, 366 cxxRecordDecl(hasMethod(hasDescendant( 367 cxxThisExpr(hasType(asString("class declToImport *"))))))); 368 } 369 370 TEST_P(ImportExpr, ImportAtomicExpr) { 371 MatchVerifier<Decl> Verifier; 372 testImport("void declToImport() { int *ptr; __atomic_load_n(ptr, 1); }", 373 Lang_C99, "", Lang_C99, Verifier, 374 functionDecl(hasDescendant(atomicExpr( 375 has(ignoringParenImpCasts( 376 declRefExpr(hasDeclaration(varDecl(hasName("ptr"))), 377 hasType(asString("int *"))))), 378 has(integerLiteral(equals(1), hasType(asString("int")))))))); 379 } 380 381 TEST_P(ImportExpr, ImportLabelDeclAndAddrLabelExpr) { 382 MatchVerifier<Decl> Verifier; 383 testImport("void declToImport() { loop: goto loop; (void)&&loop; }", Lang_C99, 384 "", Lang_C99, Verifier, 385 functionDecl(hasDescendant(labelStmt( 386 hasDeclaration(labelDecl(hasName("loop"))))), 387 hasDescendant(addrLabelExpr( 388 hasDeclaration(labelDecl(hasName("loop"))))))); 389 } 390 391 AST_MATCHER_P(TemplateDecl, hasTemplateDecl, 392 internal::Matcher<NamedDecl>, InnerMatcher) { 393 const NamedDecl *Template = Node.getTemplatedDecl(); 394 return Template && InnerMatcher.matches(*Template, Finder, Builder); 395 } 396 397 TEST_P(ImportExpr, ImportParenListExpr) { 398 MatchVerifier<Decl> Verifier; 399 testImport( 400 "template<typename T> class dummy { void f() { dummy X(*this); } };" 401 "typedef dummy<int> declToImport;" 402 "template class dummy<int>;", 403 Lang_CXX03, "", Lang_CXX03, Verifier, 404 typedefDecl(hasType(templateSpecializationType( 405 hasDeclaration(classTemplateSpecializationDecl(hasSpecializedTemplate( 406 classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod(allOf( 407 hasName("f"), 408 hasBody(compoundStmt(has(declStmt(hasSingleDecl( 409 varDecl(hasInitializer(parenListExpr(has(unaryOperator( 410 hasOperatorName("*"), 411 hasUnaryOperand(cxxThisExpr()))))))))))))))))))))))); 412 } 413 414 TEST_P(ImportExpr, ImportSwitch) { 415 MatchVerifier<Decl> Verifier; 416 testImport("void declToImport() { int b; switch (b) { case 1: break; } }", 417 Lang_C99, "", Lang_C99, Verifier, 418 functionDecl(hasDescendant( 419 switchStmt(has(compoundStmt(has(caseStmt()))))))); 420 } 421 422 TEST_P(ImportExpr, ImportStmtExpr) { 423 MatchVerifier<Decl> Verifier; 424 testImport( 425 "void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }", 426 Lang_C99, "", Lang_C99, Verifier, 427 traverse(TK_AsIs, 428 functionDecl(hasDescendant(varDecl( 429 hasName("C"), hasType(asString("int")), 430 hasInitializer(stmtExpr( 431 hasAnySubstatement(declStmt(hasSingleDecl(varDecl( 432 hasName("X"), hasType(asString("int")), 433 hasInitializer(integerLiteral(equals(4))))))), 434 hasDescendant(implicitCastExpr())))))))); 435 } 436 437 TEST_P(ImportExpr, ImportConditionalOperator) { 438 MatchVerifier<Decl> Verifier; 439 testImport("void declToImport() { (void)(true ? 1 : -5); }", Lang_CXX03, "", 440 Lang_CXX03, Verifier, 441 functionDecl(hasDescendant(conditionalOperator( 442 hasCondition(cxxBoolLiteral(equals(true))), 443 hasTrueExpression(integerLiteral(equals(1))), 444 hasFalseExpression(unaryOperator( 445 hasUnaryOperand(integerLiteral(equals(5))))))))); 446 } 447 448 TEST_P(ImportExpr, ImportBinaryConditionalOperator) { 449 MatchVerifier<Decl> Verifier; 450 testImport( 451 "void declToImport() { (void)(1 ?: -5); }", Lang_CXX03, "", Lang_CXX03, 452 Verifier, 453 traverse(TK_AsIs, 454 functionDecl(hasDescendant(binaryConditionalOperator( 455 hasCondition(implicitCastExpr( 456 hasSourceExpression(opaqueValueExpr( 457 hasSourceExpression(integerLiteral(equals(1))))), 458 hasType(booleanType()))), 459 hasTrueExpression(opaqueValueExpr( 460 hasSourceExpression(integerLiteral(equals(1))))), 461 hasFalseExpression(unaryOperator( 462 hasOperatorName("-"), 463 hasUnaryOperand(integerLiteral(equals(5)))))))))); 464 } 465 466 TEST_P(ImportExpr, ImportDesignatedInitExpr) { 467 MatchVerifier<Decl> Verifier; 468 testImport( 469 "void declToImport() {" 470 " struct point { double x; double y; };" 471 " struct point ptarray[10] = " 472 "{ [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }", 473 Lang_C99, "", Lang_C99, Verifier, 474 functionDecl(hasDescendant(initListExpr( 475 has(designatedInitExpr(designatorCountIs(2), 476 hasDescendant(floatLiteral(equals(1.0))), 477 hasDescendant(integerLiteral(equals(2))))), 478 has(designatedInitExpr(designatorCountIs(2), 479 hasDescendant(floatLiteral(equals(2.0))), 480 hasDescendant(integerLiteral(equals(2))))), 481 has(designatedInitExpr(designatorCountIs(2), 482 hasDescendant(floatLiteral(equals(1.0))), 483 hasDescendant(integerLiteral(equals(0))))))))); 484 } 485 486 TEST_P(ImportExpr, ImportPredefinedExpr) { 487 MatchVerifier<Decl> Verifier; 488 // __func__ expands as StringLiteral("declToImport") 489 testImport("void declToImport() { (void)__func__; }", Lang_CXX03, "", 490 Lang_CXX03, Verifier, 491 functionDecl(hasDescendant(predefinedExpr( 492 hasType(asString("const char [13]")), 493 has(stringLiteral(hasType(asString("const char [13]")))))))); 494 } 495 496 TEST_P(ImportExpr, ImportInitListExpr) { 497 MatchVerifier<Decl> Verifier; 498 testImport( 499 "void declToImport() {" 500 " struct point { double x; double y; };" 501 " point ptarray[10] = { [2].y = 1.0, [2].x = 2.0," 502 " [0].x = 1.0 }; }", 503 Lang_CXX03, "", Lang_CXX03, Verifier, 504 functionDecl(hasDescendant(initListExpr( 505 has(cxxConstructExpr(requiresZeroInitialization())), 506 has(initListExpr( 507 hasType(asString("struct point")), has(floatLiteral(equals(1.0))), 508 has(implicitValueInitExpr(hasType(asString("double")))))), 509 has(initListExpr(hasType(asString("struct point")), 510 has(floatLiteral(equals(2.0))), 511 has(floatLiteral(equals(1.0))))))))); 512 } 513 514 515 const internal::VariadicDynCastAllOfMatcher<Expr, VAArgExpr> vaArgExpr; 516 517 TEST_P(ImportExpr, ImportVAArgExpr) { 518 MatchVerifier<Decl> Verifier; 519 testImport("void declToImport(__builtin_va_list list, ...) {" 520 " (void)__builtin_va_arg(list, int); }", 521 Lang_CXX03, "", Lang_CXX03, Verifier, 522 functionDecl(hasDescendant( 523 cStyleCastExpr(hasSourceExpression(vaArgExpr()))))); 524 } 525 526 TEST_P(ImportExpr, CXXTemporaryObjectExpr) { 527 MatchVerifier<Decl> Verifier; 528 testImport( 529 "struct C {};" 530 "void declToImport() { C c = C(); }", 531 Lang_CXX03, "", Lang_CXX03, Verifier, 532 traverse(TK_AsIs, 533 functionDecl(hasDescendant(exprWithCleanups(has(cxxConstructExpr( 534 has(materializeTemporaryExpr(has(implicitCastExpr( 535 has(cxxTemporaryObjectExpr())))))))))))); 536 } 537 538 TEST_P(ImportType, ImportAtomicType) { 539 MatchVerifier<Decl> Verifier; 540 testImport( 541 "void declToImport() { typedef _Atomic(int) a_int; }", 542 Lang_CXX11, "", Lang_CXX11, Verifier, 543 functionDecl(hasDescendant(typedefDecl(has(atomicType()))))); 544 } 545 546 TEST_P(ImportDecl, ImportFunctionTemplateDecl) { 547 MatchVerifier<Decl> Verifier; 548 testImport("template <typename T> void declToImport() { };", Lang_CXX03, "", 549 Lang_CXX03, Verifier, functionTemplateDecl()); 550 } 551 552 TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) { 553 MatchVerifier<Decl> Verifier; 554 testImport("template <typename T> struct C { T t; };" 555 "template <typename T> void declToImport() {" 556 " C<T> d;" 557 " (void)d.t;" 558 "}" 559 "void instantiate() { declToImport<int>(); }", 560 Lang_CXX03, "", Lang_CXX03, Verifier, 561 functionTemplateDecl(hasDescendant( 562 cStyleCastExpr(has(cxxDependentScopeMemberExpr()))))); 563 testImport("template <typename T> struct C { T t; };" 564 "template <typename T> void declToImport() {" 565 " C<T> d;" 566 " (void)(&d)->t;" 567 "}" 568 "void instantiate() { declToImport<int>(); }", 569 Lang_CXX03, "", Lang_CXX03, Verifier, 570 functionTemplateDecl(hasDescendant( 571 cStyleCastExpr(has(cxxDependentScopeMemberExpr()))))); 572 } 573 574 TEST_P(ImportType, ImportTypeAliasTemplate) { 575 MatchVerifier<Decl> Verifier; 576 testImport( 577 "template <int K>" 578 "struct dummy { static const int i = K; };" 579 "template <int K> using dummy2 = dummy<K>;" 580 "int declToImport() { return dummy2<3>::i; }", 581 Lang_CXX11, "", Lang_CXX11, Verifier, 582 traverse(TK_AsIs, 583 functionDecl(hasDescendant(implicitCastExpr(has(declRefExpr()))), 584 unless(hasAncestor( 585 translationUnitDecl(has(typeAliasDecl()))))))); 586 } 587 588 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateSpecializationDecl> 589 varTemplateSpecializationDecl; 590 591 TEST_P(ImportDecl, ImportVarTemplate) { 592 MatchVerifier<Decl> Verifier; 593 testImport( 594 "template <typename T>" 595 "T pi = T(3.1415926535897932385L);" 596 "void declToImport() { (void)pi<int>; }", 597 Lang_CXX14, "", Lang_CXX14, Verifier, 598 functionDecl( 599 hasDescendant(declRefExpr(to(varTemplateSpecializationDecl()))), 600 unless(hasAncestor(translationUnitDecl(has(varDecl( 601 hasName("pi"), unless(varTemplateSpecializationDecl())))))))); 602 } 603 604 TEST_P(ImportType, ImportPackExpansion) { 605 MatchVerifier<Decl> Verifier; 606 testImport("template <typename... Args>" 607 "struct dummy {" 608 " dummy(Args... args) {}" 609 " static const int i = 4;" 610 "};" 611 "int declToImport() { return dummy<int>::i; }", 612 Lang_CXX11, "", Lang_CXX11, Verifier, 613 traverse(TK_AsIs, functionDecl(hasDescendant(returnStmt(has( 614 implicitCastExpr(has(declRefExpr())))))))); 615 } 616 617 const internal::VariadicDynCastAllOfMatcher<Type, 618 DependentTemplateSpecializationType> 619 dependentTemplateSpecializationType; 620 621 TEST_P(ImportType, ImportDependentTemplateSpecialization) { 622 MatchVerifier<Decl> Verifier; 623 testImport("template<typename T>" 624 "struct A;" 625 "template<typename T>" 626 "struct declToImport {" 627 " typename A<T>::template B<T> a;" 628 "};", 629 Lang_CXX03, "", Lang_CXX03, Verifier, 630 classTemplateDecl(has(cxxRecordDecl(has( 631 fieldDecl(hasType(dependentTemplateSpecializationType()))))))); 632 } 633 634 TEST_P(ImportType, ImportDeducedTemplateSpecialization) { 635 MatchVerifier<Decl> Verifier; 636 testImport("template <typename T>" 637 "class C { public: C(T); };" 638 "C declToImport(123);", 639 Lang_CXX17, "", Lang_CXX17, Verifier, 640 varDecl(hasType(deducedTemplateSpecializationType()))); 641 } 642 643 const internal::VariadicDynCastAllOfMatcher<Stmt, SizeOfPackExpr> 644 sizeOfPackExpr; 645 646 TEST_P(ImportExpr, ImportSizeOfPackExpr) { 647 MatchVerifier<Decl> Verifier; 648 testImport( 649 "template <typename... Ts>" 650 "void declToImport() {" 651 " const int i = sizeof...(Ts);" 652 "};" 653 "void g() { declToImport<int>(); }", 654 Lang_CXX11, "", Lang_CXX11, Verifier, 655 functionTemplateDecl(hasDescendant(sizeOfPackExpr()))); 656 testImport( 657 "template <typename... Ts>" 658 "using X = int[sizeof...(Ts)];" 659 "template <typename... Us>" 660 "struct Y {" 661 " X<Us..., int, double, int, Us...> f;" 662 "};" 663 "Y<float, int> declToImport;", 664 Lang_CXX11, "", Lang_CXX11, Verifier, 665 varDecl(hasType(classTemplateSpecializationDecl(has(fieldDecl(hasType( 666 hasUnqualifiedDesugaredType(constantArrayType(hasSize(7)))))))))); 667 } 668 669 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFoldExpr> cxxFoldExpr; 670 671 AST_MATCHER_P(CXXFoldExpr, hasOperator, BinaryOperatorKind, Op) { 672 return Node.getOperator() == Op; 673 } 674 AST_MATCHER(CXXFoldExpr, hasInit) { return Node.getInit(); } 675 AST_MATCHER(CXXFoldExpr, isRightFold) { return Node.isRightFold(); } 676 AST_MATCHER(CXXFoldExpr, isLeftFold) { return Node.isLeftFold(); } 677 678 TEST_P(ImportExpr, ImportCXXFoldExpr) { 679 auto Match1 = 680 cxxFoldExpr(hasOperator(BO_Add), isLeftFold(), unless(hasInit())); 681 auto Match2 = cxxFoldExpr(hasOperator(BO_Sub), isLeftFold(), hasInit()); 682 auto Match3 = 683 cxxFoldExpr(hasOperator(BO_Mul), isRightFold(), unless(hasInit())); 684 auto Match4 = cxxFoldExpr(hasOperator(BO_Div), isRightFold(), hasInit()); 685 686 MatchVerifier<Decl> Verifier; 687 testImport("template <typename... Ts>" 688 "void declToImport(Ts... args) {" 689 " const int i1 = (... + args);" 690 " const int i2 = (1 - ... - args);" 691 " const int i3 = (args * ...);" 692 " const int i4 = (args / ... / 1);" 693 "};" 694 "void g() { declToImport(1, 2, 3, 4, 5); }", 695 Lang_CXX17, "", Lang_CXX17, Verifier, 696 functionTemplateDecl(hasDescendant(Match1), hasDescendant(Match2), 697 hasDescendant(Match3), 698 hasDescendant(Match4))); 699 } 700 701 /// \brief Matches __builtin_types_compatible_p: 702 /// GNU extension to check equivalent types 703 /// Given 704 /// \code 705 /// __builtin_types_compatible_p(int, int) 706 /// \endcode 707 // will generate TypeTraitExpr <...> 'int' 708 const internal::VariadicDynCastAllOfMatcher<Stmt, TypeTraitExpr> typeTraitExpr; 709 710 TEST_P(ImportExpr, ImportTypeTraitExpr) { 711 MatchVerifier<Decl> Verifier; 712 testImport( 713 "void declToImport() { " 714 " (void)__builtin_types_compatible_p(int, int);" 715 "}", 716 Lang_C99, "", Lang_C99, Verifier, 717 functionDecl(hasDescendant(typeTraitExpr(hasType(asString("int")))))); 718 } 719 720 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr> cxxTypeidExpr; 721 722 TEST_P(ImportExpr, ImportCXXTypeidExpr) { 723 MatchVerifier<Decl> Verifier; 724 testImport( 725 "namespace std { class type_info {}; }" 726 "void declToImport() {" 727 " int x;" 728 " auto a = typeid(int); auto b = typeid(x);" 729 "}", 730 Lang_CXX11, "", Lang_CXX11, Verifier, 731 traverse( 732 TK_AsIs, 733 functionDecl( 734 hasDescendant(varDecl(hasName("a"), hasInitializer(hasDescendant( 735 cxxTypeidExpr())))), 736 hasDescendant(varDecl(hasName("b"), hasInitializer(hasDescendant( 737 cxxTypeidExpr()))))))); 738 } 739 740 TEST_P(ImportExpr, ImportTypeTraitExprValDep) { 741 MatchVerifier<Decl> Verifier; 742 testImport( 743 "template<typename T> struct declToImport {" 744 " void m() { (void)__is_pod(T); }" 745 "};" 746 "void f() { declToImport<int>().m(); }", 747 Lang_CXX11, "", Lang_CXX11, Verifier, 748 classTemplateDecl(has(cxxRecordDecl(has( 749 functionDecl(hasDescendant( 750 typeTraitExpr(hasType(booleanType()))))))))); 751 } 752 753 TEST_P(ImportDecl, ImportRecordDeclInFunc) { 754 MatchVerifier<Decl> Verifier; 755 testImport("int declToImport() { " 756 " struct data_t {int a;int b;};" 757 " struct data_t d;" 758 " return 0;" 759 "}", 760 Lang_C99, "", Lang_C99, Verifier, 761 functionDecl(hasBody(compoundStmt( 762 has(declStmt(hasSingleDecl(varDecl(hasName("d"))))))))); 763 } 764 765 TEST_P(ImportDecl, ImportedVarDeclPreservesThreadLocalStorage) { 766 MatchVerifier<Decl> Verifier; 767 testImport("thread_local int declToImport;", Lang_CXX11, "", Lang_CXX11, 768 Verifier, varDecl(hasThreadStorageDuration())); 769 } 770 771 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) { 772 Decl *FromTU = getTuDecl("int declToImport() { " 773 " struct data_t {int a;int b;};" 774 " struct data_t d;" 775 " return 0;" 776 "}", 777 Lang_C99, "input.c"); 778 auto *FromVar = 779 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("d"))); 780 ASSERT_TRUE(FromVar); 781 auto ToType = 782 ImportType(FromVar->getType().getCanonicalType(), FromVar, Lang_C99); 783 EXPECT_FALSE(ToType.isNull()); 784 } 785 786 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncParams) { 787 // This construct is not supported by ASTImporter. 788 Decl *FromTU = getTuDecl( 789 "int declToImport(struct data_t{int a;int b;} ***d){ return 0; }", 790 Lang_C99, "input.c"); 791 auto *From = FirstDeclMatcher<FunctionDecl>().match( 792 FromTU, functionDecl(hasName("declToImport"))); 793 ASSERT_TRUE(From); 794 auto *To = Import(From, Lang_C99); 795 EXPECT_EQ(To, nullptr); 796 } 797 798 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncFromMacro) { 799 Decl *FromTU = 800 getTuDecl("#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n" 801 "int declToImport(){ return NONAME_SIZEOF(int); }", 802 Lang_C99, "input.c"); 803 auto *From = FirstDeclMatcher<FunctionDecl>().match( 804 FromTU, functionDecl(hasName("declToImport"))); 805 ASSERT_TRUE(From); 806 auto *To = Import(From, Lang_C99); 807 ASSERT_TRUE(To); 808 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match( 809 To, functionDecl(hasName("declToImport"), 810 hasDescendant(unaryExprOrTypeTraitExpr())))); 811 } 812 813 TEST_P(ASTImporterOptionSpecificTestBase, 814 ImportRecordDeclInFuncParamsFromMacro) { 815 // This construct is not supported by ASTImporter. 816 Decl *FromTU = 817 getTuDecl("#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n" 818 "int declToImport(PAIR_STRUCT(int) ***d){ return 0; }", 819 Lang_C99, "input.c"); 820 auto *From = FirstDeclMatcher<FunctionDecl>().match( 821 FromTU, functionDecl(hasName("declToImport"))); 822 ASSERT_TRUE(From); 823 auto *To = Import(From, Lang_C99); 824 EXPECT_EQ(To, nullptr); 825 } 826 827 const internal::VariadicDynCastAllOfMatcher<Expr, CXXPseudoDestructorExpr> 828 cxxPseudoDestructorExpr; 829 830 TEST_P(ImportExpr, ImportCXXPseudoDestructorExpr) { 831 MatchVerifier<Decl> Verifier; 832 testImport( 833 "typedef int T;" 834 "void declToImport(int *p) {" 835 " T t;" 836 " p->T::~T();" 837 "}", 838 Lang_CXX03, "", Lang_CXX03, Verifier, 839 functionDecl(hasDescendant(callExpr(has(cxxPseudoDestructorExpr()))))); 840 } 841 842 TEST_P(ImportDecl, ImportUsingDecl) { 843 MatchVerifier<Decl> Verifier; 844 testImport("namespace foo { int bar; }" 845 "void declToImport() { using foo::bar; }", 846 Lang_CXX03, "", Lang_CXX03, Verifier, 847 functionDecl(hasDescendant(usingDecl()))); 848 } 849 850 /// \brief Matches shadow declarations introduced into a scope by a 851 /// (resolved) using declaration. 852 /// 853 /// Given 854 /// \code 855 /// namespace n { int f; } 856 /// namespace declToImport { using n::f; } 857 /// \endcode 858 /// usingShadowDecl() 859 /// matches \code f \endcode 860 const internal::VariadicDynCastAllOfMatcher<Decl, 861 UsingShadowDecl> usingShadowDecl; 862 863 TEST_P(ImportDecl, ImportUsingShadowDecl) { 864 MatchVerifier<Decl> Verifier; 865 testImport("namespace foo { int bar; }" 866 "namespace declToImport { using foo::bar; }", 867 Lang_CXX03, "", Lang_CXX03, Verifier, 868 namespaceDecl(has(usingShadowDecl()))); 869 } 870 871 TEST_P(ImportExpr, ImportUnresolvedLookupExpr) { 872 MatchVerifier<Decl> Verifier; 873 testImport("template<typename T> int foo();" 874 "template <typename T> void declToImport() {" 875 " (void)::foo<T>;" 876 " (void)::template foo<T>;" 877 "}" 878 "void instantiate() { declToImport<int>(); }", 879 Lang_CXX03, "", Lang_CXX03, Verifier, 880 functionTemplateDecl(hasDescendant(unresolvedLookupExpr()))); 881 } 882 883 TEST_P(ImportExpr, ImportCXXUnresolvedConstructExpr) { 884 MatchVerifier<Decl> Verifier; 885 testImport("template <typename T> struct C { T t; };" 886 "template <typename T> void declToImport() {" 887 " C<T> d;" 888 " d.t = T();" 889 "}" 890 "void instantiate() { declToImport<int>(); }", 891 Lang_CXX03, "", Lang_CXX03, Verifier, 892 functionTemplateDecl(hasDescendant( 893 binaryOperator(has(cxxUnresolvedConstructExpr()))))); 894 testImport("template <typename T> struct C { T t; };" 895 "template <typename T> void declToImport() {" 896 " C<T> d;" 897 " (&d)->t = T();" 898 "}" 899 "void instantiate() { declToImport<int>(); }", 900 Lang_CXX03, "", Lang_CXX03, Verifier, 901 functionTemplateDecl(hasDescendant( 902 binaryOperator(has(cxxUnresolvedConstructExpr()))))); 903 } 904 905 /// Check that function "declToImport()" (which is the templated function 906 /// for corresponding FunctionTemplateDecl) is not added into DeclContext. 907 /// Same for class template declarations. 908 TEST_P(ImportDecl, ImportTemplatedDeclForTemplate) { 909 MatchVerifier<Decl> Verifier; 910 testImport("template <typename T> void declToImport() { T a = 1; }" 911 "void instantiate() { declToImport<int>(); }", 912 Lang_CXX03, "", Lang_CXX03, Verifier, 913 functionTemplateDecl(hasAncestor(translationUnitDecl( 914 unless(has(functionDecl(hasName("declToImport")))))))); 915 testImport("template <typename T> struct declToImport { T t; };" 916 "void instantiate() { declToImport<int>(); }", 917 Lang_CXX03, "", Lang_CXX03, Verifier, 918 classTemplateDecl(hasAncestor(translationUnitDecl( 919 unless(has(cxxRecordDecl(hasName("declToImport")))))))); 920 } 921 922 TEST_P(ImportDecl, ImportClassTemplatePartialSpecialization) { 923 MatchVerifier<Decl> Verifier; 924 auto Code = 925 R"s( 926 struct declToImport { 927 template <typename T0> struct X; 928 template <typename T0> struct X<T0 *> {}; 929 }; 930 )s"; 931 testImport(Code, Lang_CXX03, "", Lang_CXX03, Verifier, 932 recordDecl(has(classTemplateDecl()), 933 has(classTemplateSpecializationDecl()))); 934 } 935 936 TEST_P(ImportExpr, CXXOperatorCallExpr) { 937 MatchVerifier<Decl> Verifier; 938 testImport( 939 "class declToImport {" 940 " void f() { *this = declToImport(); }" 941 "};", 942 Lang_CXX03, "", Lang_CXX03, Verifier, 943 cxxRecordDecl(has(cxxMethodDecl(hasDescendant(cxxOperatorCallExpr()))))); 944 } 945 946 TEST_P(ImportExpr, DependentSizedArrayType) { 947 MatchVerifier<Decl> Verifier; 948 testImport("template<typename T, int Size> class declToImport {" 949 " T data[Size];" 950 "};", 951 Lang_CXX03, "", Lang_CXX03, Verifier, 952 classTemplateDecl(has(cxxRecordDecl( 953 has(fieldDecl(hasType(dependentSizedArrayType()))))))); 954 } 955 956 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclNoDefaultArg) { 957 Decl *FromTU = getTuDecl("template<typename T> struct X {};", Lang_CXX03); 958 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match( 959 FromTU, templateTypeParmDecl(hasName("T"))); 960 TemplateTypeParmDecl *To = Import(From, Lang_CXX03); 961 ASSERT_FALSE(To->hasDefaultArgument()); 962 } 963 964 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclDefaultArg) { 965 Decl *FromTU = 966 getTuDecl("template<typename T = int> struct X {};", Lang_CXX03); 967 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match( 968 FromTU, templateTypeParmDecl(hasName("T"))); 969 TemplateTypeParmDecl *To = Import(From, Lang_CXX03); 970 ASSERT_TRUE(To->hasDefaultArgument()); 971 QualType ToArg = To->getDefaultArgument(); 972 ASSERT_EQ(ToArg, QualType(To->getASTContext().IntTy)); 973 } 974 975 TEST_P(ASTImporterOptionSpecificTestBase, ImportBeginLocOfDeclRefExpr) { 976 Decl *FromTU = 977 getTuDecl("class A { public: static int X; }; void f() { (void)A::X; }", 978 Lang_CXX03); 979 auto From = FirstDeclMatcher<FunctionDecl>().match( 980 FromTU, functionDecl(hasName("f"))); 981 ASSERT_TRUE(From); 982 ASSERT_TRUE( 983 cast<CStyleCastExpr>(cast<CompoundStmt>(From->getBody())->body_front()) 984 ->getSubExpr() 985 ->getBeginLoc() 986 .isValid()); 987 FunctionDecl *To = Import(From, Lang_CXX03); 988 ASSERT_TRUE(To); 989 ASSERT_TRUE( 990 cast<CStyleCastExpr>(cast<CompoundStmt>(To->getBody())->body_front()) 991 ->getSubExpr() 992 ->getBeginLoc() 993 .isValid()); 994 } 995 996 TEST_P(ASTImporterOptionSpecificTestBase, 997 TemplateTemplateParmDeclNoDefaultArg) { 998 Decl *FromTU = getTuDecl(R"( 999 template<template<typename> typename TT> struct Y {}; 1000 )", 1001 Lang_CXX17); 1002 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match( 1003 FromTU, templateTemplateParmDecl(hasName("TT"))); 1004 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17); 1005 ASSERT_FALSE(To->hasDefaultArgument()); 1006 } 1007 1008 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTemplateParmDeclDefaultArg) { 1009 Decl *FromTU = getTuDecl(R"( 1010 template<typename T> struct X {}; 1011 template<template<typename> typename TT = X> struct Y {}; 1012 )", 1013 Lang_CXX17); 1014 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match( 1015 FromTU, templateTemplateParmDecl(hasName("TT"))); 1016 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17); 1017 ASSERT_TRUE(To->hasDefaultArgument()); 1018 const TemplateArgument &ToDefaultArg = To->getDefaultArgument().getArgument(); 1019 ASSERT_TRUE(To->isTemplateDecl()); 1020 TemplateDecl *ToTemplate = ToDefaultArg.getAsTemplate().getAsTemplateDecl(); 1021 1022 // Find the default argument template 'X' in the AST and compare it against 1023 // the default argument we got. 1024 auto ToExpectedDecl = FirstDeclMatcher<ClassTemplateDecl>().match( 1025 To->getTranslationUnitDecl(), classTemplateDecl(hasName("X"))); 1026 ASSERT_EQ(ToTemplate, ToExpectedDecl); 1027 } 1028 1029 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclNoDefaultArg) { 1030 Decl *FromTU = getTuDecl("template<int N> struct X {};", Lang_CXX03); 1031 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match( 1032 FromTU, nonTypeTemplateParmDecl(hasName("N"))); 1033 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03); 1034 ASSERT_FALSE(To->hasDefaultArgument()); 1035 } 1036 1037 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclDefaultArg) { 1038 Decl *FromTU = getTuDecl("template<int S = 1> struct X {};", Lang_CXX03); 1039 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match( 1040 FromTU, nonTypeTemplateParmDecl(hasName("S"))); 1041 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03); 1042 ASSERT_TRUE(To->hasDefaultArgument()); 1043 Stmt *ToArg = To->getDefaultArgument(); 1044 ASSERT_TRUE(isa<ConstantExpr>(ToArg)); 1045 ToArg = *ToArg->child_begin(); 1046 ASSERT_TRUE(isa<IntegerLiteral>(ToArg)); 1047 ASSERT_EQ(cast<IntegerLiteral>(ToArg)->getValue().getLimitedValue(), 1U); 1048 } 1049 1050 TEST_P(ASTImporterOptionSpecificTestBase, 1051 ImportOfTemplatedDeclOfClassTemplateDecl) { 1052 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03); 1053 auto From = 1054 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl()); 1055 ASSERT_TRUE(From); 1056 auto To = cast<ClassTemplateDecl>(Import(From, Lang_CXX03)); 1057 ASSERT_TRUE(To); 1058 Decl *ToTemplated = To->getTemplatedDecl(); 1059 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03); 1060 EXPECT_TRUE(ToTemplated1); 1061 EXPECT_EQ(ToTemplated1, ToTemplated); 1062 } 1063 1064 TEST_P(ASTImporterOptionSpecificTestBase, 1065 ImportOfTemplatedDeclOfFunctionTemplateDecl) { 1066 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03); 1067 auto From = FirstDeclMatcher<FunctionTemplateDecl>().match( 1068 FromTU, functionTemplateDecl()); 1069 ASSERT_TRUE(From); 1070 auto To = cast<FunctionTemplateDecl>(Import(From, Lang_CXX03)); 1071 ASSERT_TRUE(To); 1072 Decl *ToTemplated = To->getTemplatedDecl(); 1073 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03); 1074 EXPECT_TRUE(ToTemplated1); 1075 EXPECT_EQ(ToTemplated1, ToTemplated); 1076 } 1077 1078 TEST_P(ASTImporterOptionSpecificTestBase, 1079 ImportOfTemplatedDeclShouldImportTheClassTemplateDecl) { 1080 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03); 1081 auto FromFT = 1082 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl()); 1083 ASSERT_TRUE(FromFT); 1084 1085 auto ToTemplated = 1086 cast<CXXRecordDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03)); 1087 EXPECT_TRUE(ToTemplated); 1088 auto ToTU = ToTemplated->getTranslationUnitDecl(); 1089 auto ToFT = 1090 FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, classTemplateDecl()); 1091 EXPECT_TRUE(ToFT); 1092 } 1093 1094 TEST_P(ASTImporterOptionSpecificTestBase, 1095 ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) { 1096 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03); 1097 auto FromFT = FirstDeclMatcher<FunctionTemplateDecl>().match( 1098 FromTU, functionTemplateDecl()); 1099 ASSERT_TRUE(FromFT); 1100 1101 auto ToTemplated = 1102 cast<FunctionDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03)); 1103 EXPECT_TRUE(ToTemplated); 1104 auto ToTU = ToTemplated->getTranslationUnitDecl(); 1105 auto ToFT = FirstDeclMatcher<FunctionTemplateDecl>().match( 1106 ToTU, functionTemplateDecl()); 1107 EXPECT_TRUE(ToFT); 1108 } 1109 1110 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) { 1111 auto Code = 1112 R"( 1113 namespace x { 1114 template<class X> struct S1{}; 1115 template<class X> struct S2{}; 1116 template<class X> struct S3{}; 1117 } 1118 )"; 1119 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 1120 auto FromNs = 1121 FirstDeclMatcher<NamespaceDecl>().match(FromTU, namespaceDecl()); 1122 auto ToNs = cast<NamespaceDecl>(Import(FromNs, Lang_CXX03)); 1123 ASSERT_TRUE(ToNs); 1124 auto From = 1125 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, 1126 classTemplateDecl( 1127 hasName("S2"))); 1128 auto To = 1129 FirstDeclMatcher<ClassTemplateDecl>().match(ToNs, 1130 classTemplateDecl( 1131 hasName("S2"))); 1132 ASSERT_TRUE(From); 1133 ASSERT_TRUE(To); 1134 auto ToTemplated = To->getTemplatedDecl(); 1135 auto ToTemplated1 = 1136 cast<CXXRecordDecl>(Import(From->getTemplatedDecl(), Lang_CXX03)); 1137 EXPECT_TRUE(ToTemplated1); 1138 ASSERT_EQ(ToTemplated1, ToTemplated); 1139 } 1140 1141 TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) { 1142 // This tests the import of isConditionTrue directly to make sure the importer 1143 // gets it right. 1144 Decl *From, *To; 1145 std::tie(From, To) = getImportedDecl( 1146 "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }", Lang_C99, 1147 "", Lang_C99); 1148 1149 auto ToResults = match(chooseExpr().bind("choose"), To->getASTContext()); 1150 auto FromResults = match(chooseExpr().bind("choose"), From->getASTContext()); 1151 1152 const ChooseExpr *FromChooseExpr = 1153 selectFirst<ChooseExpr>("choose", FromResults); 1154 ASSERT_TRUE(FromChooseExpr); 1155 1156 const ChooseExpr *ToChooseExpr = selectFirst<ChooseExpr>("choose", ToResults); 1157 ASSERT_TRUE(ToChooseExpr); 1158 1159 EXPECT_EQ(FromChooseExpr->isConditionTrue(), ToChooseExpr->isConditionTrue()); 1160 EXPECT_EQ(FromChooseExpr->isConditionDependent(), 1161 ToChooseExpr->isConditionDependent()); 1162 } 1163 1164 TEST_P(ASTImporterOptionSpecificTestBase, ImportGenericSelectionExpr) { 1165 Decl *From, *To; 1166 std::tie(From, To) = getImportedDecl( 1167 R"( 1168 int declToImport() { 1169 int x; 1170 return _Generic(x, int: 0, default: 1); 1171 } 1172 )", 1173 Lang_C99, "", Lang_C99); 1174 1175 auto ToResults = 1176 match(genericSelectionExpr().bind("expr"), To->getASTContext()); 1177 auto FromResults = 1178 match(genericSelectionExpr().bind("expr"), From->getASTContext()); 1179 1180 const GenericSelectionExpr *FromGenericSelectionExpr = 1181 selectFirst<GenericSelectionExpr>("expr", FromResults); 1182 ASSERT_TRUE(FromGenericSelectionExpr); 1183 1184 const GenericSelectionExpr *ToGenericSelectionExpr = 1185 selectFirst<GenericSelectionExpr>("expr", ToResults); 1186 ASSERT_TRUE(ToGenericSelectionExpr); 1187 1188 EXPECT_EQ(FromGenericSelectionExpr->isResultDependent(), 1189 ToGenericSelectionExpr->isResultDependent()); 1190 EXPECT_EQ(FromGenericSelectionExpr->getResultIndex(), 1191 ToGenericSelectionExpr->getResultIndex()); 1192 } 1193 1194 TEST_P(ASTImporterOptionSpecificTestBase, 1195 ImportFunctionWithBackReferringParameter) { 1196 Decl *From, *To; 1197 std::tie(From, To) = getImportedDecl( 1198 R"( 1199 template <typename T> struct X {}; 1200 1201 void declToImport(int y, X<int> &x) {} 1202 1203 template <> struct X<int> { 1204 void g() { 1205 X<int> x; 1206 declToImport(0, x); 1207 } 1208 }; 1209 )", 1210 Lang_CXX03, "", Lang_CXX03); 1211 1212 MatchVerifier<Decl> Verifier; 1213 auto Matcher = functionDecl(hasName("declToImport"), 1214 parameterCountIs(2), 1215 hasParameter(0, hasName("y")), 1216 hasParameter(1, hasName("x")), 1217 hasParameter(1, hasType(asString("X<int> &")))); 1218 ASSERT_TRUE(Verifier.match(From, Matcher)); 1219 EXPECT_TRUE(Verifier.match(To, Matcher)); 1220 } 1221 1222 TEST_P(ASTImporterOptionSpecificTestBase, 1223 TUshouldNotContainTemplatedDeclOfFunctionTemplates) { 1224 Decl *From, *To; 1225 std::tie(From, To) = 1226 getImportedDecl("template <typename T> void declToImport() { T a = 1; }" 1227 "void instantiate() { declToImport<int>(); }", 1228 Lang_CXX03, "", Lang_CXX03); 1229 1230 auto Check = [](Decl *D) -> bool { 1231 auto TU = D->getTranslationUnitDecl(); 1232 for (auto Child : TU->decls()) { 1233 if (auto *FD = dyn_cast<FunctionDecl>(Child)) { 1234 if (FD->getNameAsString() == "declToImport") { 1235 GTEST_NONFATAL_FAILURE_( 1236 "TU should not contain any FunctionDecl with name declToImport"); 1237 return false; 1238 } 1239 } 1240 } 1241 return true; 1242 }; 1243 1244 ASSERT_TRUE(Check(From)); 1245 EXPECT_TRUE(Check(To)); 1246 } 1247 1248 TEST_P(ASTImporterOptionSpecificTestBase, 1249 TUshouldNotContainTemplatedDeclOfClassTemplates) { 1250 Decl *From, *To; 1251 std::tie(From, To) = 1252 getImportedDecl("template <typename T> struct declToImport { T t; };" 1253 "void instantiate() { declToImport<int>(); }", 1254 Lang_CXX03, "", Lang_CXX03); 1255 1256 auto Check = [](Decl *D) -> bool { 1257 auto TU = D->getTranslationUnitDecl(); 1258 for (auto Child : TU->decls()) { 1259 if (auto *RD = dyn_cast<CXXRecordDecl>(Child)) { 1260 if (RD->getNameAsString() == "declToImport") { 1261 GTEST_NONFATAL_FAILURE_( 1262 "TU should not contain any CXXRecordDecl with name declToImport"); 1263 return false; 1264 } 1265 } 1266 } 1267 return true; 1268 }; 1269 1270 ASSERT_TRUE(Check(From)); 1271 EXPECT_TRUE(Check(To)); 1272 } 1273 1274 TEST_P(ASTImporterOptionSpecificTestBase, 1275 TUshouldNotContainTemplatedDeclOfTypeAlias) { 1276 Decl *From, *To; 1277 std::tie(From, To) = 1278 getImportedDecl( 1279 "template <typename T> struct X {};" 1280 "template <typename T> using declToImport = X<T>;" 1281 "void instantiate() { declToImport<int> a; }", 1282 Lang_CXX11, "", Lang_CXX11); 1283 1284 auto Check = [](Decl *D) -> bool { 1285 auto TU = D->getTranslationUnitDecl(); 1286 for (auto Child : TU->decls()) { 1287 if (auto *AD = dyn_cast<TypeAliasDecl>(Child)) { 1288 if (AD->getNameAsString() == "declToImport") { 1289 GTEST_NONFATAL_FAILURE_( 1290 "TU should not contain any TypeAliasDecl with name declToImport"); 1291 return false; 1292 } 1293 } 1294 } 1295 return true; 1296 }; 1297 1298 ASSERT_TRUE(Check(From)); 1299 EXPECT_TRUE(Check(To)); 1300 } 1301 1302 TEST_P(ASTImporterOptionSpecificTestBase, 1303 TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) { 1304 1305 Decl *From, *To; 1306 std::tie(From, To) = getImportedDecl( 1307 R"( 1308 template<class T> 1309 class Base {}; 1310 class declToImport : public Base<declToImport> {}; 1311 )", 1312 Lang_CXX03, "", Lang_CXX03); 1313 1314 // Check that the ClassTemplateSpecializationDecl is NOT the child of the TU. 1315 auto Pattern = 1316 translationUnitDecl(unless(has(classTemplateSpecializationDecl()))); 1317 ASSERT_TRUE( 1318 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1319 EXPECT_TRUE( 1320 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1321 1322 // Check that the ClassTemplateSpecializationDecl is the child of the 1323 // ClassTemplateDecl. 1324 Pattern = translationUnitDecl(has(classTemplateDecl( 1325 hasName("Base"), has(classTemplateSpecializationDecl())))); 1326 ASSERT_TRUE( 1327 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1328 EXPECT_TRUE( 1329 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1330 } 1331 1332 AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) { 1333 size_t Index = 0; 1334 for (Decl *D : Node.decls()) { 1335 if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) { 1336 auto *ND = cast<NamedDecl>(D); 1337 if (Index == Order.size()) 1338 return false; 1339 if (ND->getName() != Order[Index]) 1340 return false; 1341 ++Index; 1342 } 1343 } 1344 return Index == Order.size(); 1345 } 1346 1347 TEST_P(ASTImporterOptionSpecificTestBase, 1348 TUshouldContainClassTemplateSpecializationOfExplicitInstantiation) { 1349 Decl *From, *To; 1350 std::tie(From, To) = getImportedDecl( 1351 R"( 1352 namespace NS { 1353 template<class T> 1354 class X {}; 1355 template class X<int>; 1356 } 1357 )", 1358 Lang_CXX03, "", Lang_CXX03, "NS"); 1359 1360 // Check that the ClassTemplateSpecializationDecl is NOT the child of the 1361 // ClassTemplateDecl. 1362 auto Pattern = namespaceDecl(has(classTemplateDecl( 1363 hasName("X"), unless(has(classTemplateSpecializationDecl()))))); 1364 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern)); 1365 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern)); 1366 1367 // Check that the ClassTemplateSpecializationDecl is the child of the 1368 // NamespaceDecl. 1369 Pattern = namespaceDecl(has(classTemplateSpecializationDecl(hasName("X")))); 1370 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern)); 1371 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern)); 1372 } 1373 1374 TEST_P(ASTImporterOptionSpecificTestBase, 1375 CXXRecordDeclFieldsShouldBeInCorrectOrder) { 1376 Decl *From, *To; 1377 std::tie(From, To) = 1378 getImportedDecl( 1379 "struct declToImport { int a; int b; };", 1380 Lang_CXX11, "", Lang_CXX11); 1381 1382 MatchVerifier<Decl> Verifier; 1383 ASSERT_TRUE(Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b"})))); 1384 EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b"})))); 1385 } 1386 1387 TEST_P(ASTImporterOptionSpecificTestBase, 1388 CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) { 1389 Decl *From, *To; 1390 std::tie(From, To) = getImportedDecl( 1391 // The original recursive algorithm of ASTImporter first imports 'c' then 1392 // 'b' and lastly 'a'. Therefore we must restore the order somehow. 1393 R"s( 1394 struct declToImport { 1395 int a = c + b; 1396 int b = 1; 1397 int c = 2; 1398 }; 1399 )s", 1400 Lang_CXX11, "", Lang_CXX11); 1401 1402 MatchVerifier<Decl> Verifier; 1403 ASSERT_TRUE( 1404 Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b", "c"})))); 1405 EXPECT_TRUE( 1406 Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"})))); 1407 } 1408 1409 TEST_P(ASTImporterOptionSpecificTestBase, 1410 CXXRecordDeclFieldAndIndirectFieldOrder) { 1411 Decl *From, *To; 1412 std::tie(From, To) = getImportedDecl( 1413 // First field is "a", then the field for unnamed union, then "b" and "c" 1414 // from it (indirect fields), then "d". 1415 R"s( 1416 struct declToImport { 1417 int a = d; 1418 union { 1419 int b; 1420 int c; 1421 }; 1422 int d; 1423 }; 1424 )s", 1425 Lang_CXX11, "", Lang_CXX11); 1426 1427 MatchVerifier<Decl> Verifier; 1428 ASSERT_TRUE(Verifier.match( 1429 From, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"})))); 1430 EXPECT_TRUE(Verifier.match( 1431 To, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"})))); 1432 } 1433 1434 TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) { 1435 Decl *From, *To; 1436 std::tie(From, To) = getImportedDecl( 1437 R"( 1438 struct declToImport { 1439 }; 1440 )", 1441 Lang_CXX03, "", Lang_CXX03); 1442 1443 MatchVerifier<Decl> Verifier; 1444 // Match the implicit Decl. 1445 auto Matcher = cxxRecordDecl(has(cxxRecordDecl())); 1446 ASSERT_TRUE(Verifier.match(From, Matcher)); 1447 EXPECT_TRUE(Verifier.match(To, Matcher)); 1448 } 1449 1450 TEST_P(ASTImporterOptionSpecificTestBase, 1451 ShouldImportImplicitCXXRecordDeclOfClassTemplate) { 1452 Decl *From, *To; 1453 std::tie(From, To) = getImportedDecl( 1454 R"( 1455 template <typename U> 1456 struct declToImport { 1457 }; 1458 )", 1459 Lang_CXX03, "", Lang_CXX03); 1460 1461 MatchVerifier<Decl> Verifier; 1462 // Match the implicit Decl. 1463 auto Matcher = classTemplateDecl(has(cxxRecordDecl(has(cxxRecordDecl())))); 1464 ASSERT_TRUE(Verifier.match(From, Matcher)); 1465 EXPECT_TRUE(Verifier.match(To, Matcher)); 1466 } 1467 1468 TEST_P(ASTImporterOptionSpecificTestBase, 1469 ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) { 1470 Decl *From, *To; 1471 std::tie(From, To) = getImportedDecl( 1472 R"( 1473 template<class T> 1474 class Base {}; 1475 class declToImport : public Base<declToImport> {}; 1476 )", 1477 Lang_CXX03, "", Lang_CXX03); 1478 1479 auto hasImplicitClass = has(cxxRecordDecl()); 1480 auto Pattern = translationUnitDecl(has(classTemplateDecl( 1481 hasName("Base"), 1482 has(classTemplateSpecializationDecl(hasImplicitClass))))); 1483 ASSERT_TRUE( 1484 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1485 EXPECT_TRUE( 1486 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1487 } 1488 1489 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOrdinary) { 1490 Decl *From, *To; 1491 std::tie(From, To) = 1492 getImportedDecl("void declToImport() {}", Lang_CXX03, "", Lang_CXX03); 1493 1494 MatchVerifier<Decl> Verifier; 1495 auto Matcher = functionDecl(); 1496 ASSERT_TRUE(Verifier.match(From, Matcher)); 1497 EXPECT_TRUE(Verifier.match(To, Matcher)); 1498 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace()); 1499 } 1500 1501 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOfNonmemberOperator) { 1502 Decl *FromTU = getTuDecl( 1503 R"( 1504 struct X {}; 1505 void operator<<(int, X); 1506 )", 1507 Lang_CXX03); 1508 Decl *From = LastDeclMatcher<Decl>{}.match(FromTU, functionDecl()); 1509 const Decl *To = Import(From, Lang_CXX03); 1510 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace()); 1511 } 1512 1513 TEST_P(ASTImporterOptionSpecificTestBase, 1514 ShouldImportMembersOfClassTemplateSpecializationDecl) { 1515 Decl *From, *To; 1516 std::tie(From, To) = getImportedDecl( 1517 R"( 1518 template<class T> 1519 class Base { int a; }; 1520 class declToImport : Base<declToImport> {}; 1521 )", 1522 Lang_CXX03, "", Lang_CXX03); 1523 1524 auto Pattern = translationUnitDecl(has(classTemplateDecl( 1525 hasName("Base"), 1526 has(classTemplateSpecializationDecl(has(fieldDecl(hasName("a")))))))); 1527 ASSERT_TRUE( 1528 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1529 EXPECT_TRUE( 1530 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1531 } 1532 1533 TEST_P(ASTImporterOptionSpecificTestBase, 1534 ImportDefinitionOfClassTemplateAfterFwdDecl) { 1535 { 1536 Decl *FromTU = getTuDecl( 1537 R"( 1538 template <typename T> 1539 struct B; 1540 )", 1541 Lang_CXX03, "input0.cc"); 1542 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 1543 FromTU, classTemplateDecl(hasName("B"))); 1544 1545 Import(FromD, Lang_CXX03); 1546 } 1547 1548 { 1549 Decl *FromTU = getTuDecl( 1550 R"( 1551 template <typename T> 1552 struct B { 1553 void f(); 1554 }; 1555 )", 1556 Lang_CXX03, "input1.cc"); 1557 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match( 1558 FromTU, functionDecl(hasName("f"))); 1559 Import(FromD, Lang_CXX03); 1560 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match( 1561 FromTU, classTemplateDecl(hasName("B"))); 1562 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03)); 1563 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition()); 1564 } 1565 } 1566 1567 TEST_P(ASTImporterOptionSpecificTestBase, 1568 ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition) { 1569 Decl *ToTU = getToTuDecl( 1570 R"( 1571 template <typename T> 1572 struct B { 1573 void f(); 1574 }; 1575 1576 template <typename T> 1577 struct B; 1578 )", 1579 Lang_CXX03); 1580 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>( 1581 [](const ClassTemplateDecl *T) { 1582 return T->isThisDeclarationADefinition(); 1583 }) 1584 .match(ToTU, classTemplateDecl())); 1585 1586 Decl *FromTU = getTuDecl( 1587 R"( 1588 template <typename T> 1589 struct B { 1590 void f(); 1591 }; 1592 )", 1593 Lang_CXX03, "input1.cc"); 1594 ClassTemplateDecl *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 1595 FromTU, classTemplateDecl(hasName("B"))); 1596 1597 Import(FromD, Lang_CXX03); 1598 1599 // We should have only one definition. 1600 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>( 1601 [](const ClassTemplateDecl *T) { 1602 return T->isThisDeclarationADefinition(); 1603 }) 1604 .match(ToTU, classTemplateDecl())); 1605 } 1606 1607 TEST_P(ASTImporterOptionSpecificTestBase, 1608 ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition) { 1609 Decl *ToTU = getToTuDecl( 1610 R"( 1611 struct B { 1612 void f(); 1613 }; 1614 1615 struct B; 1616 )", 1617 Lang_CXX03); 1618 ASSERT_EQ(2u, DeclCounter<CXXRecordDecl>().match( 1619 ToTU, cxxRecordDecl(unless(isImplicit())))); 1620 1621 Decl *FromTU = getTuDecl( 1622 R"( 1623 struct B { 1624 void f(); 1625 }; 1626 )", 1627 Lang_CXX03, "input1.cc"); 1628 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 1629 FromTU, cxxRecordDecl(hasName("B"))); 1630 1631 Import(FromD, Lang_CXX03); 1632 1633 EXPECT_EQ(2u, DeclCounter<CXXRecordDecl>().match( 1634 ToTU, cxxRecordDecl(unless(isImplicit())))); 1635 } 1636 1637 static void CompareSourceLocs(FullSourceLoc Loc1, FullSourceLoc Loc2) { 1638 EXPECT_EQ(Loc1.getExpansionLineNumber(), Loc2.getExpansionLineNumber()); 1639 EXPECT_EQ(Loc1.getExpansionColumnNumber(), Loc2.getExpansionColumnNumber()); 1640 EXPECT_EQ(Loc1.getSpellingLineNumber(), Loc2.getSpellingLineNumber()); 1641 EXPECT_EQ(Loc1.getSpellingColumnNumber(), Loc2.getSpellingColumnNumber()); 1642 } 1643 static void CompareSourceRanges(SourceRange Range1, SourceRange Range2, 1644 SourceManager &SM1, SourceManager &SM2) { 1645 CompareSourceLocs(FullSourceLoc{ Range1.getBegin(), SM1 }, 1646 FullSourceLoc{ Range2.getBegin(), SM2 }); 1647 CompareSourceLocs(FullSourceLoc{ Range1.getEnd(), SM1 }, 1648 FullSourceLoc{ Range2.getEnd(), SM2 }); 1649 } 1650 TEST_P(ASTImporterOptionSpecificTestBase, ImportSourceLocs) { 1651 Decl *FromTU = getTuDecl( 1652 R"( 1653 #define MFOO(arg) arg = arg + 1 1654 1655 void foo() { 1656 int a = 5; 1657 MFOO(a); 1658 } 1659 )", 1660 Lang_CXX03); 1661 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 1662 auto ToD = Import(FromD, Lang_CXX03); 1663 1664 auto ToLHS = LastDeclMatcher<DeclRefExpr>().match(ToD, declRefExpr()); 1665 auto FromLHS = LastDeclMatcher<DeclRefExpr>().match(FromTU, declRefExpr()); 1666 auto ToRHS = LastDeclMatcher<IntegerLiteral>().match(ToD, integerLiteral()); 1667 auto FromRHS = 1668 LastDeclMatcher<IntegerLiteral>().match(FromTU, integerLiteral()); 1669 1670 SourceManager &ToSM = ToAST->getASTContext().getSourceManager(); 1671 SourceManager &FromSM = FromD->getASTContext().getSourceManager(); 1672 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM, 1673 FromSM); 1674 CompareSourceRanges(ToLHS->getSourceRange(), FromLHS->getSourceRange(), ToSM, 1675 FromSM); 1676 CompareSourceRanges(ToRHS->getSourceRange(), FromRHS->getSourceRange(), ToSM, 1677 FromSM); 1678 } 1679 1680 TEST_P(ASTImporterOptionSpecificTestBase, ImportNestedMacro) { 1681 Decl *FromTU = getTuDecl( 1682 R"( 1683 #define FUNC_INT void declToImport 1684 #define FUNC FUNC_INT 1685 FUNC(int a); 1686 )", 1687 Lang_CXX03); 1688 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 1689 auto ToD = Import(FromD, Lang_CXX03); 1690 1691 SourceManager &ToSM = ToAST->getASTContext().getSourceManager(); 1692 SourceManager &FromSM = FromD->getASTContext().getSourceManager(); 1693 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM, 1694 FromSM); 1695 } 1696 1697 TEST_P( 1698 ASTImporterOptionSpecificTestBase, 1699 ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition) { 1700 Decl *ToTU = getToTuDecl( 1701 R"( 1702 template <typename T> 1703 struct B; 1704 1705 template <> 1706 struct B<int> {}; 1707 1708 template <> 1709 struct B<int>; 1710 )", 1711 Lang_CXX03); 1712 // We should have only one definition. 1713 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>( 1714 [](const ClassTemplateSpecializationDecl *T) { 1715 return T->isThisDeclarationADefinition(); 1716 }) 1717 .match(ToTU, classTemplateSpecializationDecl())); 1718 1719 Decl *FromTU = getTuDecl( 1720 R"( 1721 template <typename T> 1722 struct B; 1723 1724 template <> 1725 struct B<int> {}; 1726 )", 1727 Lang_CXX03, "input1.cc"); 1728 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 1729 FromTU, classTemplateSpecializationDecl(hasName("B"))); 1730 1731 Import(FromD, Lang_CXX03); 1732 1733 // We should have only one definition. 1734 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>( 1735 [](const ClassTemplateSpecializationDecl *T) { 1736 return T->isThisDeclarationADefinition(); 1737 }) 1738 .match(ToTU, classTemplateSpecializationDecl())); 1739 } 1740 1741 TEST_P(ASTImporterOptionSpecificTestBase, ObjectsWithUnnamedStructType) { 1742 Decl *FromTU = getTuDecl( 1743 R"( 1744 struct { int a; int b; } object0 = { 2, 3 }; 1745 struct { int x; int y; int z; } object1; 1746 )", 1747 Lang_CXX03, "input0.cc"); 1748 1749 auto *Obj0 = 1750 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object0"))); 1751 auto *From0 = getRecordDecl(Obj0); 1752 auto *Obj1 = 1753 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object1"))); 1754 auto *From1 = getRecordDecl(Obj1); 1755 1756 auto *To0 = Import(From0, Lang_CXX03); 1757 auto *To1 = Import(From1, Lang_CXX03); 1758 1759 EXPECT_TRUE(To0); 1760 EXPECT_TRUE(To1); 1761 EXPECT_NE(To0, To1); 1762 EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl()); 1763 } 1764 1765 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecords) { 1766 auto *Code = 1767 R"( 1768 struct X { 1769 struct { int a; }; 1770 struct { int b; }; 1771 }; 1772 )"; 1773 Decl *FromTU0 = getTuDecl(Code, Lang_C99, "input0.c"); 1774 1775 Decl *FromTU1 = getTuDecl(Code, Lang_C99, "input1.c"); 1776 1777 auto *X0 = 1778 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X"))); 1779 auto *X1 = 1780 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X"))); 1781 Import(X0, Lang_C99); 1782 Import(X1, Lang_C99); 1783 1784 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 1785 // We expect no (ODR) warning during the import. 1786 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 1787 EXPECT_EQ(1u, 1788 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X")))); 1789 } 1790 1791 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecordsReversed) { 1792 Decl *FromTU0 = getTuDecl( 1793 R"( 1794 struct X { 1795 struct { int a; }; 1796 struct { int b; }; 1797 }; 1798 )", 1799 Lang_C99, "input0.c"); 1800 1801 Decl *FromTU1 = getTuDecl( 1802 R"( 1803 struct X { // reversed order 1804 struct { int b; }; 1805 struct { int a; }; 1806 }; 1807 )", 1808 Lang_C99, "input1.c"); 1809 1810 auto *X0 = 1811 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X"))); 1812 auto *X1 = 1813 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X"))); 1814 Import(X0, Lang_C99); 1815 Import(X1, Lang_C99); 1816 1817 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 1818 // We expect one (ODR) warning during the import. 1819 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 1820 EXPECT_EQ(1u, 1821 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X")))); 1822 } 1823 1824 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag) { 1825 auto Pattern = varDecl(hasName("x")); 1826 VarDecl *Imported1; 1827 { 1828 Decl *FromTU = getTuDecl("extern int x;", Lang_CXX03, "input0.cc"); 1829 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 1830 Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 1831 } 1832 VarDecl *Imported2; 1833 { 1834 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input1.cc"); 1835 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 1836 Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 1837 } 1838 EXPECT_EQ(Imported1->getCanonicalDecl(), Imported2->getCanonicalDecl()); 1839 EXPECT_FALSE(Imported2->isUsed(false)); 1840 { 1841 Decl *FromTU = getTuDecl("extern int x; int f() { return x; }", Lang_CXX03, 1842 "input2.cc"); 1843 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 1844 FromTU, functionDecl(hasName("f"))); 1845 Import(FromD, Lang_CXX03); 1846 } 1847 EXPECT_TRUE(Imported2->isUsed(false)); 1848 } 1849 1850 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag2) { 1851 auto Pattern = varDecl(hasName("x")); 1852 VarDecl *ExistingD; 1853 { 1854 Decl *ToTU = getToTuDecl("int x = 1;", Lang_CXX03); 1855 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern); 1856 } 1857 EXPECT_FALSE(ExistingD->isUsed(false)); 1858 { 1859 Decl *FromTU = 1860 getTuDecl("int x = 1; int f() { return x; }", Lang_CXX03, "input1.cc"); 1861 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 1862 FromTU, functionDecl(hasName("f"))); 1863 Import(FromD, Lang_CXX03); 1864 } 1865 EXPECT_TRUE(ExistingD->isUsed(false)); 1866 } 1867 1868 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag3) { 1869 auto Pattern = varDecl(hasName("a")); 1870 VarDecl *ExistingD; 1871 { 1872 Decl *ToTU = getToTuDecl( 1873 R"( 1874 struct A { 1875 static const int a = 1; 1876 }; 1877 )", 1878 Lang_CXX03); 1879 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern); 1880 } 1881 EXPECT_FALSE(ExistingD->isUsed(false)); 1882 { 1883 Decl *FromTU = getTuDecl( 1884 R"( 1885 struct A { 1886 static const int a = 1; 1887 }; 1888 const int *f() { return &A::a; } // requires storage, 1889 // thus used flag will be set 1890 )", 1891 Lang_CXX03, "input1.cc"); 1892 auto *FromFunD = FirstDeclMatcher<FunctionDecl>().match( 1893 FromTU, functionDecl(hasName("f"))); 1894 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 1895 ASSERT_TRUE(FromD->isUsed(false)); 1896 Import(FromFunD, Lang_CXX03); 1897 } 1898 EXPECT_TRUE(ExistingD->isUsed(false)); 1899 } 1900 1901 TEST_P(ASTImporterOptionSpecificTestBase, ReimportWithUsedFlag) { 1902 auto Pattern = varDecl(hasName("x")); 1903 1904 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input0.cc"); 1905 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 1906 1907 auto *Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 1908 1909 ASSERT_FALSE(Imported1->isUsed(false)); 1910 1911 FromD->setIsUsed(); 1912 auto *Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 1913 1914 EXPECT_EQ(Imported1, Imported2); 1915 EXPECT_TRUE(Imported2->isUsed(false)); 1916 } 1917 1918 struct ImportFunctions : ASTImporterOptionSpecificTestBase {}; 1919 1920 TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) { 1921 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03); 1922 auto Pattern = functionDecl(hasName("f")); 1923 auto *From = 1924 FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Proto 1925 1926 Decl *ImportedD = Import(From, Lang_CXX03); 1927 Decl *ToTU = ImportedD->getTranslationUnitDecl(); 1928 1929 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 1930 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 1931 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 1932 EXPECT_TRUE(ImportedD == To0); 1933 EXPECT_FALSE(To0->doesThisDeclarationHaveABody()); 1934 EXPECT_TRUE(To1->doesThisDeclarationHaveABody()); 1935 EXPECT_EQ(To1->getPreviousDecl(), To0); 1936 } 1937 1938 TEST_P(ImportFunctions, ImportDefinitionOfRecursiveFunction) { 1939 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03); 1940 auto Pattern = functionDecl(hasName("f")); 1941 auto *From = 1942 LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Def 1943 1944 Decl *ImportedD = Import(From, Lang_CXX03); 1945 Decl *ToTU = ImportedD->getTranslationUnitDecl(); 1946 1947 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 1948 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 1949 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 1950 EXPECT_TRUE(ImportedD == To1); 1951 EXPECT_FALSE(To0->doesThisDeclarationHaveABody()); 1952 EXPECT_TRUE(To1->doesThisDeclarationHaveABody()); 1953 EXPECT_EQ(To1->getPreviousDecl(), To0); 1954 } 1955 1956 TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) { 1957 auto Code = 1958 R"( 1959 struct B { virtual void f(); }; 1960 void B::f() {} 1961 struct D : B { void f(); }; 1962 )"; 1963 auto Pattern = 1964 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 1965 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 1966 CXXMethodDecl *Proto = 1967 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern); 1968 1969 ASSERT_EQ(Proto->size_overridden_methods(), 1u); 1970 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03)); 1971 EXPECT_EQ(To->size_overridden_methods(), 1u); 1972 } 1973 1974 TEST_P(ImportFunctions, VirtualFlagShouldBePreservedWhenImportingPrototype) { 1975 auto Code = 1976 R"( 1977 struct B { virtual void f(); }; 1978 void B::f() {} 1979 )"; 1980 auto Pattern = 1981 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 1982 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 1983 CXXMethodDecl *Proto = 1984 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern); 1985 CXXMethodDecl *Def = LastDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern); 1986 1987 ASSERT_TRUE(Proto->isVirtual()); 1988 ASSERT_TRUE(Def->isVirtual()); 1989 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03)); 1990 EXPECT_TRUE(To->isVirtual()); 1991 } 1992 1993 TEST_P(ImportFunctions, 1994 ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl) { 1995 Decl *ToTU = getToTuDecl( 1996 R"( 1997 void f() {} 1998 void f(); 1999 )", 2000 Lang_CXX03); 2001 ASSERT_EQ(1u, 2002 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) { 2003 return FD->doesThisDeclarationHaveABody(); 2004 }).match(ToTU, functionDecl())); 2005 2006 Decl *FromTU = getTuDecl("void f() {}", Lang_CXX03, "input0.cc"); 2007 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 2008 2009 Import(FromD, Lang_CXX03); 2010 2011 EXPECT_EQ(1u, 2012 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) { 2013 return FD->doesThisDeclarationHaveABody(); 2014 }).match(ToTU, functionDecl())); 2015 } 2016 2017 TEST_P(ImportFunctions, ImportOverriddenMethodTwice) { 2018 auto Code = 2019 R"( 2020 struct B { virtual void f(); }; 2021 struct D:B { void f(); }; 2022 )"; 2023 auto BFP = 2024 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2025 auto DFP = 2026 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2027 2028 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03); 2029 auto *DF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP); 2030 Import(DF, Lang_CXX03); 2031 2032 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2033 auto *BF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP); 2034 Import(BF, Lang_CXX03); 2035 2036 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2037 2038 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2039 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u); 2040 } 2041 2042 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceDefinitionFirst) { 2043 auto CodeWithoutDef = 2044 R"( 2045 struct B { virtual void f(); }; 2046 struct D:B { void f(); }; 2047 )"; 2048 auto CodeWithDef = 2049 R"( 2050 struct B { virtual void f(){}; }; 2051 struct D:B { void f(){}; }; 2052 )"; 2053 auto BFP = 2054 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2055 auto DFP = 2056 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2057 auto BFDefP = cxxMethodDecl( 2058 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition()); 2059 auto DFDefP = cxxMethodDecl( 2060 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition()); 2061 auto FDefAllP = cxxMethodDecl(hasName("f"), isDefinition()); 2062 2063 { 2064 Decl *FromTU = getTuDecl(CodeWithDef, Lang_CXX03, "input0.cc"); 2065 auto *FromD = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, DFP); 2066 Import(FromD, Lang_CXX03); 2067 } 2068 { 2069 Decl *FromTU = getTuDecl(CodeWithoutDef, Lang_CXX03, "input1.cc"); 2070 auto *FromB = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, BFP); 2071 Import(FromB, Lang_CXX03); 2072 } 2073 2074 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2075 2076 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2077 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u); 2078 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 1u); 2079 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 1u); 2080 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FDefAllP), 2u); 2081 } 2082 2083 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceOutOfClassDef) { 2084 auto Code = 2085 R"( 2086 struct B { virtual void f(); }; 2087 struct D:B { void f(); }; 2088 void B::f(){}; 2089 )"; 2090 2091 auto BFP = 2092 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2093 auto BFDefP = cxxMethodDecl( 2094 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition()); 2095 auto DFP = cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), 2096 unless(isDefinition())); 2097 2098 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03); 2099 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP); 2100 Import(D, Lang_CXX03); 2101 2102 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2103 auto *B = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP); 2104 Import(B, Lang_CXX03); 2105 2106 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2107 2108 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2109 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u); 2110 2111 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match( 2112 ToTU, cxxRecordDecl(hasName("B"))); 2113 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP); 2114 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match( 2115 ToTU, cxxMethodDecl(hasName("f"), isDefinition())); 2116 2117 // The definition should be out-of-class. 2118 EXPECT_NE(ToBFInClass, ToBFOutOfClass); 2119 EXPECT_NE(ToBFInClass->getLexicalDeclContext(), 2120 ToBFOutOfClass->getLexicalDeclContext()); 2121 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB); 2122 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU); 2123 2124 // Check that the redecl chain is intact. 2125 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass); 2126 } 2127 2128 TEST_P(ImportFunctions, 2129 ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode) { 2130 auto CodeTU0 = 2131 R"( 2132 struct B { virtual void f(); }; 2133 struct D:B { void f(); }; 2134 )"; 2135 auto CodeTU1 = 2136 R"( 2137 struct B { virtual void f(); }; 2138 struct D:B { void f(); }; 2139 void B::f(){} 2140 void D::f(){} 2141 void foo(B &b, D &d) { b.f(); d.f(); } 2142 )"; 2143 2144 auto BFP = 2145 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2146 auto BFDefP = cxxMethodDecl( 2147 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition()); 2148 auto DFP = 2149 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2150 auto DFDefP = cxxMethodDecl( 2151 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition()); 2152 auto FooDef = functionDecl(hasName("foo")); 2153 2154 { 2155 Decl *FromTU0 = getTuDecl(CodeTU0, Lang_CXX03, "input0.cc"); 2156 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP); 2157 Import(D, Lang_CXX03); 2158 } 2159 2160 { 2161 Decl *FromTU1 = getTuDecl(CodeTU1, Lang_CXX03, "input1.cc"); 2162 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(FromTU1, FooDef); 2163 Import(Foo, Lang_CXX03); 2164 } 2165 2166 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2167 2168 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2169 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u); 2170 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u); 2171 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 0u); 2172 2173 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match( 2174 ToTU, cxxRecordDecl(hasName("B"))); 2175 auto *ToD = FirstDeclMatcher<CXXRecordDecl>().match( 2176 ToTU, cxxRecordDecl(hasName("D"))); 2177 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP); 2178 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match( 2179 ToTU, cxxMethodDecl(hasName("f"), isDefinition())); 2180 auto *ToDFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, DFP); 2181 auto *ToDFOutOfClass = LastDeclMatcher<CXXMethodDecl>().match( 2182 ToTU, cxxMethodDecl(hasName("f"), isDefinition())); 2183 2184 // The definition should be out-of-class. 2185 EXPECT_NE(ToBFInClass, ToBFOutOfClass); 2186 EXPECT_NE(ToBFInClass->getLexicalDeclContext(), 2187 ToBFOutOfClass->getLexicalDeclContext()); 2188 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB); 2189 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU); 2190 2191 EXPECT_NE(ToDFInClass, ToDFOutOfClass); 2192 EXPECT_NE(ToDFInClass->getLexicalDeclContext(), 2193 ToDFOutOfClass->getLexicalDeclContext()); 2194 EXPECT_EQ(ToDFOutOfClass->getDeclContext(), ToD); 2195 EXPECT_EQ(ToDFOutOfClass->getLexicalDeclContext(), ToTU); 2196 2197 // Check that the redecl chain is intact. 2198 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass); 2199 EXPECT_EQ(ToDFOutOfClass->getPreviousDecl(), ToDFInClass); 2200 } 2201 2202 TEST_P(ASTImporterOptionSpecificTestBase, ImportVariableChainInC) { 2203 std::string Code = "static int v; static int v = 0;"; 2204 auto Pattern = varDecl(hasName("v")); 2205 2206 TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_C99, "input0.c"); 2207 2208 auto *From0 = FirstDeclMatcher<VarDecl>().match(FromTu, Pattern); 2209 auto *From1 = LastDeclMatcher<VarDecl>().match(FromTu, Pattern); 2210 2211 auto *To0 = Import(From0, Lang_C99); 2212 auto *To1 = Import(From1, Lang_C99); 2213 2214 EXPECT_TRUE(To0); 2215 ASSERT_TRUE(To1); 2216 EXPECT_NE(To0, To1); 2217 EXPECT_EQ(To1->getPreviousDecl(), To0); 2218 } 2219 2220 TEST_P(ImportFunctions, ImportFromDifferentScopedAnonNamespace) { 2221 TranslationUnitDecl *FromTu = 2222 getTuDecl("namespace NS0 { namespace { void f(); } }" 2223 "namespace NS1 { namespace { void f(); } }", 2224 Lang_CXX03, "input0.cc"); 2225 auto Pattern = functionDecl(hasName("f")); 2226 2227 auto *FromF0 = FirstDeclMatcher<FunctionDecl>().match(FromTu, Pattern); 2228 auto *FromF1 = LastDeclMatcher<FunctionDecl>().match(FromTu, Pattern); 2229 2230 auto *ToF0 = Import(FromF0, Lang_CXX03); 2231 auto *ToF1 = Import(FromF1, Lang_CXX03); 2232 2233 EXPECT_TRUE(ToF0); 2234 ASSERT_TRUE(ToF1); 2235 EXPECT_NE(ToF0, ToF1); 2236 EXPECT_FALSE(ToF1->getPreviousDecl()); 2237 } 2238 2239 TEST_P(ImportFunctions, ImportFunctionFromUnnamedNamespace) { 2240 { 2241 Decl *FromTU = getTuDecl("namespace { void f() {} } void g0() { f(); }", 2242 Lang_CXX03, "input0.cc"); 2243 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2244 FromTU, functionDecl(hasName("g0"))); 2245 2246 Import(FromD, Lang_CXX03); 2247 } 2248 { 2249 Decl *FromTU = 2250 getTuDecl("namespace { void f() { int a; } } void g1() { f(); }", 2251 Lang_CXX03, "input1.cc"); 2252 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2253 FromTU, functionDecl(hasName("g1"))); 2254 Import(FromD, Lang_CXX03); 2255 } 2256 2257 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2258 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))), 2259 2u); 2260 } 2261 2262 TEST_P(ImportFunctions, ImportImplicitFunctionsInLambda) { 2263 Decl *FromTU = getTuDecl( 2264 R"( 2265 void foo() { 2266 (void)[]() { ; }; 2267 } 2268 )", 2269 Lang_CXX11); 2270 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2271 FromTU, functionDecl(hasName("foo"))); 2272 auto *ToD = Import(FromD, Lang_CXX03); 2273 EXPECT_TRUE(ToD); 2274 CXXRecordDecl *LambdaRec = 2275 cast<LambdaExpr>(cast<CStyleCastExpr>( 2276 *cast<CompoundStmt>(ToD->getBody())->body_begin()) 2277 ->getSubExpr()) 2278 ->getLambdaClass(); 2279 EXPECT_TRUE(LambdaRec->getDestructor()); 2280 } 2281 2282 TEST_P(ImportFunctions, 2283 CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) { 2284 Decl *FromTU = getTuDecl( 2285 R"( 2286 struct X { 2287 template <typename T> 2288 void foo(){} 2289 }; 2290 void f() { 2291 X x; 2292 x.foo<int>(); 2293 } 2294 )", 2295 Lang_CXX03); 2296 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2297 FromTU, functionDecl(hasName("f"))); 2298 auto *ToD = Import(FromD, Lang_CXX03); 2299 EXPECT_TRUE(ToD); 2300 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match( 2301 ToD, functionDecl(hasName("f"), hasDescendant(declRefExpr())))); 2302 } 2303 2304 TEST_P(ImportFunctions, 2305 DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) { 2306 Decl *FromTU = getTuDecl( 2307 R"( 2308 struct X { 2309 template <typename T> 2310 void foo(){} 2311 }; 2312 template <typename T> 2313 void f() { 2314 X x; 2315 x.foo<T>(); 2316 } 2317 void g() { 2318 f<int>(); 2319 } 2320 )", 2321 Lang_CXX03); 2322 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2323 FromTU, functionDecl(hasName("g"))); 2324 auto *ToD = Import(FromD, Lang_CXX03); 2325 EXPECT_TRUE(ToD); 2326 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2327 EXPECT_TRUE(MatchVerifier<TranslationUnitDecl>().match( 2328 ToTU, translationUnitDecl(hasDescendant( 2329 functionDecl(hasName("f"), hasDescendant(declRefExpr())))))); 2330 } 2331 2332 struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {}; 2333 2334 TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) { 2335 auto Code = 2336 R"( 2337 class X { 2338 template <class T> 2339 void f(T t); 2340 }; 2341 )"; 2342 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2343 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2344 FromTU1, functionTemplateDecl(hasName("f"))); 2345 auto *ToD1 = Import(FromD1, Lang_CXX03); 2346 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc"); 2347 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2348 FromTU2, functionTemplateDecl(hasName("f"))); 2349 auto *ToD2 = Import(FromD2, Lang_CXX03); 2350 EXPECT_EQ(ToD1, ToD2); 2351 } 2352 2353 TEST_P(ImportFunctionTemplates, 2354 ImportFunctionTemplateWithDefInRecordDeclTwice) { 2355 auto Code = 2356 R"( 2357 class X { 2358 template <class T> 2359 void f(T t); 2360 }; 2361 template <class T> 2362 void X::f(T t) {}; 2363 )"; 2364 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2365 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2366 FromTU1, functionTemplateDecl(hasName("f"))); 2367 auto *ToD1 = Import(FromD1, Lang_CXX03); 2368 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc"); 2369 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2370 FromTU2, functionTemplateDecl(hasName("f"))); 2371 auto *ToD2 = Import(FromD2, Lang_CXX03); 2372 EXPECT_EQ(ToD1, ToD2); 2373 } 2374 2375 TEST_P(ImportFunctionTemplates, 2376 ImportFunctionWhenThereIsAFunTemplateWithSameName) { 2377 getToTuDecl( 2378 R"( 2379 template <typename T> 2380 void foo(T) {} 2381 void foo(); 2382 )", 2383 Lang_CXX03); 2384 Decl *FromTU = getTuDecl("void foo();", Lang_CXX03); 2385 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2386 FromTU, functionDecl(hasName("foo"))); 2387 auto *ImportedD = Import(FromD, Lang_CXX03); 2388 EXPECT_TRUE(ImportedD); 2389 } 2390 2391 TEST_P(ImportFunctionTemplates, 2392 ImportConstructorWhenThereIsAFunTemplateWithSameName) { 2393 auto Code = 2394 R"( 2395 struct Foo { 2396 template <typename T> 2397 Foo(T) {} 2398 Foo(); 2399 }; 2400 )"; 2401 getToTuDecl(Code, Lang_CXX03); 2402 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 2403 auto *FromD = 2404 LastDeclMatcher<CXXConstructorDecl>().match(FromTU, cxxConstructorDecl()); 2405 auto *ImportedD = Import(FromD, Lang_CXX03); 2406 EXPECT_TRUE(ImportedD); 2407 } 2408 2409 TEST_P(ImportFunctionTemplates, 2410 ImportOperatorWhenThereIsAFunTemplateWithSameName) { 2411 getToTuDecl( 2412 R"( 2413 template <typename T> 2414 void operator<(T,T) {} 2415 struct X{}; 2416 void operator<(X, X); 2417 )", 2418 Lang_CXX03); 2419 Decl *FromTU = getTuDecl( 2420 R"( 2421 struct X{}; 2422 void operator<(X, X); 2423 )", 2424 Lang_CXX03); 2425 auto *FromD = LastDeclMatcher<FunctionDecl>().match( 2426 FromTU, functionDecl(hasOverloadedOperatorName("<"))); 2427 auto *ImportedD = Import(FromD, Lang_CXX03); 2428 EXPECT_TRUE(ImportedD); 2429 } 2430 2431 struct ImportFriendFunctions : ImportFunctions {}; 2432 2433 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) { 2434 auto Pattern = functionDecl(hasName("f")); 2435 2436 Decl *FromTU = getTuDecl("struct X { friend void f(); };" 2437 "void f();", 2438 Lang_CXX03, "input0.cc"); 2439 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2440 2441 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2442 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2443 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2444 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2445 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2446 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody()); 2447 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2448 } 2449 2450 TEST_P(ImportFriendFunctions, 2451 ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst) { 2452 auto Pattern = functionDecl(hasName("f")); 2453 2454 Decl *FromTU = getTuDecl("void f();" 2455 "struct X { friend void f(); };", 2456 Lang_CXX03, "input0.cc"); 2457 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2458 2459 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2460 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2461 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2462 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2463 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2464 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody()); 2465 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2466 } 2467 2468 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDef) { 2469 auto Pattern = functionDecl(hasName("f")); 2470 2471 Decl *FromTU = getTuDecl("struct X { friend void f(){} };" 2472 "void f();", 2473 Lang_CXX03, "input0.cc"); 2474 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2475 2476 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2477 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2478 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2479 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody()); 2480 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2481 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody()); 2482 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2483 } 2484 2485 TEST_P(ImportFriendFunctions, 2486 ImportFriendFunctionRedeclChainDef_OutOfClassDef) { 2487 auto Pattern = functionDecl(hasName("f")); 2488 2489 Decl *FromTU = getTuDecl("struct X { friend void f(); };" 2490 "void f(){}", 2491 Lang_CXX03, "input0.cc"); 2492 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2493 2494 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2495 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2496 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2497 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2498 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2499 EXPECT_TRUE(ToFD->doesThisDeclarationHaveABody()); 2500 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2501 } 2502 2503 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDefWithClass) { 2504 auto Pattern = functionDecl(hasName("f")); 2505 2506 Decl *FromTU = getTuDecl( 2507 R"( 2508 class X; 2509 void f(X *x){} 2510 class X{ 2511 friend void f(X *x); 2512 }; 2513 )", 2514 Lang_CXX03, "input0.cc"); 2515 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2516 2517 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2518 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2519 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2520 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody()); 2521 auto *InClassFD = cast<FunctionDecl>(FirstDeclMatcher<FriendDecl>() 2522 .match(ToTU, friendDecl()) 2523 ->getFriendDecl()); 2524 EXPECT_FALSE(InClassFD->doesThisDeclarationHaveABody()); 2525 EXPECT_EQ(InClassFD->getPreviousDecl(), ImportedD); 2526 // The parameters must refer the same type 2527 EXPECT_EQ((*InClassFD->param_begin())->getOriginalType(), 2528 (*ImportedD->param_begin())->getOriginalType()); 2529 } 2530 2531 TEST_P(ImportFriendFunctions, 2532 ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) { 2533 auto Pattern = functionDecl(hasName("f")); 2534 2535 Decl *FromTU = getTuDecl( 2536 R"( 2537 class X; 2538 void f(X *x){} 2539 class X{ 2540 friend void f(X *x); 2541 }; 2542 )", 2543 Lang_CXX03, "input0.cc"); 2544 auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2545 2546 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2547 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2548 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2549 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2550 auto *OutOfClassFD = FirstDeclMatcher<FunctionDecl>().match( 2551 ToTU, functionDecl(unless(hasParent(friendDecl())))); 2552 2553 EXPECT_TRUE(OutOfClassFD->doesThisDeclarationHaveABody()); 2554 EXPECT_EQ(ImportedD->getPreviousDecl(), OutOfClassFD); 2555 // The parameters must refer the same type 2556 EXPECT_EQ((*OutOfClassFD->param_begin())->getOriginalType(), 2557 (*ImportedD->param_begin())->getOriginalType()); 2558 } 2559 2560 TEST_P(ImportFriendFunctions, ImportFriendFunctionFromMultipleTU) { 2561 auto Pattern = functionDecl(hasName("f")); 2562 2563 FunctionDecl *ImportedD; 2564 { 2565 Decl *FromTU = 2566 getTuDecl("struct X { friend void f(){} };", Lang_CXX03, "input0.cc"); 2567 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2568 ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2569 } 2570 FunctionDecl *ImportedD1; 2571 { 2572 Decl *FromTU = getTuDecl("void f();", Lang_CXX03, "input1.cc"); 2573 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2574 ImportedD1 = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2575 } 2576 2577 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2578 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2579 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody()); 2580 EXPECT_FALSE(ImportedD1->doesThisDeclarationHaveABody()); 2581 EXPECT_EQ(ImportedD1->getPreviousDecl(), ImportedD); 2582 } 2583 2584 TEST_P(ImportFriendFunctions, Lookup) { 2585 auto FunctionPattern = functionDecl(hasName("f")); 2586 auto ClassPattern = cxxRecordDecl(hasName("X")); 2587 2588 TranslationUnitDecl *FromTU = 2589 getTuDecl("struct X { friend void f(); };", Lang_CXX03, "input0.cc"); 2590 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2591 ASSERT_TRUE(FromD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2592 ASSERT_FALSE(FromD->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2593 { 2594 auto FromName = FromD->getDeclName(); 2595 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern); 2596 auto LookupRes = Class->noload_lookup(FromName); 2597 ASSERT_TRUE(LookupRes.empty()); 2598 LookupRes = FromTU->noload_lookup(FromName); 2599 ASSERT_TRUE(LookupRes.isSingleResult()); 2600 } 2601 2602 auto *ToD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2603 auto ToName = ToD->getDeclName(); 2604 2605 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2606 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern); 2607 auto LookupRes = Class->noload_lookup(ToName); 2608 EXPECT_TRUE(LookupRes.empty()); 2609 LookupRes = ToTU->noload_lookup(ToName); 2610 EXPECT_TRUE(LookupRes.isSingleResult()); 2611 2612 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 1u); 2613 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2614 EXPECT_TRUE(To0->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2615 EXPECT_FALSE(To0->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2616 } 2617 2618 TEST_P(ImportFriendFunctions, LookupWithProtoAfter) { 2619 auto FunctionPattern = functionDecl(hasName("f")); 2620 auto ClassPattern = cxxRecordDecl(hasName("X")); 2621 2622 TranslationUnitDecl *FromTU = 2623 getTuDecl("struct X { friend void f(); };" 2624 // This proto decl makes f available to normal 2625 // lookup, otherwise it is hidden. 2626 // Normal C++ lookup (implemented in 2627 // `clang::Sema::CppLookupName()` and in `LookupDirect()`) 2628 // returns the found `NamedDecl` only if the set IDNS is matched 2629 "void f();", 2630 Lang_CXX03, "input0.cc"); 2631 auto *FromFriend = 2632 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2633 auto *FromNormal = 2634 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2635 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2636 ASSERT_FALSE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2637 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2638 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2639 2640 auto FromName = FromFriend->getDeclName(); 2641 auto *FromClass = 2642 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern); 2643 auto LookupRes = FromClass->noload_lookup(FromName); 2644 ASSERT_TRUE(LookupRes.empty()); 2645 LookupRes = FromTU->noload_lookup(FromName); 2646 ASSERT_TRUE(LookupRes.isSingleResult()); 2647 2648 auto *ToFriend = cast<FunctionDecl>(Import(FromFriend, Lang_CXX03)); 2649 auto ToName = ToFriend->getDeclName(); 2650 2651 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2652 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern); 2653 LookupRes = ToClass->noload_lookup(ToName); 2654 EXPECT_TRUE(LookupRes.empty()); 2655 LookupRes = ToTU->noload_lookup(ToName); 2656 // Test is disabled because this result is 2. 2657 EXPECT_TRUE(LookupRes.isSingleResult()); 2658 2659 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u); 2660 ToFriend = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2661 auto *ToNormal = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2662 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2663 EXPECT_FALSE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2664 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2665 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2666 } 2667 2668 TEST_P(ImportFriendFunctions, LookupWithProtoBefore) { 2669 auto FunctionPattern = functionDecl(hasName("f")); 2670 auto ClassPattern = cxxRecordDecl(hasName("X")); 2671 2672 TranslationUnitDecl *FromTU = getTuDecl("void f();" 2673 "struct X { friend void f(); };", 2674 Lang_CXX03, "input0.cc"); 2675 auto *FromNormal = 2676 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2677 auto *FromFriend = 2678 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2679 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2680 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2681 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2682 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2683 2684 auto FromName = FromNormal->getDeclName(); 2685 auto *FromClass = 2686 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern); 2687 auto LookupRes = FromClass->noload_lookup(FromName); 2688 ASSERT_TRUE(LookupRes.empty()); 2689 LookupRes = FromTU->noload_lookup(FromName); 2690 ASSERT_TRUE(LookupRes.isSingleResult()); 2691 2692 auto *ToNormal = cast<FunctionDecl>(Import(FromNormal, Lang_CXX03)); 2693 auto ToName = ToNormal->getDeclName(); 2694 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2695 2696 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern); 2697 LookupRes = ToClass->noload_lookup(ToName); 2698 EXPECT_TRUE(LookupRes.empty()); 2699 LookupRes = ToTU->noload_lookup(ToName); 2700 EXPECT_TRUE(LookupRes.isSingleResult()); 2701 2702 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u); 2703 ToNormal = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2704 auto *ToFriend = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2705 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2706 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2707 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2708 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2709 } 2710 2711 TEST_P(ImportFriendFunctions, ImportFriendChangesLookup) { 2712 auto Pattern = functionDecl(hasName("f")); 2713 2714 TranslationUnitDecl *FromNormalTU = 2715 getTuDecl("void f();", Lang_CXX03, "input0.cc"); 2716 auto *FromNormalF = 2717 FirstDeclMatcher<FunctionDecl>().match(FromNormalTU, Pattern); 2718 TranslationUnitDecl *FromFriendTU = 2719 getTuDecl("class X { friend void f(); };", Lang_CXX03, "input1.cc"); 2720 auto *FromFriendF = 2721 FirstDeclMatcher<FunctionDecl>().match(FromFriendTU, Pattern); 2722 auto FromNormalName = FromNormalF->getDeclName(); 2723 auto FromFriendName = FromFriendF->getDeclName(); 2724 2725 ASSERT_TRUE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2726 ASSERT_FALSE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2727 ASSERT_FALSE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2728 ASSERT_TRUE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2729 auto LookupRes = FromNormalTU->noload_lookup(FromNormalName); 2730 ASSERT_TRUE(LookupRes.isSingleResult()); 2731 LookupRes = FromFriendTU->noload_lookup(FromFriendName); 2732 ASSERT_TRUE(LookupRes.isSingleResult()); 2733 2734 auto *ToNormalF = cast<FunctionDecl>(Import(FromNormalF, Lang_CXX03)); 2735 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2736 auto ToName = ToNormalF->getDeclName(); 2737 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2738 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2739 LookupRes = ToTU->noload_lookup(ToName); 2740 EXPECT_TRUE(LookupRes.isSingleResult()); 2741 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u); 2742 2743 auto *ToFriendF = cast<FunctionDecl>(Import(FromFriendF, Lang_CXX03)); 2744 LookupRes = ToTU->noload_lookup(ToName); 2745 EXPECT_TRUE(LookupRes.isSingleResult()); 2746 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2747 2748 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2749 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2750 2751 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2752 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2753 } 2754 2755 TEST_P(ImportFriendFunctions, ImportFriendList) { 2756 TranslationUnitDecl *FromTU = getTuDecl("struct X { friend void f(); };" 2757 "void f();", 2758 Lang_CXX03, "input0.cc"); 2759 auto *FromFriendF = FirstDeclMatcher<FunctionDecl>().match( 2760 FromTU, functionDecl(hasName("f"))); 2761 2762 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( 2763 FromTU, cxxRecordDecl(hasName("X"))); 2764 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl()); 2765 auto FromFriends = FromClass->friends(); 2766 unsigned int FrN = 0; 2767 for (auto Fr : FromFriends) { 2768 ASSERT_EQ(Fr, FromFriend); 2769 ++FrN; 2770 } 2771 ASSERT_EQ(FrN, 1u); 2772 2773 Import(FromFriendF, Lang_CXX03); 2774 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2775 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match( 2776 ToTU, cxxRecordDecl(hasName("X"))); 2777 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 2778 auto ToFriends = ToClass->friends(); 2779 FrN = 0; 2780 for (auto Fr : ToFriends) { 2781 EXPECT_EQ(Fr, ToFriend); 2782 ++FrN; 2783 } 2784 EXPECT_EQ(FrN, 1u); 2785 } 2786 2787 AST_MATCHER_P(TagDecl, hasTypedefForAnonDecl, Matcher<TypedefNameDecl>, 2788 InnerMatcher) { 2789 if (auto *Typedef = Node.getTypedefNameForAnonDecl()) 2790 return InnerMatcher.matches(*Typedef, Finder, Builder); 2791 return false; 2792 } 2793 2794 TEST_P(ImportDecl, ImportEnumSequential) { 2795 CodeFiles Samples{{"main.c", 2796 {"void foo();" 2797 "void moo();" 2798 "int main() { foo(); moo(); }", 2799 Lang_C99}}, 2800 2801 {"foo.c", 2802 {"typedef enum { THING_VALUE } thing_t;" 2803 "void conflict(thing_t type);" 2804 "void foo() { (void)THING_VALUE; }" 2805 "void conflict(thing_t type) {}", 2806 Lang_C99}}, 2807 2808 {"moo.c", 2809 {"typedef enum { THING_VALUE } thing_t;" 2810 "void conflict(thing_t type);" 2811 "void moo() { conflict(THING_VALUE); }", 2812 Lang_C99}}}; 2813 2814 auto VerificationMatcher = 2815 enumDecl(has(enumConstantDecl(hasName("THING_VALUE"))), 2816 hasTypedefForAnonDecl(hasName("thing_t"))); 2817 2818 ImportAction ImportFoo{"foo.c", "main.c", functionDecl(hasName("foo"))}, 2819 ImportMoo{"moo.c", "main.c", functionDecl(hasName("moo"))}; 2820 2821 testImportSequence( 2822 Samples, {ImportFoo, ImportMoo}, // "foo", them "moo". 2823 // Just check that there is only one enum decl in the result AST. 2824 "main.c", enumDecl(), VerificationMatcher); 2825 2826 // For different import order, result should be the same. 2827 testImportSequence( 2828 Samples, {ImportMoo, ImportFoo}, // "moo", them "foo". 2829 // Check that there is only one enum decl in the result AST. 2830 "main.c", enumDecl(), VerificationMatcher); 2831 } 2832 2833 TEST_P(ImportDecl, ImportFieldOrder) { 2834 MatchVerifier<Decl> Verifier; 2835 testImport("struct declToImport {" 2836 " int b = a + 2;" 2837 " int a = 5;" 2838 "};", 2839 Lang_CXX11, "", Lang_CXX11, Verifier, 2840 recordDecl(hasFieldOrder({"b", "a"}))); 2841 } 2842 2843 const internal::VariadicDynCastAllOfMatcher<Expr, DependentScopeDeclRefExpr> 2844 dependentScopeDeclRefExpr; 2845 2846 TEST_P(ImportExpr, DependentScopeDeclRefExpr) { 2847 MatchVerifier<Decl> Verifier; 2848 testImport("template <typename T> struct S { static T foo; };" 2849 "template <typename T> void declToImport() {" 2850 " (void) S<T>::foo;" 2851 "}" 2852 "void instantiate() { declToImport<int>(); }" 2853 "template <typename T> T S<T>::foo;", 2854 Lang_CXX11, "", Lang_CXX11, Verifier, 2855 functionTemplateDecl(has(functionDecl(has(compoundStmt( 2856 has(cStyleCastExpr(has(dependentScopeDeclRefExpr()))))))))); 2857 2858 testImport("template <typename T> struct S {" 2859 "template<typename S> static void foo(){};" 2860 "};" 2861 "template <typename T> void declToImport() {" 2862 " S<T>::template foo<T>();" 2863 "}" 2864 "void instantiate() { declToImport<int>(); }", 2865 Lang_CXX11, "", Lang_CXX11, Verifier, 2866 functionTemplateDecl(has(functionDecl(has(compoundStmt( 2867 has(callExpr(has(dependentScopeDeclRefExpr()))))))))); 2868 } 2869 2870 const internal::VariadicDynCastAllOfMatcher<Type, DependentNameType> 2871 dependentNameType; 2872 2873 TEST_P(ImportExpr, DependentNameType) { 2874 MatchVerifier<Decl> Verifier; 2875 testImport("template <typename T> struct declToImport {" 2876 " typedef typename T::type dependent_name;" 2877 "};", 2878 Lang_CXX11, "", Lang_CXX11, Verifier, 2879 classTemplateDecl(has( 2880 cxxRecordDecl(has(typedefDecl(has(dependentNameType()))))))); 2881 } 2882 2883 TEST_P(ImportExpr, UnresolvedMemberExpr) { 2884 MatchVerifier<Decl> Verifier; 2885 testImport("struct S { template <typename T> void mem(); };" 2886 "template <typename U> void declToImport() {" 2887 " S s;" 2888 " s.mem<U>();" 2889 "}" 2890 "void instantiate() { declToImport<int>(); }", 2891 Lang_CXX11, "", Lang_CXX11, Verifier, 2892 functionTemplateDecl(has(functionDecl(has( 2893 compoundStmt(has(callExpr(has(unresolvedMemberExpr()))))))))); 2894 } 2895 2896 class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase { 2897 public: 2898 static constexpr auto DefaultCode = R"( 2899 struct A { int x; }; 2900 void f() { 2901 A a; 2902 A a1(a); 2903 A a2(A{}); 2904 a = a1; 2905 a = A{}; 2906 a.~A(); 2907 })"; 2908 2909 template <typename MatcherType> 2910 void testImportOf( 2911 const MatcherType &MethodMatcher, const char *Code = DefaultCode) { 2912 test(MethodMatcher, Code, /*ExpectedCount=*/1u); 2913 } 2914 2915 template <typename MatcherType> 2916 void testNoImportOf( 2917 const MatcherType &MethodMatcher, const char *Code = DefaultCode) { 2918 test(MethodMatcher, Code, /*ExpectedCount=*/0u); 2919 } 2920 2921 private: 2922 template <typename MatcherType> 2923 void test(const MatcherType &MethodMatcher, 2924 const char *Code, unsigned int ExpectedCount) { 2925 auto ClassMatcher = cxxRecordDecl(unless(isImplicit())); 2926 2927 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 2928 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match( 2929 ToTU, ClassMatcher); 2930 2931 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 1u); 2932 2933 { 2934 CXXMethodDecl *Method = 2935 FirstDeclMatcher<CXXMethodDecl>().match(ToClass, MethodMatcher); 2936 ToClass->removeDecl(Method); 2937 SharedStatePtr->getLookupTable()->remove(Method); 2938 } 2939 2940 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 0u); 2941 2942 Decl *ImportedClass = nullptr; 2943 { 2944 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input1.cc"); 2945 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( 2946 FromTU, ClassMatcher); 2947 ImportedClass = Import(FromClass, Lang_CXX11); 2948 } 2949 2950 EXPECT_EQ(ToClass, ImportedClass); 2951 EXPECT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 2952 ExpectedCount); 2953 } 2954 }; 2955 2956 TEST_P(ImportImplicitMethods, DefaultConstructor) { 2957 testImportOf(cxxConstructorDecl(isDefaultConstructor())); 2958 } 2959 2960 TEST_P(ImportImplicitMethods, CopyConstructor) { 2961 testImportOf(cxxConstructorDecl(isCopyConstructor())); 2962 } 2963 2964 TEST_P(ImportImplicitMethods, MoveConstructor) { 2965 testImportOf(cxxConstructorDecl(isMoveConstructor())); 2966 } 2967 2968 TEST_P(ImportImplicitMethods, Destructor) { 2969 testImportOf(cxxDestructorDecl()); 2970 } 2971 2972 TEST_P(ImportImplicitMethods, CopyAssignment) { 2973 testImportOf(cxxMethodDecl(isCopyAssignmentOperator())); 2974 } 2975 2976 TEST_P(ImportImplicitMethods, MoveAssignment) { 2977 testImportOf(cxxMethodDecl(isMoveAssignmentOperator())); 2978 } 2979 2980 TEST_P(ImportImplicitMethods, DoNotImportUserProvided) { 2981 auto Code = R"( 2982 struct A { A() { int x; } }; 2983 )"; 2984 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); 2985 } 2986 2987 TEST_P(ImportImplicitMethods, DoNotImportDefault) { 2988 auto Code = R"( 2989 struct A { A() = default; }; 2990 )"; 2991 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); 2992 } 2993 2994 TEST_P(ImportImplicitMethods, DoNotImportDeleted) { 2995 auto Code = R"( 2996 struct A { A() = delete; }; 2997 )"; 2998 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); 2999 } 3000 3001 TEST_P(ImportImplicitMethods, DoNotImportOtherMethod) { 3002 auto Code = R"( 3003 struct A { void f() { } }; 3004 )"; 3005 testNoImportOf(cxxMethodDecl(hasName("f")), Code); 3006 } 3007 3008 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentRecord) { 3009 Decl *ToR1; 3010 { 3011 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input0.cc"); 3012 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3013 FromTU, cxxRecordDecl(hasName("A"))); 3014 3015 ToR1 = Import(FromR, Lang_CXX03); 3016 } 3017 3018 Decl *ToR2; 3019 { 3020 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input1.cc"); 3021 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3022 FromTU, cxxRecordDecl(hasName("A"))); 3023 3024 ToR2 = Import(FromR, Lang_CXX03); 3025 } 3026 3027 EXPECT_EQ(ToR1, ToR2); 3028 } 3029 3030 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentRecord) { 3031 Decl *ToR1; 3032 { 3033 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc"); 3034 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3035 FromTU, cxxRecordDecl(hasName("A"))); 3036 ToR1 = Import(FromR, Lang_CXX03); 3037 } 3038 Decl *ToR2; 3039 { 3040 Decl *FromTU = 3041 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc"); 3042 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3043 FromTU, cxxRecordDecl(hasName("A"))); 3044 ToR2 = Import(FromR, Lang_CXX03); 3045 } 3046 EXPECT_NE(ToR1, ToR2); 3047 } 3048 3049 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentField) { 3050 Decl *ToF1; 3051 { 3052 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc"); 3053 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3054 FromTU, fieldDecl(hasName("x"))); 3055 ToF1 = Import(FromF, Lang_CXX03); 3056 } 3057 Decl *ToF2; 3058 { 3059 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input1.cc"); 3060 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3061 FromTU, fieldDecl(hasName("x"))); 3062 ToF2 = Import(FromF, Lang_CXX03); 3063 } 3064 EXPECT_EQ(ToF1, ToF2); 3065 } 3066 3067 TEST_P(ASTImporterOptionSpecificTestBase, ImportBitfields) { 3068 Decl *FromTU = getTuDecl("struct A { unsigned x : 3; };", Lang_CXX03); 3069 auto *FromF = 3070 FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("x"))); 3071 3072 ASSERT_TRUE(FromF->isBitField()); 3073 ASSERT_EQ(3u, FromF->getBitWidthValue(FromTU->getASTContext())); 3074 auto *ToField = Import(FromF, Lang_CXX03); 3075 auto *ToTU = ToField->getTranslationUnitDecl(); 3076 3077 EXPECT_TRUE(ToField->isBitField()); 3078 EXPECT_EQ(3u, ToField->getBitWidthValue(ToTU->getASTContext())); 3079 3080 const auto *FromBT = FromF->getBitWidth()->getType()->getAs<BuiltinType>(); 3081 const auto *ToBT = ToField->getBitWidth()->getType()->getAs<BuiltinType>(); 3082 ASSERT_TRUE(FromBT); 3083 ASSERT_EQ(BuiltinType::Int, FromBT->getKind()); 3084 EXPECT_TRUE(ToBT); 3085 EXPECT_EQ(BuiltinType::Int, ToBT->getKind()); 3086 } 3087 3088 struct ImportBlock : ASTImporterOptionSpecificTestBase {}; 3089 TEST_P(ImportBlock, ImportBlocksAreUnsupported) { 3090 const auto *Code = R"( 3091 void test_block__capture_null() { 3092 int *p = 0; 3093 ^(){ 3094 *p = 1; 3095 }(); 3096 })"; 3097 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 3098 auto *FromBlock = FirstDeclMatcher<BlockDecl>().match(FromTU, blockDecl()); 3099 ASSERT_TRUE(FromBlock); 3100 3101 auto ToBlockOrError = importOrError(FromBlock, Lang_CXX03); 3102 3103 const auto ExpectUnsupportedConstructError = [](const ImportError &Error) { 3104 EXPECT_EQ(ImportError::UnsupportedConstruct, Error.Error); 3105 }; 3106 llvm::handleAllErrors(ToBlockOrError.takeError(), 3107 ExpectUnsupportedConstructError); 3108 } 3109 3110 TEST_P(ASTImporterOptionSpecificTestBase, ImportParmVarDecl) { 3111 const auto *Code = R"( 3112 template <typename T> struct Wrapper { 3113 Wrapper(T Value = {}) {} 3114 }; 3115 template class Wrapper<int>; 3116 )"; 3117 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3118 auto *FromVar = FirstDeclMatcher<ParmVarDecl>().match( 3119 FromTU, parmVarDecl(hasType(asString("int")))); 3120 ASSERT_TRUE(FromVar); 3121 ASSERT_TRUE(FromVar->hasUninstantiatedDefaultArg()); 3122 ASSERT_TRUE(FromVar->getUninstantiatedDefaultArg()); 3123 3124 const auto *ToVar = Import(FromVar, Lang_CXX11); 3125 EXPECT_TRUE(ToVar); 3126 EXPECT_TRUE(ToVar->hasUninstantiatedDefaultArg()); 3127 EXPECT_TRUE(ToVar->getUninstantiatedDefaultArg()); 3128 EXPECT_NE(FromVar->getUninstantiatedDefaultArg(), 3129 ToVar->getUninstantiatedDefaultArg()); 3130 } 3131 3132 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentField) { 3133 Decl *ToF1; 3134 { 3135 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc"); 3136 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3137 FromTU, fieldDecl(hasName("x"))); 3138 ToF1 = Import(FromF, Lang_CXX03); 3139 } 3140 Decl *ToF2; 3141 { 3142 Decl *FromTU = 3143 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc"); 3144 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3145 FromTU, fieldDecl(hasName("x"))); 3146 ToF2 = Import(FromF, Lang_CXX03); 3147 } 3148 EXPECT_NE(ToF1, ToF2); 3149 } 3150 3151 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentMethod) { 3152 Decl *ToM1; 3153 { 3154 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }", 3155 Lang_CXX03, "input0.cc"); 3156 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3157 FromTU, functionDecl(hasName("x"), isDefinition())); 3158 ToM1 = Import(FromM, Lang_CXX03); 3159 } 3160 Decl *ToM2; 3161 { 3162 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }", 3163 Lang_CXX03, "input1.cc"); 3164 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3165 FromTU, functionDecl(hasName("x"), isDefinition())); 3166 ToM2 = Import(FromM, Lang_CXX03); 3167 } 3168 EXPECT_EQ(ToM1, ToM2); 3169 } 3170 3171 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentMethod) { 3172 Decl *ToM1; 3173 { 3174 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }", 3175 Lang_CXX03, "input0.cc"); 3176 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3177 FromTU, functionDecl(hasName("x"), isDefinition())); 3178 ToM1 = Import(FromM, Lang_CXX03); 3179 } 3180 Decl *ToM2; 3181 { 3182 Decl *FromTU = 3183 getTuDecl("struct A { void x() const; }; void A::x() const { }", 3184 Lang_CXX03, "input1.cc"); 3185 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3186 FromTU, functionDecl(hasName("x"), isDefinition())); 3187 ToM2 = Import(FromM, Lang_CXX03); 3188 } 3189 EXPECT_NE(ToM1, ToM2); 3190 } 3191 3192 TEST_P(ASTImporterOptionSpecificTestBase, 3193 ImportUnnamedStructsWithRecursingField) { 3194 Decl *FromTU = getTuDecl( 3195 R"( 3196 struct A { 3197 struct { 3198 struct A *next; 3199 } entry0; 3200 struct { 3201 struct A *next; 3202 } entry1; 3203 }; 3204 )", 3205 Lang_C99, "input0.cc"); 3206 auto *From = 3207 FirstDeclMatcher<RecordDecl>().match(FromTU, recordDecl(hasName("A"))); 3208 3209 Import(From, Lang_C99); 3210 3211 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 3212 auto *Entry0 = 3213 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0"))); 3214 auto *Entry1 = 3215 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry1"))); 3216 auto *R0 = getRecordDecl(Entry0); 3217 auto *R1 = getRecordDecl(Entry1); 3218 EXPECT_NE(R0, R1); 3219 EXPECT_TRUE(MatchVerifier<RecordDecl>().match( 3220 R0, recordDecl(has(fieldDecl(hasName("next")))))); 3221 EXPECT_TRUE(MatchVerifier<RecordDecl>().match( 3222 R1, recordDecl(has(fieldDecl(hasName("next")))))); 3223 } 3224 3225 TEST_P(ASTImporterOptionSpecificTestBase, ImportUnnamedFieldsInCorrectOrder) { 3226 Decl *FromTU = getTuDecl( 3227 R"( 3228 void f(int X, int Y, bool Z) { 3229 (void)[X, Y, Z] { (void)Z; }; 3230 } 3231 )", 3232 Lang_CXX11, "input0.cc"); 3233 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 3234 FromTU, functionDecl(hasName("f"))); 3235 auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11)); 3236 EXPECT_TRUE(ToF); 3237 3238 CXXRecordDecl *FromLambda = 3239 cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>( 3240 FromF->getBody())->body_front())->getSubExpr())->getLambdaClass(); 3241 3242 auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11)); 3243 EXPECT_TRUE(ToLambda); 3244 3245 // Check if the fields of the lambda class are imported in correct order. 3246 unsigned FromIndex = 0u; 3247 for (auto *FromField : FromLambda->fields()) { 3248 ASSERT_FALSE(FromField->getDeclName()); 3249 auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11)); 3250 EXPECT_TRUE(ToField); 3251 Optional<unsigned> ToIndex = ASTImporter::getFieldIndex(ToField); 3252 EXPECT_TRUE(ToIndex); 3253 EXPECT_EQ(*ToIndex, FromIndex); 3254 ++FromIndex; 3255 } 3256 3257 EXPECT_EQ(FromIndex, 3u); 3258 } 3259 3260 TEST_P(ASTImporterOptionSpecificTestBase, 3261 MergeFieldDeclsOfClassTemplateSpecialization) { 3262 std::string ClassTemplate = 3263 R"( 3264 template <typename T> 3265 struct X { 3266 int a{0}; // FieldDecl with InitListExpr 3267 X(char) : a(3) {} // (1) 3268 X(int) {} // (2) 3269 }; 3270 )"; 3271 Decl *ToTU = getToTuDecl(ClassTemplate + 3272 R"( 3273 void foo() { 3274 // ClassTemplateSpec with ctor (1): FieldDecl without InitlistExpr 3275 X<char> xc('c'); 3276 } 3277 )", Lang_CXX11); 3278 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3279 ToTU, classTemplateSpecializationDecl(hasName("X"))); 3280 // FieldDecl without InitlistExpr: 3281 auto *ToField = *ToSpec->field_begin(); 3282 ASSERT_TRUE(ToField); 3283 ASSERT_FALSE(ToField->getInClassInitializer()); 3284 Decl *FromTU = getTuDecl(ClassTemplate + 3285 R"( 3286 void bar() { 3287 // ClassTemplateSpec with ctor (2): FieldDecl WITH InitlistExpr 3288 X<char> xc(1); 3289 } 3290 )", Lang_CXX11); 3291 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3292 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3293 // FieldDecl with InitlistExpr: 3294 auto *FromField = *FromSpec->field_begin(); 3295 ASSERT_TRUE(FromField); 3296 ASSERT_TRUE(FromField->getInClassInitializer()); 3297 3298 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3299 ASSERT_TRUE(ImportedSpec); 3300 EXPECT_EQ(ImportedSpec, ToSpec); 3301 // After the import, the FieldDecl has to be merged, thus it should have the 3302 // InitListExpr. 3303 EXPECT_TRUE(ToField->getInClassInitializer()); 3304 } 3305 3306 TEST_P(ASTImporterOptionSpecificTestBase, 3307 MergeFunctionOfClassTemplateSpecialization) { 3308 std::string ClassTemplate = 3309 R"( 3310 template <typename T> 3311 struct X { 3312 void f() {} 3313 void g() {} 3314 }; 3315 )"; 3316 Decl *ToTU = getToTuDecl(ClassTemplate + 3317 R"( 3318 void foo() { 3319 X<char> x; 3320 x.f(); 3321 } 3322 )", Lang_CXX11); 3323 Decl *FromTU = getTuDecl(ClassTemplate + 3324 R"( 3325 void bar() { 3326 X<char> x; 3327 x.g(); 3328 } 3329 )", Lang_CXX11); 3330 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3331 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3332 auto FunPattern = functionDecl(hasName("g"), 3333 hasParent(classTemplateSpecializationDecl())); 3334 auto *FromFun = 3335 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunPattern); 3336 auto *ToFun = 3337 FirstDeclMatcher<FunctionDecl>().match(ToTU, FunPattern); 3338 ASSERT_TRUE(FromFun->hasBody()); 3339 ASSERT_FALSE(ToFun->hasBody()); 3340 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3341 ASSERT_TRUE(ImportedSpec); 3342 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3343 ToTU, classTemplateSpecializationDecl(hasName("X"))); 3344 EXPECT_EQ(ImportedSpec, ToSpec); 3345 EXPECT_TRUE(ToFun->hasBody()); 3346 } 3347 3348 TEST_P(ASTImporterOptionSpecificTestBase, MergeTemplateSpecWithForwardDecl) { 3349 std::string ClassTemplate = 3350 R"( 3351 template<typename T> 3352 struct X { int m; }; 3353 template<> 3354 struct X<int> { int m; }; 3355 )"; 3356 // Append a forward decl for our template specialization. 3357 getToTuDecl(ClassTemplate + "template<> struct X<int>;", Lang_CXX11); 3358 Decl *FromTU = getTuDecl(ClassTemplate, Lang_CXX11); 3359 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3360 FromTU, classTemplateSpecializationDecl(hasName("X"), isDefinition())); 3361 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3362 // Check that our definition got merged with the existing definition. 3363 EXPECT_TRUE(FromSpec->isThisDeclarationADefinition()); 3364 EXPECT_TRUE(ImportedSpec->isThisDeclarationADefinition()); 3365 } 3366 3367 TEST_P(ASTImporterOptionSpecificTestBase, 3368 ODRViolationOfClassTemplateSpecializationsShouldBeReported) { 3369 std::string ClassTemplate = 3370 R"( 3371 template <typename T> 3372 struct X {}; 3373 )"; 3374 Decl *ToTU = getToTuDecl(ClassTemplate + 3375 R"( 3376 template <> 3377 struct X<char> { 3378 int a; 3379 }; 3380 void foo() { 3381 X<char> x; 3382 } 3383 )", 3384 Lang_CXX11); 3385 Decl *FromTU = getTuDecl(ClassTemplate + 3386 R"( 3387 template <> 3388 struct X<char> { 3389 int b; 3390 }; 3391 void foo() { 3392 X<char> x; 3393 } 3394 )", 3395 Lang_CXX11); 3396 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3397 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3398 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3399 3400 // We expect one (ODR) warning during the import. 3401 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 3402 3403 // The second specialization is different from the first, thus it violates 3404 // ODR, consequently we expect to keep the first specialization only, which is 3405 // already in the "To" context. 3406 EXPECT_FALSE(ImportedSpec); 3407 EXPECT_EQ(1u, 3408 DeclCounter<ClassTemplateSpecializationDecl>().match( 3409 ToTU, classTemplateSpecializationDecl(hasName("X")))); 3410 } 3411 3412 TEST_P(ASTImporterOptionSpecificTestBase, 3413 MergeCtorOfClassTemplateSpecialization) { 3414 std::string ClassTemplate = 3415 R"( 3416 template <typename T> 3417 struct X { 3418 X(char) {} 3419 X(int) {} 3420 }; 3421 )"; 3422 Decl *ToTU = getToTuDecl(ClassTemplate + 3423 R"( 3424 void foo() { 3425 X<char> x('c'); 3426 } 3427 )", Lang_CXX11); 3428 Decl *FromTU = getTuDecl(ClassTemplate + 3429 R"( 3430 void bar() { 3431 X<char> x(1); 3432 } 3433 )", Lang_CXX11); 3434 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3435 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3436 // Match the void(int) ctor. 3437 auto CtorPattern = 3438 cxxConstructorDecl(hasParameter(0, varDecl(hasType(asString("int")))), 3439 hasParent(classTemplateSpecializationDecl())); 3440 auto *FromCtor = 3441 FirstDeclMatcher<CXXConstructorDecl>().match(FromTU, CtorPattern); 3442 auto *ToCtor = 3443 FirstDeclMatcher<CXXConstructorDecl>().match(ToTU, CtorPattern); 3444 ASSERT_TRUE(FromCtor->hasBody()); 3445 ASSERT_FALSE(ToCtor->hasBody()); 3446 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3447 ASSERT_TRUE(ImportedSpec); 3448 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3449 ToTU, classTemplateSpecializationDecl(hasName("X"))); 3450 EXPECT_EQ(ImportedSpec, ToSpec); 3451 EXPECT_TRUE(ToCtor->hasBody()); 3452 } 3453 3454 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateFriendDecl) { 3455 const auto *Code = 3456 R"( 3457 template <class T> class X { friend T; }; 3458 struct Y {}; 3459 template class X<Y>; 3460 )"; 3461 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3462 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3463 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3464 FromTU, classTemplateSpecializationDecl()); 3465 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3466 ToTU, classTemplateSpecializationDecl()); 3467 3468 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3469 EXPECT_EQ(ImportedSpec, ToSpec); 3470 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match( 3471 ToTU, classTemplateSpecializationDecl())); 3472 } 3473 3474 TEST_P(ASTImporterOptionSpecificTestBase, 3475 ClassTemplatePartialSpecializationsShouldNotBeDuplicated) { 3476 auto Code = 3477 R"( 3478 // primary template 3479 template<class T1, class T2, int I> 3480 class A {}; 3481 3482 // partial specialization 3483 template<class T, int I> 3484 class A<T, T*, I> {}; 3485 )"; 3486 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3487 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3488 auto *FromSpec = 3489 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match( 3490 FromTU, classTemplatePartialSpecializationDecl()); 3491 auto *ToSpec = 3492 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match( 3493 ToTU, classTemplatePartialSpecializationDecl()); 3494 3495 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3496 EXPECT_EQ(ImportedSpec, ToSpec); 3497 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match( 3498 ToTU, classTemplatePartialSpecializationDecl())); 3499 } 3500 3501 TEST_P(ASTImporterOptionSpecificTestBase, 3502 ClassTemplateSpecializationsShouldNotBeDuplicated) { 3503 auto Code = 3504 R"( 3505 // primary template 3506 template<class T1, class T2, int I> 3507 class A {}; 3508 3509 // full specialization 3510 template<> 3511 class A<int, int, 1> {}; 3512 )"; 3513 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3514 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3515 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3516 FromTU, classTemplateSpecializationDecl()); 3517 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3518 ToTU, classTemplateSpecializationDecl()); 3519 3520 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3521 EXPECT_EQ(ImportedSpec, ToSpec); 3522 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match( 3523 ToTU, classTemplateSpecializationDecl())); 3524 } 3525 3526 TEST_P(ASTImporterOptionSpecificTestBase, 3527 ClassTemplateFullAndPartialSpecsShouldNotBeMixed) { 3528 std::string PrimaryTemplate = 3529 R"( 3530 template<class T1, class T2, int I> 3531 class A {}; 3532 )"; 3533 auto PartialSpec = 3534 R"( 3535 template<class T, int I> 3536 class A<T, T*, I> {}; 3537 )"; 3538 auto FullSpec = 3539 R"( 3540 template<> 3541 class A<int, int, 1> {}; 3542 )"; 3543 Decl *ToTU = getToTuDecl(PrimaryTemplate + FullSpec, Lang_CXX11); 3544 Decl *FromTU = getTuDecl(PrimaryTemplate + PartialSpec, Lang_CXX11); 3545 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3546 FromTU, classTemplateSpecializationDecl()); 3547 3548 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3549 EXPECT_TRUE(ImportedSpec); 3550 // Check the number of partial specializations. 3551 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match( 3552 ToTU, classTemplatePartialSpecializationDecl())); 3553 // Check the number of full specializations. 3554 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match( 3555 ToTU, classTemplateSpecializationDecl( 3556 unless(classTemplatePartialSpecializationDecl())))); 3557 } 3558 3559 TEST_P(ASTImporterOptionSpecificTestBase, 3560 InitListExprValueKindShouldBeImported) { 3561 Decl *TU = getTuDecl( 3562 R"( 3563 const int &init(); 3564 void foo() { const int &a{init()}; } 3565 )", Lang_CXX11, "input0.cc"); 3566 auto *FromD = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("a"))); 3567 ASSERT_TRUE(FromD->getAnyInitializer()); 3568 auto *InitExpr = FromD->getAnyInitializer(); 3569 ASSERT_TRUE(InitExpr); 3570 ASSERT_TRUE(InitExpr->isGLValue()); 3571 3572 auto *ToD = Import(FromD, Lang_CXX11); 3573 EXPECT_TRUE(ToD); 3574 auto *ToInitExpr = cast<VarDecl>(ToD)->getAnyInitializer(); 3575 EXPECT_TRUE(ToInitExpr); 3576 EXPECT_TRUE(ToInitExpr->isGLValue()); 3577 } 3578 3579 struct ImportVariables : ASTImporterOptionSpecificTestBase {}; 3580 3581 TEST_P(ImportVariables, ImportOfOneDeclBringsInTheWholeChain) { 3582 Decl *FromTU = getTuDecl( 3583 R"( 3584 struct A { 3585 static const int a = 1 + 2; 3586 }; 3587 const int A::a; 3588 )", 3589 Lang_CXX03, "input1.cc"); 3590 3591 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match( 3592 FromTU, varDecl(hasName("a"))); // Decl with init 3593 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match( 3594 FromTU, varDecl(hasName("a"))); // Decl with definition 3595 ASSERT_NE(FromDWithInit, FromDWithDef); 3596 ASSERT_EQ(FromDWithDef->getPreviousDecl(), FromDWithInit); 3597 3598 auto *ToD0 = cast<VarDecl>(Import(FromDWithInit, Lang_CXX11)); 3599 auto *ToD1 = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11)); 3600 ASSERT_TRUE(ToD0); 3601 ASSERT_TRUE(ToD1); 3602 EXPECT_NE(ToD0, ToD1); 3603 EXPECT_EQ(ToD1->getPreviousDecl(), ToD0); 3604 } 3605 3606 TEST_P(ImportVariables, InitAndDefinitionAreInDifferentTUs) { 3607 auto StructA = 3608 R"( 3609 struct A { 3610 static const int a = 1 + 2; 3611 }; 3612 )"; 3613 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03); 3614 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a;", Lang_CXX03, 3615 "input1.cc"); 3616 3617 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match( 3618 FromTU, varDecl(hasName("a"))); // Decl with init 3619 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match( 3620 FromTU, varDecl(hasName("a"))); // Decl with definition 3621 ASSERT_EQ(FromDWithInit, FromDWithDef->getPreviousDecl()); 3622 ASSERT_TRUE(FromDWithInit->getInit()); 3623 ASSERT_FALSE(FromDWithInit->isThisDeclarationADefinition()); 3624 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition()); 3625 ASSERT_FALSE(FromDWithDef->getInit()); 3626 3627 auto *ToD = FirstDeclMatcher<VarDecl>().match( 3628 ToTU, varDecl(hasName("a"))); // Decl with init 3629 ASSERT_TRUE(ToD->getInit()); 3630 ASSERT_FALSE(ToD->getDefinition()); 3631 3632 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11)); 3633 EXPECT_TRUE(ImportedD->getAnyInitializer()); 3634 EXPECT_TRUE(ImportedD->getDefinition()); 3635 } 3636 3637 TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) { 3638 auto StructA = 3639 R"( 3640 struct A { 3641 static const int a; 3642 }; 3643 )"; 3644 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03); 3645 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a = 1 + 2;", 3646 Lang_CXX03, "input1.cc"); 3647 3648 auto *FromDDeclarationOnly = FirstDeclMatcher<VarDecl>().match( 3649 FromTU, varDecl(hasName("a"))); 3650 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match( 3651 FromTU, varDecl(hasName("a"))); // Decl with definition and with init. 3652 ASSERT_EQ(FromDDeclarationOnly, FromDWithDef->getPreviousDecl()); 3653 ASSERT_FALSE(FromDDeclarationOnly->getInit()); 3654 ASSERT_FALSE(FromDDeclarationOnly->isThisDeclarationADefinition()); 3655 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition()); 3656 ASSERT_TRUE(FromDWithDef->getInit()); 3657 3658 auto *ToD = FirstDeclMatcher<VarDecl>().match( 3659 ToTU, varDecl(hasName("a"))); 3660 ASSERT_FALSE(ToD->getInit()); 3661 ASSERT_FALSE(ToD->getDefinition()); 3662 3663 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11)); 3664 EXPECT_TRUE(ImportedD->getAnyInitializer()); 3665 EXPECT_TRUE(ImportedD->getDefinition()); 3666 } 3667 3668 struct ImportClasses : ASTImporterOptionSpecificTestBase {}; 3669 3670 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) { 3671 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C99); 3672 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc"); 3673 auto Pattern = recordDecl(hasName("X"), unless(isImplicit())); 3674 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3675 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern); 3676 3677 Decl *ImportedDef = Import(FromDef, Lang_C99); 3678 3679 EXPECT_NE(ImportedDef, ToProto); 3680 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u); 3681 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3682 EXPECT_TRUE(ImportedDef == ToDef); 3683 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 3684 EXPECT_FALSE(ToProto->isThisDeclarationADefinition()); 3685 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto); 3686 } 3687 3688 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContextCXX) { 3689 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_CXX03); 3690 Decl *FromTU1 = getTuDecl("struct X {};", Lang_CXX03, "input1.cc"); 3691 auto Pattern = recordDecl(hasName("X"), unless(isImplicit())); 3692 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3693 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern); 3694 3695 Decl *ImportedDef = Import(FromDef, Lang_CXX03); 3696 3697 EXPECT_NE(ImportedDef, ToProto); 3698 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u); 3699 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3700 EXPECT_TRUE(ImportedDef == ToDef); 3701 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 3702 EXPECT_FALSE(ToProto->isThisDeclarationADefinition()); 3703 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto); 3704 } 3705 3706 TEST_P(ImportClasses, ImportNestedPrototypeThenDefinition) { 3707 Decl *FromTU0 = 3708 getTuDecl("struct A { struct X *Xp; };", Lang_C99, "input0.cc"); 3709 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc"); 3710 auto Pattern = recordDecl(hasName("X"), unless(isImplicit())); 3711 auto FromProto = FirstDeclMatcher<RecordDecl>().match(FromTU0, Pattern); 3712 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern); 3713 3714 Decl *ImportedProto = Import(FromProto, Lang_C99); 3715 Decl *ImportedDef = Import(FromDef, Lang_C99); 3716 Decl *ToTU = ImportedDef->getTranslationUnitDecl(); 3717 3718 EXPECT_NE(ImportedDef, ImportedProto); 3719 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u); 3720 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3721 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3722 EXPECT_TRUE(ImportedDef == ToDef); 3723 EXPECT_TRUE(ImportedProto == ToProto); 3724 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 3725 EXPECT_FALSE(ToProto->isThisDeclarationADefinition()); 3726 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto); 3727 } 3728 3729 3730 struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {}; 3731 3732 TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) { 3733 Decl *FromTU = getTuDecl( 3734 R"( 3735 class A { 3736 template <int I> class F {}; 3737 class X { 3738 template <int I> friend class F; 3739 }; 3740 }; 3741 )", 3742 Lang_CXX03, "input0.cc"); 3743 3744 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( 3745 FromTU, cxxRecordDecl(hasName("F"), isDefinition())); 3746 auto *FromFriendClass = LastDeclMatcher<CXXRecordDecl>().match( 3747 FromTU, cxxRecordDecl(hasName("F"))); 3748 3749 ASSERT_TRUE(FromClass); 3750 ASSERT_TRUE(FromFriendClass); 3751 ASSERT_NE(FromClass, FromFriendClass); 3752 ASSERT_EQ(FromFriendClass->getDefinition(), FromClass); 3753 ASSERT_EQ(FromFriendClass->getPreviousDecl(), FromClass); 3754 ASSERT_EQ(FromFriendClass->getDescribedClassTemplate()->getPreviousDecl(), 3755 FromClass->getDescribedClassTemplate()); 3756 3757 auto *ToClass = cast<CXXRecordDecl>(Import(FromClass, Lang_CXX03)); 3758 auto *ToFriendClass = 3759 cast<CXXRecordDecl>(Import(FromFriendClass, Lang_CXX03)); 3760 3761 EXPECT_TRUE(ToClass); 3762 EXPECT_TRUE(ToFriendClass); 3763 EXPECT_NE(ToClass, ToFriendClass); 3764 EXPECT_EQ(ToFriendClass->getDefinition(), ToClass); 3765 EXPECT_EQ(ToFriendClass->getPreviousDecl(), ToClass); 3766 EXPECT_EQ(ToFriendClass->getDescribedClassTemplate()->getPreviousDecl(), 3767 ToClass->getDescribedClassTemplate()); 3768 } 3769 3770 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClass) { 3771 Decl *FromTu = getTuDecl( 3772 R"( 3773 class declToImport { 3774 friend class declToImport; 3775 }; 3776 )", 3777 Lang_CXX03, "input.cc"); 3778 3779 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 3780 FromTu, cxxRecordDecl(hasName("declToImport"))); 3781 auto *ToD = Import(FromD, Lang_CXX03); 3782 auto Pattern = cxxRecordDecl(has(friendDecl())); 3783 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern)); 3784 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern)); 3785 } 3786 3787 TEST_P(ImportFriendClasses, UndeclaredFriendClassShouldNotBeVisible) { 3788 Decl *FromTu = 3789 getTuDecl("class X { friend class Y; };", Lang_CXX03, "from.cc"); 3790 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 3791 FromTu, cxxRecordDecl(hasName("X"))); 3792 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 3793 RecordDecl *FromRecordOfFriend = 3794 const_cast<RecordDecl *>(getRecordDeclOfFriend(FromFriend)); 3795 3796 ASSERT_EQ(FromRecordOfFriend->getDeclContext(), cast<DeclContext>(FromTu)); 3797 ASSERT_EQ(FromRecordOfFriend->getLexicalDeclContext(), 3798 cast<DeclContext>(FromX)); 3799 ASSERT_FALSE( 3800 FromRecordOfFriend->getDeclContext()->containsDecl(FromRecordOfFriend)); 3801 ASSERT_FALSE(FromRecordOfFriend->getLexicalDeclContext()->containsDecl( 3802 FromRecordOfFriend)); 3803 ASSERT_FALSE(FromRecordOfFriend->getLookupParent() 3804 ->lookup(FromRecordOfFriend->getDeclName()) 3805 .empty()); 3806 3807 auto *ToX = Import(FromX, Lang_CXX03); 3808 ASSERT_TRUE(ToX); 3809 3810 Decl *ToTu = ToX->getTranslationUnitDecl(); 3811 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 3812 RecordDecl *ToRecordOfFriend = 3813 const_cast<RecordDecl *>(getRecordDeclOfFriend(ToFriend)); 3814 3815 ASSERT_EQ(ToRecordOfFriend->getDeclContext(), cast<DeclContext>(ToTu)); 3816 ASSERT_EQ(ToRecordOfFriend->getLexicalDeclContext(), cast<DeclContext>(ToX)); 3817 EXPECT_FALSE( 3818 ToRecordOfFriend->getDeclContext()->containsDecl(ToRecordOfFriend)); 3819 EXPECT_FALSE(ToRecordOfFriend->getLexicalDeclContext()->containsDecl( 3820 ToRecordOfFriend)); 3821 EXPECT_FALSE(ToRecordOfFriend->getLookupParent() 3822 ->lookup(ToRecordOfFriend->getDeclName()) 3823 .empty()); 3824 } 3825 3826 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClassTemplate) { 3827 Decl *FromTu = getTuDecl( 3828 R"( 3829 template<class A> class declToImport { 3830 template<class A1> friend class declToImport; 3831 }; 3832 )", 3833 Lang_CXX03, "input.cc"); 3834 3835 auto *FromD = 3836 FirstDeclMatcher<ClassTemplateDecl>().match(FromTu, classTemplateDecl()); 3837 auto *ToD = Import(FromD, Lang_CXX03); 3838 3839 auto Pattern = classTemplateDecl( 3840 has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl())))))); 3841 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern)); 3842 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern)); 3843 3844 auto *Class = 3845 FirstDeclMatcher<ClassTemplateDecl>().match(ToD, classTemplateDecl()); 3846 auto *Friend = FirstDeclMatcher<FriendDecl>().match(ToD, friendDecl()); 3847 EXPECT_NE(Friend->getFriendDecl(), Class); 3848 EXPECT_EQ(Friend->getFriendDecl()->getPreviousDecl(), Class); 3849 } 3850 3851 TEST_P(ImportFriendClasses, ProperPrevDeclForClassTemplateDecls) { 3852 auto Pattern = classTemplateSpecializationDecl(hasName("X")); 3853 3854 ClassTemplateSpecializationDecl *Imported1; 3855 { 3856 Decl *FromTU = getTuDecl("template<class T> class X;" 3857 "struct Y { friend class X<int>; };", 3858 Lang_CXX03, "input0.cc"); 3859 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3860 FromTU, Pattern); 3861 3862 Imported1 = 3863 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03)); 3864 } 3865 ClassTemplateSpecializationDecl *Imported2; 3866 { 3867 Decl *FromTU = getTuDecl("template<class T> class X;" 3868 "template<> class X<int>{};" 3869 "struct Z { friend class X<int>; };", 3870 Lang_CXX03, "input1.cc"); 3871 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3872 FromTU, Pattern); 3873 3874 Imported2 = 3875 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03)); 3876 } 3877 3878 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 3879 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(ToTU, Pattern), 3880 2u); 3881 ASSERT_TRUE(Imported2->getPreviousDecl()); 3882 EXPECT_EQ(Imported2->getPreviousDecl(), Imported1); 3883 } 3884 3885 TEST_P(ImportFriendClasses, TypeForDeclShouldBeSetInTemplated) { 3886 Decl *FromTU0 = getTuDecl( 3887 R"( 3888 class X { 3889 class Y; 3890 }; 3891 class X::Y { 3892 template <typename T> 3893 friend class F; // The decl context of F is the global namespace. 3894 }; 3895 )", 3896 Lang_CXX03, "input0.cc"); 3897 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match( 3898 FromTU0, classTemplateDecl(hasName("F"))); 3899 auto *Imported0 = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03)); 3900 Decl *FromTU1 = getTuDecl( 3901 R"( 3902 template <typename T> 3903 class F {}; 3904 )", 3905 Lang_CXX03, "input1.cc"); 3906 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match( 3907 FromTU1, classTemplateDecl(hasName("F"))); 3908 auto *Imported1 = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03)); 3909 EXPECT_EQ(Imported0->getTemplatedDecl()->getTypeForDecl(), 3910 Imported1->getTemplatedDecl()->getTypeForDecl()); 3911 } 3912 3913 TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) { 3914 Decl *From, *To; 3915 std::tie(From, To) = 3916 getImportedDecl("class declToImport {};", Lang_CXX03, 3917 "class Y { friend class declToImport; };", Lang_CXX03); 3918 auto *Imported = cast<CXXRecordDecl>(To); 3919 3920 EXPECT_TRUE(Imported->getPreviousDecl()); 3921 } 3922 3923 TEST_P(ImportFriendClasses, 3924 ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) { 3925 Decl *ToTU = getToTuDecl( 3926 R"( 3927 class X { 3928 class Y; 3929 }; 3930 class X::Y { 3931 template <typename T> 3932 friend class F; // The decl context of F is the global namespace. 3933 }; 3934 )", 3935 Lang_CXX03); 3936 auto *ToDecl = FirstDeclMatcher<ClassTemplateDecl>().match( 3937 ToTU, classTemplateDecl(hasName("F"))); 3938 Decl *FromTU = getTuDecl( 3939 R"( 3940 template <typename T> 3941 class F {}; 3942 )", 3943 Lang_CXX03, "input0.cc"); 3944 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match( 3945 FromTU, classTemplateDecl(hasName("F"))); 3946 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03)); 3947 EXPECT_TRUE(ImportedDef->getPreviousDecl()); 3948 EXPECT_EQ(ToDecl, ImportedDef->getPreviousDecl()); 3949 EXPECT_EQ(ToDecl->getTemplatedDecl(), 3950 ImportedDef->getTemplatedDecl()->getPreviousDecl()); 3951 } 3952 3953 TEST_P(ImportFriendClasses, 3954 ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked) { 3955 Decl *FromTU0 = getTuDecl( 3956 R"( 3957 class X { 3958 class Y; 3959 }; 3960 class X::Y { 3961 template <typename T> 3962 friend class F; // The decl context of F is the global namespace. 3963 }; 3964 )", 3965 Lang_CXX03, "input0.cc"); 3966 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match( 3967 FromTU0, classTemplateDecl(hasName("F"))); 3968 auto *ImportedFwd = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03)); 3969 Decl *FromTU1 = getTuDecl( 3970 R"( 3971 template <typename T> 3972 class F {}; 3973 )", 3974 Lang_CXX03, "input1.cc"); 3975 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match( 3976 FromTU1, classTemplateDecl(hasName("F"))); 3977 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03)); 3978 EXPECT_TRUE(ImportedDef->getPreviousDecl()); 3979 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl()); 3980 EXPECT_EQ(ImportedFwd->getTemplatedDecl(), 3981 ImportedDef->getTemplatedDecl()->getPreviousDecl()); 3982 } 3983 3984 TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) { 3985 Decl *FromTU0 = getTuDecl( 3986 R"( 3987 class X { 3988 class Y; 3989 }; 3990 class X::Y { 3991 friend class F; // The decl context of F is the global namespace. 3992 }; 3993 )", 3994 Lang_CXX03, "input0.cc"); 3995 auto *Friend = FirstDeclMatcher<FriendDecl>().match(FromTU0, friendDecl()); 3996 QualType FT = Friend->getFriendType()->getType(); 3997 FT = FromTU0->getASTContext().getCanonicalType(FT); 3998 auto *Fwd = cast<TagType>(FT)->getDecl(); 3999 auto *ImportedFwd = Import(Fwd, Lang_CXX03); 4000 Decl *FromTU1 = getTuDecl( 4001 R"( 4002 class F {}; 4003 )", 4004 Lang_CXX03, "input1.cc"); 4005 auto *Definition = FirstDeclMatcher<CXXRecordDecl>().match( 4006 FromTU1, cxxRecordDecl(hasName("F"))); 4007 auto *ImportedDef = Import(Definition, Lang_CXX03); 4008 EXPECT_TRUE(ImportedDef->getPreviousDecl()); 4009 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl()); 4010 } 4011 4012 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendType) { 4013 const char *Code = 4014 R"( 4015 class Container { 4016 friend class X; 4017 friend class X; 4018 }; 4019 )"; 4020 Decl *ToTu = getToTuDecl(Code, Lang_CXX03); 4021 Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc"); 4022 4023 auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4024 auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4025 auto *FromFriend1 = 4026 FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4027 auto *FromFriend2 = LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4028 4029 FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03); 4030 FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03); 4031 4032 EXPECT_NE(ToImportedFriend1, ToImportedFriend2); 4033 EXPECT_EQ(ToFriend1, ToImportedFriend1); 4034 EXPECT_EQ(ToFriend2, ToImportedFriend2); 4035 } 4036 4037 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendDecl) { 4038 const char *Code = 4039 R"( 4040 class Container { 4041 friend void f(); 4042 friend void f(); 4043 }; 4044 )"; 4045 Decl *ToTu = getToTuDecl(Code, Lang_CXX03); 4046 Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc"); 4047 4048 auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4049 auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4050 auto *FromFriend1 = 4051 FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4052 auto *FromFriend2 = LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4053 4054 FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03); 4055 FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03); 4056 4057 EXPECT_NE(ToImportedFriend1, ToImportedFriend2); 4058 EXPECT_EQ(ToFriend1, ToImportedFriend1); 4059 EXPECT_EQ(ToFriend2, ToImportedFriend2); 4060 } 4061 4062 TEST_P(ASTImporterOptionSpecificTestBase, FriendFunInClassTemplate) { 4063 auto *Code = R"( 4064 template <class T> 4065 struct X { 4066 friend void foo(){} 4067 }; 4068 )"; 4069 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 4070 auto *ToFoo = FirstDeclMatcher<FunctionDecl>().match( 4071 ToTU, functionDecl(hasName("foo"))); 4072 4073 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc"); 4074 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match( 4075 FromTU, functionDecl(hasName("foo"))); 4076 auto *ImportedFoo = Import(FromFoo, Lang_CXX03); 4077 EXPECT_EQ(ImportedFoo, ToFoo); 4078 } 4079 4080 struct DeclContextTest : ASTImporterOptionSpecificTestBase {}; 4081 4082 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) { 4083 Decl *TU = getTuDecl( 4084 R"( 4085 namespace NS { 4086 4087 template <typename T> 4088 struct S {}; 4089 template struct S<int>; 4090 4091 inline namespace INS { 4092 template <typename T> 4093 struct S {}; 4094 template struct S<int>; 4095 } 4096 4097 } 4098 )", Lang_CXX11, "input0.cc"); 4099 auto *NS = FirstDeclMatcher<NamespaceDecl>().match( 4100 TU, namespaceDecl()); 4101 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4102 TU, classTemplateSpecializationDecl()); 4103 ASSERT_TRUE(NS->containsDecl(Spec)); 4104 4105 NS->removeDecl(Spec); 4106 EXPECT_FALSE(NS->containsDecl(Spec)); 4107 } 4108 4109 TEST_P(DeclContextTest, 4110 removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage) { 4111 Decl *TU = getTuDecl("extern int A; int A;", Lang_CXX03); 4112 auto *A0 = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A"))); 4113 auto *A1 = LastDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A"))); 4114 4115 // Investigate the list. 4116 auto *DC = A0->getDeclContext(); 4117 ASSERT_TRUE(DC->containsDecl(A0)); 4118 ASSERT_TRUE(DC->containsDecl(A1)); 4119 4120 // Investigate the lookup table. 4121 auto *Map = DC->getLookupPtr(); 4122 ASSERT_TRUE(Map); 4123 auto I = Map->find(A0->getDeclName()); 4124 ASSERT_NE(I, Map->end()); 4125 StoredDeclsList &L = I->second; 4126 // The lookup table contains the most recent decl of A. 4127 ASSERT_NE(L.getAsDecl(), A0); 4128 ASSERT_EQ(L.getAsDecl(), A1); 4129 4130 ASSERT_TRUE(L.getAsDecl()); 4131 // Simulate the private function DeclContext::reconcileExternalVisibleStorage. 4132 // We do not have a list with one element. 4133 L.setHasExternalDecls(); 4134 ASSERT_FALSE(L.getAsList()); 4135 auto Results = L.getLookupResult(); 4136 ASSERT_EQ(1u, std::distance(Results.begin(), Results.end())); 4137 4138 // This asserts in the old implementation. 4139 DC->removeDecl(A0); 4140 EXPECT_FALSE(DC->containsDecl(A0)); 4141 } 4142 4143 struct ImportFunctionTemplateSpecializations 4144 : ASTImporterOptionSpecificTestBase {}; 4145 4146 TEST_P(ImportFunctionTemplateSpecializations, 4147 TUshouldNotContainFunctionTemplateImplicitInstantiation) { 4148 4149 Decl *FromTU = getTuDecl( 4150 R"( 4151 template<class T> 4152 int f() { return 0; } 4153 void foo() { f<int>(); } 4154 )", 4155 Lang_CXX03, "input0.cc"); 4156 4157 // Check that the function template instantiation is NOT the child of the TU. 4158 auto Pattern = translationUnitDecl( 4159 unless(has(functionDecl(hasName("f"), isTemplateInstantiation())))); 4160 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern)); 4161 4162 auto *Foo = FirstDeclMatcher<FunctionDecl>().match( 4163 FromTU, functionDecl(hasName("foo"))); 4164 ASSERT_TRUE(Import(Foo, Lang_CXX03)); 4165 4166 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4167 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern)); 4168 } 4169 4170 TEST_P(ImportFunctionTemplateSpecializations, 4171 TUshouldNotContainFunctionTemplateExplicitInstantiation) { 4172 4173 Decl *FromTU = getTuDecl( 4174 R"( 4175 template<class T> 4176 int f() { return 0; } 4177 template int f<int>(); 4178 )", 4179 Lang_CXX03, "input0.cc"); 4180 4181 // Check that the function template instantiation is NOT the child of the TU. 4182 auto Instantiation = functionDecl(hasName("f"), isTemplateInstantiation()); 4183 auto Pattern = translationUnitDecl(unless(has(Instantiation))); 4184 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern)); 4185 4186 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Instantiation), 4187 Lang_CXX03)); 4188 4189 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4190 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern)); 4191 } 4192 4193 TEST_P(ImportFunctionTemplateSpecializations, 4194 TUshouldContainFunctionTemplateSpecialization) { 4195 4196 Decl *FromTU = getTuDecl( 4197 R"( 4198 template<class T> 4199 int f() { return 0; } 4200 template <> int f<int>() { return 4; } 4201 )", 4202 Lang_CXX03, "input0.cc"); 4203 4204 // Check that the function template specialization is the child of the TU. 4205 auto Specialization = 4206 functionDecl(hasName("f"), isExplicitTemplateSpecialization()); 4207 auto Pattern = translationUnitDecl(has(Specialization)); 4208 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern)); 4209 4210 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Specialization), 4211 Lang_CXX03)); 4212 4213 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4214 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern)); 4215 } 4216 4217 TEST_P(ImportFunctionTemplateSpecializations, 4218 FunctionTemplateSpecializationRedeclChain) { 4219 4220 Decl *FromTU = getTuDecl( 4221 R"( 4222 template<class T> 4223 int f() { return 0; } 4224 template <> int f<int>() { return 4; } 4225 )", 4226 Lang_CXX03, "input0.cc"); 4227 4228 auto Spec = functionDecl(hasName("f"), isExplicitTemplateSpecialization(), 4229 hasParent(translationUnitDecl())); 4230 auto *FromSpecD = FirstDeclMatcher<Decl>().match(FromTU, Spec); 4231 { 4232 auto *TU = FromTU; 4233 auto *SpecD = FromSpecD; 4234 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match( 4235 TU, functionTemplateDecl()); 4236 auto *FirstSpecD = *(TemplateD->spec_begin()); 4237 ASSERT_EQ(SpecD, FirstSpecD); 4238 ASSERT_TRUE(SpecD->getPreviousDecl()); 4239 ASSERT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl()) 4240 ->doesThisDeclarationHaveABody()); 4241 } 4242 4243 ASSERT_TRUE(Import(FromSpecD, Lang_CXX03)); 4244 4245 { 4246 auto *TU = ToAST->getASTContext().getTranslationUnitDecl(); 4247 auto *SpecD = FirstDeclMatcher<Decl>().match(TU, Spec); 4248 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match( 4249 TU, functionTemplateDecl()); 4250 auto *FirstSpecD = *(TemplateD->spec_begin()); 4251 EXPECT_EQ(SpecD, FirstSpecD); 4252 ASSERT_TRUE(SpecD->getPreviousDecl()); 4253 EXPECT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl()) 4254 ->doesThisDeclarationHaveABody()); 4255 } 4256 } 4257 4258 TEST_P(ImportFunctionTemplateSpecializations, 4259 MatchNumberOfFunctionTemplateSpecializations) { 4260 4261 Decl *FromTU = getTuDecl( 4262 R"( 4263 template <typename T> constexpr int f() { return 0; } 4264 template <> constexpr int f<int>() { return 4; } 4265 void foo() { 4266 static_assert(f<char>() == 0, ""); 4267 static_assert(f<int>() == 4, ""); 4268 } 4269 )", 4270 Lang_CXX11, "input0.cc"); 4271 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 4272 FromTU, functionDecl(hasName("foo"))); 4273 4274 Import(FromD, Lang_CXX11); 4275 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4276 EXPECT_EQ( 4277 DeclCounter<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))), 4278 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f")))); 4279 } 4280 4281 TEST_P(ASTImporterOptionSpecificTestBase, 4282 ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) { 4283 { 4284 Decl *FromTU = getTuDecl( 4285 R"( 4286 template <typename T> 4287 struct B; 4288 )", 4289 Lang_CXX03, "input0.cc"); 4290 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 4291 FromTU, classTemplateDecl(hasName("B"))); 4292 4293 Import(FromD, Lang_CXX03); 4294 } 4295 4296 { 4297 Decl *FromTU = getTuDecl( 4298 R"( 4299 template <typename T> 4300 struct B { 4301 void f(); 4302 B* b; 4303 }; 4304 )", 4305 Lang_CXX03, "input1.cc"); 4306 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match( 4307 FromTU, functionDecl(hasName("f"))); 4308 Import(FromD, Lang_CXX03); 4309 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match( 4310 FromTU, classTemplateDecl(hasName("B"))); 4311 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03)); 4312 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition()); 4313 4314 // We expect no (ODR) warning during the import. 4315 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4316 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 4317 } 4318 } 4319 4320 TEST_P(ASTImporterOptionSpecificTestBase, 4321 ImportingTypedefShouldImportTheCompleteType) { 4322 // We already have an incomplete underlying type in the "To" context. 4323 auto Code = 4324 R"( 4325 template <typename T> 4326 struct S { 4327 void foo(); 4328 }; 4329 using U = S<int>; 4330 )"; 4331 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 4332 auto *ToD = FirstDeclMatcher<TypedefNameDecl>().match(ToTU, 4333 typedefNameDecl(hasName("U"))); 4334 ASSERT_TRUE(ToD->getUnderlyingType()->isIncompleteType()); 4335 4336 // The "From" context has the same typedef, but the underlying type is 4337 // complete this time. 4338 Decl *FromTU = getTuDecl(std::string(Code) + 4339 R"( 4340 void foo(U* u) { 4341 u->foo(); 4342 } 4343 )", Lang_CXX11); 4344 auto *FromD = FirstDeclMatcher<TypedefNameDecl>().match(FromTU, 4345 typedefNameDecl(hasName("U"))); 4346 ASSERT_FALSE(FromD->getUnderlyingType()->isIncompleteType()); 4347 4348 // The imported type should be complete. 4349 auto *ImportedD = cast<TypedefNameDecl>(Import(FromD, Lang_CXX11)); 4350 EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType()); 4351 } 4352 4353 TEST_P(ASTImporterOptionSpecificTestBase, ImportTemplateParameterLists) { 4354 auto Code = 4355 R"( 4356 template<class T> 4357 int f() { return 0; } 4358 template <> int f<int>() { return 4; } 4359 )"; 4360 4361 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 4362 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, 4363 functionDecl(hasName("f"), isExplicitTemplateSpecialization())); 4364 ASSERT_EQ(FromD->getNumTemplateParameterLists(), 1u); 4365 4366 auto *ToD = Import(FromD, Lang_CXX03); 4367 // The template parameter list should exist. 4368 EXPECT_EQ(ToD->getNumTemplateParameterLists(), 1u); 4369 } 4370 4371 struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {}; 4372 4373 TEST_P(ASTImporterLookupTableTest, OneDecl) { 4374 auto *ToTU = getToTuDecl("int a;", Lang_CXX03); 4375 auto *D = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("a"))); 4376 ASTImporterLookupTable LT(*ToTU); 4377 auto Res = LT.lookup(ToTU, D->getDeclName()); 4378 ASSERT_EQ(Res.size(), 1u); 4379 EXPECT_EQ(*Res.begin(), D); 4380 } 4381 4382 static Decl *findInDeclListOfDC(DeclContext *DC, DeclarationName Name) { 4383 for (Decl *D : DC->decls()) { 4384 if (auto *ND = dyn_cast<NamedDecl>(D)) 4385 if (ND->getDeclName() == Name) 4386 return ND; 4387 } 4388 return nullptr; 4389 } 4390 4391 TEST_P(ASTImporterLookupTableTest, 4392 FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup) { 4393 auto *Code = R"( 4394 template <class T> 4395 struct X { 4396 friend void foo(){} 4397 }; 4398 )"; 4399 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 4400 auto *X = FirstDeclMatcher<ClassTemplateDecl>().match( 4401 ToTU, classTemplateDecl(hasName("X"))); 4402 auto *Foo = FirstDeclMatcher<FunctionDecl>().match( 4403 ToTU, functionDecl(hasName("foo"))); 4404 DeclContext *FooDC = Foo->getDeclContext(); 4405 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext(); 4406 ASSERT_EQ(cast<Decl>(FooLexicalDC), X->getTemplatedDecl()); 4407 ASSERT_EQ(cast<Decl>(FooDC), ToTU); 4408 DeclarationName FooName = Foo->getDeclName(); 4409 4410 // Cannot find in the LookupTable of its DC (TUDecl) 4411 SmallVector<NamedDecl *, 2> FoundDecls; 4412 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 4413 EXPECT_EQ(FoundDecls.size(), 0u); 4414 4415 // Cannot find in the LookupTable of its LexicalDC (X) 4416 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 4417 EXPECT_EQ(FoundDecls.size(), 0u); 4418 4419 // Can't find in the list of Decls of the DC. 4420 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr); 4421 4422 // Can't find in the list of Decls of the LexicalDC 4423 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), nullptr); 4424 4425 // ASTImporter specific lookup finds it. 4426 ASTImporterLookupTable LT(*ToTU); 4427 auto Res = LT.lookup(FooDC, Foo->getDeclName()); 4428 ASSERT_EQ(Res.size(), 1u); 4429 EXPECT_EQ(*Res.begin(), Foo); 4430 } 4431 4432 TEST_P(ASTImporterLookupTableTest, 4433 FwdDeclStructShouldBeFoundByImporterSpecificLookup) { 4434 TranslationUnitDecl *ToTU = 4435 getToTuDecl("struct A { struct Foo *p; };", Lang_C99); 4436 auto *Foo = 4437 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("Foo"))); 4438 auto *A = 4439 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A"))); 4440 DeclContext *FooDC = Foo->getDeclContext(); 4441 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext(); 4442 ASSERT_EQ(cast<Decl>(FooLexicalDC), A); 4443 ASSERT_EQ(cast<Decl>(FooDC), ToTU); 4444 DeclarationName FooName = Foo->getDeclName(); 4445 4446 // Cannot find in the LookupTable of its DC (TUDecl). 4447 SmallVector<NamedDecl *, 2> FoundDecls; 4448 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 4449 EXPECT_EQ(FoundDecls.size(), 0u); 4450 4451 // Cannot find in the LookupTable of its LexicalDC (A). 4452 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 4453 EXPECT_EQ(FoundDecls.size(), 0u); 4454 4455 // Can't find in the list of Decls of the DC. 4456 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr); 4457 4458 // Can find in the list of Decls of the LexicalDC. 4459 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), Foo); 4460 4461 // ASTImporter specific lookup finds it. 4462 ASTImporterLookupTable LT(*ToTU); 4463 auto Res = LT.lookup(FooDC, Foo->getDeclName()); 4464 ASSERT_EQ(Res.size(), 1u); 4465 EXPECT_EQ(*Res.begin(), Foo); 4466 } 4467 4468 TEST_P(ASTImporterLookupTableTest, LookupFindsNamesInDifferentDC) { 4469 TranslationUnitDecl *ToTU = 4470 getToTuDecl("int V; struct A { int V; }; struct B { int V; };", Lang_C99); 4471 DeclarationName VName = FirstDeclMatcher<VarDecl>() 4472 .match(ToTU, varDecl(hasName("V"))) 4473 ->getDeclName(); 4474 auto *A = 4475 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A"))); 4476 auto *B = 4477 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("B"))); 4478 4479 ASTImporterLookupTable LT(*ToTU); 4480 4481 auto Res = LT.lookup(cast<DeclContext>(A), VName); 4482 ASSERT_EQ(Res.size(), 1u); 4483 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match( 4484 ToTU, fieldDecl(hasName("V"), 4485 hasParent(recordDecl(hasName("A")))))); 4486 Res = LT.lookup(cast<DeclContext>(B), VName); 4487 ASSERT_EQ(Res.size(), 1u); 4488 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match( 4489 ToTU, fieldDecl(hasName("V"), 4490 hasParent(recordDecl(hasName("B")))))); 4491 Res = LT.lookup(ToTU, VName); 4492 ASSERT_EQ(Res.size(), 1u); 4493 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<VarDecl>().match( 4494 ToTU, varDecl(hasName("V"), 4495 hasParent(translationUnitDecl())))); 4496 } 4497 4498 TEST_P(ASTImporterLookupTableTest, LookupFindsOverloadedNames) { 4499 TranslationUnitDecl *ToTU = getToTuDecl( 4500 R"( 4501 void foo(); 4502 void foo(int); 4503 void foo(int, int); 4504 )", 4505 Lang_CXX03); 4506 4507 ASTImporterLookupTable LT(*ToTU); 4508 auto *F0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl()); 4509 auto *F2 = LastDeclMatcher<FunctionDecl>().match(ToTU, functionDecl()); 4510 DeclarationName Name = F0->getDeclName(); 4511 auto Res = LT.lookup(ToTU, Name); 4512 EXPECT_EQ(Res.size(), 3u); 4513 EXPECT_EQ(Res.count(F0), 1u); 4514 EXPECT_EQ(Res.count(F2), 1u); 4515 } 4516 4517 TEST_P(ASTImporterLookupTableTest, 4518 DifferentOperatorsShouldHaveDifferentResultSet) { 4519 TranslationUnitDecl *ToTU = getToTuDecl( 4520 R"( 4521 struct X{}; 4522 void operator+(X, X); 4523 void operator-(X, X); 4524 )", 4525 Lang_CXX03); 4526 4527 ASTImporterLookupTable LT(*ToTU); 4528 auto *FPlus = FirstDeclMatcher<FunctionDecl>().match( 4529 ToTU, functionDecl(hasOverloadedOperatorName("+"))); 4530 auto *FMinus = FirstDeclMatcher<FunctionDecl>().match( 4531 ToTU, functionDecl(hasOverloadedOperatorName("-"))); 4532 DeclarationName NamePlus = FPlus->getDeclName(); 4533 auto ResPlus = LT.lookup(ToTU, NamePlus); 4534 EXPECT_EQ(ResPlus.size(), 1u); 4535 EXPECT_EQ(ResPlus.count(FPlus), 1u); 4536 EXPECT_EQ(ResPlus.count(FMinus), 0u); 4537 DeclarationName NameMinus = FMinus->getDeclName(); 4538 auto ResMinus = LT.lookup(ToTU, NameMinus); 4539 EXPECT_EQ(ResMinus.size(), 1u); 4540 EXPECT_EQ(ResMinus.count(FMinus), 1u); 4541 EXPECT_EQ(ResMinus.count(FPlus), 0u); 4542 EXPECT_NE(*ResMinus.begin(), *ResPlus.begin()); 4543 } 4544 4545 TEST_P(ASTImporterLookupTableTest, LookupDeclNamesFromDifferentTUs) { 4546 TranslationUnitDecl *ToTU = getToTuDecl( 4547 R"( 4548 struct X {}; 4549 void operator+(X, X); 4550 )", 4551 Lang_CXX03); 4552 auto *ToPlus = FirstDeclMatcher<FunctionDecl>().match( 4553 ToTU, functionDecl(hasOverloadedOperatorName("+"))); 4554 4555 Decl *FromTU = getTuDecl( 4556 R"( 4557 struct X {}; 4558 void operator+(X, X); 4559 )", 4560 Lang_CXX03); 4561 auto *FromPlus = FirstDeclMatcher<FunctionDecl>().match( 4562 FromTU, functionDecl(hasOverloadedOperatorName("+"))); 4563 4564 // FromPlus have a different TU, thus its DeclarationName is different too. 4565 ASSERT_NE(ToPlus->getDeclName(), FromPlus->getDeclName()); 4566 4567 ASTImporterLookupTable LT(*ToTU); 4568 auto Res = LT.lookup(ToTU, ToPlus->getDeclName()); 4569 ASSERT_EQ(Res.size(), 1u); 4570 EXPECT_EQ(*Res.begin(), ToPlus); 4571 4572 // FromPlus have a different TU, thus its DeclarationName is different too. 4573 Res = LT.lookup(ToTU, FromPlus->getDeclName()); 4574 ASSERT_EQ(Res.size(), 0u); 4575 } 4576 4577 TEST_P(ASTImporterLookupTableTest, 4578 LookupFindsFwdFriendClassDeclWithElaboratedType) { 4579 TranslationUnitDecl *ToTU = getToTuDecl( 4580 R"( 4581 class Y { friend class F; }; 4582 )", 4583 Lang_CXX03); 4584 4585 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent. 4586 // So we must dig up the underlying CXXRecordDecl. 4587 ASTImporterLookupTable LT(*ToTU); 4588 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 4589 const RecordDecl *RD = getRecordDeclOfFriend(FriendD); 4590 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match( 4591 ToTU, cxxRecordDecl(hasName("Y"))); 4592 4593 DeclarationName Name = RD->getDeclName(); 4594 auto Res = LT.lookup(ToTU, Name); 4595 EXPECT_EQ(Res.size(), 1u); 4596 EXPECT_EQ(*Res.begin(), RD); 4597 4598 Res = LT.lookup(Y, Name); 4599 EXPECT_EQ(Res.size(), 0u); 4600 } 4601 4602 TEST_P(ASTImporterLookupTableTest, 4603 LookupFindsFwdFriendClassDeclWithUnelaboratedType) { 4604 TranslationUnitDecl *ToTU = getToTuDecl( 4605 R"( 4606 class F; 4607 class Y { friend F; }; 4608 )", 4609 Lang_CXX11); 4610 4611 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent. 4612 // So we must dig up the underlying CXXRecordDecl. 4613 ASTImporterLookupTable LT(*ToTU); 4614 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 4615 const RecordDecl *RD = getRecordDeclOfFriend(FriendD); 4616 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, cxxRecordDecl(hasName("Y"))); 4617 4618 DeclarationName Name = RD->getDeclName(); 4619 auto Res = LT.lookup(ToTU, Name); 4620 EXPECT_EQ(Res.size(), 1u); 4621 EXPECT_EQ(*Res.begin(), RD); 4622 4623 Res = LT.lookup(Y, Name); 4624 EXPECT_EQ(Res.size(), 0u); 4625 } 4626 4627 TEST_P(ASTImporterLookupTableTest, 4628 LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert) { 4629 TranslationUnitDecl *ToTU = getToTuDecl( 4630 R"( 4631 class F; 4632 using alias_of_f = F; 4633 class Y { friend alias_of_f; }; 4634 )", 4635 Lang_CXX11); 4636 4637 // ASTImporterLookupTable constructor handles using declarations correctly, 4638 // no assert is expected. 4639 ASTImporterLookupTable LT(*ToTU); 4640 4641 auto *Alias = FirstDeclMatcher<TypeAliasDecl>().match( 4642 ToTU, typeAliasDecl(hasName("alias_of_f"))); 4643 DeclarationName Name = Alias->getDeclName(); 4644 auto Res = LT.lookup(ToTU, Name); 4645 EXPECT_EQ(Res.count(Alias), 1u); 4646 } 4647 4648 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassTemplateDecl) { 4649 TranslationUnitDecl *ToTU = getToTuDecl( 4650 R"( 4651 class Y { template <class T> friend class F; }; 4652 )", 4653 Lang_CXX03); 4654 4655 ASTImporterLookupTable LT(*ToTU); 4656 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match( 4657 ToTU, classTemplateDecl(hasName("F"))); 4658 DeclarationName Name = F->getDeclName(); 4659 auto Res = LT.lookup(ToTU, Name); 4660 EXPECT_EQ(Res.size(), 2u); 4661 EXPECT_EQ(Res.count(F), 1u); 4662 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 4663 } 4664 4665 TEST_P(ASTImporterLookupTableTest, DependentFriendClass) { 4666 TranslationUnitDecl *ToTU = getToTuDecl( 4667 R"( 4668 template <typename T> 4669 class F; 4670 4671 template <typename T> 4672 class Y { 4673 friend class F<T>; 4674 }; 4675 )", 4676 Lang_CXX03); 4677 4678 ASTImporterLookupTable LT(*ToTU); 4679 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match( 4680 ToTU, classTemplateDecl(hasName("F"))); 4681 DeclarationName Name = F->getDeclName(); 4682 auto Res = LT.lookup(ToTU, Name); 4683 EXPECT_EQ(Res.size(), 2u); 4684 EXPECT_EQ(Res.count(F), 1u); 4685 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 4686 } 4687 4688 TEST_P(ASTImporterLookupTableTest, FriendClassTemplateSpecialization) { 4689 TranslationUnitDecl *ToTU = getToTuDecl( 4690 R"( 4691 template <typename T> 4692 class F; 4693 4694 class Y { 4695 friend class F<int>; 4696 }; 4697 )", 4698 Lang_CXX03); 4699 4700 ASTImporterLookupTable LT(*ToTU); 4701 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match( 4702 ToTU, classTemplateDecl(hasName("F"))); 4703 DeclarationName Name = F->getDeclName(); 4704 auto Res = LT.lookup(ToTU, Name); 4705 ASSERT_EQ(Res.size(), 3u); 4706 EXPECT_EQ(Res.count(F), 1u); 4707 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 4708 EXPECT_EQ(Res.count(*F->spec_begin()), 1u); 4709 } 4710 4711 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionDecl) { 4712 TranslationUnitDecl *ToTU = getToTuDecl( 4713 R"( 4714 class Y { friend void F(); }; 4715 )", 4716 Lang_CXX03); 4717 4718 ASTImporterLookupTable LT(*ToTU); 4719 auto *F = 4720 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("F"))); 4721 DeclarationName Name = F->getDeclName(); 4722 auto Res = LT.lookup(ToTU, Name); 4723 EXPECT_EQ(Res.size(), 1u); 4724 EXPECT_EQ(*Res.begin(), F); 4725 } 4726 4727 TEST_P(ASTImporterLookupTableTest, 4728 LookupFindsDeclsInClassTemplateSpecialization) { 4729 TranslationUnitDecl *ToTU = getToTuDecl( 4730 R"( 4731 template <typename T> 4732 struct X { 4733 int F; 4734 }; 4735 void foo() { 4736 X<char> xc; 4737 } 4738 )", 4739 Lang_CXX03); 4740 4741 ASTImporterLookupTable LT(*ToTU); 4742 4743 auto *Template = FirstDeclMatcher<ClassTemplateDecl>().match( 4744 ToTU, classTemplateDecl(hasName("X"))); 4745 auto *FieldInTemplate = FirstDeclMatcher<FieldDecl>().match( 4746 ToTU, 4747 fieldDecl(hasParent(cxxRecordDecl(hasParent(classTemplateDecl()))))); 4748 4749 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4750 ToTU, classTemplateSpecializationDecl(hasName("X"))); 4751 FieldDecl *FieldInSpec = *Spec->field_begin(); 4752 ASSERT_TRUE(FieldInSpec); 4753 4754 DeclarationName Name = FieldInSpec->getDeclName(); 4755 auto TemplateDC = cast<DeclContext>(Template->getTemplatedDecl()); 4756 4757 SmallVector<NamedDecl *, 2> FoundDecls; 4758 TemplateDC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); 4759 EXPECT_EQ(FoundDecls.size(), 1u); 4760 EXPECT_EQ(FoundDecls[0], FieldInTemplate); 4761 4762 auto Res = LT.lookup(TemplateDC, Name); 4763 ASSERT_EQ(Res.size(), 1u); 4764 EXPECT_EQ(*Res.begin(), FieldInTemplate); 4765 4766 cast<DeclContext>(Spec)->getRedeclContext()->localUncachedLookup(Name, 4767 FoundDecls); 4768 EXPECT_EQ(FoundDecls.size(), 1u); 4769 EXPECT_EQ(FoundDecls[0], FieldInSpec); 4770 4771 Res = LT.lookup(cast<DeclContext>(Spec), Name); 4772 ASSERT_EQ(Res.size(), 1u); 4773 EXPECT_EQ(*Res.begin(), FieldInSpec); 4774 } 4775 4776 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionTemplateDecl) { 4777 TranslationUnitDecl *ToTU = getToTuDecl( 4778 R"( 4779 class Y { template <class T> friend void F(); }; 4780 )", 4781 Lang_CXX03); 4782 4783 ASTImporterLookupTable LT(*ToTU); 4784 auto *F = FirstDeclMatcher<FunctionTemplateDecl>().match( 4785 ToTU, functionTemplateDecl(hasName("F"))); 4786 DeclarationName Name = F->getDeclName(); 4787 auto Res = LT.lookup(ToTU, Name); 4788 EXPECT_EQ(Res.size(), 2u); 4789 EXPECT_EQ(Res.count(F), 1u); 4790 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 4791 } 4792 4793 TEST_P(ASTImporterLookupTableTest, MultipleBefriendingClasses) { 4794 TranslationUnitDecl *ToTU = getToTuDecl( 4795 R"( 4796 struct X; 4797 struct A { 4798 friend struct X; 4799 }; 4800 struct B { 4801 friend struct X; 4802 }; 4803 )", 4804 Lang_CXX03); 4805 4806 ASTImporterLookupTable LT(*ToTU); 4807 auto *X = FirstDeclMatcher<CXXRecordDecl>().match( 4808 ToTU, cxxRecordDecl(hasName("X"))); 4809 auto *FriendD0 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 4810 auto *FriendD1 = LastDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 4811 const RecordDecl *RD0 = getRecordDeclOfFriend(FriendD0); 4812 const RecordDecl *RD1 = getRecordDeclOfFriend(FriendD1); 4813 ASSERT_EQ(RD0, RD1); 4814 ASSERT_EQ(RD1, X); 4815 4816 DeclarationName Name = X->getDeclName(); 4817 auto Res = LT.lookup(ToTU, Name); 4818 EXPECT_EQ(Res.size(), 1u); 4819 EXPECT_EQ(*Res.begin(), X); 4820 } 4821 4822 TEST_P(ASTImporterLookupTableTest, EnumConstantDecl) { 4823 TranslationUnitDecl *ToTU = getToTuDecl( 4824 R"( 4825 enum E { 4826 A, 4827 B 4828 }; 4829 )", 4830 Lang_C99); 4831 4832 ASTImporterLookupTable LT(*ToTU); 4833 auto *E = FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(hasName("E"))); 4834 auto *A = FirstDeclMatcher<EnumConstantDecl>().match( 4835 ToTU, enumConstantDecl(hasName("A"))); 4836 4837 DeclarationName Name = A->getDeclName(); 4838 // Redecl context is the TU. 4839 ASSERT_EQ(E->getRedeclContext(), ToTU); 4840 4841 SmallVector<NamedDecl *, 2> FoundDecls; 4842 // Normal lookup finds in the DC. 4843 E->localUncachedLookup(Name, FoundDecls); 4844 EXPECT_EQ(FoundDecls.size(), 1u); 4845 4846 // Normal lookup finds in the Redecl context. 4847 ToTU->localUncachedLookup(Name, FoundDecls); 4848 EXPECT_EQ(FoundDecls.size(), 1u); 4849 4850 // Import specific lookup finds in the DC. 4851 auto Res = LT.lookup(E, Name); 4852 ASSERT_EQ(Res.size(), 1u); 4853 EXPECT_EQ(*Res.begin(), A); 4854 4855 // Import specific lookup finds in the Redecl context. 4856 Res = LT.lookup(ToTU, Name); 4857 ASSERT_EQ(Res.size(), 1u); 4858 EXPECT_EQ(*Res.begin(), A); 4859 } 4860 4861 TEST_P(ASTImporterLookupTableTest, LookupSearchesInTheWholeRedeclChain) { 4862 TranslationUnitDecl *ToTU = getToTuDecl( 4863 R"( 4864 namespace N { 4865 int A; 4866 } 4867 namespace N { 4868 } 4869 )", 4870 Lang_CXX03); 4871 auto *N1 = 4872 LastDeclMatcher<NamespaceDecl>().match(ToTU, namespaceDecl(hasName("N"))); 4873 auto *A = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("A"))); 4874 DeclarationName Name = A->getDeclName(); 4875 4876 ASTImporterLookupTable LT(*ToTU); 4877 auto Res = LT.lookup(N1, Name); 4878 ASSERT_EQ(Res.size(), 1u); 4879 EXPECT_EQ(*Res.begin(), A); 4880 } 4881 4882 TEST_P(ASTImporterOptionSpecificTestBase, 4883 RedeclChainShouldBeCorrectAmongstNamespaces) { 4884 Decl *FromTU = getTuDecl( 4885 R"( 4886 namespace NS { 4887 struct X; 4888 struct Y { 4889 static const int I = 3; 4890 }; 4891 } 4892 namespace NS { 4893 struct X { // <--- To be imported 4894 void method(int i = Y::I) {} 4895 int f; 4896 }; 4897 } 4898 )", 4899 Lang_CXX03); 4900 auto *FromFwd = FirstDeclMatcher<CXXRecordDecl>().match( 4901 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit()))); 4902 auto *FromDef = LastDeclMatcher<CXXRecordDecl>().match( 4903 FromTU, 4904 cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit()))); 4905 ASSERT_NE(FromFwd, FromDef); 4906 ASSERT_FALSE(FromFwd->isThisDeclarationADefinition()); 4907 ASSERT_TRUE(FromDef->isThisDeclarationADefinition()); 4908 ASSERT_EQ(FromFwd->getCanonicalDecl(), FromDef->getCanonicalDecl()); 4909 4910 auto *ToDef = cast_or_null<CXXRecordDecl>(Import(FromDef, Lang_CXX03)); 4911 auto *ToFwd = cast_or_null<CXXRecordDecl>(Import(FromFwd, Lang_CXX03)); 4912 EXPECT_NE(ToFwd, ToDef); 4913 EXPECT_FALSE(ToFwd->isThisDeclarationADefinition()); 4914 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 4915 EXPECT_EQ(ToFwd->getCanonicalDecl(), ToDef->getCanonicalDecl()); 4916 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4917 // We expect no (ODR) warning during the import. 4918 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 4919 } 4920 4921 struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {}; 4922 4923 TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) { 4924 Decl *ToTU = getToTuDecl( 4925 R"( 4926 class X { 4927 template <typename T> friend void foo(); 4928 }; 4929 )", 4930 Lang_CXX03); 4931 auto *Friend = FirstDeclMatcher<FunctionTemplateDecl>().match( 4932 ToTU, functionTemplateDecl(hasName("foo"))); 4933 4934 Decl *FromTU = getTuDecl( 4935 R"( 4936 template <typename T> void foo(); 4937 )", 4938 Lang_CXX03); 4939 auto *FromFoo = FirstDeclMatcher<FunctionTemplateDecl>().match( 4940 FromTU, functionTemplateDecl(hasName("foo"))); 4941 auto *Imported = Import(FromFoo, Lang_CXX03); 4942 4943 EXPECT_EQ(Imported->getPreviousDecl(), Friend); 4944 } 4945 4946 struct ASTImporterWithFakeErrors : ASTImporter { 4947 using ASTImporter::ASTImporter; 4948 bool returnWithErrorInTest() override { return true; } 4949 }; 4950 4951 struct ErrorHandlingTest : ASTImporterOptionSpecificTestBase { 4952 ErrorHandlingTest() { 4953 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 4954 ASTContext &FromContext, FileManager &FromFileManager, 4955 bool MinimalImport, 4956 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 4957 return new ASTImporterWithFakeErrors(ToContext, ToFileManager, 4958 FromContext, FromFileManager, 4959 MinimalImport, SharedState); 4960 }; 4961 } 4962 // In this test we purposely report an error (UnsupportedConstruct) when 4963 // importing the below stmt. 4964 static constexpr auto* ErroneousStmt = R"( asm(""); )"; 4965 }; 4966 4967 // Check a case when no new AST node is created in the AST before encountering 4968 // the error. 4969 TEST_P(ErrorHandlingTest, ErrorHappensBeforeCreatingANewNode) { 4970 TranslationUnitDecl *ToTU = getToTuDecl( 4971 R"( 4972 template <typename T> 4973 class X {}; 4974 template <> 4975 class X<int> { int a; }; 4976 )", 4977 Lang_CXX03); 4978 TranslationUnitDecl *FromTU = getTuDecl( 4979 R"( 4980 template <typename T> 4981 class X {}; 4982 template <> 4983 class X<int> { double b; }; 4984 )", 4985 Lang_CXX03); 4986 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4987 FromTU, classTemplateSpecializationDecl(hasName("X"))); 4988 ClassTemplateSpecializationDecl *ImportedSpec = Import(FromSpec, Lang_CXX03); 4989 EXPECT_FALSE(ImportedSpec); 4990 4991 // The original Decl is kept, no new decl is created. 4992 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match( 4993 ToTU, classTemplateSpecializationDecl(hasName("X"))), 4994 1u); 4995 4996 // But an error is set to the counterpart in the "from" context. 4997 ASTImporter *Importer = findFromTU(FromSpec)->Importer.get(); 4998 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromSpec); 4999 ASSERT_TRUE(OptErr); 5000 EXPECT_EQ(OptErr->Error, ImportError::NameConflict); 5001 } 5002 5003 // Check a case when a new AST node is created but not linked to the AST before 5004 // encountering the error. 5005 TEST_P(ErrorHandlingTest, 5006 ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST) { 5007 TranslationUnitDecl *FromTU = getTuDecl( 5008 std::string("void foo() { ") + ErroneousStmt + " }", Lang_CXX03); 5009 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match( 5010 FromTU, functionDecl(hasName("foo"))); 5011 5012 FunctionDecl *ImportedFoo = Import(FromFoo, Lang_CXX03); 5013 EXPECT_FALSE(ImportedFoo); 5014 5015 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 5016 // Created, but not linked. 5017 EXPECT_EQ( 5018 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("foo"))), 5019 0u); 5020 5021 ASTImporter *Importer = findFromTU(FromFoo)->Importer.get(); 5022 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFoo); 5023 ASSERT_TRUE(OptErr); 5024 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5025 } 5026 5027 // Check a case when a new AST node is created and linked to the AST before 5028 // encountering the error. The error is set for the counterpart of the nodes in 5029 // the "from" context. 5030 TEST_P(ErrorHandlingTest, ErrorHappensAfterNodeIsCreatedAndLinked) { 5031 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5032 void f(); 5033 void f() { )") + ErroneousStmt + R"( } 5034 )", 5035 Lang_CXX03); 5036 auto *FromProto = FirstDeclMatcher<FunctionDecl>().match( 5037 FromTU, functionDecl(hasName("f"))); 5038 auto *FromDef = 5039 LastDeclMatcher<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))); 5040 FunctionDecl *ImportedProto = Import(FromProto, Lang_CXX03); 5041 EXPECT_FALSE(ImportedProto); // Could not import. 5042 // However, we created two nodes in the AST. 1) the fwd decl 2) the 5043 // definition. The definition is not added to its DC, but the fwd decl is 5044 // there. 5045 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 5046 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))), 5047 1u); 5048 // Match the fwd decl. 5049 auto *ToProto = 5050 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))); 5051 EXPECT_TRUE(ToProto); 5052 // An error is set to the counterpart in the "from" context both for the fwd 5053 // decl and the definition. 5054 ASTImporter *Importer = findFromTU(FromProto)->Importer.get(); 5055 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromProto); 5056 ASSERT_TRUE(OptErr); 5057 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5058 OptErr = Importer->getImportDeclErrorIfAny(FromDef); 5059 ASSERT_TRUE(OptErr); 5060 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5061 } 5062 5063 // An error should be set for a class if we cannot import one member. 5064 TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) { 5065 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5066 class X { 5067 void f() { )") + ErroneousStmt + R"( } // This member has the error 5068 // during import. 5069 void ok(); // The error should not prevent importing this. 5070 }; // An error will be set for X too. 5071 )", 5072 Lang_CXX03); 5073 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5074 FromTU, cxxRecordDecl(hasName("X"))); 5075 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 5076 5077 // An error is set for X. 5078 EXPECT_FALSE(ImportedX); 5079 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5080 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5081 ASSERT_TRUE(OptErr); 5082 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5083 5084 // An error is set for f(). 5085 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match( 5086 FromTU, cxxMethodDecl(hasName("f"))); 5087 OptErr = Importer->getImportDeclErrorIfAny(FromF); 5088 ASSERT_TRUE(OptErr); 5089 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5090 // And any subsequent import should fail. 5091 CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX03); 5092 EXPECT_FALSE(ImportedF); 5093 5094 // There is an error set for the other member too. 5095 auto *FromOK = FirstDeclMatcher<CXXMethodDecl>().match( 5096 FromTU, cxxMethodDecl(hasName("ok"))); 5097 OptErr = Importer->getImportDeclErrorIfAny(FromOK); 5098 EXPECT_TRUE(OptErr); 5099 // Cannot import the other member. 5100 CXXMethodDecl *ImportedOK = Import(FromOK, Lang_CXX03); 5101 EXPECT_FALSE(ImportedOK); 5102 } 5103 5104 // Check that an error propagates to the dependent AST nodes. 5105 // In the below code it means that an error in X should propagate to A. 5106 // And even to F since the containing A is erroneous. 5107 // And to all AST nodes which we visit during the import process which finally 5108 // ends up in a failure (in the error() function). 5109 TEST_P(ErrorHandlingTest, ErrorPropagatesThroughImportCycles) { 5110 Decl *FromTU = getTuDecl(std::string(R"( 5111 namespace NS { 5112 class A { 5113 template <int I> class F {}; 5114 class X { 5115 template <int I> friend class F; 5116 void error() { )") + 5117 ErroneousStmt + R"( } 5118 }; 5119 }; 5120 5121 class B {}; 5122 } // NS 5123 )", 5124 Lang_CXX03, "input0.cc"); 5125 5126 auto *FromFRD = FirstDeclMatcher<CXXRecordDecl>().match( 5127 FromTU, cxxRecordDecl(hasName("F"), isDefinition())); 5128 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 5129 FromTU, cxxRecordDecl(hasName("A"), isDefinition())); 5130 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match( 5131 FromTU, cxxRecordDecl(hasName("B"), isDefinition())); 5132 auto *FromNS = FirstDeclMatcher<NamespaceDecl>().match( 5133 FromTU, namespaceDecl(hasName("NS"))); 5134 5135 // Start by importing the templated CXXRecordDecl of F. 5136 // Import fails for that. 5137 EXPECT_FALSE(Import(FromFRD, Lang_CXX03)); 5138 // Import fails for A. 5139 EXPECT_FALSE(Import(FromA, Lang_CXX03)); 5140 // But we should be able to import the independent B. 5141 EXPECT_TRUE(Import(FromB, Lang_CXX03)); 5142 // And the namespace. 5143 EXPECT_TRUE(Import(FromNS, Lang_CXX03)); 5144 5145 // An error is set to the templated CXXRecordDecl of F. 5146 ASTImporter *Importer = findFromTU(FromFRD)->Importer.get(); 5147 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFRD); 5148 EXPECT_TRUE(OptErr); 5149 5150 // An error is set to A. 5151 OptErr = Importer->getImportDeclErrorIfAny(FromA); 5152 EXPECT_TRUE(OptErr); 5153 5154 // There is no error set to B. 5155 OptErr = Importer->getImportDeclErrorIfAny(FromB); 5156 EXPECT_FALSE(OptErr); 5157 5158 // There is no error set to NS. 5159 OptErr = Importer->getImportDeclErrorIfAny(FromNS); 5160 EXPECT_FALSE(OptErr); 5161 5162 // Check some of those decls whose ancestor is X, they all should have an 5163 // error set if we visited them during an import process which finally failed. 5164 // These decls are part of a cycle in an ImportPath. 5165 // There would not be any error set for these decls if we hadn't follow the 5166 // ImportPaths and the cycles. 5167 OptErr = Importer->getImportDeclErrorIfAny( 5168 FirstDeclMatcher<ClassTemplateDecl>().match( 5169 FromTU, classTemplateDecl(hasName("F")))); 5170 // An error is set to the 'F' ClassTemplateDecl. 5171 EXPECT_TRUE(OptErr); 5172 // An error is set to the FriendDecl. 5173 OptErr = Importer->getImportDeclErrorIfAny( 5174 FirstDeclMatcher<FriendDecl>().match( 5175 FromTU, friendDecl())); 5176 EXPECT_TRUE(OptErr); 5177 // An error is set to the implicit class of A. 5178 OptErr = 5179 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match( 5180 FromTU, cxxRecordDecl(hasName("A"), isImplicit()))); 5181 EXPECT_TRUE(OptErr); 5182 // An error is set to the implicit class of X. 5183 OptErr = 5184 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match( 5185 FromTU, cxxRecordDecl(hasName("X"), isImplicit()))); 5186 EXPECT_TRUE(OptErr); 5187 } 5188 5189 TEST_P(ErrorHandlingTest, ErrorIsNotPropagatedFromMemberToNamespace) { 5190 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5191 namespace X { 5192 void f() { )") + ErroneousStmt + R"( } // This member has the error 5193 // during import. 5194 void ok(); // The error should not prevent importing this. 5195 }; // An error will be set for X too. 5196 )", 5197 Lang_CXX03); 5198 auto *FromX = FirstDeclMatcher<NamespaceDecl>().match( 5199 FromTU, namespaceDecl(hasName("X"))); 5200 NamespaceDecl *ImportedX = Import(FromX, Lang_CXX03); 5201 5202 // There is no error set for X. 5203 EXPECT_TRUE(ImportedX); 5204 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5205 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5206 ASSERT_FALSE(OptErr); 5207 5208 // An error is set for f(). 5209 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 5210 FromTU, functionDecl(hasName("f"))); 5211 OptErr = Importer->getImportDeclErrorIfAny(FromF); 5212 ASSERT_TRUE(OptErr); 5213 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5214 // And any subsequent import should fail. 5215 FunctionDecl *ImportedF = Import(FromF, Lang_CXX03); 5216 EXPECT_FALSE(ImportedF); 5217 5218 // There is no error set for ok(). 5219 auto *FromOK = FirstDeclMatcher<FunctionDecl>().match( 5220 FromTU, functionDecl(hasName("ok"))); 5221 OptErr = Importer->getImportDeclErrorIfAny(FromOK); 5222 EXPECT_FALSE(OptErr); 5223 // And we should be able to import. 5224 FunctionDecl *ImportedOK = Import(FromOK, Lang_CXX03); 5225 EXPECT_TRUE(ImportedOK); 5226 } 5227 5228 // An error should be set for a class if it had a previous import with an error 5229 // from another TU. 5230 TEST_P(ErrorHandlingTest, 5231 ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt) { 5232 // We already have a fwd decl. 5233 TranslationUnitDecl *ToTU = getToTuDecl("class X;", Lang_CXX03); 5234 // Then we import a definition. 5235 { 5236 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5237 class X { 5238 void f() { )") + ErroneousStmt + R"( } 5239 void ok(); 5240 }; 5241 )", 5242 Lang_CXX03); 5243 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5244 FromTU, cxxRecordDecl(hasName("X"))); 5245 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 5246 5247 // An error is set for X ... 5248 EXPECT_FALSE(ImportedX); 5249 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5250 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5251 ASSERT_TRUE(OptErr); 5252 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5253 } 5254 // ... but the node had been created. 5255 auto *ToXDef = FirstDeclMatcher<CXXRecordDecl>().match( 5256 ToTU, cxxRecordDecl(hasName("X"), isDefinition())); 5257 // An error is set for "ToXDef" in the shared state. 5258 Optional<ImportError> OptErr = 5259 SharedStatePtr->getImportDeclErrorIfAny(ToXDef); 5260 ASSERT_TRUE(OptErr); 5261 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5262 5263 auto *ToXFwd = FirstDeclMatcher<CXXRecordDecl>().match( 5264 ToTU, cxxRecordDecl(hasName("X"), unless(isDefinition()))); 5265 // An error is NOT set for the fwd Decl of X in the shared state. 5266 OptErr = SharedStatePtr->getImportDeclErrorIfAny(ToXFwd); 5267 ASSERT_FALSE(OptErr); 5268 5269 // Try to import X again but from another TU. 5270 { 5271 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5272 class X { 5273 void f() { )") + ErroneousStmt + R"( } 5274 void ok(); 5275 }; 5276 )", 5277 Lang_CXX03, "input1.cc"); 5278 5279 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5280 FromTU, cxxRecordDecl(hasName("X"))); 5281 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 5282 5283 // If we did not save the errors for the "to" context then the below checks 5284 // would fail, because the lookup finds the fwd Decl of the existing 5285 // definition in the "to" context. We can reach the existing definition via 5286 // the found fwd Decl. That existing definition is structurally equivalent 5287 // (we check only the fields) with this one we want to import, so we return 5288 // with the existing definition, which is erroneous (one method is missing). 5289 5290 // The import should fail. 5291 EXPECT_FALSE(ImportedX); 5292 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5293 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5294 // And an error is set for this new X in the "from" ctx. 5295 ASSERT_TRUE(OptErr); 5296 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5297 } 5298 } 5299 5300 TEST_P(ErrorHandlingTest, ImportOfOverriddenMethods) { 5301 auto MatchFooA = 5302 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A")))); 5303 auto MatchFooB = 5304 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B")))); 5305 auto MatchFooC = 5306 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("C")))); 5307 5308 // Provoke import of a method that has overridden methods with import error. 5309 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5310 struct C; 5311 struct A { 5312 virtual void foo(); 5313 void f1(C *); 5314 }; 5315 void A::foo() { 5316 )") + ErroneousStmt + R"( 5317 } 5318 struct B : public A { 5319 void foo() override; 5320 }; 5321 struct C : public B { 5322 void foo() override; 5323 }; 5324 )", 5325 Lang_CXX11); 5326 auto *FromFooA = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooA); 5327 auto *FromFooB = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooB); 5328 auto *FromFooC = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooC); 5329 5330 EXPECT_FALSE(Import(FromFooA, Lang_CXX11)); 5331 ASTImporter *Importer = findFromTU(FromFooA)->Importer.get(); 5332 auto CheckError = [&Importer](Decl *FromD) { 5333 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromD); 5334 ASSERT_TRUE(OptErr); 5335 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5336 }; 5337 CheckError(FromFooA); 5338 EXPECT_FALSE(Import(FromFooB, Lang_CXX11)); 5339 CheckError(FromFooB); 5340 EXPECT_FALSE(Import(FromFooC, Lang_CXX11)); 5341 CheckError(FromFooC); 5342 } 5343 5344 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) { 5345 Decl *FromTU = getTuDecl( 5346 R"( 5347 void f() { 5348 auto L = [](){}; 5349 } 5350 )", 5351 Lang_CXX11, "input0.cc"); 5352 auto Pattern = lambdaExpr(); 5353 CXXRecordDecl *FromL = 5354 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 5355 5356 auto ToL = Import(FromL, Lang_CXX11); 5357 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); 5358 unsigned FromLSize = 5359 std::distance(FromL->decls().begin(), FromL->decls().end()); 5360 EXPECT_NE(ToLSize, 0u); 5361 EXPECT_EQ(ToLSize, FromLSize); 5362 } 5363 5364 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) { 5365 Decl *FromTU = getTuDecl( 5366 R"( 5367 template <typename F> 5368 void f(F L = [](){}) {} 5369 )", 5370 Lang_CXX11, "input0.cc"); 5371 auto Pattern = lambdaExpr(); 5372 CXXRecordDecl *FromL = 5373 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 5374 5375 auto ToL = Import(FromL, Lang_CXX11); 5376 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); 5377 unsigned FromLSize = 5378 std::distance(FromL->decls().begin(), FromL->decls().end()); 5379 EXPECT_NE(ToLSize, 0u); 5380 EXPECT_EQ(ToLSize, FromLSize); 5381 } 5382 5383 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInGlobalScope) { 5384 Decl *FromTU = getTuDecl( 5385 R"( 5386 auto l1 = [](unsigned lp) { return 1; }; 5387 auto l2 = [](int lp) { return 2; }; 5388 int f(int p) { 5389 return l1(p) + l2(p); 5390 } 5391 )", 5392 Lang_CXX11, "input0.cc"); 5393 FunctionDecl *FromF = FirstDeclMatcher<FunctionDecl>().match( 5394 FromTU, functionDecl(hasName("f"))); 5395 FunctionDecl *ToF = Import(FromF, Lang_CXX11); 5396 EXPECT_TRUE(ToF); 5397 } 5398 5399 TEST_P(ASTImporterOptionSpecificTestBase, 5400 ImportExistingFriendClassTemplateDef) { 5401 auto Code = 5402 R"( 5403 template <class T1, class T2> 5404 struct Base { 5405 template <class U1, class U2> 5406 friend struct Class; 5407 }; 5408 template <class T1, class T2> 5409 struct Class { }; 5410 )"; 5411 5412 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 5413 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc"); 5414 5415 auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match( 5416 ToTU, classTemplateDecl(hasName("Class"))); 5417 auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match( 5418 ToTU, classTemplateDecl(hasName("Class"))); 5419 ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition()); 5420 ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition()); 5421 // Previous friend decl is not linked to it! 5422 ASSERT_FALSE(ToClassDef->getPreviousDecl()); 5423 ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef); 5424 ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto); 5425 5426 auto *FromClassProto = FirstDeclMatcher<ClassTemplateDecl>().match( 5427 FromTU, classTemplateDecl(hasName("Class"))); 5428 auto *FromClassDef = LastDeclMatcher<ClassTemplateDecl>().match( 5429 FromTU, classTemplateDecl(hasName("Class"))); 5430 ASSERT_FALSE(FromClassProto->isThisDeclarationADefinition()); 5431 ASSERT_TRUE(FromClassDef->isThisDeclarationADefinition()); 5432 ASSERT_FALSE(FromClassDef->getPreviousDecl()); 5433 ASSERT_EQ(FromClassDef->getMostRecentDecl(), FromClassDef); 5434 ASSERT_EQ(FromClassProto->getMostRecentDecl(), FromClassProto); 5435 5436 auto *ImportedDef = Import(FromClassDef, Lang_CXX03); 5437 // At import we should find the definition for 'Class' even if the 5438 // prototype (inside 'friend') for it comes first in the AST and is not 5439 // linked to the definition. 5440 EXPECT_EQ(ImportedDef, ToClassDef); 5441 } 5442 5443 struct LLDBLookupTest : ASTImporterOptionSpecificTestBase { 5444 LLDBLookupTest() { 5445 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 5446 ASTContext &FromContext, FileManager &FromFileManager, 5447 bool MinimalImport, 5448 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 5449 return new ASTImporter(ToContext, ToFileManager, FromContext, 5450 FromFileManager, MinimalImport, 5451 // We use the regular lookup. 5452 /*SharedState=*/nullptr); 5453 }; 5454 } 5455 }; 5456 5457 TEST_P(LLDBLookupTest, ImporterShouldFindInTransparentContext) { 5458 TranslationUnitDecl *ToTU = getToTuDecl( 5459 R"( 5460 extern "C" { 5461 class X{}; 5462 }; 5463 )", 5464 Lang_CXX03); 5465 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match( 5466 ToTU, cxxRecordDecl(hasName("X"))); 5467 5468 // Set up a stub external storage. 5469 ToTU->setHasExternalLexicalStorage(true); 5470 // Set up DeclContextBits.HasLazyExternalLexicalLookups to true. 5471 ToTU->setMustBuildLookupTable(); 5472 struct TestExternalASTSource : ExternalASTSource {}; 5473 ToTU->getASTContext().setExternalSource(new TestExternalASTSource()); 5474 5475 Decl *FromTU = getTuDecl( 5476 R"( 5477 class X; 5478 )", 5479 Lang_CXX03); 5480 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5481 FromTU, cxxRecordDecl(hasName("X"))); 5482 auto *ImportedX = Import(FromX, Lang_CXX03); 5483 // The lookup must find the existing class definition in the LinkageSpecDecl. 5484 // Then the importer renders the existing and the new decl into one chain. 5485 EXPECT_EQ(ImportedX->getCanonicalDecl(), ToX->getCanonicalDecl()); 5486 } 5487 5488 struct SVEBuiltins : ASTImporterOptionSpecificTestBase {}; 5489 5490 TEST_P(SVEBuiltins, ImportTypes) { 5491 static const char *const TypeNames[] = { 5492 "__SVInt8_t", 5493 "__SVInt16_t", 5494 "__SVInt32_t", 5495 "__SVInt64_t", 5496 "__SVUint8_t", 5497 "__SVUint16_t", 5498 "__SVUint32_t", 5499 "__SVUint64_t", 5500 "__SVFloat16_t", 5501 "__SVBFloat16_t", 5502 "__SVFloat32_t", 5503 "__SVFloat64_t", 5504 "__SVBool_t" 5505 }; 5506 5507 TranslationUnitDecl *ToTU = getToTuDecl("", Lang_CXX03); 5508 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cc"); 5509 for (auto *TypeName : TypeNames) { 5510 auto *ToTypedef = FirstDeclMatcher<TypedefDecl>().match( 5511 ToTU, typedefDecl(hasName(TypeName))); 5512 QualType ToType = ToTypedef->getUnderlyingType(); 5513 5514 auto *FromTypedef = FirstDeclMatcher<TypedefDecl>().match( 5515 FromTU, typedefDecl(hasName(TypeName))); 5516 QualType FromType = FromTypedef->getUnderlyingType(); 5517 5518 QualType ImportedType = ImportType(FromType, FromTypedef, Lang_CXX03); 5519 EXPECT_EQ(ImportedType, ToType); 5520 } 5521 } 5522 5523 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfDefaultImplicitFunctions) { 5524 // Test that import of implicit functions works and the functions 5525 // are merged into one chain. 5526 auto GetDeclToImport = [this](StringRef File) { 5527 Decl *FromTU = getTuDecl( 5528 R"( 5529 struct X { }; 5530 // Force generating some implicit operator definitions for X. 5531 void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; } 5532 )", 5533 Lang_CXX11, File); 5534 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 5535 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit()))); 5536 // Destructor is picked as one example of implicit function. 5537 return FromD->getDestructor(); 5538 }; 5539 5540 auto *ToD1 = Import(GetDeclToImport("input1.cc"), Lang_CXX11); 5541 ASSERT_TRUE(ToD1); 5542 5543 auto *ToD2 = Import(GetDeclToImport("input2.cc"), Lang_CXX11); 5544 ASSERT_TRUE(ToD2); 5545 5546 EXPECT_EQ(ToD1->getCanonicalDecl(), ToD2->getCanonicalDecl()); 5547 } 5548 5549 TEST_P(ASTImporterOptionSpecificTestBase, 5550 ImportOfExplicitlyDefaultedOrDeleted) { 5551 Decl *FromTU = getTuDecl( 5552 R"( 5553 struct X { X() = default; X(const X&) = delete; }; 5554 )", 5555 Lang_CXX11); 5556 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5557 FromTU, cxxRecordDecl(hasName("X"))); 5558 auto *ImportedX = Import(FromX, Lang_CXX11); 5559 auto *Constr1 = FirstDeclMatcher<CXXConstructorDecl>().match( 5560 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit()))); 5561 auto *Constr2 = LastDeclMatcher<CXXConstructorDecl>().match( 5562 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit()))); 5563 5564 ASSERT_TRUE(ImportedX); 5565 EXPECT_TRUE(Constr1->isDefaulted()); 5566 EXPECT_TRUE(Constr1->isExplicitlyDefaulted()); 5567 EXPECT_TRUE(Constr2->isDeletedAsWritten()); 5568 EXPECT_EQ(ImportedX->isAggregate(), FromX->isAggregate()); 5569 } 5570 5571 INSTANTIATE_TEST_CASE_P(ParameterizedTests, SVEBuiltins, 5572 ::testing::Values(std::vector<std::string>{ 5573 "-target", "aarch64-linux-gnu"}), ); 5574 5575 INSTANTIATE_TEST_CASE_P(ParameterizedTests, DeclContextTest, 5576 ::testing::Values(std::vector<std::string>()), ); 5577 5578 INSTANTIATE_TEST_CASE_P(ParameterizedTests, CanonicalRedeclChain, 5579 ::testing::Values(std::vector<std::string>()), ); 5580 5581 TEST_P(ASTImporterOptionSpecificTestBase, LambdasAreDifferentiated) { 5582 Decl *FromTU = getTuDecl( 5583 R"( 5584 void f() { 5585 auto L0 = [](){}; 5586 auto L1 = [](){}; 5587 } 5588 )", 5589 Lang_CXX11, "input0.cc"); 5590 auto Pattern = lambdaExpr(); 5591 CXXRecordDecl *FromL0 = 5592 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 5593 CXXRecordDecl *FromL1 = 5594 LastDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 5595 ASSERT_NE(FromL0, FromL1); 5596 5597 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 5598 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 5599 EXPECT_NE(ToL0, ToL1); 5600 } 5601 5602 TEST_P(ASTImporterOptionSpecificTestBase, 5603 LambdasInFunctionParamsAreDifferentiated) { 5604 Decl *FromTU = getTuDecl( 5605 R"( 5606 template <typename F0, typename F1> 5607 void f(F0 L0 = [](){}, F1 L1 = [](){}) {} 5608 )", 5609 Lang_CXX11, "input0.cc"); 5610 auto Pattern = cxxRecordDecl(isLambda()); 5611 CXXRecordDecl *FromL0 = 5612 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 5613 CXXRecordDecl *FromL1 = 5614 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 5615 ASSERT_NE(FromL0, FromL1); 5616 5617 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 5618 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 5619 ASSERT_NE(ToL0, ToL1); 5620 } 5621 5622 TEST_P(ASTImporterOptionSpecificTestBase, 5623 LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed) { 5624 Decl *FromTU = getTuDecl( 5625 R"( 5626 #define LAMBDA [](){} 5627 template <typename F0, typename F1> 5628 void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {} 5629 )", 5630 Lang_CXX11, "input0.cc"); 5631 auto Pattern = cxxRecordDecl(isLambda()); 5632 CXXRecordDecl *FromL0 = 5633 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 5634 CXXRecordDecl *FromL1 = 5635 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 5636 ASSERT_NE(FromL0, FromL1); 5637 5638 Import(FromL0, Lang_CXX11); 5639 Import(FromL1, Lang_CXX11); 5640 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 5641 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 5642 ASSERT_NE(ToL0, ToL1); 5643 } 5644 5645 TEST_P(ASTImporterOptionSpecificTestBase, ImportAssignedLambda) { 5646 Decl *FromTU = getTuDecl( 5647 R"( 5648 void f() { 5649 auto x = []{} = {}; auto x2 = x; 5650 } 5651 )", 5652 Lang_CXX20, "input0.cc"); 5653 auto FromF = FirstDeclMatcher<FunctionDecl>().match( 5654 FromTU, functionDecl(hasName("f"))); 5655 // We have only one lambda class. 5656 ASSERT_EQ( 5657 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())), 5658 1u); 5659 5660 FunctionDecl *ToF = Import(FromF, Lang_CXX20); 5661 EXPECT_TRUE(ToF); 5662 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 5663 // We have only one lambda class after the import. 5664 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())), 5665 1u); 5666 } 5667 5668 TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) { 5669 Decl *FromTU = getTuDecl( 5670 R"( 5671 void f() { 5672 auto x = []{} = {}; 5673 auto xb = []{} = {}; 5674 } 5675 )", 5676 Lang_CXX20, "input0.cc"); 5677 auto FromF = FirstDeclMatcher<FunctionDecl>().match( 5678 FromTU, functionDecl(hasName("f"))); 5679 // We have two lambda classes. 5680 ASSERT_EQ( 5681 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())), 5682 2u); 5683 5684 FunctionDecl *ToF = Import(FromF, Lang_CXX20); 5685 EXPECT_TRUE(ToF); 5686 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 5687 // We have two lambda classes after the import. 5688 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())), 5689 2u); 5690 } 5691 5692 struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {}; 5693 5694 TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) { 5695 Decl *FromTU = getTuDecl( 5696 R"( 5697 auto X = [](long l) { 5698 using int_type = long; 5699 auto dur = 13; 5700 return static_cast<int_type>(dur); 5701 }; 5702 )", 5703 Lang_CXX14, "input0.cc"); 5704 CXXMethodDecl *From = 5705 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, cxxMethodDecl()); 5706 5707 // Explicitly set the return type of the lambda's operator() to the TypeAlias. 5708 // Normally the return type would be the built-in 'long' type. However, there 5709 // are cases when Clang does not use the canonical type and the TypeAlias is 5710 // used. I could not create such an AST from regular source code, it requires 5711 // some special state in the preprocessor. I've found such an AST when Clang 5712 // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce 5713 // that with creduce, because after preprocessing, the AST no longer 5714 // contained the TypeAlias as a return type of the lambda. 5715 ASTContext &Ctx = From->getASTContext(); 5716 TypeAliasDecl *FromTA = 5717 FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl()); 5718 QualType TT = Ctx.getTypedefType(FromTA); 5719 const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType()); 5720 QualType NewFunType = 5721 Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo()); 5722 From->setType(NewFunType); 5723 5724 CXXMethodDecl *To = Import(From, Lang_CXX14); 5725 EXPECT_TRUE(To); 5726 EXPECT_TRUE(isa<TypedefType>(To->getReturnType())); 5727 } 5728 5729 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside) { 5730 Decl *FromTU = getTuDecl( 5731 R"( 5732 auto foo() { 5733 struct X {}; 5734 return X(); 5735 } 5736 )", 5737 Lang_CXX14, "input0.cc"); 5738 FunctionDecl *From = 5739 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 5740 5741 FunctionDecl *To = Import(From, Lang_CXX14); 5742 EXPECT_TRUE(To); 5743 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 5744 } 5745 5746 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside2) { 5747 Decl *FromTU = getTuDecl( 5748 R"( 5749 auto foo() { 5750 struct X {}; 5751 return X(); 5752 } 5753 )", 5754 Lang_CXX14, "input0.cc"); 5755 FunctionDecl *From = 5756 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 5757 5758 // This time import the type directly. 5759 QualType ToT = ImportType(From->getType(), From, Lang_CXX14); 5760 const FunctionProtoType *FPT = cast<FunctionProtoType>(ToT); 5761 EXPECT_TRUE(isa<AutoType>(FPT->getReturnType())); 5762 } 5763 5764 TEST_P(ImportAutoFunctions, ReturnWithTypedefToStructDeclaredInside) { 5765 Decl *FromTU = getTuDecl( 5766 R"( 5767 auto foo() { 5768 struct X {}; 5769 using Y = X; 5770 return Y(); 5771 } 5772 )", 5773 Lang_CXX14, "input0.cc"); 5774 FunctionDecl *From = 5775 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 5776 5777 FunctionDecl *To = Import(From, Lang_CXX14); 5778 EXPECT_TRUE(To); 5779 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 5780 } 5781 5782 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredNestedInside) { 5783 Decl *FromTU = getTuDecl( 5784 R"( 5785 auto foo() { 5786 struct X { struct Y{}; }; 5787 return X::Y(); 5788 } 5789 )", 5790 Lang_CXX14, "input0.cc"); 5791 FunctionDecl *From = 5792 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 5793 5794 FunctionDecl *To = Import(From, Lang_CXX14); 5795 EXPECT_TRUE(To); 5796 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 5797 } 5798 5799 TEST_P(ImportAutoFunctions, ReturnWithInternalLambdaType) { 5800 Decl *FromTU = getTuDecl( 5801 R"( 5802 auto f() { 5803 auto l = []() { 5804 struct X {}; 5805 return X(); 5806 }; 5807 return l(); 5808 } 5809 )", 5810 Lang_CXX17, "input0.cc"); 5811 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 5812 FromTU, functionDecl(hasName("f"))); 5813 5814 FunctionDecl *To = Import(From, Lang_CXX17); 5815 EXPECT_TRUE(To); 5816 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 5817 } 5818 5819 TEST_P(ImportAutoFunctions, ReturnWithTypeInIf) { 5820 Decl *FromTU = getTuDecl( 5821 R"( 5822 auto f() { 5823 if (struct X {} x; true) 5824 return X(); 5825 else 5826 return X(); 5827 } 5828 )", 5829 Lang_CXX17, "input0.cc"); 5830 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 5831 FromTU, functionDecl(hasName("f"))); 5832 5833 FunctionDecl *To = Import(From, Lang_CXX17); 5834 EXPECT_TRUE(To); 5835 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 5836 } 5837 5838 TEST_P(ImportAutoFunctions, ReturnWithTypeInFor) { 5839 Decl *FromTU = getTuDecl( 5840 R"( 5841 auto f() { 5842 for (struct X {} x;;) 5843 return X(); 5844 } 5845 )", 5846 Lang_CXX17, "input0.cc"); 5847 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 5848 FromTU, functionDecl(hasName("f"))); 5849 5850 FunctionDecl *To = Import(From, Lang_CXX17); 5851 EXPECT_TRUE(To); 5852 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 5853 } 5854 5855 TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) { 5856 Decl *FromTU = getTuDecl( 5857 R"( 5858 auto f() { 5859 switch (struct X {} x; 10) { 5860 case 10: 5861 return X(); 5862 } 5863 } 5864 )", 5865 Lang_CXX17, "input0.cc"); 5866 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 5867 FromTU, functionDecl(hasName("f"))); 5868 5869 FunctionDecl *To = Import(From, Lang_CXX17); 5870 EXPECT_TRUE(To); 5871 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 5872 } 5873 5874 struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {}; 5875 5876 TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) { 5877 // Tests that the FileID tree structure (with the links being the include 5878 // chains) is preserved while importing other files (which need to be 5879 // added to this structure with fake include locations. 5880 5881 SourceLocation Location1; 5882 { 5883 auto Pattern = varDecl(hasName("X")); 5884 Decl *FromTU = getTuDecl("int X;", Lang_C99, "input0.c"); 5885 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 5886 5887 Location1 = Import(FromD, Lang_C99)->getLocation(); 5888 } 5889 SourceLocation Location2; 5890 { 5891 auto Pattern = varDecl(hasName("Y")); 5892 Decl *FromTU = getTuDecl("int Y;", Lang_C99, "input1.c"); 5893 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 5894 5895 Location2 = Import(FromD, Lang_C99)->getLocation(); 5896 } 5897 5898 SourceManager &ToSM = ToAST->getSourceManager(); 5899 FileID FileID1 = ToSM.getFileID(Location1); 5900 FileID FileID2 = ToSM.getFileID(Location2); 5901 5902 // Check that the imported files look like as if they were included from the 5903 // start of the main file. 5904 SourceLocation FileStart = ToSM.getLocForStartOfFile(ToSM.getMainFileID()); 5905 EXPECT_NE(FileID1, ToSM.getMainFileID()); 5906 EXPECT_NE(FileID2, ToSM.getMainFileID()); 5907 EXPECT_EQ(ToSM.getIncludeLoc(FileID1), FileStart); 5908 EXPECT_EQ(ToSM.getIncludeLoc(FileID2), FileStart); 5909 5910 // Let the SourceManager check the order of the locations. The order should 5911 // be the order in which the declarations are imported. 5912 EXPECT_TRUE(ToSM.isBeforeInTranslationUnit(Location1, Location2)); 5913 EXPECT_FALSE(ToSM.isBeforeInTranslationUnit(Location2, Location1)); 5914 } 5915 5916 TEST_P(ImportSourceLocations, NormalFileBuffer) { 5917 // Test importing normal file buffers. 5918 5919 std::string Path = "input0.c"; 5920 std::string Source = "int X;"; 5921 TranslationUnitDecl *FromTU = getTuDecl(Source, Lang_C99, Path); 5922 5923 SourceLocation ImportedLoc; 5924 { 5925 // Import the VarDecl to trigger the importing of the FileID. 5926 auto Pattern = varDecl(hasName("X")); 5927 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 5928 ImportedLoc = Import(FromD, Lang_C99)->getLocation(); 5929 } 5930 5931 // Make sure the imported buffer has the original contents. 5932 SourceManager &ToSM = ToAST->getSourceManager(); 5933 FileID ImportedID = ToSM.getFileID(ImportedLoc); 5934 EXPECT_EQ(Source, 5935 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer()); 5936 } 5937 5938 TEST_P(ImportSourceLocations, OverwrittenFileBuffer) { 5939 // Test importing overwritten file buffers. 5940 5941 std::string Path = "input0.c"; 5942 TranslationUnitDecl *FromTU = getTuDecl("int X;", Lang_C99, Path); 5943 5944 // Overwrite the file buffer for our input file with new content. 5945 const std::string Contents = "overwritten contents"; 5946 SourceLocation ImportedLoc; 5947 { 5948 SourceManager &FromSM = FromTU->getASTContext().getSourceManager(); 5949 clang::FileManager &FM = FromSM.getFileManager(); 5950 const clang::FileEntry &FE = 5951 *FM.getVirtualFile(Path, static_cast<off_t>(Contents.size()), 0); 5952 5953 llvm::SmallVector<char, 64> Buffer; 5954 Buffer.append(Contents.begin(), Contents.end()); 5955 auto FileContents = 5956 std::make_unique<llvm::SmallVectorMemoryBuffer>(std::move(Buffer), Path); 5957 FromSM.overrideFileContents(&FE, std::move(FileContents)); 5958 5959 // Import the VarDecl to trigger the importing of the FileID. 5960 auto Pattern = varDecl(hasName("X")); 5961 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 5962 ImportedLoc = Import(FromD, Lang_C99)->getLocation(); 5963 } 5964 5965 // Make sure the imported buffer has the overwritten contents. 5966 SourceManager &ToSM = ToAST->getSourceManager(); 5967 FileID ImportedID = ToSM.getFileID(ImportedLoc); 5968 EXPECT_EQ(Contents, 5969 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer()); 5970 } 5971 5972 TEST_P(ASTImporterOptionSpecificTestBase, ImportExprOfAlignmentAttr) { 5973 // Test if import of these packed and aligned attributes does not trigger an 5974 // error situation where source location from 'From' context is referenced in 5975 // 'To' context through evaluation of the alignof attribute. 5976 // This happens if the 'alignof(A)' expression is not imported correctly. 5977 Decl *FromTU = getTuDecl( 5978 R"( 5979 struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; }; 5980 struct alignas(alignof(A)) S {}; 5981 )", 5982 Lang_CXX11, "input.cc"); 5983 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 5984 FromTU, cxxRecordDecl(hasName("S"), unless(isImplicit()))); 5985 ASSERT_TRUE(FromD); 5986 5987 auto *ToD = Import(FromD, Lang_CXX11); 5988 ASSERT_TRUE(ToD); 5989 5990 auto *FromAttr = FromD->getAttr<AlignedAttr>(); 5991 auto *ToAttr = ToD->getAttr<AlignedAttr>(); 5992 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited()); 5993 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion()); 5994 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit()); 5995 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax()); 5996 EXPECT_EQ(FromAttr->getSemanticSpelling(), ToAttr->getSemanticSpelling()); 5997 EXPECT_TRUE(ToAttr->getAlignmentExpr()); 5998 5999 auto *ToA = FirstDeclMatcher<CXXRecordDecl>().match( 6000 ToD->getTranslationUnitDecl(), 6001 cxxRecordDecl(hasName("A"), unless(isImplicit()))); 6002 // Ensure that 'struct A' was imported (through reference from attribute of 6003 // 'S'). 6004 EXPECT_TRUE(ToA); 6005 } 6006 6007 TEST_P(ASTImporterOptionSpecificTestBase, ImportFormatAttr) { 6008 Decl *FromTU = getTuDecl( 6009 R"( 6010 int foo(const char * fmt, ...) 6011 __attribute__ ((__format__ (__scanf__, 1, 2))); 6012 )", 6013 Lang_CXX03, "input.cc"); 6014 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 6015 FromTU, functionDecl(hasName("foo"))); 6016 ASSERT_TRUE(FromD); 6017 6018 auto *ToD = Import(FromD, Lang_CXX03); 6019 ASSERT_TRUE(ToD); 6020 ToD->dump(); // Should not crash! 6021 6022 auto *FromAttr = FromD->getAttr<FormatAttr>(); 6023 auto *ToAttr = ToD->getAttr<FormatAttr>(); 6024 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited()); 6025 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion()); 6026 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit()); 6027 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax()); 6028 EXPECT_EQ(FromAttr->getAttributeSpellingListIndex(), 6029 ToAttr->getAttributeSpellingListIndex()); 6030 EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName()); 6031 } 6032 template <typename T> 6033 auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) { 6034 auto Copy = Values; 6035 for (std::vector<std::string> &ArgV : Copy) { 6036 for (const std::string &Arg : Args) { 6037 ArgV.push_back(Arg); 6038 } 6039 } 6040 return ::testing::ValuesIn(Copy); 6041 } 6042 6043 struct ImportWithExternalSource : ASTImporterOptionSpecificTestBase { 6044 ImportWithExternalSource() { 6045 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 6046 ASTContext &FromContext, FileManager &FromFileManager, 6047 bool MinimalImport, 6048 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 6049 return new ASTImporter(ToContext, ToFileManager, FromContext, 6050 FromFileManager, MinimalImport, 6051 // We use the regular lookup. 6052 /*SharedState=*/nullptr); 6053 }; 6054 } 6055 }; 6056 6057 /// An ExternalASTSource that keeps track of the tags is completed. 6058 struct SourceWithCompletedTagList : clang::ExternalASTSource { 6059 std::vector<clang::TagDecl *> &CompletedTags; 6060 SourceWithCompletedTagList(std::vector<clang::TagDecl *> &CompletedTags) 6061 : CompletedTags(CompletedTags) {} 6062 void CompleteType(TagDecl *Tag) override { 6063 auto *Record = cast<CXXRecordDecl>(Tag); 6064 Record->startDefinition(); 6065 Record->completeDefinition(); 6066 CompletedTags.push_back(Tag); 6067 } 6068 using clang::ExternalASTSource::CompleteType; 6069 }; 6070 6071 TEST_P(ImportWithExternalSource, CompleteRecordBeforeImporting) { 6072 // Create an empty TU. 6073 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cpp"); 6074 6075 // Create and add the test ExternalASTSource. 6076 std::vector<clang::TagDecl *> CompletedTags; 6077 IntrusiveRefCntPtr<ExternalASTSource> source = 6078 new SourceWithCompletedTagList(CompletedTags); 6079 clang::ASTContext &Context = FromTU->getASTContext(); 6080 Context.setExternalSource(std::move(source)); 6081 6082 // Create a dummy class by hand with external lexical storage. 6083 IdentifierInfo &Ident = Context.Idents.get("test_class"); 6084 auto *Record = CXXRecordDecl::Create( 6085 Context, TTK_Class, FromTU, SourceLocation(), SourceLocation(), &Ident); 6086 Record->setHasExternalLexicalStorage(); 6087 FromTU->addDecl(Record); 6088 6089 // Do a minimal import of the created class. 6090 EXPECT_EQ(0U, CompletedTags.size()); 6091 Import(Record, Lang_CXX03); 6092 EXPECT_EQ(0U, CompletedTags.size()); 6093 6094 // Import the definition of the created class. 6095 llvm::Error Err = findFromTU(Record)->Importer->ImportDefinition(Record); 6096 EXPECT_FALSE((bool)Err); 6097 consumeError(std::move(Err)); 6098 6099 // Make sure the class was completed once. 6100 EXPECT_EQ(1U, CompletedTags.size()); 6101 EXPECT_EQ(Record, CompletedTags.front()); 6102 } 6103 6104 TEST_P(ImportFunctions, CTADImplicit) { 6105 Decl *FromTU = getTuDecl( 6106 R"( 6107 template <typename T> struct A { 6108 A(T); 6109 }; 6110 A a{(int)0}; 6111 )", 6112 Lang_CXX17, "input.cc"); 6113 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 6114 FromTU, 6115 cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>"))))); 6116 auto *ToD = Import(FromD, Lang_CXX17); 6117 ASSERT_TRUE(ToD); 6118 EXPECT_TRUE(ToD->isCopyDeductionCandidate()); 6119 // Check that the deduced class template is also imported. 6120 EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull( 6121 FromD->getDeducedTemplate())); 6122 } 6123 6124 TEST_P(ImportFunctions, CTADUserDefinedExplicit) { 6125 Decl *FromTU = getTuDecl( 6126 R"( 6127 template <typename T> struct A { 6128 A(T); 6129 }; 6130 template <typename T> explicit A(T) -> A<float>; 6131 A a{(int)0}; // calls A<float>::A(float) 6132 )", 6133 Lang_CXX17, "input.cc"); 6134 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 6135 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 6136 // Not-implicit: i.e. not compiler-generated, user defined. 6137 ASSERT_FALSE(FromD->isImplicit()); 6138 ASSERT_TRUE(FromD->isExplicit()); // Has the explicit keyword. 6139 auto *ToD = Import(FromD, Lang_CXX17); 6140 ASSERT_TRUE(ToD); 6141 EXPECT_FALSE(FromD->isImplicit()); 6142 EXPECT_TRUE(ToD->isExplicit()); 6143 } 6144 6145 TEST_P(ImportFunctions, CTADWithLocalTypedef) { 6146 Decl *TU = getTuDecl( 6147 R"( 6148 template <typename T> struct A { 6149 typedef T U; 6150 A(U); 6151 }; 6152 A a{(int)0}; 6153 )", 6154 Lang_CXX17, "input.cc"); 6155 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 6156 TU, cxxDeductionGuideDecl()); 6157 auto *ToD = Import(FromD, Lang_CXX17); 6158 ASSERT_TRUE(ToD); 6159 } 6160 6161 // FIXME Move these tests out of ASTImporterTest. For that we need to factor 6162 // out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase 6163 // into a new test Fixture. Then we should lift up this Fixture to its own 6164 // implementation file and only then could we reuse the Fixture in other AST 6165 // unitttests. 6166 struct CTAD : ASTImporterOptionSpecificTestBase {}; 6167 6168 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) { 6169 Decl *TU = getTuDecl( 6170 R"( 6171 typedef int U; 6172 template <typename T> struct A { 6173 A(U, T); 6174 }; 6175 A a{(int)0, (int)0}; 6176 )", 6177 Lang_CXX17, "input.cc"); 6178 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 6179 TU, cxxDeductionGuideDecl()); 6180 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 6181 TU, typedefNameDecl(hasName("U"))); 6182 ParmVarDecl *Param = Guide->getParamDecl(0); 6183 // The type of the first param (which is a typedef) should match the typedef 6184 // in the global scope. 6185 EXPECT_EQ(Param->getType()->castAs<TypedefType>()->getDecl(), Typedef); 6186 } 6187 6188 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) { 6189 Decl *TU = getTuDecl( 6190 R"( 6191 typedef int U; 6192 template <typename T> struct A { 6193 A(U*, T); 6194 }; 6195 A a{(int*)0, (int)0}; 6196 )", 6197 Lang_CXX17, "input.cc"); 6198 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 6199 TU, cxxDeductionGuideDecl()); 6200 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 6201 TU, typedefNameDecl(hasName("U"))); 6202 ParmVarDecl *Param = Guide->getParamDecl(0); 6203 EXPECT_EQ(Param->getType() 6204 ->getAs<PointerType>() 6205 ->getPointeeType() 6206 ->getAs<TypedefType>() 6207 ->getDecl(), 6208 Typedef); 6209 } 6210 6211 TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) { 6212 Decl *TU = getTuDecl( 6213 R"( 6214 template <typename T> struct A { 6215 typedef T U; 6216 A(U, T); 6217 }; 6218 A a{(int)0, (int)0}; 6219 )", 6220 Lang_CXX17, "input.cc"); 6221 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 6222 TU, cxxDeductionGuideDecl()); 6223 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 6224 TU, typedefNameDecl(hasName("U"))); 6225 ParmVarDecl *Param = Guide->getParamDecl(0); 6226 EXPECT_NE(Param->getType()->castAs<TypedefType>()->getDecl(), Typedef); 6227 } 6228 6229 INSTANTIATE_TEST_CASE_P(ParameterizedTests, CTAD, 6230 DefaultTestValuesForRunOptions, ); 6231 6232 TEST_P(ASTImporterOptionSpecificTestBase, TypedefWithAttribute) { 6233 Decl *TU = getTuDecl( 6234 R"( 6235 namespace N { 6236 typedef int X __attribute__((annotate("A"))); 6237 } 6238 )", 6239 Lang_CXX17, "input.cc"); 6240 auto *FromD = 6241 FirstDeclMatcher<TypedefDecl>().match(TU, typedefDecl(hasName("X"))); 6242 auto *ToD = Import(FromD, Lang_CXX17); 6243 ASSERT_TRUE(ToD); 6244 ASSERT_EQ(ToD->getAttrs().size(), 1U); 6245 auto *ToAttr = dyn_cast<AnnotateAttr>(ToD->getAttrs()[0]); 6246 ASSERT_TRUE(ToAttr); 6247 EXPECT_EQ(ToAttr->getAnnotation(), "A"); 6248 } 6249 6250 TEST_P(ASTImporterOptionSpecificTestBase, 6251 ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) { 6252 Decl *FromTU = getTuDecl( 6253 R"( 6254 6255 namespace std { 6256 template<typename T> 6257 class basic_stringbuf; 6258 } 6259 namespace std { 6260 class char_traits; 6261 template<typename T = char_traits> 6262 class basic_stringbuf; 6263 } 6264 namespace std { 6265 template<typename T> 6266 class basic_stringbuf {}; 6267 } 6268 6269 )", 6270 Lang_CXX11); 6271 6272 auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match( 6273 FromTU, 6274 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); 6275 auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11)); 6276 EXPECT_TRUE(To1); 6277 6278 auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match( 6279 FromTU, 6280 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); 6281 auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11)); 6282 EXPECT_TRUE(To2); 6283 } 6284 6285 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfCapturedVLAType) { 6286 Decl *FromTU = getTuDecl( 6287 R"( 6288 void declToImport(int N) { 6289 int VLA[N]; 6290 [&VLA] {}; // FieldDecl inside the lambda. 6291 } 6292 )", 6293 Lang_CXX14); 6294 auto *FromFD = FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl()); 6295 ASSERT_TRUE(FromFD); 6296 ASSERT_TRUE(FromFD->hasCapturedVLAType()); 6297 6298 auto *ToFD = Import(FromFD, Lang_CXX14); 6299 EXPECT_TRUE(ToFD); 6300 EXPECT_TRUE(ToFD->hasCapturedVLAType()); 6301 EXPECT_NE(FromFD->getCapturedVLAType(), ToFD->getCapturedVLAType()); 6302 } 6303 6304 TEST_P(ASTImporterOptionSpecificTestBase, ImportEnumMemberSpecialization) { 6305 Decl *FromTU = getTuDecl( 6306 R"( 6307 template <class T> struct A { 6308 enum tagname { enumerator }; 6309 }; 6310 template struct A<int>; 6311 )", 6312 Lang_CXX03); 6313 auto *FromD = FirstDeclMatcher<EnumDecl>().match( 6314 FromTU, enumDecl(hasName("tagname"), 6315 hasParent(classTemplateSpecializationDecl()))); 6316 ASSERT_TRUE(FromD); 6317 ASSERT_TRUE(FromD->getMemberSpecializationInfo()); 6318 6319 auto *ToD = Import(FromD, Lang_CXX03); 6320 EXPECT_TRUE(ToD); 6321 EXPECT_TRUE(ToD->getMemberSpecializationInfo()); 6322 EXPECT_EQ(FromD->getTemplateSpecializationKind(), 6323 ToD->getTemplateSpecializationKind()); 6324 } 6325 6326 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, 6327 DefaultTestValuesForRunOptions, ); 6328 6329 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportPath, 6330 ::testing::Values(std::vector<std::string>()), ); 6331 6332 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportExpr, 6333 DefaultTestValuesForRunOptions, ); 6334 6335 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFixedPointExpr, 6336 ExtendWithOptions(DefaultTestArrayForRunOptions, 6337 std::vector<std::string>{ 6338 "-ffixed-point"}), ); 6339 6340 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportBlock, 6341 ExtendWithOptions(DefaultTestArrayForRunOptions, 6342 std::vector<std::string>{ 6343 "-fblocks"}), ); 6344 6345 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportType, 6346 DefaultTestValuesForRunOptions, ); 6347 6348 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportDecl, 6349 DefaultTestValuesForRunOptions, ); 6350 6351 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterOptionSpecificTestBase, 6352 DefaultTestValuesForRunOptions, ); 6353 6354 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ErrorHandlingTest, 6355 DefaultTestValuesForRunOptions, ); 6356 6357 INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedirectingImporterTest, 6358 DefaultTestValuesForRunOptions, ); 6359 6360 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctions, 6361 DefaultTestValuesForRunOptions, ); 6362 6363 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportAutoFunctions, 6364 DefaultTestValuesForRunOptions, ); 6365 6366 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionTemplates, 6367 DefaultTestValuesForRunOptions, ); 6368 6369 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctionTemplates, 6370 DefaultTestValuesForRunOptions, ); 6371 6372 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses, 6373 DefaultTestValuesForRunOptions, ); 6374 6375 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions, 6376 DefaultTestValuesForRunOptions, ); 6377 6378 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendClasses, 6379 DefaultTestValuesForRunOptions, ); 6380 6381 INSTANTIATE_TEST_CASE_P(ParameterizedTests, 6382 ImportFunctionTemplateSpecializations, 6383 DefaultTestValuesForRunOptions, ); 6384 6385 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportImplicitMethods, 6386 DefaultTestValuesForRunOptions, ); 6387 6388 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportVariables, 6389 DefaultTestValuesForRunOptions, ); 6390 6391 INSTANTIATE_TEST_CASE_P(ParameterizedTests, LLDBLookupTest, 6392 DefaultTestValuesForRunOptions, ); 6393 6394 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportSourceLocations, 6395 DefaultTestValuesForRunOptions, ); 6396 6397 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportWithExternalSource, 6398 DefaultTestValuesForRunOptions, ); 6399 6400 } // end namespace ast_matchers 6401 } // end namespace clang 6402