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 const internal::VariadicDynCastAllOfMatcher<Stmt, ShuffleVectorExpr> 294 shuffleVectorExpr; 295 296 TEST_P(ImportExpr, ImportShuffleVectorExpr) { 297 MatchVerifier<Decl> Verifier; 298 constexpr auto Code = R"code( 299 typedef double vector4double __attribute__((__vector_size__(32))); 300 vector4double declToImport(vector4double a, vector4double b) { 301 return __builtin_shufflevector(a, b, 0, 1, 2, 3); 302 } 303 )code"; 304 const auto Pattern = functionDecl(hasDescendant(shuffleVectorExpr( 305 allOf(has(declRefExpr(to(parmVarDecl(hasName("a"))))), 306 has(declRefExpr(to(parmVarDecl(hasName("b"))))), 307 has(integerLiteral(equals(0))), has(integerLiteral(equals(1))), 308 has(integerLiteral(equals(2))), has(integerLiteral(equals(3))))))); 309 testImport(Code, Lang_C99, "", Lang_C99, Verifier, Pattern); 310 } 311 312 TEST_P(ImportExpr, ImportGNUNullExpr) { 313 MatchVerifier<Decl> Verifier; 314 testImport("void declToImport() { (void)__null; }", Lang_CXX03, "", 315 Lang_CXX03, Verifier, 316 functionDecl(hasDescendant(gnuNullExpr(hasType(isInteger()))))); 317 } 318 319 TEST_P(ImportExpr, ImportGenericSelectionExpr) { 320 MatchVerifier<Decl> Verifier; 321 322 testImport( 323 "void declToImport() { int x; (void)_Generic(x, int: 0, float: 1); }", 324 Lang_C99, "", Lang_C99, Verifier, 325 functionDecl(hasDescendant(genericSelectionExpr()))); 326 } 327 328 TEST_P(ImportExpr, ImportCXXNullPtrLiteralExpr) { 329 MatchVerifier<Decl> Verifier; 330 testImport( 331 "void declToImport() { (void)nullptr; }", 332 Lang_CXX11, "", Lang_CXX11, Verifier, 333 functionDecl(hasDescendant(cxxNullPtrLiteralExpr()))); 334 } 335 336 337 TEST_P(ImportExpr, ImportFloatinglLiteralExpr) { 338 MatchVerifier<Decl> Verifier; 339 testImport("void declToImport() { (void)1.0; }", Lang_C99, "", Lang_C99, 340 Verifier, 341 functionDecl(hasDescendant( 342 floatLiteral(equals(1.0), hasType(asString("double")))))); 343 testImport("void declToImport() { (void)1.0e-5f; }", Lang_C99, "", Lang_C99, 344 Verifier, 345 functionDecl(hasDescendant( 346 floatLiteral(equals(1.0e-5f), hasType(asString("float")))))); 347 } 348 349 TEST_P(ImportFixedPointExpr, ImportFixedPointerLiteralExpr) { 350 MatchVerifier<Decl> Verifier; 351 testImport("void declToImport() { (void)1.0k; }", Lang_C99, "", Lang_C99, 352 Verifier, functionDecl(hasDescendant(fixedPointLiteral()))); 353 testImport("void declToImport() { (void)0.75r; }", Lang_C99, "", Lang_C99, 354 Verifier, functionDecl(hasDescendant(fixedPointLiteral()))); 355 } 356 357 TEST_P(ImportExpr, ImportImaginaryLiteralExpr) { 358 MatchVerifier<Decl> Verifier; 359 testImport( 360 "void declToImport() { (void)1.0i; }", 361 Lang_CXX14, "", Lang_CXX14, Verifier, 362 functionDecl(hasDescendant(imaginaryLiteral()))); 363 } 364 365 TEST_P(ImportExpr, ImportCompoundLiteralExpr) { 366 MatchVerifier<Decl> Verifier; 367 testImport("void declToImport() {" 368 " struct s { int x; long y; unsigned z; }; " 369 " (void)(struct s){ 42, 0L, 1U }; }", 370 Lang_CXX03, "", Lang_CXX03, Verifier, 371 functionDecl(hasDescendant(compoundLiteralExpr( 372 hasType(asString("struct s")), 373 has(initListExpr( 374 hasType(asString("struct s")), 375 has(integerLiteral(equals(42), hasType(asString("int")))), 376 has(integerLiteral(equals(0), hasType(asString("long")))), 377 has(integerLiteral( 378 equals(1), hasType(asString("unsigned int")))))))))); 379 } 380 381 TEST_P(ImportExpr, ImportCXXThisExpr) { 382 MatchVerifier<Decl> Verifier; 383 testImport("class declToImport { void f() { (void)this; } };", Lang_CXX03, "", 384 Lang_CXX03, Verifier, 385 cxxRecordDecl(hasMethod(hasDescendant( 386 cxxThisExpr(hasType(asString("class declToImport *"))))))); 387 } 388 389 TEST_P(ImportExpr, ImportAtomicExpr) { 390 MatchVerifier<Decl> Verifier; 391 testImport("void declToImport() { int *ptr; __atomic_load_n(ptr, 1); }", 392 Lang_C99, "", Lang_C99, Verifier, 393 functionDecl(hasDescendant(atomicExpr( 394 has(ignoringParenImpCasts( 395 declRefExpr(hasDeclaration(varDecl(hasName("ptr"))), 396 hasType(asString("int *"))))), 397 has(integerLiteral(equals(1), hasType(asString("int")))))))); 398 } 399 400 TEST_P(ImportExpr, ImportLabelDeclAndAddrLabelExpr) { 401 MatchVerifier<Decl> Verifier; 402 testImport("void declToImport() { loop: goto loop; (void)&&loop; }", Lang_C99, 403 "", Lang_C99, Verifier, 404 functionDecl(hasDescendant(labelStmt( 405 hasDeclaration(labelDecl(hasName("loop"))))), 406 hasDescendant(addrLabelExpr( 407 hasDeclaration(labelDecl(hasName("loop"))))))); 408 } 409 410 AST_MATCHER_P(TemplateDecl, hasTemplateDecl, 411 internal::Matcher<NamedDecl>, InnerMatcher) { 412 const NamedDecl *Template = Node.getTemplatedDecl(); 413 return Template && InnerMatcher.matches(*Template, Finder, Builder); 414 } 415 416 TEST_P(ImportExpr, ImportParenListExpr) { 417 MatchVerifier<Decl> Verifier; 418 testImport( 419 "template<typename T> class dummy { void f() { dummy X(*this); } };" 420 "typedef dummy<int> declToImport;" 421 "template class dummy<int>;", 422 Lang_CXX03, "", Lang_CXX03, Verifier, 423 typedefDecl(hasType(templateSpecializationType( 424 hasDeclaration(classTemplateSpecializationDecl(hasSpecializedTemplate( 425 classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod(allOf( 426 hasName("f"), 427 hasBody(compoundStmt(has(declStmt(hasSingleDecl( 428 varDecl(hasInitializer(parenListExpr(has(unaryOperator( 429 hasOperatorName("*"), 430 hasUnaryOperand(cxxThisExpr()))))))))))))))))))))))); 431 } 432 433 TEST_P(ImportExpr, ImportSwitch) { 434 MatchVerifier<Decl> Verifier; 435 testImport("void declToImport() { int b; switch (b) { case 1: break; } }", 436 Lang_C99, "", Lang_C99, Verifier, 437 functionDecl(hasDescendant( 438 switchStmt(has(compoundStmt(has(caseStmt()))))))); 439 } 440 441 TEST_P(ImportExpr, ImportStmtExpr) { 442 MatchVerifier<Decl> Verifier; 443 testImport( 444 "void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }", 445 Lang_C99, "", Lang_C99, Verifier, 446 traverse(TK_AsIs, 447 functionDecl(hasDescendant(varDecl( 448 hasName("C"), hasType(asString("int")), 449 hasInitializer(stmtExpr( 450 hasAnySubstatement(declStmt(hasSingleDecl(varDecl( 451 hasName("X"), hasType(asString("int")), 452 hasInitializer(integerLiteral(equals(4))))))), 453 hasDescendant(implicitCastExpr())))))))); 454 } 455 456 TEST_P(ImportExpr, ImportConditionalOperator) { 457 MatchVerifier<Decl> Verifier; 458 testImport("void declToImport() { (void)(true ? 1 : -5); }", Lang_CXX03, "", 459 Lang_CXX03, Verifier, 460 functionDecl(hasDescendant(conditionalOperator( 461 hasCondition(cxxBoolLiteral(equals(true))), 462 hasTrueExpression(integerLiteral(equals(1))), 463 hasFalseExpression(unaryOperator( 464 hasUnaryOperand(integerLiteral(equals(5))))))))); 465 } 466 467 TEST_P(ImportExpr, ImportBinaryConditionalOperator) { 468 MatchVerifier<Decl> Verifier; 469 testImport( 470 "void declToImport() { (void)(1 ?: -5); }", Lang_CXX03, "", Lang_CXX03, 471 Verifier, 472 traverse(TK_AsIs, 473 functionDecl(hasDescendant(binaryConditionalOperator( 474 hasCondition(implicitCastExpr( 475 hasSourceExpression(opaqueValueExpr( 476 hasSourceExpression(integerLiteral(equals(1))))), 477 hasType(booleanType()))), 478 hasTrueExpression(opaqueValueExpr( 479 hasSourceExpression(integerLiteral(equals(1))))), 480 hasFalseExpression(unaryOperator( 481 hasOperatorName("-"), 482 hasUnaryOperand(integerLiteral(equals(5)))))))))); 483 } 484 485 TEST_P(ImportExpr, ImportDesignatedInitExpr) { 486 MatchVerifier<Decl> Verifier; 487 testImport( 488 "void declToImport() {" 489 " struct point { double x; double y; };" 490 " struct point ptarray[10] = " 491 "{ [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }", 492 Lang_C99, "", Lang_C99, Verifier, 493 functionDecl(hasDescendant(initListExpr( 494 has(designatedInitExpr(designatorCountIs(2), 495 hasDescendant(floatLiteral(equals(1.0))), 496 hasDescendant(integerLiteral(equals(2))))), 497 has(designatedInitExpr(designatorCountIs(2), 498 hasDescendant(floatLiteral(equals(2.0))), 499 hasDescendant(integerLiteral(equals(2))))), 500 has(designatedInitExpr(designatorCountIs(2), 501 hasDescendant(floatLiteral(equals(1.0))), 502 hasDescendant(integerLiteral(equals(0))))))))); 503 } 504 505 TEST_P(ImportExpr, ImportPredefinedExpr) { 506 MatchVerifier<Decl> Verifier; 507 // __func__ expands as StringLiteral("declToImport") 508 testImport("void declToImport() { (void)__func__; }", Lang_CXX03, "", 509 Lang_CXX03, Verifier, 510 functionDecl(hasDescendant(predefinedExpr( 511 hasType(asString("const char[13]")), 512 has(stringLiteral(hasType(asString("const char[13]")))))))); 513 } 514 515 TEST_P(ImportExpr, ImportInitListExpr) { 516 MatchVerifier<Decl> Verifier; 517 testImport( 518 "void declToImport() {" 519 " struct point { double x; double y; };" 520 " point ptarray[10] = { [2].y = 1.0, [2].x = 2.0," 521 " [0].x = 1.0 }; }", 522 Lang_CXX03, "", Lang_CXX03, Verifier, 523 functionDecl(hasDescendant(initListExpr( 524 has(cxxConstructExpr(requiresZeroInitialization())), 525 has(initListExpr( 526 hasType(asString("struct point")), has(floatLiteral(equals(1.0))), 527 has(implicitValueInitExpr(hasType(asString("double")))))), 528 has(initListExpr(hasType(asString("struct point")), 529 has(floatLiteral(equals(2.0))), 530 has(floatLiteral(equals(1.0))))))))); 531 } 532 533 const internal::VariadicDynCastAllOfMatcher<Expr, CXXDefaultInitExpr> 534 cxxDefaultInitExpr; 535 536 TEST_P(ImportExpr, ImportCXXDefaultInitExpr) { 537 MatchVerifier<Decl> Verifier; 538 testImport("class declToImport { int DefInit = 5; }; declToImport X;", 539 Lang_CXX11, "", Lang_CXX11, Verifier, 540 cxxRecordDecl(hasDescendant(cxxConstructorDecl( 541 hasAnyConstructorInitializer(cxxCtorInitializer( 542 withInitializer(cxxDefaultInitExpr()))))))); 543 testImport( 544 "struct X { int A = 5; }; X declToImport{};", Lang_CXX17, "", Lang_CXX17, 545 Verifier, 546 varDecl(hasInitializer(initListExpr(hasInit(0, cxxDefaultInitExpr()))))); 547 } 548 549 const internal::VariadicDynCastAllOfMatcher<Expr, VAArgExpr> vaArgExpr; 550 551 TEST_P(ImportExpr, ImportVAArgExpr) { 552 MatchVerifier<Decl> Verifier; 553 testImport("void declToImport(__builtin_va_list list, ...) {" 554 " (void)__builtin_va_arg(list, int); }", 555 Lang_CXX03, "", Lang_CXX03, Verifier, 556 functionDecl(hasDescendant( 557 cStyleCastExpr(hasSourceExpression(vaArgExpr()))))); 558 } 559 560 TEST_P(ImportExpr, CXXTemporaryObjectExpr) { 561 MatchVerifier<Decl> Verifier; 562 testImport( 563 "struct C {};" 564 "void declToImport() { C c = C(); }", 565 Lang_CXX03, "", Lang_CXX03, Verifier, 566 traverse(TK_AsIs, 567 functionDecl(hasDescendant(exprWithCleanups(has(cxxConstructExpr( 568 has(materializeTemporaryExpr(has(implicitCastExpr( 569 has(cxxTemporaryObjectExpr())))))))))))); 570 } 571 572 TEST_P(ImportType, ImportAtomicType) { 573 MatchVerifier<Decl> Verifier; 574 testImport( 575 "void declToImport() { typedef _Atomic(int) a_int; }", 576 Lang_CXX11, "", Lang_CXX11, Verifier, 577 functionDecl(hasDescendant(typedefDecl(has(atomicType()))))); 578 } 579 580 TEST_P(ImportType, ImportUsingType) { 581 MatchVerifier<Decl> Verifier; 582 testImport("struct C {};" 583 "void declToImport() { using ::C; new C{}; }", 584 Lang_CXX11, "", Lang_CXX11, Verifier, 585 functionDecl(hasDescendant( 586 cxxNewExpr(hasType(pointerType(pointee(usingType()))))))); 587 } 588 589 TEST_P(ImportDecl, ImportFunctionTemplateDecl) { 590 MatchVerifier<Decl> Verifier; 591 testImport("template <typename T> void declToImport() { };", Lang_CXX03, "", 592 Lang_CXX03, Verifier, functionTemplateDecl()); 593 } 594 595 TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) { 596 MatchVerifier<Decl> Verifier; 597 testImport("template <typename T> struct C { T t; };" 598 "template <typename T> void declToImport() {" 599 " C<T> d;" 600 " (void)d.t;" 601 "}" 602 "void instantiate() { declToImport<int>(); }", 603 Lang_CXX03, "", Lang_CXX03, Verifier, 604 functionTemplateDecl(hasDescendant( 605 cStyleCastExpr(has(cxxDependentScopeMemberExpr()))))); 606 testImport("template <typename T> struct C { T t; };" 607 "template <typename T> void declToImport() {" 608 " C<T> d;" 609 " (void)(&d)->t;" 610 "}" 611 "void instantiate() { declToImport<int>(); }", 612 Lang_CXX03, "", Lang_CXX03, Verifier, 613 functionTemplateDecl(hasDescendant( 614 cStyleCastExpr(has(cxxDependentScopeMemberExpr()))))); 615 } 616 617 TEST_P(ImportType, ImportTypeAliasTemplate) { 618 MatchVerifier<Decl> Verifier; 619 testImport( 620 "template <int K>" 621 "struct dummy { static const int i = K; };" 622 "template <int K> using dummy2 = dummy<K>;" 623 "int declToImport() { return dummy2<3>::i; }", 624 Lang_CXX11, "", Lang_CXX11, Verifier, 625 traverse(TK_AsIs, 626 functionDecl(hasDescendant(implicitCastExpr(has(declRefExpr()))), 627 unless(hasAncestor( 628 translationUnitDecl(has(typeAliasDecl()))))))); 629 } 630 631 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateSpecializationDecl> 632 varTemplateSpecializationDecl; 633 634 TEST_P(ImportDecl, ImportVarTemplate) { 635 MatchVerifier<Decl> Verifier; 636 testImport( 637 "template <typename T>" 638 "T pi = T(3.1415926535897932385L);" 639 "void declToImport() { (void)pi<int>; }", 640 Lang_CXX14, "", Lang_CXX14, Verifier, 641 functionDecl( 642 hasDescendant(declRefExpr(to(varTemplateSpecializationDecl()))), 643 unless(hasAncestor(translationUnitDecl(has(varDecl( 644 hasName("pi"), unless(varTemplateSpecializationDecl())))))))); 645 } 646 647 TEST_P(ImportType, ImportPackExpansion) { 648 MatchVerifier<Decl> Verifier; 649 testImport("template <typename... Args>" 650 "struct dummy {" 651 " dummy(Args... args) {}" 652 " static const int i = 4;" 653 "};" 654 "int declToImport() { return dummy<int>::i; }", 655 Lang_CXX11, "", Lang_CXX11, Verifier, 656 traverse(TK_AsIs, functionDecl(hasDescendant(returnStmt(has( 657 implicitCastExpr(has(declRefExpr())))))))); 658 } 659 660 const internal::VariadicDynCastAllOfMatcher<Type, 661 DependentTemplateSpecializationType> 662 dependentTemplateSpecializationType; 663 664 TEST_P(ImportType, ImportDependentTemplateSpecialization) { 665 MatchVerifier<Decl> Verifier; 666 testImport("template<typename T>" 667 "struct A;" 668 "template<typename T>" 669 "struct declToImport {" 670 " typename A<T>::template B<T> a;" 671 "};", 672 Lang_CXX03, "", Lang_CXX03, Verifier, 673 classTemplateDecl(has(cxxRecordDecl(has( 674 fieldDecl(hasType(dependentTemplateSpecializationType()))))))); 675 } 676 677 TEST_P(ImportType, ImportDeducedTemplateSpecialization) { 678 MatchVerifier<Decl> Verifier; 679 testImport("template <typename T>" 680 "class C { public: C(T); };" 681 "C declToImport(123);", 682 Lang_CXX17, "", Lang_CXX17, Verifier, 683 varDecl(hasType(deducedTemplateSpecializationType()))); 684 } 685 686 const internal::VariadicDynCastAllOfMatcher<Stmt, SizeOfPackExpr> 687 sizeOfPackExpr; 688 689 TEST_P(ImportExpr, ImportSizeOfPackExpr) { 690 MatchVerifier<Decl> Verifier; 691 testImport( 692 "template <typename... Ts>" 693 "void declToImport() {" 694 " const int i = sizeof...(Ts);" 695 "};" 696 "void g() { declToImport<int>(); }", 697 Lang_CXX11, "", Lang_CXX11, Verifier, 698 functionTemplateDecl(hasDescendant(sizeOfPackExpr()))); 699 testImport( 700 "template <typename... Ts>" 701 "using X = int[sizeof...(Ts)];" 702 "template <typename... Us>" 703 "struct Y {" 704 " X<Us..., int, double, int, Us...> f;" 705 "};" 706 "Y<float, int> declToImport;", 707 Lang_CXX11, "", Lang_CXX11, Verifier, 708 varDecl(hasType(classTemplateSpecializationDecl(has(fieldDecl(hasType( 709 hasUnqualifiedDesugaredType(constantArrayType(hasSize(7)))))))))); 710 } 711 712 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFoldExpr> cxxFoldExpr; 713 714 AST_MATCHER_P(CXXFoldExpr, hasOperator, BinaryOperatorKind, Op) { 715 return Node.getOperator() == Op; 716 } 717 AST_MATCHER(CXXFoldExpr, hasInit) { return Node.getInit(); } 718 AST_MATCHER(CXXFoldExpr, isRightFold) { return Node.isRightFold(); } 719 AST_MATCHER(CXXFoldExpr, isLeftFold) { return Node.isLeftFold(); } 720 721 TEST_P(ImportExpr, ImportCXXFoldExpr) { 722 auto Match1 = 723 cxxFoldExpr(hasOperator(BO_Add), isLeftFold(), unless(hasInit())); 724 auto Match2 = cxxFoldExpr(hasOperator(BO_Sub), isLeftFold(), hasInit()); 725 auto Match3 = 726 cxxFoldExpr(hasOperator(BO_Mul), isRightFold(), unless(hasInit())); 727 auto Match4 = cxxFoldExpr(hasOperator(BO_Div), isRightFold(), hasInit()); 728 729 MatchVerifier<Decl> Verifier; 730 testImport("template <typename... Ts>" 731 "void declToImport(Ts... args) {" 732 " const int i1 = (... + args);" 733 " const int i2 = (1 - ... - args);" 734 " const int i3 = (args * ...);" 735 " const int i4 = (args / ... / 1);" 736 "};" 737 "void g() { declToImport(1, 2, 3, 4, 5); }", 738 Lang_CXX17, "", Lang_CXX17, Verifier, 739 functionTemplateDecl(hasDescendant(Match1), hasDescendant(Match2), 740 hasDescendant(Match3), 741 hasDescendant(Match4))); 742 } 743 744 /// \brief Matches __builtin_types_compatible_p: 745 /// GNU extension to check equivalent types 746 /// Given 747 /// \code 748 /// __builtin_types_compatible_p(int, int) 749 /// \endcode 750 // will generate TypeTraitExpr <...> 'int' 751 const internal::VariadicDynCastAllOfMatcher<Stmt, TypeTraitExpr> typeTraitExpr; 752 753 TEST_P(ImportExpr, ImportTypeTraitExpr) { 754 MatchVerifier<Decl> Verifier; 755 testImport( 756 "void declToImport() { " 757 " (void)__builtin_types_compatible_p(int, int);" 758 "}", 759 Lang_C99, "", Lang_C99, Verifier, 760 functionDecl(hasDescendant(typeTraitExpr(hasType(asString("int")))))); 761 } 762 763 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr> cxxTypeidExpr; 764 765 TEST_P(ImportExpr, ImportCXXTypeidExpr) { 766 MatchVerifier<Decl> Verifier; 767 testImport( 768 "namespace std { class type_info {}; }" 769 "void declToImport() {" 770 " int x;" 771 " auto a = typeid(int); auto b = typeid(x);" 772 "}", 773 Lang_CXX11, "", Lang_CXX11, Verifier, 774 traverse( 775 TK_AsIs, 776 functionDecl( 777 hasDescendant(varDecl(hasName("a"), hasInitializer(hasDescendant( 778 cxxTypeidExpr())))), 779 hasDescendant(varDecl(hasName("b"), hasInitializer(hasDescendant( 780 cxxTypeidExpr()))))))); 781 } 782 783 TEST_P(ImportExpr, ImportTypeTraitExprValDep) { 784 MatchVerifier<Decl> Verifier; 785 testImport( 786 "template<typename T> struct declToImport {" 787 " void m() { (void)__is_pod(T); }" 788 "};" 789 "void f() { declToImport<int>().m(); }", 790 Lang_CXX11, "", Lang_CXX11, Verifier, 791 classTemplateDecl(has(cxxRecordDecl(has( 792 functionDecl(hasDescendant( 793 typeTraitExpr(hasType(booleanType()))))))))); 794 } 795 796 TEST_P(ImportDecl, ImportRecordDeclInFunc) { 797 MatchVerifier<Decl> Verifier; 798 testImport("int declToImport() { " 799 " struct data_t {int a;int b;};" 800 " struct data_t d;" 801 " return 0;" 802 "}", 803 Lang_C99, "", Lang_C99, Verifier, 804 functionDecl(hasBody(compoundStmt( 805 has(declStmt(hasSingleDecl(varDecl(hasName("d"))))))))); 806 } 807 808 TEST_P(ImportDecl, ImportedVarDeclPreservesThreadLocalStorage) { 809 MatchVerifier<Decl> Verifier; 810 testImport("thread_local int declToImport;", Lang_CXX11, "", Lang_CXX11, 811 Verifier, varDecl(hasThreadStorageDuration())); 812 } 813 814 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) { 815 Decl *FromTU = getTuDecl("int declToImport() { " 816 " struct data_t {int a;int b;};" 817 " struct data_t d;" 818 " return 0;" 819 "}", 820 Lang_C99, "input.c"); 821 auto *FromVar = 822 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("d"))); 823 ASSERT_TRUE(FromVar); 824 auto ToType = 825 ImportType(FromVar->getType().getCanonicalType(), FromVar, Lang_C99); 826 EXPECT_FALSE(ToType.isNull()); 827 } 828 829 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncParams) { 830 // This construct is not supported by ASTImporter. 831 Decl *FromTU = getTuDecl( 832 "int declToImport(struct data_t{int a;int b;} ***d){ return 0; }", 833 Lang_C99, "input.c"); 834 auto *From = FirstDeclMatcher<FunctionDecl>().match( 835 FromTU, functionDecl(hasName("declToImport"))); 836 ASSERT_TRUE(From); 837 auto *To = Import(From, Lang_C99); 838 EXPECT_EQ(To, nullptr); 839 } 840 841 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncFromMacro) { 842 Decl *FromTU = 843 getTuDecl("#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n" 844 "int declToImport(){ return NONAME_SIZEOF(int); }", 845 Lang_C99, "input.c"); 846 auto *From = FirstDeclMatcher<FunctionDecl>().match( 847 FromTU, functionDecl(hasName("declToImport"))); 848 ASSERT_TRUE(From); 849 auto *To = Import(From, Lang_C99); 850 ASSERT_TRUE(To); 851 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match( 852 To, functionDecl(hasName("declToImport"), 853 hasDescendant(unaryExprOrTypeTraitExpr())))); 854 } 855 856 TEST_P(ASTImporterOptionSpecificTestBase, 857 ImportRecordDeclInFuncParamsFromMacro) { 858 // This construct is not supported by ASTImporter. 859 Decl *FromTU = 860 getTuDecl("#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n" 861 "int declToImport(PAIR_STRUCT(int) ***d){ return 0; }", 862 Lang_C99, "input.c"); 863 auto *From = FirstDeclMatcher<FunctionDecl>().match( 864 FromTU, functionDecl(hasName("declToImport"))); 865 ASSERT_TRUE(From); 866 auto *To = Import(From, Lang_C99); 867 EXPECT_EQ(To, nullptr); 868 } 869 870 const internal::VariadicDynCastAllOfMatcher<Expr, CXXPseudoDestructorExpr> 871 cxxPseudoDestructorExpr; 872 873 TEST_P(ImportExpr, ImportCXXPseudoDestructorExpr) { 874 MatchVerifier<Decl> Verifier; 875 testImport( 876 "typedef int T;" 877 "void declToImport(int *p) {" 878 " T t;" 879 " p->T::~T();" 880 "}", 881 Lang_CXX03, "", Lang_CXX03, Verifier, 882 functionDecl(hasDescendant(callExpr(has(cxxPseudoDestructorExpr()))))); 883 } 884 885 TEST_P(ImportDecl, ImportUsingDecl) { 886 MatchVerifier<Decl> Verifier; 887 testImport("namespace foo { int bar; }" 888 "void declToImport() { using foo::bar; }", 889 Lang_CXX03, "", Lang_CXX03, Verifier, 890 functionDecl(hasDescendant(usingDecl(hasName("bar"))))); 891 } 892 893 TEST_P(ImportDecl, ImportUsingTemplate) { 894 MatchVerifier<Decl> Verifier; 895 testImport("namespace ns { template <typename T> struct S {}; }" 896 "template <template <typename> class T> class X {};" 897 "void declToImport() {" 898 "using ns::S; X<S> xi; }", 899 Lang_CXX11, "", Lang_CXX11, Verifier, 900 functionDecl( 901 hasDescendant(varDecl(hasTypeLoc(templateSpecializationTypeLoc( 902 hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))); 903 } 904 905 TEST_P(ImportDecl, ImportUsingEnumDecl) { 906 MatchVerifier<Decl> Verifier; 907 testImport("namespace foo { enum bar { baz, toto, quux }; }" 908 "void declToImport() { using enum foo::bar; }", 909 Lang_CXX20, "", Lang_CXX20, Verifier, 910 functionDecl(hasDescendant(usingEnumDecl(hasName("bar"))))); 911 } 912 913 const internal::VariadicDynCastAllOfMatcher<Decl, UsingPackDecl> usingPackDecl; 914 915 TEST_P(ImportDecl, ImportUsingPackDecl) { 916 MatchVerifier<Decl> Verifier; 917 testImport( 918 "struct A { int operator()() { return 1; } };" 919 "struct B { int operator()() { return 2; } };" 920 "template<typename ...T> struct C : T... { using T::operator()...; };" 921 "C<A, B> declToImport;", 922 Lang_CXX20, "", Lang_CXX20, Verifier, 923 varDecl(hasType(templateSpecializationType(hasDeclaration( 924 classTemplateSpecializationDecl(hasDescendant(usingPackDecl()))))))); 925 } 926 927 /// \brief Matches shadow declarations introduced into a scope by a 928 /// (resolved) using declaration. 929 /// 930 /// Given 931 /// \code 932 /// namespace n { int f; } 933 /// namespace declToImport { using n::f; } 934 /// \endcode 935 /// usingShadowDecl() 936 /// matches \code f \endcode 937 const internal::VariadicDynCastAllOfMatcher<Decl, 938 UsingShadowDecl> usingShadowDecl; 939 940 TEST_P(ImportDecl, ImportUsingShadowDecl) { 941 MatchVerifier<Decl> Verifier; 942 // from using-decl 943 testImport("namespace foo { int bar; }" 944 "namespace declToImport { using foo::bar; }", 945 Lang_CXX03, "", Lang_CXX03, Verifier, 946 namespaceDecl(has(usingShadowDecl(hasName("bar"))))); 947 // from using-enum-decl 948 testImport("namespace foo { enum bar {baz, toto, quux }; }" 949 "namespace declToImport { using enum foo::bar; }", 950 Lang_CXX20, "", Lang_CXX20, Verifier, 951 namespaceDecl(has(usingShadowDecl(hasName("baz"))))); 952 } 953 954 TEST_P(ImportExpr, ImportUnresolvedLookupExpr) { 955 MatchVerifier<Decl> Verifier; 956 testImport("template<typename T> int foo();" 957 "template <typename T> void declToImport() {" 958 " (void)::foo<T>;" 959 " (void)::template foo<T>;" 960 "}" 961 "void instantiate() { declToImport<int>(); }", 962 Lang_CXX03, "", Lang_CXX03, Verifier, 963 functionTemplateDecl(hasDescendant(unresolvedLookupExpr()))); 964 } 965 966 TEST_P(ImportExpr, ImportCXXUnresolvedConstructExpr) { 967 MatchVerifier<Decl> Verifier; 968 testImport("template <typename T> struct C { T t; };" 969 "template <typename T> void declToImport() {" 970 " C<T> d;" 971 " d.t = T();" 972 "}" 973 "void instantiate() { declToImport<int>(); }", 974 Lang_CXX03, "", Lang_CXX03, Verifier, 975 functionTemplateDecl(hasDescendant( 976 binaryOperator(has(cxxUnresolvedConstructExpr()))))); 977 testImport("template <typename T> struct C { T t; };" 978 "template <typename T> void declToImport() {" 979 " C<T> d;" 980 " (&d)->t = T();" 981 "}" 982 "void instantiate() { declToImport<int>(); }", 983 Lang_CXX03, "", Lang_CXX03, Verifier, 984 functionTemplateDecl(hasDescendant( 985 binaryOperator(has(cxxUnresolvedConstructExpr()))))); 986 } 987 988 /// Check that function "declToImport()" (which is the templated function 989 /// for corresponding FunctionTemplateDecl) is not added into DeclContext. 990 /// Same for class template declarations. 991 TEST_P(ImportDecl, ImportTemplatedDeclForTemplate) { 992 MatchVerifier<Decl> Verifier; 993 testImport("template <typename T> void declToImport() { T a = 1; }" 994 "void instantiate() { declToImport<int>(); }", 995 Lang_CXX03, "", Lang_CXX03, Verifier, 996 functionTemplateDecl(hasAncestor(translationUnitDecl( 997 unless(has(functionDecl(hasName("declToImport")))))))); 998 testImport("template <typename T> struct declToImport { T t; };" 999 "void instantiate() { declToImport<int>(); }", 1000 Lang_CXX03, "", Lang_CXX03, Verifier, 1001 classTemplateDecl(hasAncestor(translationUnitDecl( 1002 unless(has(cxxRecordDecl(hasName("declToImport")))))))); 1003 } 1004 1005 TEST_P(ImportDecl, ImportClassTemplatePartialSpecialization) { 1006 MatchVerifier<Decl> Verifier; 1007 auto Code = 1008 R"s( 1009 struct declToImport { 1010 template <typename T0> struct X; 1011 template <typename T0> struct X<T0 *> {}; 1012 }; 1013 )s"; 1014 testImport(Code, Lang_CXX03, "", Lang_CXX03, Verifier, 1015 recordDecl(has(classTemplateDecl()), 1016 has(classTemplateSpecializationDecl()))); 1017 } 1018 1019 TEST_P(ImportExpr, CXXOperatorCallExpr) { 1020 MatchVerifier<Decl> Verifier; 1021 testImport( 1022 "class declToImport {" 1023 " void f() { *this = declToImport(); }" 1024 "};", 1025 Lang_CXX03, "", Lang_CXX03, Verifier, 1026 cxxRecordDecl(has(cxxMethodDecl(hasDescendant(cxxOperatorCallExpr()))))); 1027 } 1028 1029 TEST_P(ImportExpr, DependentSizedArrayType) { 1030 MatchVerifier<Decl> Verifier; 1031 testImport("template<typename T, int Size> class declToImport {" 1032 " T data[Size];" 1033 "};", 1034 Lang_CXX03, "", Lang_CXX03, Verifier, 1035 classTemplateDecl(has(cxxRecordDecl( 1036 has(fieldDecl(hasType(dependentSizedArrayType()))))))); 1037 } 1038 1039 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingPackDecl) { 1040 Decl *FromTU = getTuDecl( 1041 "struct A { int operator()() { return 1; } };" 1042 "struct B { int operator()() { return 2; } };" 1043 "template<typename ...T> struct C : T... { using T::operator()...; };" 1044 "C<A, B> Var;", 1045 Lang_CXX20); 1046 1047 auto From = FirstDeclMatcher<UsingPackDecl>().match(FromTU, usingPackDecl()); 1048 ASSERT_TRUE(From); 1049 auto To = cast<UsingPackDecl>(Import(From, Lang_CXX20)); 1050 ASSERT_TRUE(To); 1051 1052 ArrayRef<NamedDecl *> FromExpansions = From->expansions(); 1053 ArrayRef<NamedDecl *> ToExpansions = To->expansions(); 1054 ASSERT_EQ(FromExpansions.size(), ToExpansions.size()); 1055 for (unsigned int I = 0; I < FromExpansions.size(); ++I) { 1056 auto ImportedExpansion = Import(FromExpansions[I], Lang_CXX20); 1057 EXPECT_EQ(ImportedExpansion, ToExpansions[I]); 1058 } 1059 1060 auto ImportedDC = cast<Decl>(Import(From->getDeclContext(), Lang_CXX20)); 1061 EXPECT_EQ(ImportedDC, cast<Decl>(To->getDeclContext())); 1062 } 1063 1064 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclNoDefaultArg) { 1065 Decl *FromTU = getTuDecl("template<typename T> struct X {};", Lang_CXX03); 1066 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match( 1067 FromTU, templateTypeParmDecl(hasName("T"))); 1068 TemplateTypeParmDecl *To = Import(From, Lang_CXX03); 1069 ASSERT_FALSE(To->hasDefaultArgument()); 1070 } 1071 1072 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclDefaultArg) { 1073 Decl *FromTU = 1074 getTuDecl("template<typename T = int> struct X {};", Lang_CXX03); 1075 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match( 1076 FromTU, templateTypeParmDecl(hasName("T"))); 1077 TemplateTypeParmDecl *To = Import(From, Lang_CXX03); 1078 ASSERT_TRUE(To->hasDefaultArgument()); 1079 QualType ToArg = To->getDefaultArgument(); 1080 ASSERT_EQ(ToArg, QualType(To->getASTContext().IntTy)); 1081 } 1082 1083 TEST_P(ASTImporterOptionSpecificTestBase, ImportBeginLocOfDeclRefExpr) { 1084 Decl *FromTU = 1085 getTuDecl("class A { public: static int X; }; void f() { (void)A::X; }", 1086 Lang_CXX03); 1087 auto From = FirstDeclMatcher<FunctionDecl>().match( 1088 FromTU, functionDecl(hasName("f"))); 1089 ASSERT_TRUE(From); 1090 ASSERT_TRUE( 1091 cast<CStyleCastExpr>(cast<CompoundStmt>(From->getBody())->body_front()) 1092 ->getSubExpr() 1093 ->getBeginLoc() 1094 .isValid()); 1095 FunctionDecl *To = Import(From, Lang_CXX03); 1096 ASSERT_TRUE(To); 1097 ASSERT_TRUE( 1098 cast<CStyleCastExpr>(cast<CompoundStmt>(To->getBody())->body_front()) 1099 ->getSubExpr() 1100 ->getBeginLoc() 1101 .isValid()); 1102 } 1103 1104 TEST_P(ASTImporterOptionSpecificTestBase, 1105 TemplateTemplateParmDeclNoDefaultArg) { 1106 Decl *FromTU = getTuDecl(R"( 1107 template<template<typename> typename TT> struct Y {}; 1108 )", 1109 Lang_CXX17); 1110 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match( 1111 FromTU, templateTemplateParmDecl(hasName("TT"))); 1112 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17); 1113 ASSERT_FALSE(To->hasDefaultArgument()); 1114 } 1115 1116 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTemplateParmDeclDefaultArg) { 1117 Decl *FromTU = getTuDecl(R"( 1118 template<typename T> struct X {}; 1119 template<template<typename> typename TT = X> struct Y {}; 1120 )", 1121 Lang_CXX17); 1122 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match( 1123 FromTU, templateTemplateParmDecl(hasName("TT"))); 1124 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17); 1125 ASSERT_TRUE(To->hasDefaultArgument()); 1126 const TemplateArgument &ToDefaultArg = To->getDefaultArgument().getArgument(); 1127 ASSERT_TRUE(To->isTemplateDecl()); 1128 TemplateDecl *ToTemplate = ToDefaultArg.getAsTemplate().getAsTemplateDecl(); 1129 1130 // Find the default argument template 'X' in the AST and compare it against 1131 // the default argument we got. 1132 auto ToExpectedDecl = FirstDeclMatcher<ClassTemplateDecl>().match( 1133 To->getTranslationUnitDecl(), classTemplateDecl(hasName("X"))); 1134 ASSERT_EQ(ToTemplate, ToExpectedDecl); 1135 } 1136 1137 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclNoDefaultArg) { 1138 Decl *FromTU = getTuDecl("template<int N> struct X {};", Lang_CXX03); 1139 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match( 1140 FromTU, nonTypeTemplateParmDecl(hasName("N"))); 1141 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03); 1142 ASSERT_FALSE(To->hasDefaultArgument()); 1143 } 1144 1145 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclDefaultArg) { 1146 Decl *FromTU = getTuDecl("template<int S = 1> struct X {};", Lang_CXX03); 1147 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match( 1148 FromTU, nonTypeTemplateParmDecl(hasName("S"))); 1149 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03); 1150 ASSERT_TRUE(To->hasDefaultArgument()); 1151 Stmt *ToArg = To->getDefaultArgument(); 1152 ASSERT_TRUE(isa<ConstantExpr>(ToArg)); 1153 ToArg = *ToArg->child_begin(); 1154 ASSERT_TRUE(isa<IntegerLiteral>(ToArg)); 1155 ASSERT_EQ(cast<IntegerLiteral>(ToArg)->getValue().getLimitedValue(), 1U); 1156 } 1157 1158 TEST_P(ASTImporterOptionSpecificTestBase, 1159 ImportOfTemplatedDeclOfClassTemplateDecl) { 1160 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03); 1161 auto From = 1162 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl()); 1163 ASSERT_TRUE(From); 1164 auto To = cast<ClassTemplateDecl>(Import(From, Lang_CXX03)); 1165 ASSERT_TRUE(To); 1166 Decl *ToTemplated = To->getTemplatedDecl(); 1167 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03); 1168 EXPECT_TRUE(ToTemplated1); 1169 EXPECT_EQ(ToTemplated1, ToTemplated); 1170 } 1171 1172 TEST_P(ASTImporterOptionSpecificTestBase, 1173 ImportOfTemplatedDeclOfFunctionTemplateDecl) { 1174 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03); 1175 auto From = FirstDeclMatcher<FunctionTemplateDecl>().match( 1176 FromTU, functionTemplateDecl()); 1177 ASSERT_TRUE(From); 1178 auto To = cast<FunctionTemplateDecl>(Import(From, Lang_CXX03)); 1179 ASSERT_TRUE(To); 1180 Decl *ToTemplated = To->getTemplatedDecl(); 1181 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03); 1182 EXPECT_TRUE(ToTemplated1); 1183 EXPECT_EQ(ToTemplated1, ToTemplated); 1184 } 1185 1186 TEST_P(ASTImporterOptionSpecificTestBase, 1187 ImportOfTemplatedDeclShouldImportTheClassTemplateDecl) { 1188 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03); 1189 auto FromFT = 1190 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl()); 1191 ASSERT_TRUE(FromFT); 1192 1193 auto ToTemplated = 1194 cast<CXXRecordDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03)); 1195 EXPECT_TRUE(ToTemplated); 1196 auto ToTU = ToTemplated->getTranslationUnitDecl(); 1197 auto ToFT = 1198 FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, classTemplateDecl()); 1199 EXPECT_TRUE(ToFT); 1200 } 1201 1202 TEST_P(ASTImporterOptionSpecificTestBase, 1203 ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) { 1204 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03); 1205 auto FromFT = FirstDeclMatcher<FunctionTemplateDecl>().match( 1206 FromTU, functionTemplateDecl()); 1207 ASSERT_TRUE(FromFT); 1208 1209 auto ToTemplated = 1210 cast<FunctionDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03)); 1211 EXPECT_TRUE(ToTemplated); 1212 auto ToTU = ToTemplated->getTranslationUnitDecl(); 1213 auto ToFT = FirstDeclMatcher<FunctionTemplateDecl>().match( 1214 ToTU, functionTemplateDecl()); 1215 EXPECT_TRUE(ToFT); 1216 } 1217 1218 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) { 1219 auto Code = 1220 R"( 1221 namespace x { 1222 template<class X> struct S1{}; 1223 template<class X> struct S2{}; 1224 template<class X> struct S3{}; 1225 } 1226 )"; 1227 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 1228 auto FromNs = 1229 FirstDeclMatcher<NamespaceDecl>().match(FromTU, namespaceDecl()); 1230 auto ToNs = cast<NamespaceDecl>(Import(FromNs, Lang_CXX03)); 1231 ASSERT_TRUE(ToNs); 1232 auto From = 1233 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, 1234 classTemplateDecl( 1235 hasName("S2"))); 1236 auto To = 1237 FirstDeclMatcher<ClassTemplateDecl>().match(ToNs, 1238 classTemplateDecl( 1239 hasName("S2"))); 1240 ASSERT_TRUE(From); 1241 ASSERT_TRUE(To); 1242 auto ToTemplated = To->getTemplatedDecl(); 1243 auto ToTemplated1 = 1244 cast<CXXRecordDecl>(Import(From->getTemplatedDecl(), Lang_CXX03)); 1245 EXPECT_TRUE(ToTemplated1); 1246 ASSERT_EQ(ToTemplated1, ToTemplated); 1247 } 1248 1249 TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) { 1250 // This tests the import of isConditionTrue directly to make sure the importer 1251 // gets it right. 1252 Decl *From, *To; 1253 std::tie(From, To) = getImportedDecl( 1254 "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }", Lang_C99, 1255 "", Lang_C99); 1256 1257 auto ToResults = match(chooseExpr().bind("choose"), To->getASTContext()); 1258 auto FromResults = match(chooseExpr().bind("choose"), From->getASTContext()); 1259 1260 const ChooseExpr *FromChooseExpr = 1261 selectFirst<ChooseExpr>("choose", FromResults); 1262 ASSERT_TRUE(FromChooseExpr); 1263 1264 const ChooseExpr *ToChooseExpr = selectFirst<ChooseExpr>("choose", ToResults); 1265 ASSERT_TRUE(ToChooseExpr); 1266 1267 EXPECT_EQ(FromChooseExpr->isConditionTrue(), ToChooseExpr->isConditionTrue()); 1268 EXPECT_EQ(FromChooseExpr->isConditionDependent(), 1269 ToChooseExpr->isConditionDependent()); 1270 } 1271 1272 TEST_P(ASTImporterOptionSpecificTestBase, ImportGenericSelectionExpr) { 1273 Decl *From, *To; 1274 std::tie(From, To) = getImportedDecl( 1275 R"( 1276 int declToImport() { 1277 int x; 1278 return _Generic(x, int: 0, default: 1); 1279 } 1280 )", 1281 Lang_C99, "", Lang_C99); 1282 1283 auto ToResults = 1284 match(genericSelectionExpr().bind("expr"), To->getASTContext()); 1285 auto FromResults = 1286 match(genericSelectionExpr().bind("expr"), From->getASTContext()); 1287 1288 const GenericSelectionExpr *FromGenericSelectionExpr = 1289 selectFirst<GenericSelectionExpr>("expr", FromResults); 1290 ASSERT_TRUE(FromGenericSelectionExpr); 1291 1292 const GenericSelectionExpr *ToGenericSelectionExpr = 1293 selectFirst<GenericSelectionExpr>("expr", ToResults); 1294 ASSERT_TRUE(ToGenericSelectionExpr); 1295 1296 EXPECT_EQ(FromGenericSelectionExpr->isResultDependent(), 1297 ToGenericSelectionExpr->isResultDependent()); 1298 EXPECT_EQ(FromGenericSelectionExpr->getResultIndex(), 1299 ToGenericSelectionExpr->getResultIndex()); 1300 } 1301 1302 TEST_P(ASTImporterOptionSpecificTestBase, 1303 ImportFunctionWithBackReferringParameter) { 1304 Decl *From, *To; 1305 std::tie(From, To) = getImportedDecl( 1306 R"( 1307 template <typename T> struct X {}; 1308 1309 void declToImport(int y, X<int> &x) {} 1310 1311 template <> struct X<int> { 1312 void g() { 1313 X<int> x; 1314 declToImport(0, x); 1315 } 1316 }; 1317 )", 1318 Lang_CXX03, "", Lang_CXX03); 1319 1320 MatchVerifier<Decl> Verifier; 1321 auto Matcher = functionDecl(hasName("declToImport"), 1322 parameterCountIs(2), 1323 hasParameter(0, hasName("y")), 1324 hasParameter(1, hasName("x")), 1325 hasParameter(1, hasType(asString("X<int> &")))); 1326 ASSERT_TRUE(Verifier.match(From, Matcher)); 1327 EXPECT_TRUE(Verifier.match(To, Matcher)); 1328 } 1329 1330 TEST_P(ASTImporterOptionSpecificTestBase, 1331 TUshouldNotContainTemplatedDeclOfFunctionTemplates) { 1332 Decl *From, *To; 1333 std::tie(From, To) = 1334 getImportedDecl("template <typename T> void declToImport() { T a = 1; }" 1335 "void instantiate() { declToImport<int>(); }", 1336 Lang_CXX03, "", Lang_CXX03); 1337 1338 auto Check = [](Decl *D) -> bool { 1339 auto TU = D->getTranslationUnitDecl(); 1340 for (auto Child : TU->decls()) { 1341 if (auto *FD = dyn_cast<FunctionDecl>(Child)) { 1342 if (FD->getNameAsString() == "declToImport") { 1343 GTEST_NONFATAL_FAILURE_( 1344 "TU should not contain any FunctionDecl with name declToImport"); 1345 return false; 1346 } 1347 } 1348 } 1349 return true; 1350 }; 1351 1352 ASSERT_TRUE(Check(From)); 1353 EXPECT_TRUE(Check(To)); 1354 } 1355 1356 TEST_P(ASTImporterOptionSpecificTestBase, 1357 TUshouldNotContainTemplatedDeclOfClassTemplates) { 1358 Decl *From, *To; 1359 std::tie(From, To) = 1360 getImportedDecl("template <typename T> struct declToImport { T t; };" 1361 "void instantiate() { declToImport<int>(); }", 1362 Lang_CXX03, "", Lang_CXX03); 1363 1364 auto Check = [](Decl *D) -> bool { 1365 auto TU = D->getTranslationUnitDecl(); 1366 for (auto Child : TU->decls()) { 1367 if (auto *RD = dyn_cast<CXXRecordDecl>(Child)) { 1368 if (RD->getNameAsString() == "declToImport") { 1369 GTEST_NONFATAL_FAILURE_( 1370 "TU should not contain any CXXRecordDecl with name declToImport"); 1371 return false; 1372 } 1373 } 1374 } 1375 return true; 1376 }; 1377 1378 ASSERT_TRUE(Check(From)); 1379 EXPECT_TRUE(Check(To)); 1380 } 1381 1382 TEST_P(ASTImporterOptionSpecificTestBase, 1383 TUshouldNotContainTemplatedDeclOfTypeAlias) { 1384 Decl *From, *To; 1385 std::tie(From, To) = 1386 getImportedDecl( 1387 "template <typename T> struct X {};" 1388 "template <typename T> using declToImport = X<T>;" 1389 "void instantiate() { declToImport<int> a; }", 1390 Lang_CXX11, "", Lang_CXX11); 1391 1392 auto Check = [](Decl *D) -> bool { 1393 auto TU = D->getTranslationUnitDecl(); 1394 for (auto Child : TU->decls()) { 1395 if (auto *AD = dyn_cast<TypeAliasDecl>(Child)) { 1396 if (AD->getNameAsString() == "declToImport") { 1397 GTEST_NONFATAL_FAILURE_( 1398 "TU should not contain any TypeAliasDecl with name declToImport"); 1399 return false; 1400 } 1401 } 1402 } 1403 return true; 1404 }; 1405 1406 ASSERT_TRUE(Check(From)); 1407 EXPECT_TRUE(Check(To)); 1408 } 1409 1410 TEST_P(ASTImporterOptionSpecificTestBase, 1411 TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) { 1412 1413 Decl *From, *To; 1414 std::tie(From, To) = getImportedDecl( 1415 R"( 1416 template<class T> 1417 class Base {}; 1418 class declToImport : public Base<declToImport> {}; 1419 )", 1420 Lang_CXX03, "", Lang_CXX03); 1421 1422 // Check that the ClassTemplateSpecializationDecl is NOT the child of the TU. 1423 auto Pattern = 1424 translationUnitDecl(unless(has(classTemplateSpecializationDecl()))); 1425 ASSERT_TRUE( 1426 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1427 EXPECT_TRUE( 1428 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1429 1430 // Check that the ClassTemplateSpecializationDecl is the child of the 1431 // ClassTemplateDecl. 1432 Pattern = translationUnitDecl(has(classTemplateDecl( 1433 hasName("Base"), has(classTemplateSpecializationDecl())))); 1434 ASSERT_TRUE( 1435 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1436 EXPECT_TRUE( 1437 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1438 } 1439 1440 AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) { 1441 size_t Index = 0; 1442 for (Decl *D : Node.decls()) { 1443 if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) { 1444 auto *ND = cast<NamedDecl>(D); 1445 if (Index == Order.size()) 1446 return false; 1447 if (ND->getName() != Order[Index]) 1448 return false; 1449 ++Index; 1450 } 1451 } 1452 return Index == Order.size(); 1453 } 1454 1455 TEST_P(ASTImporterOptionSpecificTestBase, 1456 TUshouldContainClassTemplateSpecializationOfExplicitInstantiation) { 1457 Decl *From, *To; 1458 std::tie(From, To) = getImportedDecl( 1459 R"( 1460 namespace NS { 1461 template<class T> 1462 class X {}; 1463 template class X<int>; 1464 } 1465 )", 1466 Lang_CXX03, "", Lang_CXX03, "NS"); 1467 1468 // Check that the ClassTemplateSpecializationDecl is NOT the child of the 1469 // ClassTemplateDecl. 1470 auto Pattern = namespaceDecl(has(classTemplateDecl( 1471 hasName("X"), unless(has(classTemplateSpecializationDecl()))))); 1472 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern)); 1473 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern)); 1474 1475 // Check that the ClassTemplateSpecializationDecl is the child of the 1476 // NamespaceDecl. 1477 Pattern = namespaceDecl(has(classTemplateSpecializationDecl(hasName("X")))); 1478 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern)); 1479 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern)); 1480 } 1481 1482 TEST_P(ASTImporterOptionSpecificTestBase, 1483 CXXRecordDeclFieldsShouldBeInCorrectOrder) { 1484 Decl *From, *To; 1485 std::tie(From, To) = 1486 getImportedDecl( 1487 "struct declToImport { int a; int b; };", 1488 Lang_CXX11, "", Lang_CXX11); 1489 1490 MatchVerifier<Decl> Verifier; 1491 ASSERT_TRUE(Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b"})))); 1492 EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b"})))); 1493 } 1494 1495 TEST_P(ASTImporterOptionSpecificTestBase, 1496 CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) { 1497 Decl *From, *To; 1498 std::tie(From, To) = getImportedDecl( 1499 // The original recursive algorithm of ASTImporter first imports 'c' then 1500 // 'b' and lastly 'a'. Therefore we must restore the order somehow. 1501 R"s( 1502 struct declToImport { 1503 int a = c + b; 1504 int b = 1; 1505 int c = 2; 1506 }; 1507 )s", 1508 Lang_CXX11, "", Lang_CXX11); 1509 1510 MatchVerifier<Decl> Verifier; 1511 ASSERT_TRUE( 1512 Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b", "c"})))); 1513 EXPECT_TRUE( 1514 Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"})))); 1515 } 1516 1517 TEST_P(ASTImporterOptionSpecificTestBase, 1518 CXXRecordDeclFieldAndIndirectFieldOrder) { 1519 Decl *From, *To; 1520 std::tie(From, To) = getImportedDecl( 1521 // First field is "a", then the field for unnamed union, then "b" and "c" 1522 // from it (indirect fields), then "d". 1523 R"s( 1524 struct declToImport { 1525 int a = d; 1526 union { 1527 int b; 1528 int c; 1529 }; 1530 int d; 1531 }; 1532 )s", 1533 Lang_CXX11, "", Lang_CXX11); 1534 1535 MatchVerifier<Decl> Verifier; 1536 ASSERT_TRUE(Verifier.match( 1537 From, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"})))); 1538 EXPECT_TRUE(Verifier.match( 1539 To, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"})))); 1540 } 1541 1542 TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) { 1543 Decl *From, *To; 1544 std::tie(From, To) = getImportedDecl( 1545 R"( 1546 struct declToImport { 1547 }; 1548 )", 1549 Lang_CXX03, "", Lang_CXX03); 1550 1551 MatchVerifier<Decl> Verifier; 1552 // Match the implicit Decl. 1553 auto Matcher = cxxRecordDecl(has(cxxRecordDecl())); 1554 ASSERT_TRUE(Verifier.match(From, Matcher)); 1555 EXPECT_TRUE(Verifier.match(To, Matcher)); 1556 } 1557 1558 TEST_P(ASTImporterOptionSpecificTestBase, 1559 ShouldImportImplicitCXXRecordDeclOfClassTemplate) { 1560 Decl *From, *To; 1561 std::tie(From, To) = getImportedDecl( 1562 R"( 1563 template <typename U> 1564 struct declToImport { 1565 }; 1566 )", 1567 Lang_CXX03, "", Lang_CXX03); 1568 1569 MatchVerifier<Decl> Verifier; 1570 // Match the implicit Decl. 1571 auto Matcher = classTemplateDecl(has(cxxRecordDecl(has(cxxRecordDecl())))); 1572 ASSERT_TRUE(Verifier.match(From, Matcher)); 1573 EXPECT_TRUE(Verifier.match(To, Matcher)); 1574 } 1575 1576 TEST_P(ASTImporterOptionSpecificTestBase, 1577 ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) { 1578 Decl *From, *To; 1579 std::tie(From, To) = getImportedDecl( 1580 R"( 1581 template<class T> 1582 class Base {}; 1583 class declToImport : public Base<declToImport> {}; 1584 )", 1585 Lang_CXX03, "", Lang_CXX03); 1586 1587 auto hasImplicitClass = has(cxxRecordDecl()); 1588 auto Pattern = translationUnitDecl(has(classTemplateDecl( 1589 hasName("Base"), 1590 has(classTemplateSpecializationDecl(hasImplicitClass))))); 1591 ASSERT_TRUE( 1592 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1593 EXPECT_TRUE( 1594 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1595 } 1596 1597 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOrdinary) { 1598 Decl *From, *To; 1599 std::tie(From, To) = 1600 getImportedDecl("void declToImport() {}", Lang_CXX03, "", Lang_CXX03); 1601 1602 MatchVerifier<Decl> Verifier; 1603 auto Matcher = functionDecl(); 1604 ASSERT_TRUE(Verifier.match(From, Matcher)); 1605 EXPECT_TRUE(Verifier.match(To, Matcher)); 1606 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace()); 1607 } 1608 1609 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOfNonmemberOperator) { 1610 Decl *FromTU = getTuDecl( 1611 R"( 1612 struct X {}; 1613 void operator<<(int, X); 1614 )", 1615 Lang_CXX03); 1616 Decl *From = LastDeclMatcher<Decl>{}.match(FromTU, functionDecl()); 1617 const Decl *To = Import(From, Lang_CXX03); 1618 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace()); 1619 } 1620 1621 TEST_P(ASTImporterOptionSpecificTestBase, 1622 ShouldImportMembersOfClassTemplateSpecializationDecl) { 1623 Decl *From, *To; 1624 std::tie(From, To) = getImportedDecl( 1625 R"( 1626 template<class T> 1627 class Base { int a; }; 1628 class declToImport : Base<declToImport> {}; 1629 )", 1630 Lang_CXX03, "", Lang_CXX03); 1631 1632 auto Pattern = translationUnitDecl(has(classTemplateDecl( 1633 hasName("Base"), 1634 has(classTemplateSpecializationDecl(has(fieldDecl(hasName("a")))))))); 1635 ASSERT_TRUE( 1636 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1637 EXPECT_TRUE( 1638 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1639 } 1640 1641 TEST_P(ASTImporterOptionSpecificTestBase, 1642 ImportDefinitionOfClassTemplateAfterFwdDecl) { 1643 { 1644 Decl *FromTU = getTuDecl( 1645 R"( 1646 template <typename T> 1647 struct B; 1648 )", 1649 Lang_CXX03, "input0.cc"); 1650 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 1651 FromTU, classTemplateDecl(hasName("B"))); 1652 1653 Import(FromD, Lang_CXX03); 1654 } 1655 1656 { 1657 Decl *FromTU = getTuDecl( 1658 R"( 1659 template <typename T> 1660 struct B { 1661 void f(); 1662 }; 1663 )", 1664 Lang_CXX03, "input1.cc"); 1665 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match( 1666 FromTU, functionDecl(hasName("f"))); 1667 Import(FromD, Lang_CXX03); 1668 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match( 1669 FromTU, classTemplateDecl(hasName("B"))); 1670 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03)); 1671 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition()); 1672 } 1673 } 1674 1675 TEST_P(ASTImporterOptionSpecificTestBase, 1676 ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition) { 1677 Decl *ToTU = getToTuDecl( 1678 R"( 1679 template <typename T> 1680 struct B { 1681 void f(); 1682 }; 1683 1684 template <typename T> 1685 struct B; 1686 )", 1687 Lang_CXX03); 1688 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>( 1689 [](const ClassTemplateDecl *T) { 1690 return T->isThisDeclarationADefinition(); 1691 }) 1692 .match(ToTU, classTemplateDecl())); 1693 1694 Decl *FromTU = getTuDecl( 1695 R"( 1696 template <typename T> 1697 struct B { 1698 void f(); 1699 }; 1700 )", 1701 Lang_CXX03, "input1.cc"); 1702 ClassTemplateDecl *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 1703 FromTU, classTemplateDecl(hasName("B"))); 1704 1705 Import(FromD, Lang_CXX03); 1706 1707 // We should have only one definition. 1708 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>( 1709 [](const ClassTemplateDecl *T) { 1710 return T->isThisDeclarationADefinition(); 1711 }) 1712 .match(ToTU, classTemplateDecl())); 1713 } 1714 1715 TEST_P(ASTImporterOptionSpecificTestBase, 1716 ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition) { 1717 Decl *ToTU = getToTuDecl( 1718 R"( 1719 struct B { 1720 void f(); 1721 }; 1722 1723 struct B; 1724 )", 1725 Lang_CXX03); 1726 ASSERT_EQ(2u, DeclCounter<CXXRecordDecl>().match( 1727 ToTU, cxxRecordDecl(unless(isImplicit())))); 1728 1729 Decl *FromTU = getTuDecl( 1730 R"( 1731 struct B { 1732 void f(); 1733 }; 1734 )", 1735 Lang_CXX03, "input1.cc"); 1736 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 1737 FromTU, cxxRecordDecl(hasName("B"))); 1738 1739 Import(FromD, Lang_CXX03); 1740 1741 EXPECT_EQ(2u, DeclCounter<CXXRecordDecl>().match( 1742 ToTU, cxxRecordDecl(unless(isImplicit())))); 1743 } 1744 1745 static void CompareSourceLocs(FullSourceLoc Loc1, FullSourceLoc Loc2) { 1746 EXPECT_EQ(Loc1.getExpansionLineNumber(), Loc2.getExpansionLineNumber()); 1747 EXPECT_EQ(Loc1.getExpansionColumnNumber(), Loc2.getExpansionColumnNumber()); 1748 EXPECT_EQ(Loc1.getSpellingLineNumber(), Loc2.getSpellingLineNumber()); 1749 EXPECT_EQ(Loc1.getSpellingColumnNumber(), Loc2.getSpellingColumnNumber()); 1750 } 1751 static void CompareSourceRanges(SourceRange Range1, SourceRange Range2, 1752 SourceManager &SM1, SourceManager &SM2) { 1753 CompareSourceLocs(FullSourceLoc{ Range1.getBegin(), SM1 }, 1754 FullSourceLoc{ Range2.getBegin(), SM2 }); 1755 CompareSourceLocs(FullSourceLoc{ Range1.getEnd(), SM1 }, 1756 FullSourceLoc{ Range2.getEnd(), SM2 }); 1757 } 1758 TEST_P(ASTImporterOptionSpecificTestBase, ImportSourceLocs) { 1759 Decl *FromTU = getTuDecl( 1760 R"( 1761 #define MFOO(arg) arg = arg + 1 1762 1763 void foo() { 1764 int a = 5; 1765 MFOO(a); 1766 } 1767 )", 1768 Lang_CXX03); 1769 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 1770 auto ToD = Import(FromD, Lang_CXX03); 1771 1772 auto ToLHS = LastDeclMatcher<DeclRefExpr>().match(ToD, declRefExpr()); 1773 auto FromLHS = LastDeclMatcher<DeclRefExpr>().match(FromTU, declRefExpr()); 1774 auto ToRHS = LastDeclMatcher<IntegerLiteral>().match(ToD, integerLiteral()); 1775 auto FromRHS = 1776 LastDeclMatcher<IntegerLiteral>().match(FromTU, integerLiteral()); 1777 1778 SourceManager &ToSM = ToAST->getASTContext().getSourceManager(); 1779 SourceManager &FromSM = FromD->getASTContext().getSourceManager(); 1780 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM, 1781 FromSM); 1782 CompareSourceRanges(ToLHS->getSourceRange(), FromLHS->getSourceRange(), ToSM, 1783 FromSM); 1784 CompareSourceRanges(ToRHS->getSourceRange(), FromRHS->getSourceRange(), ToSM, 1785 FromSM); 1786 } 1787 1788 TEST_P(ASTImporterOptionSpecificTestBase, ImportNestedMacro) { 1789 Decl *FromTU = getTuDecl( 1790 R"( 1791 #define FUNC_INT void declToImport 1792 #define FUNC FUNC_INT 1793 FUNC(int a); 1794 )", 1795 Lang_CXX03); 1796 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 1797 auto ToD = Import(FromD, Lang_CXX03); 1798 1799 SourceManager &ToSM = ToAST->getASTContext().getSourceManager(); 1800 SourceManager &FromSM = FromD->getASTContext().getSourceManager(); 1801 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM, 1802 FromSM); 1803 } 1804 1805 TEST_P( 1806 ASTImporterOptionSpecificTestBase, 1807 ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition) { 1808 Decl *ToTU = getToTuDecl( 1809 R"( 1810 template <typename T> 1811 struct B; 1812 1813 template <> 1814 struct B<int> {}; 1815 1816 template <> 1817 struct B<int>; 1818 )", 1819 Lang_CXX03); 1820 // We should have only one definition. 1821 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>( 1822 [](const ClassTemplateSpecializationDecl *T) { 1823 return T->isThisDeclarationADefinition(); 1824 }) 1825 .match(ToTU, classTemplateSpecializationDecl())); 1826 1827 Decl *FromTU = getTuDecl( 1828 R"( 1829 template <typename T> 1830 struct B; 1831 1832 template <> 1833 struct B<int> {}; 1834 )", 1835 Lang_CXX03, "input1.cc"); 1836 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 1837 FromTU, classTemplateSpecializationDecl(hasName("B"))); 1838 1839 Import(FromD, Lang_CXX03); 1840 1841 // We should have only one definition. 1842 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>( 1843 [](const ClassTemplateSpecializationDecl *T) { 1844 return T->isThisDeclarationADefinition(); 1845 }) 1846 .match(ToTU, classTemplateSpecializationDecl())); 1847 } 1848 1849 TEST_P(ASTImporterOptionSpecificTestBase, ObjectsWithUnnamedStructType) { 1850 Decl *FromTU = getTuDecl( 1851 R"( 1852 struct { int a; int b; } object0 = { 2, 3 }; 1853 struct { int x; int y; int z; } object1; 1854 )", 1855 Lang_CXX03, "input0.cc"); 1856 1857 auto *Obj0 = 1858 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object0"))); 1859 auto *From0 = getRecordDecl(Obj0); 1860 auto *Obj1 = 1861 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object1"))); 1862 auto *From1 = getRecordDecl(Obj1); 1863 1864 auto *To0 = Import(From0, Lang_CXX03); 1865 auto *To1 = Import(From1, Lang_CXX03); 1866 1867 EXPECT_TRUE(To0); 1868 EXPECT_TRUE(To1); 1869 EXPECT_NE(To0, To1); 1870 EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl()); 1871 } 1872 1873 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecords) { 1874 auto *Code = 1875 R"( 1876 struct X { 1877 struct { int a; }; 1878 struct { int b; }; 1879 }; 1880 )"; 1881 Decl *FromTU0 = getTuDecl(Code, Lang_C99, "input0.c"); 1882 1883 Decl *FromTU1 = getTuDecl(Code, Lang_C99, "input1.c"); 1884 1885 auto *X0 = 1886 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X"))); 1887 auto *X1 = 1888 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X"))); 1889 Import(X0, Lang_C99); 1890 Import(X1, Lang_C99); 1891 1892 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 1893 // We expect no (ODR) warning during the import. 1894 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 1895 EXPECT_EQ(1u, 1896 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X")))); 1897 } 1898 1899 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecordsReversed) { 1900 Decl *FromTU0 = getTuDecl( 1901 R"( 1902 struct X { 1903 struct { int a; }; 1904 struct { int b; }; 1905 }; 1906 )", 1907 Lang_C99, "input0.c"); 1908 1909 Decl *FromTU1 = getTuDecl( 1910 R"( 1911 struct X { // reversed order 1912 struct { int b; }; 1913 struct { int a; }; 1914 }; 1915 )", 1916 Lang_C99, "input1.c"); 1917 1918 auto *X0 = 1919 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X"))); 1920 auto *X1 = 1921 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X"))); 1922 Import(X0, Lang_C99); 1923 Import(X1, Lang_C99); 1924 1925 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 1926 // We expect one (ODR) warning during the import. 1927 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 1928 EXPECT_EQ(1u, 1929 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X")))); 1930 } 1931 1932 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag) { 1933 auto Pattern = varDecl(hasName("x")); 1934 VarDecl *Imported1; 1935 { 1936 Decl *FromTU = getTuDecl("extern int x;", Lang_CXX03, "input0.cc"); 1937 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 1938 Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 1939 } 1940 VarDecl *Imported2; 1941 { 1942 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input1.cc"); 1943 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 1944 Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 1945 } 1946 EXPECT_EQ(Imported1->getCanonicalDecl(), Imported2->getCanonicalDecl()); 1947 EXPECT_FALSE(Imported2->isUsed(false)); 1948 { 1949 Decl *FromTU = getTuDecl("extern int x; int f() { return x; }", Lang_CXX03, 1950 "input2.cc"); 1951 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 1952 FromTU, functionDecl(hasName("f"))); 1953 Import(FromD, Lang_CXX03); 1954 } 1955 EXPECT_TRUE(Imported2->isUsed(false)); 1956 } 1957 1958 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag2) { 1959 auto Pattern = varDecl(hasName("x")); 1960 VarDecl *ExistingD; 1961 { 1962 Decl *ToTU = getToTuDecl("int x = 1;", Lang_CXX03); 1963 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern); 1964 } 1965 EXPECT_FALSE(ExistingD->isUsed(false)); 1966 { 1967 Decl *FromTU = 1968 getTuDecl("int x = 1; int f() { return x; }", Lang_CXX03, "input1.cc"); 1969 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 1970 FromTU, functionDecl(hasName("f"))); 1971 Import(FromD, Lang_CXX03); 1972 } 1973 EXPECT_TRUE(ExistingD->isUsed(false)); 1974 } 1975 1976 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag3) { 1977 auto Pattern = varDecl(hasName("a")); 1978 VarDecl *ExistingD; 1979 { 1980 Decl *ToTU = getToTuDecl( 1981 R"( 1982 struct A { 1983 static const int a = 1; 1984 }; 1985 )", 1986 Lang_CXX03); 1987 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern); 1988 } 1989 EXPECT_FALSE(ExistingD->isUsed(false)); 1990 { 1991 Decl *FromTU = getTuDecl( 1992 R"( 1993 struct A { 1994 static const int a = 1; 1995 }; 1996 const int *f() { return &A::a; } // requires storage, 1997 // thus used flag will be set 1998 )", 1999 Lang_CXX03, "input1.cc"); 2000 auto *FromFunD = FirstDeclMatcher<FunctionDecl>().match( 2001 FromTU, functionDecl(hasName("f"))); 2002 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 2003 ASSERT_TRUE(FromD->isUsed(false)); 2004 Import(FromFunD, Lang_CXX03); 2005 } 2006 EXPECT_TRUE(ExistingD->isUsed(false)); 2007 } 2008 2009 TEST_P(ASTImporterOptionSpecificTestBase, ReimportWithUsedFlag) { 2010 auto Pattern = varDecl(hasName("x")); 2011 2012 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input0.cc"); 2013 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 2014 2015 auto *Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 2016 2017 ASSERT_FALSE(Imported1->isUsed(false)); 2018 2019 FromD->setIsUsed(); 2020 auto *Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 2021 2022 EXPECT_EQ(Imported1, Imported2); 2023 EXPECT_TRUE(Imported2->isUsed(false)); 2024 } 2025 2026 struct ImportFunctions : ASTImporterOptionSpecificTestBase {}; 2027 2028 TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) { 2029 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03); 2030 auto Pattern = functionDecl(hasName("f")); 2031 auto *From = 2032 FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Proto 2033 2034 Decl *ImportedD = Import(From, Lang_CXX03); 2035 Decl *ToTU = ImportedD->getTranslationUnitDecl(); 2036 2037 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2038 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2039 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2040 EXPECT_TRUE(ImportedD == To0); 2041 EXPECT_FALSE(To0->doesThisDeclarationHaveABody()); 2042 EXPECT_TRUE(To1->doesThisDeclarationHaveABody()); 2043 EXPECT_EQ(To1->getPreviousDecl(), To0); 2044 } 2045 2046 TEST_P(ImportFunctions, ImportDefinitionOfRecursiveFunction) { 2047 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03); 2048 auto Pattern = functionDecl(hasName("f")); 2049 auto *From = 2050 LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Def 2051 2052 Decl *ImportedD = Import(From, Lang_CXX03); 2053 Decl *ToTU = ImportedD->getTranslationUnitDecl(); 2054 2055 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2056 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2057 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2058 EXPECT_TRUE(ImportedD == To1); 2059 EXPECT_FALSE(To0->doesThisDeclarationHaveABody()); 2060 EXPECT_TRUE(To1->doesThisDeclarationHaveABody()); 2061 EXPECT_EQ(To1->getPreviousDecl(), To0); 2062 } 2063 2064 TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) { 2065 auto Code = 2066 R"( 2067 struct B { virtual void f(); }; 2068 void B::f() {} 2069 struct D : B { void f(); }; 2070 )"; 2071 auto Pattern = 2072 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2073 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 2074 CXXMethodDecl *Proto = 2075 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern); 2076 2077 ASSERT_EQ(Proto->size_overridden_methods(), 1u); 2078 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03)); 2079 EXPECT_EQ(To->size_overridden_methods(), 1u); 2080 } 2081 2082 TEST_P(ImportFunctions, VirtualFlagShouldBePreservedWhenImportingPrototype) { 2083 auto Code = 2084 R"( 2085 struct B { virtual void f(); }; 2086 void B::f() {} 2087 )"; 2088 auto Pattern = 2089 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2090 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 2091 CXXMethodDecl *Proto = 2092 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern); 2093 CXXMethodDecl *Def = LastDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern); 2094 2095 ASSERT_TRUE(Proto->isVirtual()); 2096 ASSERT_TRUE(Def->isVirtual()); 2097 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03)); 2098 EXPECT_TRUE(To->isVirtual()); 2099 } 2100 2101 TEST_P(ImportFunctions, 2102 ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl) { 2103 Decl *ToTU = getToTuDecl( 2104 R"( 2105 void f() {} 2106 void f(); 2107 )", 2108 Lang_CXX03); 2109 ASSERT_EQ(1u, 2110 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) { 2111 return FD->doesThisDeclarationHaveABody(); 2112 }).match(ToTU, functionDecl())); 2113 2114 Decl *FromTU = getTuDecl("void f() {}", Lang_CXX03, "input0.cc"); 2115 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 2116 2117 Import(FromD, Lang_CXX03); 2118 2119 EXPECT_EQ(1u, 2120 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) { 2121 return FD->doesThisDeclarationHaveABody(); 2122 }).match(ToTU, functionDecl())); 2123 } 2124 2125 TEST_P(ImportFunctions, ImportOverriddenMethodTwice) { 2126 auto Code = 2127 R"( 2128 struct B { virtual void f(); }; 2129 struct D:B { void f(); }; 2130 )"; 2131 auto BFP = 2132 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2133 auto DFP = 2134 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2135 2136 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03); 2137 auto *DF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP); 2138 Import(DF, Lang_CXX03); 2139 2140 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2141 auto *BF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP); 2142 Import(BF, Lang_CXX03); 2143 2144 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2145 2146 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2147 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u); 2148 } 2149 2150 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceDefinitionFirst) { 2151 auto CodeWithoutDef = 2152 R"( 2153 struct B { virtual void f(); }; 2154 struct D:B { void f(); }; 2155 )"; 2156 auto CodeWithDef = 2157 R"( 2158 struct B { virtual void f(){}; }; 2159 struct D:B { void f(){}; }; 2160 )"; 2161 auto BFP = 2162 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2163 auto DFP = 2164 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2165 auto BFDefP = cxxMethodDecl( 2166 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition()); 2167 auto DFDefP = cxxMethodDecl( 2168 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition()); 2169 auto FDefAllP = cxxMethodDecl(hasName("f"), isDefinition()); 2170 2171 { 2172 Decl *FromTU = getTuDecl(CodeWithDef, Lang_CXX03, "input0.cc"); 2173 auto *FromD = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, DFP); 2174 Import(FromD, Lang_CXX03); 2175 } 2176 { 2177 Decl *FromTU = getTuDecl(CodeWithoutDef, Lang_CXX03, "input1.cc"); 2178 auto *FromB = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, BFP); 2179 Import(FromB, Lang_CXX03); 2180 } 2181 2182 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2183 2184 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2185 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u); 2186 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 1u); 2187 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 1u); 2188 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FDefAllP), 2u); 2189 } 2190 2191 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceOutOfClassDef) { 2192 auto Code = 2193 R"( 2194 struct B { virtual void f(); }; 2195 struct D:B { void f(); }; 2196 void B::f(){}; 2197 )"; 2198 2199 auto BFP = 2200 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2201 auto BFDefP = cxxMethodDecl( 2202 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition()); 2203 auto DFP = cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), 2204 unless(isDefinition())); 2205 2206 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03); 2207 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP); 2208 Import(D, Lang_CXX03); 2209 2210 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2211 auto *B = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP); 2212 Import(B, Lang_CXX03); 2213 2214 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2215 2216 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2217 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u); 2218 2219 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match( 2220 ToTU, cxxRecordDecl(hasName("B"))); 2221 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP); 2222 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match( 2223 ToTU, cxxMethodDecl(hasName("f"), isDefinition())); 2224 2225 // The definition should be out-of-class. 2226 EXPECT_NE(ToBFInClass, ToBFOutOfClass); 2227 EXPECT_NE(ToBFInClass->getLexicalDeclContext(), 2228 ToBFOutOfClass->getLexicalDeclContext()); 2229 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB); 2230 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU); 2231 2232 // Check that the redecl chain is intact. 2233 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass); 2234 } 2235 2236 TEST_P(ImportFunctions, 2237 ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode) { 2238 auto CodeTU0 = 2239 R"( 2240 struct B { virtual void f(); }; 2241 struct D:B { void f(); }; 2242 )"; 2243 auto CodeTU1 = 2244 R"( 2245 struct B { virtual void f(); }; 2246 struct D:B { void f(); }; 2247 void B::f(){} 2248 void D::f(){} 2249 void foo(B &b, D &d) { b.f(); d.f(); } 2250 )"; 2251 2252 auto BFP = 2253 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2254 auto BFDefP = cxxMethodDecl( 2255 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition()); 2256 auto DFP = 2257 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2258 auto DFDefP = cxxMethodDecl( 2259 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition()); 2260 auto FooDef = functionDecl(hasName("foo")); 2261 2262 { 2263 Decl *FromTU0 = getTuDecl(CodeTU0, Lang_CXX03, "input0.cc"); 2264 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP); 2265 Import(D, Lang_CXX03); 2266 } 2267 2268 { 2269 Decl *FromTU1 = getTuDecl(CodeTU1, Lang_CXX03, "input1.cc"); 2270 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(FromTU1, FooDef); 2271 Import(Foo, Lang_CXX03); 2272 } 2273 2274 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2275 2276 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2277 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u); 2278 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u); 2279 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 0u); 2280 2281 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match( 2282 ToTU, cxxRecordDecl(hasName("B"))); 2283 auto *ToD = FirstDeclMatcher<CXXRecordDecl>().match( 2284 ToTU, cxxRecordDecl(hasName("D"))); 2285 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP); 2286 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match( 2287 ToTU, cxxMethodDecl(hasName("f"), isDefinition())); 2288 auto *ToDFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, DFP); 2289 auto *ToDFOutOfClass = LastDeclMatcher<CXXMethodDecl>().match( 2290 ToTU, cxxMethodDecl(hasName("f"), isDefinition())); 2291 2292 // The definition should be out-of-class. 2293 EXPECT_NE(ToBFInClass, ToBFOutOfClass); 2294 EXPECT_NE(ToBFInClass->getLexicalDeclContext(), 2295 ToBFOutOfClass->getLexicalDeclContext()); 2296 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB); 2297 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU); 2298 2299 EXPECT_NE(ToDFInClass, ToDFOutOfClass); 2300 EXPECT_NE(ToDFInClass->getLexicalDeclContext(), 2301 ToDFOutOfClass->getLexicalDeclContext()); 2302 EXPECT_EQ(ToDFOutOfClass->getDeclContext(), ToD); 2303 EXPECT_EQ(ToDFOutOfClass->getLexicalDeclContext(), ToTU); 2304 2305 // Check that the redecl chain is intact. 2306 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass); 2307 EXPECT_EQ(ToDFOutOfClass->getPreviousDecl(), ToDFInClass); 2308 } 2309 2310 TEST_P(ASTImporterOptionSpecificTestBase, ImportVariableChainInC) { 2311 std::string Code = "static int v; static int v = 0;"; 2312 auto Pattern = varDecl(hasName("v")); 2313 2314 TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_C99, "input0.c"); 2315 2316 auto *From0 = FirstDeclMatcher<VarDecl>().match(FromTu, Pattern); 2317 auto *From1 = LastDeclMatcher<VarDecl>().match(FromTu, Pattern); 2318 2319 auto *To0 = Import(From0, Lang_C99); 2320 auto *To1 = Import(From1, Lang_C99); 2321 2322 EXPECT_TRUE(To0); 2323 ASSERT_TRUE(To1); 2324 EXPECT_NE(To0, To1); 2325 EXPECT_EQ(To1->getPreviousDecl(), To0); 2326 } 2327 2328 TEST_P(ImportFunctions, ImportFromDifferentScopedAnonNamespace) { 2329 TranslationUnitDecl *FromTu = 2330 getTuDecl("namespace NS0 { namespace { void f(); } }" 2331 "namespace NS1 { namespace { void f(); } }", 2332 Lang_CXX03, "input0.cc"); 2333 auto Pattern = functionDecl(hasName("f")); 2334 2335 auto *FromF0 = FirstDeclMatcher<FunctionDecl>().match(FromTu, Pattern); 2336 auto *FromF1 = LastDeclMatcher<FunctionDecl>().match(FromTu, Pattern); 2337 2338 auto *ToF0 = Import(FromF0, Lang_CXX03); 2339 auto *ToF1 = Import(FromF1, Lang_CXX03); 2340 2341 EXPECT_TRUE(ToF0); 2342 ASSERT_TRUE(ToF1); 2343 EXPECT_NE(ToF0, ToF1); 2344 EXPECT_FALSE(ToF1->getPreviousDecl()); 2345 } 2346 2347 TEST_P(ImportFunctions, ImportFunctionFromUnnamedNamespace) { 2348 { 2349 Decl *FromTU = getTuDecl("namespace { void f() {} } void g0() { f(); }", 2350 Lang_CXX03, "input0.cc"); 2351 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2352 FromTU, functionDecl(hasName("g0"))); 2353 2354 Import(FromD, Lang_CXX03); 2355 } 2356 { 2357 Decl *FromTU = 2358 getTuDecl("namespace { void f() { int a; } } void g1() { f(); }", 2359 Lang_CXX03, "input1.cc"); 2360 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2361 FromTU, functionDecl(hasName("g1"))); 2362 Import(FromD, Lang_CXX03); 2363 } 2364 2365 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2366 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))), 2367 2u); 2368 } 2369 2370 TEST_P(ImportFunctions, ImportImplicitFunctionsInLambda) { 2371 Decl *FromTU = getTuDecl( 2372 R"( 2373 void foo() { 2374 (void)[]() { ; }; 2375 } 2376 )", 2377 Lang_CXX11); 2378 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2379 FromTU, functionDecl(hasName("foo"))); 2380 auto *ToD = Import(FromD, Lang_CXX03); 2381 EXPECT_TRUE(ToD); 2382 CXXRecordDecl *LambdaRec = 2383 cast<LambdaExpr>(cast<CStyleCastExpr>( 2384 *cast<CompoundStmt>(ToD->getBody())->body_begin()) 2385 ->getSubExpr()) 2386 ->getLambdaClass(); 2387 EXPECT_TRUE(LambdaRec->getDestructor()); 2388 } 2389 2390 TEST_P(ImportFunctions, 2391 CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) { 2392 Decl *FromTU = getTuDecl( 2393 R"( 2394 struct X { 2395 template <typename T> 2396 void foo(){} 2397 }; 2398 void f() { 2399 X x; 2400 x.foo<int>(); 2401 } 2402 )", 2403 Lang_CXX03); 2404 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2405 FromTU, functionDecl(hasName("f"))); 2406 auto *ToD = Import(FromD, Lang_CXX03); 2407 EXPECT_TRUE(ToD); 2408 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match( 2409 ToD, functionDecl(hasName("f"), hasDescendant(declRefExpr())))); 2410 } 2411 2412 TEST_P(ImportFunctions, 2413 DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) { 2414 Decl *FromTU = getTuDecl( 2415 R"( 2416 struct X { 2417 template <typename T> 2418 void foo(){} 2419 }; 2420 template <typename T> 2421 void f() { 2422 X x; 2423 x.foo<T>(); 2424 } 2425 void g() { 2426 f<int>(); 2427 } 2428 )", 2429 Lang_CXX03); 2430 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2431 FromTU, functionDecl(hasName("g"))); 2432 auto *ToD = Import(FromD, Lang_CXX03); 2433 EXPECT_TRUE(ToD); 2434 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2435 EXPECT_TRUE(MatchVerifier<TranslationUnitDecl>().match( 2436 ToTU, translationUnitDecl(hasDescendant( 2437 functionDecl(hasName("f"), hasDescendant(declRefExpr())))))); 2438 } 2439 2440 struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {}; 2441 2442 TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) { 2443 auto Code = 2444 R"( 2445 class X { 2446 template <class T> 2447 void f(T t); 2448 }; 2449 )"; 2450 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2451 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2452 FromTU1, functionTemplateDecl(hasName("f"))); 2453 auto *ToD1 = Import(FromD1, Lang_CXX03); 2454 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc"); 2455 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2456 FromTU2, functionTemplateDecl(hasName("f"))); 2457 auto *ToD2 = Import(FromD2, Lang_CXX03); 2458 EXPECT_EQ(ToD1, ToD2); 2459 } 2460 2461 TEST_P(ImportFunctionTemplates, 2462 ImportFunctionTemplateWithDefInRecordDeclTwice) { 2463 auto Code = 2464 R"( 2465 class X { 2466 template <class T> 2467 void f(T t); 2468 }; 2469 template <class T> 2470 void X::f(T t) {}; 2471 )"; 2472 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2473 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2474 FromTU1, functionTemplateDecl(hasName("f"))); 2475 auto *ToD1 = Import(FromD1, Lang_CXX03); 2476 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc"); 2477 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2478 FromTU2, functionTemplateDecl(hasName("f"))); 2479 auto *ToD2 = Import(FromD2, Lang_CXX03); 2480 EXPECT_EQ(ToD1, ToD2); 2481 } 2482 2483 TEST_P(ImportFunctionTemplates, 2484 ImportFunctionWhenThereIsAFunTemplateWithSameName) { 2485 getToTuDecl( 2486 R"( 2487 template <typename T> 2488 void foo(T) {} 2489 void foo(); 2490 )", 2491 Lang_CXX03); 2492 Decl *FromTU = getTuDecl("void foo();", Lang_CXX03); 2493 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2494 FromTU, functionDecl(hasName("foo"))); 2495 auto *ImportedD = Import(FromD, Lang_CXX03); 2496 EXPECT_TRUE(ImportedD); 2497 } 2498 2499 TEST_P(ImportFunctionTemplates, 2500 ImportConstructorWhenThereIsAFunTemplateWithSameName) { 2501 auto Code = 2502 R"( 2503 struct Foo { 2504 template <typename T> 2505 Foo(T) {} 2506 Foo(); 2507 }; 2508 )"; 2509 getToTuDecl(Code, Lang_CXX03); 2510 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 2511 auto *FromD = 2512 LastDeclMatcher<CXXConstructorDecl>().match(FromTU, cxxConstructorDecl()); 2513 auto *ImportedD = Import(FromD, Lang_CXX03); 2514 EXPECT_TRUE(ImportedD); 2515 } 2516 2517 TEST_P(ImportFunctionTemplates, 2518 ImportOperatorWhenThereIsAFunTemplateWithSameName) { 2519 getToTuDecl( 2520 R"( 2521 template <typename T> 2522 void operator<(T,T) {} 2523 struct X{}; 2524 void operator<(X, X); 2525 )", 2526 Lang_CXX03); 2527 Decl *FromTU = getTuDecl( 2528 R"( 2529 struct X{}; 2530 void operator<(X, X); 2531 )", 2532 Lang_CXX03); 2533 auto *FromD = LastDeclMatcher<FunctionDecl>().match( 2534 FromTU, functionDecl(hasOverloadedOperatorName("<"))); 2535 auto *ImportedD = Import(FromD, Lang_CXX03); 2536 EXPECT_TRUE(ImportedD); 2537 } 2538 2539 struct ImportFriendFunctions : ImportFunctions {}; 2540 2541 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) { 2542 auto Pattern = functionDecl(hasName("f")); 2543 2544 Decl *FromTU = getTuDecl("struct X { friend void f(); };" 2545 "void f();", 2546 Lang_CXX03, "input0.cc"); 2547 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2548 2549 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2550 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2551 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2552 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2553 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2554 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody()); 2555 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2556 } 2557 2558 TEST_P(ImportFriendFunctions, 2559 ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst) { 2560 auto Pattern = functionDecl(hasName("f")); 2561 2562 Decl *FromTU = getTuDecl("void f();" 2563 "struct X { friend void f(); };", 2564 Lang_CXX03, "input0.cc"); 2565 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2566 2567 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2568 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2569 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2570 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2571 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2572 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody()); 2573 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2574 } 2575 2576 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDef) { 2577 auto Pattern = functionDecl(hasName("f")); 2578 2579 Decl *FromTU = getTuDecl("struct X { friend void f(){} };" 2580 "void f();", 2581 Lang_CXX03, "input0.cc"); 2582 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2583 2584 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2585 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2586 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2587 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody()); 2588 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2589 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody()); 2590 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2591 } 2592 2593 TEST_P(ImportFriendFunctions, 2594 ImportFriendFunctionRedeclChainDef_OutOfClassDef) { 2595 auto Pattern = functionDecl(hasName("f")); 2596 2597 Decl *FromTU = getTuDecl("struct X { friend void f(); };" 2598 "void f(){}", 2599 Lang_CXX03, "input0.cc"); 2600 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2601 2602 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2603 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2604 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2605 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2606 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2607 EXPECT_TRUE(ToFD->doesThisDeclarationHaveABody()); 2608 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2609 } 2610 2611 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDefWithClass) { 2612 auto Pattern = functionDecl(hasName("f")); 2613 2614 Decl *FromTU = getTuDecl( 2615 R"( 2616 class X; 2617 void f(X *x){} 2618 class X{ 2619 friend void f(X *x); 2620 }; 2621 )", 2622 Lang_CXX03, "input0.cc"); 2623 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2624 2625 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2626 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2627 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2628 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody()); 2629 auto *InClassFD = cast<FunctionDecl>(FirstDeclMatcher<FriendDecl>() 2630 .match(ToTU, friendDecl()) 2631 ->getFriendDecl()); 2632 EXPECT_FALSE(InClassFD->doesThisDeclarationHaveABody()); 2633 EXPECT_EQ(InClassFD->getPreviousDecl(), ImportedD); 2634 // The parameters must refer the same type 2635 EXPECT_EQ((*InClassFD->param_begin())->getOriginalType(), 2636 (*ImportedD->param_begin())->getOriginalType()); 2637 } 2638 2639 TEST_P(ImportFriendFunctions, 2640 ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) { 2641 auto Pattern = functionDecl(hasName("f")); 2642 2643 Decl *FromTU = getTuDecl( 2644 R"( 2645 class X; 2646 void f(X *x){} 2647 class X{ 2648 friend void f(X *x); 2649 }; 2650 )", 2651 Lang_CXX03, "input0.cc"); 2652 auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2653 2654 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2655 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2656 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2657 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2658 auto *OutOfClassFD = FirstDeclMatcher<FunctionDecl>().match( 2659 ToTU, functionDecl(unless(hasParent(friendDecl())))); 2660 2661 EXPECT_TRUE(OutOfClassFD->doesThisDeclarationHaveABody()); 2662 EXPECT_EQ(ImportedD->getPreviousDecl(), OutOfClassFD); 2663 // The parameters must refer the same type 2664 EXPECT_EQ((*OutOfClassFD->param_begin())->getOriginalType(), 2665 (*ImportedD->param_begin())->getOriginalType()); 2666 } 2667 2668 TEST_P(ImportFriendFunctions, ImportFriendFunctionFromMultipleTU) { 2669 auto Pattern = functionDecl(hasName("f")); 2670 2671 FunctionDecl *ImportedD; 2672 { 2673 Decl *FromTU = 2674 getTuDecl("struct X { friend void f(){} };", Lang_CXX03, "input0.cc"); 2675 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2676 ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2677 } 2678 FunctionDecl *ImportedD1; 2679 { 2680 Decl *FromTU = getTuDecl("void f();", Lang_CXX03, "input1.cc"); 2681 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2682 ImportedD1 = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2683 } 2684 2685 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2686 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2687 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody()); 2688 EXPECT_FALSE(ImportedD1->doesThisDeclarationHaveABody()); 2689 EXPECT_EQ(ImportedD1->getPreviousDecl(), ImportedD); 2690 } 2691 2692 TEST_P(ImportFriendFunctions, Lookup) { 2693 auto FunctionPattern = functionDecl(hasName("f")); 2694 auto ClassPattern = cxxRecordDecl(hasName("X")); 2695 2696 TranslationUnitDecl *FromTU = 2697 getTuDecl("struct X { friend void f(); };", Lang_CXX03, "input0.cc"); 2698 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2699 ASSERT_TRUE(FromD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2700 ASSERT_FALSE(FromD->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2701 { 2702 auto FromName = FromD->getDeclName(); 2703 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern); 2704 auto LookupRes = Class->noload_lookup(FromName); 2705 ASSERT_TRUE(LookupRes.empty()); 2706 LookupRes = FromTU->noload_lookup(FromName); 2707 ASSERT_TRUE(LookupRes.isSingleResult()); 2708 } 2709 2710 auto *ToD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2711 auto ToName = ToD->getDeclName(); 2712 2713 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2714 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern); 2715 auto LookupRes = Class->noload_lookup(ToName); 2716 EXPECT_TRUE(LookupRes.empty()); 2717 LookupRes = ToTU->noload_lookup(ToName); 2718 EXPECT_TRUE(LookupRes.isSingleResult()); 2719 2720 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 1u); 2721 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2722 EXPECT_TRUE(To0->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2723 EXPECT_FALSE(To0->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2724 } 2725 2726 TEST_P(ImportFriendFunctions, LookupWithProtoAfter) { 2727 auto FunctionPattern = functionDecl(hasName("f")); 2728 auto ClassPattern = cxxRecordDecl(hasName("X")); 2729 2730 TranslationUnitDecl *FromTU = 2731 getTuDecl("struct X { friend void f(); };" 2732 // This proto decl makes f available to normal 2733 // lookup, otherwise it is hidden. 2734 // Normal C++ lookup (implemented in 2735 // `clang::Sema::CppLookupName()` and in `LookupDirect()`) 2736 // returns the found `NamedDecl` only if the set IDNS is matched 2737 "void f();", 2738 Lang_CXX03, "input0.cc"); 2739 auto *FromFriend = 2740 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2741 auto *FromNormal = 2742 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2743 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2744 ASSERT_FALSE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2745 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2746 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2747 2748 auto FromName = FromFriend->getDeclName(); 2749 auto *FromClass = 2750 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern); 2751 auto LookupRes = FromClass->noload_lookup(FromName); 2752 ASSERT_TRUE(LookupRes.empty()); 2753 LookupRes = FromTU->noload_lookup(FromName); 2754 ASSERT_TRUE(LookupRes.isSingleResult()); 2755 2756 auto *ToFriend = cast<FunctionDecl>(Import(FromFriend, Lang_CXX03)); 2757 auto ToName = ToFriend->getDeclName(); 2758 2759 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2760 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern); 2761 LookupRes = ToClass->noload_lookup(ToName); 2762 EXPECT_TRUE(LookupRes.empty()); 2763 LookupRes = ToTU->noload_lookup(ToName); 2764 // Test is disabled because this result is 2. 2765 EXPECT_TRUE(LookupRes.isSingleResult()); 2766 2767 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u); 2768 ToFriend = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2769 auto *ToNormal = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2770 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2771 EXPECT_FALSE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2772 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2773 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2774 } 2775 2776 TEST_P(ImportFriendFunctions, LookupWithProtoBefore) { 2777 auto FunctionPattern = functionDecl(hasName("f")); 2778 auto ClassPattern = cxxRecordDecl(hasName("X")); 2779 2780 TranslationUnitDecl *FromTU = getTuDecl("void f();" 2781 "struct X { friend void f(); };", 2782 Lang_CXX03, "input0.cc"); 2783 auto *FromNormal = 2784 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2785 auto *FromFriend = 2786 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2787 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2788 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2789 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2790 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2791 2792 auto FromName = FromNormal->getDeclName(); 2793 auto *FromClass = 2794 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern); 2795 auto LookupRes = FromClass->noload_lookup(FromName); 2796 ASSERT_TRUE(LookupRes.empty()); 2797 LookupRes = FromTU->noload_lookup(FromName); 2798 ASSERT_TRUE(LookupRes.isSingleResult()); 2799 2800 auto *ToNormal = cast<FunctionDecl>(Import(FromNormal, Lang_CXX03)); 2801 auto ToName = ToNormal->getDeclName(); 2802 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2803 2804 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern); 2805 LookupRes = ToClass->noload_lookup(ToName); 2806 EXPECT_TRUE(LookupRes.empty()); 2807 LookupRes = ToTU->noload_lookup(ToName); 2808 EXPECT_TRUE(LookupRes.isSingleResult()); 2809 2810 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u); 2811 ToNormal = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2812 auto *ToFriend = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2813 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2814 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2815 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2816 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2817 } 2818 2819 TEST_P(ImportFriendFunctions, ImportFriendChangesLookup) { 2820 auto Pattern = functionDecl(hasName("f")); 2821 2822 TranslationUnitDecl *FromNormalTU = 2823 getTuDecl("void f();", Lang_CXX03, "input0.cc"); 2824 auto *FromNormalF = 2825 FirstDeclMatcher<FunctionDecl>().match(FromNormalTU, Pattern); 2826 TranslationUnitDecl *FromFriendTU = 2827 getTuDecl("class X { friend void f(); };", Lang_CXX03, "input1.cc"); 2828 auto *FromFriendF = 2829 FirstDeclMatcher<FunctionDecl>().match(FromFriendTU, Pattern); 2830 auto FromNormalName = FromNormalF->getDeclName(); 2831 auto FromFriendName = FromFriendF->getDeclName(); 2832 2833 ASSERT_TRUE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2834 ASSERT_FALSE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2835 ASSERT_FALSE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2836 ASSERT_TRUE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2837 auto LookupRes = FromNormalTU->noload_lookup(FromNormalName); 2838 ASSERT_TRUE(LookupRes.isSingleResult()); 2839 LookupRes = FromFriendTU->noload_lookup(FromFriendName); 2840 ASSERT_TRUE(LookupRes.isSingleResult()); 2841 2842 auto *ToNormalF = cast<FunctionDecl>(Import(FromNormalF, Lang_CXX03)); 2843 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2844 auto ToName = ToNormalF->getDeclName(); 2845 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2846 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2847 LookupRes = ToTU->noload_lookup(ToName); 2848 EXPECT_TRUE(LookupRes.isSingleResult()); 2849 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u); 2850 2851 auto *ToFriendF = cast<FunctionDecl>(Import(FromFriendF, Lang_CXX03)); 2852 LookupRes = ToTU->noload_lookup(ToName); 2853 EXPECT_TRUE(LookupRes.isSingleResult()); 2854 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2855 2856 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2857 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2858 2859 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2860 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2861 } 2862 2863 TEST_P(ImportFriendFunctions, ImportFriendList) { 2864 TranslationUnitDecl *FromTU = getTuDecl("struct X { friend void f(); };" 2865 "void f();", 2866 Lang_CXX03, "input0.cc"); 2867 auto *FromFriendF = FirstDeclMatcher<FunctionDecl>().match( 2868 FromTU, functionDecl(hasName("f"))); 2869 2870 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( 2871 FromTU, cxxRecordDecl(hasName("X"))); 2872 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl()); 2873 auto FromFriends = FromClass->friends(); 2874 unsigned int FrN = 0; 2875 for (auto Fr : FromFriends) { 2876 ASSERT_EQ(Fr, FromFriend); 2877 ++FrN; 2878 } 2879 ASSERT_EQ(FrN, 1u); 2880 2881 Import(FromFriendF, Lang_CXX03); 2882 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2883 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match( 2884 ToTU, cxxRecordDecl(hasName("X"))); 2885 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 2886 auto ToFriends = ToClass->friends(); 2887 FrN = 0; 2888 for (auto Fr : ToFriends) { 2889 EXPECT_EQ(Fr, ToFriend); 2890 ++FrN; 2891 } 2892 EXPECT_EQ(FrN, 1u); 2893 } 2894 2895 AST_MATCHER_P(TagDecl, hasTypedefForAnonDecl, Matcher<TypedefNameDecl>, 2896 InnerMatcher) { 2897 if (auto *Typedef = Node.getTypedefNameForAnonDecl()) 2898 return InnerMatcher.matches(*Typedef, Finder, Builder); 2899 return false; 2900 } 2901 2902 TEST_P(ImportDecl, ImportEnumSequential) { 2903 CodeFiles Samples{{"main.c", 2904 {"void foo();" 2905 "void moo();" 2906 "int main() { foo(); moo(); }", 2907 Lang_C99}}, 2908 2909 {"foo.c", 2910 {"typedef enum { THING_VALUE } thing_t;" 2911 "void conflict(thing_t type);" 2912 "void foo() { (void)THING_VALUE; }" 2913 "void conflict(thing_t type) {}", 2914 Lang_C99}}, 2915 2916 {"moo.c", 2917 {"typedef enum { THING_VALUE } thing_t;" 2918 "void conflict(thing_t type);" 2919 "void moo() { conflict(THING_VALUE); }", 2920 Lang_C99}}}; 2921 2922 auto VerificationMatcher = 2923 enumDecl(has(enumConstantDecl(hasName("THING_VALUE"))), 2924 hasTypedefForAnonDecl(hasName("thing_t"))); 2925 2926 ImportAction ImportFoo{"foo.c", "main.c", functionDecl(hasName("foo"))}, 2927 ImportMoo{"moo.c", "main.c", functionDecl(hasName("moo"))}; 2928 2929 testImportSequence( 2930 Samples, {ImportFoo, ImportMoo}, // "foo", them "moo". 2931 // Just check that there is only one enum decl in the result AST. 2932 "main.c", enumDecl(), VerificationMatcher); 2933 2934 // For different import order, result should be the same. 2935 testImportSequence( 2936 Samples, {ImportMoo, ImportFoo}, // "moo", them "foo". 2937 // Check that there is only one enum decl in the result AST. 2938 "main.c", enumDecl(), VerificationMatcher); 2939 } 2940 2941 TEST_P(ImportDecl, ImportFieldOrder) { 2942 MatchVerifier<Decl> Verifier; 2943 testImport("struct declToImport {" 2944 " int b = a + 2;" 2945 " int a = 5;" 2946 "};", 2947 Lang_CXX11, "", Lang_CXX11, Verifier, 2948 recordDecl(hasFieldOrder({"b", "a"}))); 2949 } 2950 2951 const internal::VariadicDynCastAllOfMatcher<Expr, DependentScopeDeclRefExpr> 2952 dependentScopeDeclRefExpr; 2953 2954 TEST_P(ImportExpr, DependentScopeDeclRefExpr) { 2955 MatchVerifier<Decl> Verifier; 2956 testImport("template <typename T> struct S { static T foo; };" 2957 "template <typename T> void declToImport() {" 2958 " (void) S<T>::foo;" 2959 "}" 2960 "void instantiate() { declToImport<int>(); }" 2961 "template <typename T> T S<T>::foo;", 2962 Lang_CXX11, "", Lang_CXX11, Verifier, 2963 functionTemplateDecl(has(functionDecl(has(compoundStmt( 2964 has(cStyleCastExpr(has(dependentScopeDeclRefExpr()))))))))); 2965 2966 testImport("template <typename T> struct S {" 2967 "template<typename S> static void foo(){};" 2968 "};" 2969 "template <typename T> void declToImport() {" 2970 " S<T>::template foo<T>();" 2971 "}" 2972 "void instantiate() { declToImport<int>(); }", 2973 Lang_CXX11, "", Lang_CXX11, Verifier, 2974 functionTemplateDecl(has(functionDecl(has(compoundStmt( 2975 has(callExpr(has(dependentScopeDeclRefExpr()))))))))); 2976 } 2977 2978 const internal::VariadicDynCastAllOfMatcher<Type, DependentNameType> 2979 dependentNameType; 2980 2981 TEST_P(ImportExpr, DependentNameType) { 2982 MatchVerifier<Decl> Verifier; 2983 testImport("template <typename T> struct declToImport {" 2984 " typedef typename T::type dependent_name;" 2985 "};", 2986 Lang_CXX11, "", Lang_CXX11, Verifier, 2987 classTemplateDecl(has( 2988 cxxRecordDecl(has(typedefDecl(has(dependentNameType()))))))); 2989 } 2990 2991 TEST_P(ImportExpr, UnresolvedMemberExpr) { 2992 MatchVerifier<Decl> Verifier; 2993 testImport("struct S { template <typename T> void mem(); };" 2994 "template <typename U> void declToImport() {" 2995 " S s;" 2996 " s.mem<U>();" 2997 "}" 2998 "void instantiate() { declToImport<int>(); }", 2999 Lang_CXX11, "", Lang_CXX11, Verifier, 3000 functionTemplateDecl(has(functionDecl(has( 3001 compoundStmt(has(callExpr(has(unresolvedMemberExpr()))))))))); 3002 } 3003 3004 class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase { 3005 public: 3006 static constexpr auto DefaultCode = R"( 3007 struct A { int x; }; 3008 void f() { 3009 A a; 3010 A a1(a); 3011 A a2(A{}); 3012 a = a1; 3013 a = A{}; 3014 a.~A(); 3015 })"; 3016 3017 template <typename MatcherType> 3018 void testImportOf( 3019 const MatcherType &MethodMatcher, const char *Code = DefaultCode) { 3020 test(MethodMatcher, Code, /*ExpectedCount=*/1u); 3021 } 3022 3023 template <typename MatcherType> 3024 void testNoImportOf( 3025 const MatcherType &MethodMatcher, const char *Code = DefaultCode) { 3026 test(MethodMatcher, Code, /*ExpectedCount=*/0u); 3027 } 3028 3029 private: 3030 template <typename MatcherType> 3031 void test(const MatcherType &MethodMatcher, 3032 const char *Code, unsigned int ExpectedCount) { 3033 auto ClassMatcher = cxxRecordDecl(unless(isImplicit())); 3034 3035 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3036 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match( 3037 ToTU, ClassMatcher); 3038 3039 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 1u); 3040 3041 { 3042 CXXMethodDecl *Method = 3043 FirstDeclMatcher<CXXMethodDecl>().match(ToClass, MethodMatcher); 3044 ToClass->removeDecl(Method); 3045 SharedStatePtr->getLookupTable()->remove(Method); 3046 } 3047 3048 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 0u); 3049 3050 Decl *ImportedClass = nullptr; 3051 { 3052 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input1.cc"); 3053 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( 3054 FromTU, ClassMatcher); 3055 ImportedClass = Import(FromClass, Lang_CXX11); 3056 } 3057 3058 EXPECT_EQ(ToClass, ImportedClass); 3059 EXPECT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 3060 ExpectedCount); 3061 } 3062 }; 3063 3064 TEST_P(ImportImplicitMethods, DefaultConstructor) { 3065 testImportOf(cxxConstructorDecl(isDefaultConstructor())); 3066 } 3067 3068 TEST_P(ImportImplicitMethods, CopyConstructor) { 3069 testImportOf(cxxConstructorDecl(isCopyConstructor())); 3070 } 3071 3072 TEST_P(ImportImplicitMethods, MoveConstructor) { 3073 testImportOf(cxxConstructorDecl(isMoveConstructor())); 3074 } 3075 3076 TEST_P(ImportImplicitMethods, Destructor) { 3077 testImportOf(cxxDestructorDecl()); 3078 } 3079 3080 TEST_P(ImportImplicitMethods, CopyAssignment) { 3081 testImportOf(cxxMethodDecl(isCopyAssignmentOperator())); 3082 } 3083 3084 TEST_P(ImportImplicitMethods, MoveAssignment) { 3085 testImportOf(cxxMethodDecl(isMoveAssignmentOperator())); 3086 } 3087 3088 TEST_P(ImportImplicitMethods, DoNotImportUserProvided) { 3089 auto Code = R"( 3090 struct A { A() { int x; } }; 3091 )"; 3092 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); 3093 } 3094 3095 TEST_P(ImportImplicitMethods, DoNotImportDefault) { 3096 auto Code = R"( 3097 struct A { A() = default; }; 3098 )"; 3099 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); 3100 } 3101 3102 TEST_P(ImportImplicitMethods, DoNotImportDeleted) { 3103 auto Code = R"( 3104 struct A { A() = delete; }; 3105 )"; 3106 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); 3107 } 3108 3109 TEST_P(ImportImplicitMethods, DoNotImportOtherMethod) { 3110 auto Code = R"( 3111 struct A { void f() { } }; 3112 )"; 3113 testNoImportOf(cxxMethodDecl(hasName("f")), Code); 3114 } 3115 3116 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentRecord) { 3117 Decl *ToR1; 3118 { 3119 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input0.cc"); 3120 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3121 FromTU, cxxRecordDecl(hasName("A"))); 3122 3123 ToR1 = Import(FromR, Lang_CXX03); 3124 } 3125 3126 Decl *ToR2; 3127 { 3128 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input1.cc"); 3129 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3130 FromTU, cxxRecordDecl(hasName("A"))); 3131 3132 ToR2 = Import(FromR, Lang_CXX03); 3133 } 3134 3135 EXPECT_EQ(ToR1, ToR2); 3136 } 3137 3138 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentRecord) { 3139 Decl *ToR1; 3140 { 3141 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc"); 3142 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3143 FromTU, cxxRecordDecl(hasName("A"))); 3144 ToR1 = Import(FromR, Lang_CXX03); 3145 } 3146 Decl *ToR2; 3147 { 3148 Decl *FromTU = 3149 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc"); 3150 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3151 FromTU, cxxRecordDecl(hasName("A"))); 3152 ToR2 = Import(FromR, Lang_CXX03); 3153 } 3154 EXPECT_NE(ToR1, ToR2); 3155 } 3156 3157 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentField) { 3158 Decl *ToF1; 3159 { 3160 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc"); 3161 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3162 FromTU, fieldDecl(hasName("x"))); 3163 ToF1 = Import(FromF, Lang_CXX03); 3164 } 3165 Decl *ToF2; 3166 { 3167 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input1.cc"); 3168 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3169 FromTU, fieldDecl(hasName("x"))); 3170 ToF2 = Import(FromF, Lang_CXX03); 3171 } 3172 EXPECT_EQ(ToF1, ToF2); 3173 } 3174 3175 TEST_P(ASTImporterOptionSpecificTestBase, ImportBitfields) { 3176 Decl *FromTU = getTuDecl("struct A { unsigned x : 3; };", Lang_CXX03); 3177 auto *FromF = 3178 FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("x"))); 3179 3180 ASSERT_TRUE(FromF->isBitField()); 3181 ASSERT_EQ(3u, FromF->getBitWidthValue(FromTU->getASTContext())); 3182 auto *ToField = Import(FromF, Lang_CXX03); 3183 auto *ToTU = ToField->getTranslationUnitDecl(); 3184 3185 EXPECT_TRUE(ToField->isBitField()); 3186 EXPECT_EQ(3u, ToField->getBitWidthValue(ToTU->getASTContext())); 3187 3188 const auto *FromBT = FromF->getBitWidth()->getType()->getAs<BuiltinType>(); 3189 const auto *ToBT = ToField->getBitWidth()->getType()->getAs<BuiltinType>(); 3190 ASSERT_TRUE(FromBT); 3191 ASSERT_EQ(BuiltinType::Int, FromBT->getKind()); 3192 EXPECT_TRUE(ToBT); 3193 EXPECT_EQ(BuiltinType::Int, ToBT->getKind()); 3194 } 3195 3196 struct ImportBlock : ASTImporterOptionSpecificTestBase {}; 3197 TEST_P(ImportBlock, ImportBlocksAreUnsupported) { 3198 const auto *Code = R"( 3199 void test_block__capture_null() { 3200 int *p = 0; 3201 ^(){ 3202 *p = 1; 3203 }(); 3204 })"; 3205 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 3206 auto *FromBlock = FirstDeclMatcher<BlockDecl>().match(FromTU, blockDecl()); 3207 ASSERT_TRUE(FromBlock); 3208 3209 auto ToBlockOrError = importOrError(FromBlock, Lang_CXX03); 3210 3211 const auto ExpectUnsupportedConstructError = [](const ASTImportError &Error) { 3212 EXPECT_EQ(ASTImportError::UnsupportedConstruct, Error.Error); 3213 }; 3214 llvm::handleAllErrors(ToBlockOrError.takeError(), 3215 ExpectUnsupportedConstructError); 3216 } 3217 3218 TEST_P(ASTImporterOptionSpecificTestBase, ImportParmVarDecl) { 3219 const auto *Code = R"( 3220 template <typename T> struct Wrapper { 3221 Wrapper(T Value = {}) {} 3222 }; 3223 template class Wrapper<int>; 3224 )"; 3225 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3226 auto *FromVar = FirstDeclMatcher<ParmVarDecl>().match( 3227 FromTU, parmVarDecl(hasType(asString("int")))); 3228 ASSERT_TRUE(FromVar); 3229 ASSERT_TRUE(FromVar->hasUninstantiatedDefaultArg()); 3230 ASSERT_TRUE(FromVar->getUninstantiatedDefaultArg()); 3231 3232 const auto *ToVar = Import(FromVar, Lang_CXX11); 3233 EXPECT_TRUE(ToVar); 3234 EXPECT_TRUE(ToVar->hasUninstantiatedDefaultArg()); 3235 EXPECT_TRUE(ToVar->getUninstantiatedDefaultArg()); 3236 EXPECT_NE(FromVar->getUninstantiatedDefaultArg(), 3237 ToVar->getUninstantiatedDefaultArg()); 3238 } 3239 3240 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentField) { 3241 Decl *ToF1; 3242 { 3243 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc"); 3244 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3245 FromTU, fieldDecl(hasName("x"))); 3246 ToF1 = Import(FromF, Lang_CXX03); 3247 } 3248 Decl *ToF2; 3249 { 3250 Decl *FromTU = 3251 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc"); 3252 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3253 FromTU, fieldDecl(hasName("x"))); 3254 ToF2 = Import(FromF, Lang_CXX03); 3255 } 3256 EXPECT_NE(ToF1, ToF2); 3257 } 3258 3259 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentMethod) { 3260 Decl *ToM1; 3261 { 3262 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }", 3263 Lang_CXX03, "input0.cc"); 3264 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3265 FromTU, functionDecl(hasName("x"), isDefinition())); 3266 ToM1 = Import(FromM, Lang_CXX03); 3267 } 3268 Decl *ToM2; 3269 { 3270 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }", 3271 Lang_CXX03, "input1.cc"); 3272 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3273 FromTU, functionDecl(hasName("x"), isDefinition())); 3274 ToM2 = Import(FromM, Lang_CXX03); 3275 } 3276 EXPECT_EQ(ToM1, ToM2); 3277 } 3278 3279 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentMethod) { 3280 Decl *ToM1; 3281 { 3282 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }", 3283 Lang_CXX03, "input0.cc"); 3284 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3285 FromTU, functionDecl(hasName("x"), isDefinition())); 3286 ToM1 = Import(FromM, Lang_CXX03); 3287 } 3288 Decl *ToM2; 3289 { 3290 Decl *FromTU = 3291 getTuDecl("struct A { void x() const; }; void A::x() const { }", 3292 Lang_CXX03, "input1.cc"); 3293 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3294 FromTU, functionDecl(hasName("x"), isDefinition())); 3295 ToM2 = Import(FromM, Lang_CXX03); 3296 } 3297 EXPECT_NE(ToM1, ToM2); 3298 } 3299 3300 TEST_P(ASTImporterOptionSpecificTestBase, 3301 ImportUnnamedStructsWithRecursingField) { 3302 Decl *FromTU = getTuDecl( 3303 R"( 3304 struct A { 3305 struct { 3306 struct A *next; 3307 } entry0; 3308 struct { 3309 struct A *next; 3310 } entry1; 3311 }; 3312 )", 3313 Lang_C99, "input0.cc"); 3314 auto *From = 3315 FirstDeclMatcher<RecordDecl>().match(FromTU, recordDecl(hasName("A"))); 3316 3317 Import(From, Lang_C99); 3318 3319 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 3320 auto *Entry0 = 3321 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0"))); 3322 auto *Entry1 = 3323 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry1"))); 3324 auto *R0 = getRecordDecl(Entry0); 3325 auto *R1 = getRecordDecl(Entry1); 3326 EXPECT_NE(R0, R1); 3327 EXPECT_TRUE(MatchVerifier<RecordDecl>().match( 3328 R0, recordDecl(has(fieldDecl(hasName("next")))))); 3329 EXPECT_TRUE(MatchVerifier<RecordDecl>().match( 3330 R1, recordDecl(has(fieldDecl(hasName("next")))))); 3331 } 3332 3333 TEST_P(ASTImporterOptionSpecificTestBase, ImportUnnamedFieldsInCorrectOrder) { 3334 Decl *FromTU = getTuDecl( 3335 R"( 3336 void f(int X, int Y, bool Z) { 3337 (void)[X, Y, Z] { (void)Z; }; 3338 } 3339 )", 3340 Lang_CXX11, "input0.cc"); 3341 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 3342 FromTU, functionDecl(hasName("f"))); 3343 auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11)); 3344 EXPECT_TRUE(ToF); 3345 3346 CXXRecordDecl *FromLambda = 3347 cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>( 3348 FromF->getBody())->body_front())->getSubExpr())->getLambdaClass(); 3349 3350 auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11)); 3351 EXPECT_TRUE(ToLambda); 3352 3353 // Check if the fields of the lambda class are imported in correct order. 3354 unsigned FromIndex = 0u; 3355 for (auto *FromField : FromLambda->fields()) { 3356 ASSERT_FALSE(FromField->getDeclName()); 3357 auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11)); 3358 EXPECT_TRUE(ToField); 3359 Optional<unsigned> ToIndex = ASTImporter::getFieldIndex(ToField); 3360 EXPECT_TRUE(ToIndex); 3361 EXPECT_EQ(*ToIndex, FromIndex); 3362 ++FromIndex; 3363 } 3364 3365 EXPECT_EQ(FromIndex, 3u); 3366 } 3367 3368 TEST_P(ASTImporterOptionSpecificTestBase, 3369 MergeFieldDeclsOfClassTemplateSpecialization) { 3370 std::string ClassTemplate = 3371 R"( 3372 template <typename T> 3373 struct X { 3374 int a{0}; // FieldDecl with InitListExpr 3375 X(char) : a(3) {} // (1) 3376 X(int) {} // (2) 3377 }; 3378 )"; 3379 Decl *ToTU = getToTuDecl(ClassTemplate + 3380 R"( 3381 void foo() { 3382 // ClassTemplateSpec with ctor (1): FieldDecl without InitlistExpr 3383 X<char> xc('c'); 3384 } 3385 )", Lang_CXX11); 3386 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3387 ToTU, classTemplateSpecializationDecl(hasName("X"))); 3388 // FieldDecl without InitlistExpr: 3389 auto *ToField = *ToSpec->field_begin(); 3390 ASSERT_TRUE(ToField); 3391 ASSERT_FALSE(ToField->getInClassInitializer()); 3392 Decl *FromTU = getTuDecl(ClassTemplate + 3393 R"( 3394 void bar() { 3395 // ClassTemplateSpec with ctor (2): FieldDecl WITH InitlistExpr 3396 X<char> xc(1); 3397 } 3398 )", Lang_CXX11); 3399 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3400 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3401 // FieldDecl with InitlistExpr: 3402 auto *FromField = *FromSpec->field_begin(); 3403 ASSERT_TRUE(FromField); 3404 ASSERT_TRUE(FromField->getInClassInitializer()); 3405 3406 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3407 ASSERT_TRUE(ImportedSpec); 3408 EXPECT_EQ(ImportedSpec, ToSpec); 3409 // After the import, the FieldDecl has to be merged, thus it should have the 3410 // InitListExpr. 3411 EXPECT_TRUE(ToField->getInClassInitializer()); 3412 } 3413 3414 TEST_P(ASTImporterOptionSpecificTestBase, 3415 MergeFunctionOfClassTemplateSpecialization) { 3416 std::string ClassTemplate = 3417 R"( 3418 template <typename T> 3419 struct X { 3420 void f() {} 3421 void g() {} 3422 }; 3423 )"; 3424 Decl *ToTU = getToTuDecl(ClassTemplate + 3425 R"( 3426 void foo() { 3427 X<char> x; 3428 x.f(); 3429 } 3430 )", Lang_CXX11); 3431 Decl *FromTU = getTuDecl(ClassTemplate + 3432 R"( 3433 void bar() { 3434 X<char> x; 3435 x.g(); 3436 } 3437 )", Lang_CXX11); 3438 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3439 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3440 auto FunPattern = functionDecl(hasName("g"), 3441 hasParent(classTemplateSpecializationDecl())); 3442 auto *FromFun = 3443 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunPattern); 3444 auto *ToFun = 3445 FirstDeclMatcher<FunctionDecl>().match(ToTU, FunPattern); 3446 ASSERT_TRUE(FromFun->hasBody()); 3447 ASSERT_FALSE(ToFun->hasBody()); 3448 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3449 ASSERT_TRUE(ImportedSpec); 3450 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3451 ToTU, classTemplateSpecializationDecl(hasName("X"))); 3452 EXPECT_EQ(ImportedSpec, ToSpec); 3453 EXPECT_TRUE(ToFun->hasBody()); 3454 } 3455 3456 TEST_P(ASTImporterOptionSpecificTestBase, MergeTemplateSpecWithForwardDecl) { 3457 std::string ClassTemplate = 3458 R"( 3459 template<typename T> 3460 struct X { int m; }; 3461 template<> 3462 struct X<int> { int m; }; 3463 )"; 3464 // Append a forward decl for our template specialization. 3465 getToTuDecl(ClassTemplate + "template<> struct X<int>;", Lang_CXX11); 3466 Decl *FromTU = getTuDecl(ClassTemplate, Lang_CXX11); 3467 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3468 FromTU, classTemplateSpecializationDecl(hasName("X"), isDefinition())); 3469 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3470 // Check that our definition got merged with the existing definition. 3471 EXPECT_TRUE(FromSpec->isThisDeclarationADefinition()); 3472 EXPECT_TRUE(ImportedSpec->isThisDeclarationADefinition()); 3473 } 3474 3475 TEST_P(ASTImporterOptionSpecificTestBase, 3476 ODRViolationOfClassTemplateSpecializationsShouldBeReported) { 3477 std::string ClassTemplate = 3478 R"( 3479 template <typename T> 3480 struct X {}; 3481 )"; 3482 Decl *ToTU = getToTuDecl(ClassTemplate + 3483 R"( 3484 template <> 3485 struct X<char> { 3486 int a; 3487 }; 3488 void foo() { 3489 X<char> x; 3490 } 3491 )", 3492 Lang_CXX11); 3493 Decl *FromTU = getTuDecl(ClassTemplate + 3494 R"( 3495 template <> 3496 struct X<char> { 3497 int b; 3498 }; 3499 void foo() { 3500 X<char> x; 3501 } 3502 )", 3503 Lang_CXX11); 3504 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3505 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3506 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3507 3508 // We expect one (ODR) warning during the import. 3509 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 3510 3511 // The second specialization is different from the first, thus it violates 3512 // ODR, consequently we expect to keep the first specialization only, which is 3513 // already in the "To" context. 3514 EXPECT_FALSE(ImportedSpec); 3515 EXPECT_EQ(1u, 3516 DeclCounter<ClassTemplateSpecializationDecl>().match( 3517 ToTU, classTemplateSpecializationDecl(hasName("X")))); 3518 } 3519 3520 TEST_P(ASTImporterOptionSpecificTestBase, 3521 MergeCtorOfClassTemplateSpecialization) { 3522 std::string ClassTemplate = 3523 R"( 3524 template <typename T> 3525 struct X { 3526 X(char) {} 3527 X(int) {} 3528 }; 3529 )"; 3530 Decl *ToTU = getToTuDecl(ClassTemplate + 3531 R"( 3532 void foo() { 3533 X<char> x('c'); 3534 } 3535 )", Lang_CXX11); 3536 Decl *FromTU = getTuDecl(ClassTemplate + 3537 R"( 3538 void bar() { 3539 X<char> x(1); 3540 } 3541 )", Lang_CXX11); 3542 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3543 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3544 // Match the void(int) ctor. 3545 auto CtorPattern = 3546 cxxConstructorDecl(hasParameter(0, varDecl(hasType(asString("int")))), 3547 hasParent(classTemplateSpecializationDecl())); 3548 auto *FromCtor = 3549 FirstDeclMatcher<CXXConstructorDecl>().match(FromTU, CtorPattern); 3550 auto *ToCtor = 3551 FirstDeclMatcher<CXXConstructorDecl>().match(ToTU, CtorPattern); 3552 ASSERT_TRUE(FromCtor->hasBody()); 3553 ASSERT_FALSE(ToCtor->hasBody()); 3554 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3555 ASSERT_TRUE(ImportedSpec); 3556 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3557 ToTU, classTemplateSpecializationDecl(hasName("X"))); 3558 EXPECT_EQ(ImportedSpec, ToSpec); 3559 EXPECT_TRUE(ToCtor->hasBody()); 3560 } 3561 3562 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateFriendDecl) { 3563 const auto *Code = 3564 R"( 3565 template <class T> class X { friend T; }; 3566 struct Y {}; 3567 template class X<Y>; 3568 )"; 3569 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3570 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3571 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3572 FromTU, classTemplateSpecializationDecl()); 3573 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3574 ToTU, classTemplateSpecializationDecl()); 3575 3576 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3577 EXPECT_EQ(ImportedSpec, ToSpec); 3578 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match( 3579 ToTU, classTemplateSpecializationDecl())); 3580 } 3581 3582 TEST_P(ASTImporterOptionSpecificTestBase, 3583 ClassTemplatePartialSpecializationsShouldNotBeDuplicated) { 3584 auto Code = 3585 R"( 3586 // primary template 3587 template<class T1, class T2, int I> 3588 class A {}; 3589 3590 // partial specialization 3591 template<class T, int I> 3592 class A<T, T*, I> {}; 3593 )"; 3594 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3595 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3596 auto *FromSpec = 3597 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match( 3598 FromTU, classTemplatePartialSpecializationDecl()); 3599 auto *ToSpec = 3600 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match( 3601 ToTU, classTemplatePartialSpecializationDecl()); 3602 3603 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3604 EXPECT_EQ(ImportedSpec, ToSpec); 3605 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match( 3606 ToTU, classTemplatePartialSpecializationDecl())); 3607 } 3608 3609 TEST_P(ASTImporterOptionSpecificTestBase, 3610 ClassTemplateSpecializationsShouldNotBeDuplicated) { 3611 auto Code = 3612 R"( 3613 // primary template 3614 template<class T1, class T2, int I> 3615 class A {}; 3616 3617 // full specialization 3618 template<> 3619 class A<int, int, 1> {}; 3620 )"; 3621 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3622 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3623 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3624 FromTU, classTemplateSpecializationDecl()); 3625 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3626 ToTU, classTemplateSpecializationDecl()); 3627 3628 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3629 EXPECT_EQ(ImportedSpec, ToSpec); 3630 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match( 3631 ToTU, classTemplateSpecializationDecl())); 3632 } 3633 3634 TEST_P(ASTImporterOptionSpecificTestBase, 3635 ClassTemplateFullAndPartialSpecsShouldNotBeMixed) { 3636 std::string PrimaryTemplate = 3637 R"( 3638 template<class T1, class T2, int I> 3639 class A {}; 3640 )"; 3641 auto PartialSpec = 3642 R"( 3643 template<class T, int I> 3644 class A<T, T*, I> {}; 3645 )"; 3646 auto FullSpec = 3647 R"( 3648 template<> 3649 class A<int, int, 1> {}; 3650 )"; 3651 Decl *ToTU = getToTuDecl(PrimaryTemplate + FullSpec, Lang_CXX11); 3652 Decl *FromTU = getTuDecl(PrimaryTemplate + PartialSpec, Lang_CXX11); 3653 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3654 FromTU, classTemplateSpecializationDecl()); 3655 3656 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3657 EXPECT_TRUE(ImportedSpec); 3658 // Check the number of partial specializations. 3659 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match( 3660 ToTU, classTemplatePartialSpecializationDecl())); 3661 // Check the number of full specializations. 3662 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match( 3663 ToTU, classTemplateSpecializationDecl( 3664 unless(classTemplatePartialSpecializationDecl())))); 3665 } 3666 3667 TEST_P(ASTImporterOptionSpecificTestBase, 3668 InitListExprValueKindShouldBeImported) { 3669 Decl *TU = getTuDecl( 3670 R"( 3671 const int &init(); 3672 void foo() { const int &a{init()}; } 3673 )", Lang_CXX11, "input0.cc"); 3674 auto *FromD = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("a"))); 3675 ASSERT_TRUE(FromD->getAnyInitializer()); 3676 auto *InitExpr = FromD->getAnyInitializer(); 3677 ASSERT_TRUE(InitExpr); 3678 ASSERT_TRUE(InitExpr->isGLValue()); 3679 3680 auto *ToD = Import(FromD, Lang_CXX11); 3681 EXPECT_TRUE(ToD); 3682 auto *ToInitExpr = cast<VarDecl>(ToD)->getAnyInitializer(); 3683 EXPECT_TRUE(ToInitExpr); 3684 EXPECT_TRUE(ToInitExpr->isGLValue()); 3685 } 3686 3687 struct ImportVariables : ASTImporterOptionSpecificTestBase {}; 3688 3689 TEST_P(ImportVariables, ImportOfOneDeclBringsInTheWholeChain) { 3690 Decl *FromTU = getTuDecl( 3691 R"( 3692 struct A { 3693 static const int a = 1 + 2; 3694 }; 3695 const int A::a; 3696 )", 3697 Lang_CXX03, "input1.cc"); 3698 3699 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match( 3700 FromTU, varDecl(hasName("a"))); // Decl with init 3701 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match( 3702 FromTU, varDecl(hasName("a"))); // Decl with definition 3703 ASSERT_NE(FromDWithInit, FromDWithDef); 3704 ASSERT_EQ(FromDWithDef->getPreviousDecl(), FromDWithInit); 3705 3706 auto *ToD0 = cast<VarDecl>(Import(FromDWithInit, Lang_CXX11)); 3707 auto *ToD1 = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11)); 3708 ASSERT_TRUE(ToD0); 3709 ASSERT_TRUE(ToD1); 3710 EXPECT_NE(ToD0, ToD1); 3711 EXPECT_EQ(ToD1->getPreviousDecl(), ToD0); 3712 } 3713 3714 TEST_P(ImportVariables, InitAndDefinitionAreInDifferentTUs) { 3715 auto StructA = 3716 R"( 3717 struct A { 3718 static const int a = 1 + 2; 3719 }; 3720 )"; 3721 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03); 3722 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a;", Lang_CXX03, 3723 "input1.cc"); 3724 3725 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match( 3726 FromTU, varDecl(hasName("a"))); // Decl with init 3727 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match( 3728 FromTU, varDecl(hasName("a"))); // Decl with definition 3729 ASSERT_EQ(FromDWithInit, FromDWithDef->getPreviousDecl()); 3730 ASSERT_TRUE(FromDWithInit->getInit()); 3731 ASSERT_FALSE(FromDWithInit->isThisDeclarationADefinition()); 3732 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition()); 3733 ASSERT_FALSE(FromDWithDef->getInit()); 3734 3735 auto *ToD = FirstDeclMatcher<VarDecl>().match( 3736 ToTU, varDecl(hasName("a"))); // Decl with init 3737 ASSERT_TRUE(ToD->getInit()); 3738 ASSERT_FALSE(ToD->getDefinition()); 3739 3740 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11)); 3741 EXPECT_TRUE(ImportedD->getAnyInitializer()); 3742 EXPECT_TRUE(ImportedD->getDefinition()); 3743 } 3744 3745 TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) { 3746 auto StructA = 3747 R"( 3748 struct A { 3749 static const int a; 3750 }; 3751 )"; 3752 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03); 3753 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a = 1 + 2;", 3754 Lang_CXX03, "input1.cc"); 3755 3756 auto *FromDDeclarationOnly = FirstDeclMatcher<VarDecl>().match( 3757 FromTU, varDecl(hasName("a"))); 3758 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match( 3759 FromTU, varDecl(hasName("a"))); // Decl with definition and with init. 3760 ASSERT_EQ(FromDDeclarationOnly, FromDWithDef->getPreviousDecl()); 3761 ASSERT_FALSE(FromDDeclarationOnly->getInit()); 3762 ASSERT_FALSE(FromDDeclarationOnly->isThisDeclarationADefinition()); 3763 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition()); 3764 ASSERT_TRUE(FromDWithDef->getInit()); 3765 3766 auto *ToD = FirstDeclMatcher<VarDecl>().match( 3767 ToTU, varDecl(hasName("a"))); 3768 ASSERT_FALSE(ToD->getInit()); 3769 ASSERT_FALSE(ToD->getDefinition()); 3770 3771 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11)); 3772 EXPECT_TRUE(ImportedD->getAnyInitializer()); 3773 EXPECT_TRUE(ImportedD->getDefinition()); 3774 } 3775 3776 TEST_P(ImportVariables, ImportBindingDecl) { 3777 Decl *From, *To; 3778 std::tie(From, To) = getImportedDecl( 3779 R"( 3780 void declToImport() { 3781 int a[2] = {1,2}; 3782 auto [x1,y1] = a; 3783 auto& [x2,y2] = a; 3784 3785 struct S { 3786 mutable int x1 : 2; 3787 volatile double y1; 3788 }; 3789 S b; 3790 const auto [x3, y3] = b; 3791 }; 3792 )", 3793 Lang_CXX17, "", Lang_CXX17); 3794 3795 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl(); 3796 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 3797 FromTU, functionDecl(hasName("declToImport"))); 3798 auto *ToF = Import(FromF, Lang_CXX17); 3799 EXPECT_TRUE(ToF); 3800 3801 auto VerifyImport = [&](llvm::StringRef BindName) { 3802 auto *FromB = FirstDeclMatcher<BindingDecl>().match( 3803 FromF, bindingDecl(hasName(BindName))); 3804 ASSERT_TRUE(FromB); 3805 auto *ToB = Import(FromB, Lang_CXX17); 3806 EXPECT_TRUE(ToB); 3807 EXPECT_EQ(FromB->getBinding() != nullptr, ToB->getBinding() != nullptr); 3808 EXPECT_EQ(FromB->getDecomposedDecl() != nullptr, 3809 ToB->getDecomposedDecl() != nullptr); 3810 EXPECT_EQ(FromB->getHoldingVar() != nullptr, 3811 ToB->getHoldingVar() != nullptr); 3812 }; 3813 3814 VerifyImport("x1"); 3815 VerifyImport("y1"); 3816 VerifyImport("x2"); 3817 VerifyImport("y2"); 3818 VerifyImport("x3"); 3819 VerifyImport("y3"); 3820 } 3821 3822 TEST_P(ImportVariables, ImportDecompositionDeclArray) { 3823 Decl *From, *To; 3824 std::tie(From, To) = getImportedDecl( 3825 R"( 3826 void declToImport() { 3827 int a[2] = {1,2}; 3828 auto [x1,y1] = a; 3829 }; 3830 )", 3831 Lang_CXX17, "", Lang_CXX17); 3832 3833 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl(); 3834 auto *FromDecomp = 3835 FirstDeclMatcher<DecompositionDecl>().match(FromTU, decompositionDecl()); 3836 auto *ToDecomp = Import(FromDecomp, Lang_CXX17); 3837 EXPECT_TRUE(ToDecomp); 3838 3839 ArrayRef<BindingDecl *> FromB = FromDecomp->bindings(); 3840 ArrayRef<BindingDecl *> ToB = ToDecomp->bindings(); 3841 EXPECT_EQ(FromB.size(), ToB.size()); 3842 for (unsigned int I = 0; I < FromB.size(); ++I) { 3843 auto *ToBI = Import(FromB[I], Lang_CXX17); 3844 EXPECT_EQ(ToBI, ToB[I]); 3845 } 3846 } 3847 3848 struct ImportClasses : ASTImporterOptionSpecificTestBase {}; 3849 3850 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) { 3851 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C99); 3852 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc"); 3853 auto Pattern = recordDecl(hasName("X"), unless(isImplicit())); 3854 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3855 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern); 3856 3857 Decl *ImportedDef = Import(FromDef, Lang_C99); 3858 3859 EXPECT_NE(ImportedDef, ToProto); 3860 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u); 3861 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3862 EXPECT_TRUE(ImportedDef == ToDef); 3863 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 3864 EXPECT_FALSE(ToProto->isThisDeclarationADefinition()); 3865 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto); 3866 } 3867 3868 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContextCXX) { 3869 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_CXX03); 3870 Decl *FromTU1 = getTuDecl("struct X {};", Lang_CXX03, "input1.cc"); 3871 auto Pattern = recordDecl(hasName("X"), unless(isImplicit())); 3872 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3873 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern); 3874 3875 Decl *ImportedDef = Import(FromDef, Lang_CXX03); 3876 3877 EXPECT_NE(ImportedDef, ToProto); 3878 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u); 3879 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3880 EXPECT_TRUE(ImportedDef == ToDef); 3881 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 3882 EXPECT_FALSE(ToProto->isThisDeclarationADefinition()); 3883 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto); 3884 } 3885 3886 TEST_P(ImportClasses, ImportNestedPrototypeThenDefinition) { 3887 Decl *FromTU0 = 3888 getTuDecl("struct A { struct X *Xp; };", Lang_C99, "input0.cc"); 3889 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc"); 3890 auto Pattern = recordDecl(hasName("X"), unless(isImplicit())); 3891 auto FromProto = FirstDeclMatcher<RecordDecl>().match(FromTU0, Pattern); 3892 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern); 3893 3894 Decl *ImportedProto = Import(FromProto, Lang_C99); 3895 Decl *ImportedDef = Import(FromDef, Lang_C99); 3896 Decl *ToTU = ImportedDef->getTranslationUnitDecl(); 3897 3898 EXPECT_NE(ImportedDef, ImportedProto); 3899 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u); 3900 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3901 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern); 3902 EXPECT_TRUE(ImportedDef == ToDef); 3903 EXPECT_TRUE(ImportedProto == ToProto); 3904 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 3905 EXPECT_FALSE(ToProto->isThisDeclarationADefinition()); 3906 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto); 3907 } 3908 3909 3910 struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {}; 3911 3912 TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) { 3913 Decl *FromTU = getTuDecl( 3914 R"( 3915 class A { 3916 template <int I> class F {}; 3917 class X { 3918 template <int I> friend class F; 3919 }; 3920 }; 3921 )", 3922 Lang_CXX03, "input0.cc"); 3923 3924 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( 3925 FromTU, cxxRecordDecl(hasName("F"), isDefinition())); 3926 auto *FromFriendClass = LastDeclMatcher<CXXRecordDecl>().match( 3927 FromTU, cxxRecordDecl(hasName("F"))); 3928 3929 ASSERT_TRUE(FromClass); 3930 ASSERT_TRUE(FromFriendClass); 3931 ASSERT_NE(FromClass, FromFriendClass); 3932 ASSERT_EQ(FromFriendClass->getDefinition(), FromClass); 3933 ASSERT_EQ(FromFriendClass->getPreviousDecl(), FromClass); 3934 ASSERT_EQ(FromFriendClass->getDescribedClassTemplate()->getPreviousDecl(), 3935 FromClass->getDescribedClassTemplate()); 3936 3937 auto *ToClass = cast<CXXRecordDecl>(Import(FromClass, Lang_CXX03)); 3938 auto *ToFriendClass = 3939 cast<CXXRecordDecl>(Import(FromFriendClass, Lang_CXX03)); 3940 3941 EXPECT_TRUE(ToClass); 3942 EXPECT_TRUE(ToFriendClass); 3943 EXPECT_NE(ToClass, ToFriendClass); 3944 EXPECT_EQ(ToFriendClass->getDefinition(), ToClass); 3945 EXPECT_EQ(ToFriendClass->getPreviousDecl(), ToClass); 3946 EXPECT_EQ(ToFriendClass->getDescribedClassTemplate()->getPreviousDecl(), 3947 ToClass->getDescribedClassTemplate()); 3948 } 3949 3950 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClass) { 3951 Decl *FromTu = getTuDecl( 3952 R"( 3953 class declToImport { 3954 friend class declToImport; 3955 }; 3956 )", 3957 Lang_CXX03, "input.cc"); 3958 3959 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 3960 FromTu, cxxRecordDecl(hasName("declToImport"))); 3961 auto *ToD = Import(FromD, Lang_CXX03); 3962 auto Pattern = cxxRecordDecl(has(friendDecl())); 3963 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern)); 3964 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern)); 3965 } 3966 3967 TEST_P(ImportFriendClasses, UndeclaredFriendClassShouldNotBeVisible) { 3968 Decl *FromTu = 3969 getTuDecl("class X { friend class Y; };", Lang_CXX03, "from.cc"); 3970 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 3971 FromTu, cxxRecordDecl(hasName("X"))); 3972 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 3973 RecordDecl *FromRecordOfFriend = 3974 const_cast<RecordDecl *>(getRecordDeclOfFriend(FromFriend)); 3975 3976 ASSERT_EQ(FromRecordOfFriend->getDeclContext(), cast<DeclContext>(FromTu)); 3977 ASSERT_EQ(FromRecordOfFriend->getLexicalDeclContext(), 3978 cast<DeclContext>(FromX)); 3979 ASSERT_FALSE( 3980 FromRecordOfFriend->getDeclContext()->containsDecl(FromRecordOfFriend)); 3981 ASSERT_FALSE(FromRecordOfFriend->getLexicalDeclContext()->containsDecl( 3982 FromRecordOfFriend)); 3983 ASSERT_FALSE(FromRecordOfFriend->getLookupParent() 3984 ->lookup(FromRecordOfFriend->getDeclName()) 3985 .empty()); 3986 3987 auto *ToX = Import(FromX, Lang_CXX03); 3988 ASSERT_TRUE(ToX); 3989 3990 Decl *ToTu = ToX->getTranslationUnitDecl(); 3991 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 3992 RecordDecl *ToRecordOfFriend = 3993 const_cast<RecordDecl *>(getRecordDeclOfFriend(ToFriend)); 3994 3995 ASSERT_EQ(ToRecordOfFriend->getDeclContext(), cast<DeclContext>(ToTu)); 3996 ASSERT_EQ(ToRecordOfFriend->getLexicalDeclContext(), cast<DeclContext>(ToX)); 3997 EXPECT_FALSE( 3998 ToRecordOfFriend->getDeclContext()->containsDecl(ToRecordOfFriend)); 3999 EXPECT_FALSE(ToRecordOfFriend->getLexicalDeclContext()->containsDecl( 4000 ToRecordOfFriend)); 4001 EXPECT_FALSE(ToRecordOfFriend->getLookupParent() 4002 ->lookup(ToRecordOfFriend->getDeclName()) 4003 .empty()); 4004 } 4005 4006 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClassTemplate) { 4007 Decl *FromTu = getTuDecl( 4008 R"( 4009 template<class A> class declToImport { 4010 template<class A1> friend class declToImport; 4011 }; 4012 )", 4013 Lang_CXX03, "input.cc"); 4014 4015 auto *FromD = 4016 FirstDeclMatcher<ClassTemplateDecl>().match(FromTu, classTemplateDecl()); 4017 auto *ToD = Import(FromD, Lang_CXX03); 4018 4019 auto Pattern = classTemplateDecl( 4020 has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl())))))); 4021 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern)); 4022 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern)); 4023 4024 auto *Class = 4025 FirstDeclMatcher<ClassTemplateDecl>().match(ToD, classTemplateDecl()); 4026 auto *Friend = FirstDeclMatcher<FriendDecl>().match(ToD, friendDecl()); 4027 EXPECT_NE(Friend->getFriendDecl(), Class); 4028 EXPECT_EQ(Friend->getFriendDecl()->getPreviousDecl(), Class); 4029 } 4030 4031 TEST_P(ImportFriendClasses, ProperPrevDeclForClassTemplateDecls) { 4032 auto Pattern = classTemplateSpecializationDecl(hasName("X")); 4033 4034 ClassTemplateSpecializationDecl *Imported1; 4035 { 4036 Decl *FromTU = getTuDecl("template<class T> class X;" 4037 "struct Y { friend class X<int>; };", 4038 Lang_CXX03, "input0.cc"); 4039 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4040 FromTU, Pattern); 4041 4042 Imported1 = 4043 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03)); 4044 } 4045 ClassTemplateSpecializationDecl *Imported2; 4046 { 4047 Decl *FromTU = getTuDecl("template<class T> class X;" 4048 "template<> class X<int>{};" 4049 "struct Z { friend class X<int>; };", 4050 Lang_CXX03, "input1.cc"); 4051 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4052 FromTU, Pattern); 4053 4054 Imported2 = 4055 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03)); 4056 } 4057 4058 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4059 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(ToTU, Pattern), 4060 2u); 4061 ASSERT_TRUE(Imported2->getPreviousDecl()); 4062 EXPECT_EQ(Imported2->getPreviousDecl(), Imported1); 4063 } 4064 4065 TEST_P(ImportFriendClasses, TypeForDeclShouldBeSetInTemplated) { 4066 Decl *FromTU0 = getTuDecl( 4067 R"( 4068 class X { 4069 class Y; 4070 }; 4071 class X::Y { 4072 template <typename T> 4073 friend class F; // The decl context of F is the global namespace. 4074 }; 4075 )", 4076 Lang_CXX03, "input0.cc"); 4077 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match( 4078 FromTU0, classTemplateDecl(hasName("F"))); 4079 auto *Imported0 = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03)); 4080 Decl *FromTU1 = getTuDecl( 4081 R"( 4082 template <typename T> 4083 class F {}; 4084 )", 4085 Lang_CXX03, "input1.cc"); 4086 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match( 4087 FromTU1, classTemplateDecl(hasName("F"))); 4088 auto *Imported1 = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03)); 4089 EXPECT_EQ(Imported0->getTemplatedDecl()->getTypeForDecl(), 4090 Imported1->getTemplatedDecl()->getTypeForDecl()); 4091 } 4092 4093 TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) { 4094 Decl *From, *To; 4095 std::tie(From, To) = 4096 getImportedDecl("class declToImport {};", Lang_CXX03, 4097 "class Y { friend class declToImport; };", Lang_CXX03); 4098 auto *Imported = cast<CXXRecordDecl>(To); 4099 4100 EXPECT_TRUE(Imported->getPreviousDecl()); 4101 } 4102 4103 TEST_P(ImportFriendClasses, 4104 ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) { 4105 Decl *ToTU = getToTuDecl( 4106 R"( 4107 class X { 4108 class Y; 4109 }; 4110 class X::Y { 4111 template <typename T> 4112 friend class F; // The decl context of F is the global namespace. 4113 }; 4114 )", 4115 Lang_CXX03); 4116 auto *ToDecl = FirstDeclMatcher<ClassTemplateDecl>().match( 4117 ToTU, classTemplateDecl(hasName("F"))); 4118 Decl *FromTU = getTuDecl( 4119 R"( 4120 template <typename T> 4121 class F {}; 4122 )", 4123 Lang_CXX03, "input0.cc"); 4124 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match( 4125 FromTU, classTemplateDecl(hasName("F"))); 4126 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03)); 4127 EXPECT_TRUE(ImportedDef->getPreviousDecl()); 4128 EXPECT_EQ(ToDecl, ImportedDef->getPreviousDecl()); 4129 EXPECT_EQ(ToDecl->getTemplatedDecl(), 4130 ImportedDef->getTemplatedDecl()->getPreviousDecl()); 4131 } 4132 4133 TEST_P(ImportFriendClasses, 4134 ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked) { 4135 Decl *FromTU0 = getTuDecl( 4136 R"( 4137 class X { 4138 class Y; 4139 }; 4140 class X::Y { 4141 template <typename T> 4142 friend class F; // The decl context of F is the global namespace. 4143 }; 4144 )", 4145 Lang_CXX03, "input0.cc"); 4146 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match( 4147 FromTU0, classTemplateDecl(hasName("F"))); 4148 auto *ImportedFwd = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03)); 4149 Decl *FromTU1 = getTuDecl( 4150 R"( 4151 template <typename T> 4152 class F {}; 4153 )", 4154 Lang_CXX03, "input1.cc"); 4155 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match( 4156 FromTU1, classTemplateDecl(hasName("F"))); 4157 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03)); 4158 EXPECT_TRUE(ImportedDef->getPreviousDecl()); 4159 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl()); 4160 EXPECT_EQ(ImportedFwd->getTemplatedDecl(), 4161 ImportedDef->getTemplatedDecl()->getPreviousDecl()); 4162 } 4163 4164 TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) { 4165 Decl *FromTU0 = getTuDecl( 4166 R"( 4167 class X { 4168 class Y; 4169 }; 4170 class X::Y { 4171 friend class F; // The decl context of F is the global namespace. 4172 }; 4173 )", 4174 Lang_CXX03, "input0.cc"); 4175 auto *Friend = FirstDeclMatcher<FriendDecl>().match(FromTU0, friendDecl()); 4176 QualType FT = Friend->getFriendType()->getType(); 4177 FT = FromTU0->getASTContext().getCanonicalType(FT); 4178 auto *Fwd = cast<TagType>(FT)->getDecl(); 4179 auto *ImportedFwd = Import(Fwd, Lang_CXX03); 4180 Decl *FromTU1 = getTuDecl( 4181 R"( 4182 class F {}; 4183 )", 4184 Lang_CXX03, "input1.cc"); 4185 auto *Definition = FirstDeclMatcher<CXXRecordDecl>().match( 4186 FromTU1, cxxRecordDecl(hasName("F"))); 4187 auto *ImportedDef = Import(Definition, Lang_CXX03); 4188 EXPECT_TRUE(ImportedDef->getPreviousDecl()); 4189 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl()); 4190 } 4191 4192 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendType) { 4193 const char *Code = 4194 R"( 4195 class Container { 4196 friend class X; 4197 friend class X; 4198 }; 4199 )"; 4200 Decl *ToTu = getToTuDecl(Code, Lang_CXX03); 4201 Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc"); 4202 4203 auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4204 auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4205 auto *FromFriend1 = 4206 FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4207 auto *FromFriend2 = LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4208 4209 FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03); 4210 FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03); 4211 4212 EXPECT_NE(ToImportedFriend1, ToImportedFriend2); 4213 EXPECT_EQ(ToFriend1, ToImportedFriend1); 4214 EXPECT_EQ(ToFriend2, ToImportedFriend2); 4215 } 4216 4217 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendDecl) { 4218 const char *Code = 4219 R"( 4220 class Container { 4221 friend void f(); 4222 friend void f(); 4223 }; 4224 )"; 4225 Decl *ToTu = getToTuDecl(Code, Lang_CXX03); 4226 Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc"); 4227 4228 auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4229 auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4230 auto *FromFriend1 = 4231 FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4232 auto *FromFriend2 = LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4233 4234 FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03); 4235 FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03); 4236 4237 EXPECT_NE(ToImportedFriend1, ToImportedFriend2); 4238 EXPECT_EQ(ToFriend1, ToImportedFriend1); 4239 EXPECT_EQ(ToFriend2, ToImportedFriend2); 4240 } 4241 4242 TEST_P(ASTImporterOptionSpecificTestBase, FriendFunInClassTemplate) { 4243 auto *Code = R"( 4244 template <class T> 4245 struct X { 4246 friend void foo(){} 4247 }; 4248 )"; 4249 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 4250 auto *ToFoo = FirstDeclMatcher<FunctionDecl>().match( 4251 ToTU, functionDecl(hasName("foo"))); 4252 4253 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc"); 4254 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match( 4255 FromTU, functionDecl(hasName("foo"))); 4256 auto *ImportedFoo = Import(FromFoo, Lang_CXX03); 4257 EXPECT_EQ(ImportedFoo, ToFoo); 4258 } 4259 4260 struct DeclContextTest : ASTImporterOptionSpecificTestBase {}; 4261 4262 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) { 4263 Decl *TU = getTuDecl( 4264 R"( 4265 namespace NS { 4266 4267 template <typename T> 4268 struct S {}; 4269 template struct S<int>; 4270 4271 inline namespace INS { 4272 template <typename T> 4273 struct S {}; 4274 template struct S<int>; 4275 } 4276 4277 } 4278 )", Lang_CXX11, "input0.cc"); 4279 auto *NS = FirstDeclMatcher<NamespaceDecl>().match( 4280 TU, namespaceDecl()); 4281 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4282 TU, classTemplateSpecializationDecl()); 4283 ASSERT_TRUE(NS->containsDecl(Spec)); 4284 4285 NS->removeDecl(Spec); 4286 EXPECT_FALSE(NS->containsDecl(Spec)); 4287 } 4288 4289 TEST_P(DeclContextTest, 4290 removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage) { 4291 Decl *TU = getTuDecl("extern int A; int A;", Lang_CXX03); 4292 auto *A0 = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A"))); 4293 auto *A1 = LastDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A"))); 4294 4295 // Investigate the list. 4296 auto *DC = A0->getDeclContext(); 4297 ASSERT_TRUE(DC->containsDecl(A0)); 4298 ASSERT_TRUE(DC->containsDecl(A1)); 4299 4300 // Investigate the lookup table. 4301 auto *Map = DC->getLookupPtr(); 4302 ASSERT_TRUE(Map); 4303 auto I = Map->find(A0->getDeclName()); 4304 ASSERT_NE(I, Map->end()); 4305 StoredDeclsList &L = I->second; 4306 // The lookup table contains the most recent decl of A. 4307 ASSERT_NE(L.getAsDecl(), A0); 4308 ASSERT_EQ(L.getAsDecl(), A1); 4309 4310 ASSERT_TRUE(L.getAsDecl()); 4311 // Simulate the private function DeclContext::reconcileExternalVisibleStorage. 4312 // We do not have a list with one element. 4313 L.setHasExternalDecls(); 4314 ASSERT_FALSE(L.getAsList()); 4315 auto Results = L.getLookupResult(); 4316 ASSERT_EQ(1u, std::distance(Results.begin(), Results.end())); 4317 4318 // This asserts in the old implementation. 4319 DC->removeDecl(A0); 4320 EXPECT_FALSE(DC->containsDecl(A0)); 4321 4322 // Make sure we do not leave a StoredDeclsList with no entries. 4323 DC->removeDecl(A1); 4324 ASSERT_EQ(Map->find(A1->getDeclName()), Map->end()); 4325 } 4326 4327 struct ImportFunctionTemplateSpecializations 4328 : ASTImporterOptionSpecificTestBase {}; 4329 4330 TEST_P(ImportFunctionTemplateSpecializations, 4331 TUshouldNotContainFunctionTemplateImplicitInstantiation) { 4332 4333 Decl *FromTU = getTuDecl( 4334 R"( 4335 template<class T> 4336 int f() { return 0; } 4337 void foo() { f<int>(); } 4338 )", 4339 Lang_CXX03, "input0.cc"); 4340 4341 // Check that the function template instantiation is NOT the child of the TU. 4342 auto Pattern = translationUnitDecl( 4343 unless(has(functionDecl(hasName("f"), isTemplateInstantiation())))); 4344 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern)); 4345 4346 auto *Foo = FirstDeclMatcher<FunctionDecl>().match( 4347 FromTU, functionDecl(hasName("foo"))); 4348 ASSERT_TRUE(Import(Foo, Lang_CXX03)); 4349 4350 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4351 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern)); 4352 } 4353 4354 TEST_P(ImportFunctionTemplateSpecializations, 4355 TUshouldNotContainFunctionTemplateExplicitInstantiation) { 4356 4357 Decl *FromTU = getTuDecl( 4358 R"( 4359 template<class T> 4360 int f() { return 0; } 4361 template int f<int>(); 4362 )", 4363 Lang_CXX03, "input0.cc"); 4364 4365 // Check that the function template instantiation is NOT the child of the TU. 4366 auto Instantiation = functionDecl(hasName("f"), isTemplateInstantiation()); 4367 auto Pattern = translationUnitDecl(unless(has(Instantiation))); 4368 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern)); 4369 4370 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Instantiation), 4371 Lang_CXX03)); 4372 4373 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4374 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern)); 4375 } 4376 4377 TEST_P(ImportFunctionTemplateSpecializations, 4378 TUshouldContainFunctionTemplateSpecialization) { 4379 4380 Decl *FromTU = getTuDecl( 4381 R"( 4382 template<class T> 4383 int f() { return 0; } 4384 template <> int f<int>() { return 4; } 4385 )", 4386 Lang_CXX03, "input0.cc"); 4387 4388 // Check that the function template specialization is the child of the TU. 4389 auto Specialization = 4390 functionDecl(hasName("f"), isExplicitTemplateSpecialization()); 4391 auto Pattern = translationUnitDecl(has(Specialization)); 4392 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern)); 4393 4394 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Specialization), 4395 Lang_CXX03)); 4396 4397 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4398 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern)); 4399 } 4400 4401 TEST_P(ImportFunctionTemplateSpecializations, 4402 FunctionTemplateSpecializationRedeclChain) { 4403 4404 Decl *FromTU = getTuDecl( 4405 R"( 4406 template<class T> 4407 int f() { return 0; } 4408 template <> int f<int>() { return 4; } 4409 )", 4410 Lang_CXX03, "input0.cc"); 4411 4412 auto Spec = functionDecl(hasName("f"), isExplicitTemplateSpecialization(), 4413 hasParent(translationUnitDecl())); 4414 auto *FromSpecD = FirstDeclMatcher<Decl>().match(FromTU, Spec); 4415 { 4416 auto *TU = FromTU; 4417 auto *SpecD = FromSpecD; 4418 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match( 4419 TU, functionTemplateDecl()); 4420 auto *FirstSpecD = *(TemplateD->spec_begin()); 4421 ASSERT_EQ(SpecD, FirstSpecD); 4422 ASSERT_TRUE(SpecD->getPreviousDecl()); 4423 ASSERT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl()) 4424 ->doesThisDeclarationHaveABody()); 4425 } 4426 4427 ASSERT_TRUE(Import(FromSpecD, Lang_CXX03)); 4428 4429 { 4430 auto *TU = ToAST->getASTContext().getTranslationUnitDecl(); 4431 auto *SpecD = FirstDeclMatcher<Decl>().match(TU, Spec); 4432 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match( 4433 TU, functionTemplateDecl()); 4434 auto *FirstSpecD = *(TemplateD->spec_begin()); 4435 EXPECT_EQ(SpecD, FirstSpecD); 4436 ASSERT_TRUE(SpecD->getPreviousDecl()); 4437 EXPECT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl()) 4438 ->doesThisDeclarationHaveABody()); 4439 } 4440 } 4441 4442 TEST_P(ImportFunctionTemplateSpecializations, 4443 MatchNumberOfFunctionTemplateSpecializations) { 4444 4445 Decl *FromTU = getTuDecl( 4446 R"( 4447 template <typename T> constexpr int f() { return 0; } 4448 template <> constexpr int f<int>() { return 4; } 4449 void foo() { 4450 static_assert(f<char>() == 0, ""); 4451 static_assert(f<int>() == 4, ""); 4452 } 4453 )", 4454 Lang_CXX11, "input0.cc"); 4455 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 4456 FromTU, functionDecl(hasName("foo"))); 4457 4458 Import(FromD, Lang_CXX11); 4459 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4460 EXPECT_EQ( 4461 DeclCounter<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))), 4462 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f")))); 4463 } 4464 4465 TEST_P(ASTImporterOptionSpecificTestBase, 4466 ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) { 4467 { 4468 Decl *FromTU = getTuDecl( 4469 R"( 4470 template <typename T> 4471 struct B; 4472 )", 4473 Lang_CXX03, "input0.cc"); 4474 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 4475 FromTU, classTemplateDecl(hasName("B"))); 4476 4477 Import(FromD, Lang_CXX03); 4478 } 4479 4480 { 4481 Decl *FromTU = getTuDecl( 4482 R"( 4483 template <typename T> 4484 struct B { 4485 void f(); 4486 B* b; 4487 }; 4488 )", 4489 Lang_CXX03, "input1.cc"); 4490 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match( 4491 FromTU, functionDecl(hasName("f"))); 4492 Import(FromD, Lang_CXX03); 4493 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match( 4494 FromTU, classTemplateDecl(hasName("B"))); 4495 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03)); 4496 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition()); 4497 4498 // We expect no (ODR) warning during the import. 4499 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4500 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 4501 } 4502 } 4503 4504 TEST_P(ASTImporterOptionSpecificTestBase, 4505 ImportingTypedefShouldImportTheCompleteType) { 4506 // We already have an incomplete underlying type in the "To" context. 4507 auto Code = 4508 R"( 4509 template <typename T> 4510 struct S { 4511 void foo(); 4512 }; 4513 using U = S<int>; 4514 )"; 4515 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 4516 auto *ToD = FirstDeclMatcher<TypedefNameDecl>().match(ToTU, 4517 typedefNameDecl(hasName("U"))); 4518 ASSERT_TRUE(ToD->getUnderlyingType()->isIncompleteType()); 4519 4520 // The "From" context has the same typedef, but the underlying type is 4521 // complete this time. 4522 Decl *FromTU = getTuDecl(std::string(Code) + 4523 R"( 4524 void foo(U* u) { 4525 u->foo(); 4526 } 4527 )", Lang_CXX11); 4528 auto *FromD = FirstDeclMatcher<TypedefNameDecl>().match(FromTU, 4529 typedefNameDecl(hasName("U"))); 4530 ASSERT_FALSE(FromD->getUnderlyingType()->isIncompleteType()); 4531 4532 // The imported type should be complete. 4533 auto *ImportedD = cast<TypedefNameDecl>(Import(FromD, Lang_CXX11)); 4534 EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType()); 4535 } 4536 4537 TEST_P(ASTImporterOptionSpecificTestBase, ImportTemplateParameterLists) { 4538 auto Code = 4539 R"( 4540 template<class T> 4541 int f() { return 0; } 4542 template <> int f<int>() { return 4; } 4543 )"; 4544 4545 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 4546 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, 4547 functionDecl(hasName("f"), isExplicitTemplateSpecialization())); 4548 ASSERT_EQ(FromD->getNumTemplateParameterLists(), 1u); 4549 4550 auto *ToD = Import(FromD, Lang_CXX03); 4551 // The template parameter list should exist. 4552 EXPECT_EQ(ToD->getNumTemplateParameterLists(), 1u); 4553 } 4554 4555 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl> 4556 varTemplateDecl; 4557 4558 const internal::VariadicDynCastAllOfMatcher< 4559 Decl, VarTemplatePartialSpecializationDecl> 4560 varTemplatePartialSpecializationDecl; 4561 4562 TEST_P(ASTImporterOptionSpecificTestBase, 4563 FunctionTemplateParameterDeclContext) { 4564 constexpr auto Code = 4565 R"( 4566 template<class T> 4567 void f() {}; 4568 )"; 4569 4570 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 4571 4572 auto *FromD = FirstDeclMatcher<FunctionTemplateDecl>().match( 4573 FromTU, functionTemplateDecl(hasName("f"))); 4574 4575 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(), 4576 FromD->getTemplatedDecl()); 4577 4578 auto *ToD = Import(FromD, Lang_CXX11); 4579 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(), 4580 ToD->getTemplatedDecl()); 4581 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 4582 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0))); 4583 } 4584 4585 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateParameterDeclContext) { 4586 constexpr auto Code = 4587 R"( 4588 template<class T1, class T2> 4589 struct S {}; 4590 template<class T2> 4591 struct S<int, T2> {}; 4592 )"; 4593 4594 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 4595 4596 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 4597 FromTU, classTemplateDecl(hasName("S"))); 4598 auto *FromDPart = 4599 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match( 4600 FromTU, classTemplatePartialSpecializationDecl(hasName("S"))); 4601 4602 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(), 4603 FromD->getTemplatedDecl()); 4604 ASSERT_EQ(FromDPart->getTemplateParameters()->getParam(0)->getDeclContext(), 4605 FromDPart); 4606 4607 auto *ToD = Import(FromD, Lang_CXX11); 4608 auto *ToDPart = Import(FromDPart, Lang_CXX11); 4609 4610 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(), 4611 ToD->getTemplatedDecl()); 4612 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 4613 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0))); 4614 4615 EXPECT_EQ(ToDPart->getTemplateParameters()->getParam(0)->getDeclContext(), 4616 ToDPart); 4617 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 4618 ToDPart, ToDPart->getTemplateParameters()->getParam(0))); 4619 } 4620 4621 TEST_P(ASTImporterOptionSpecificTestBase, 4622 CXXDeductionGuideTemplateParameterDeclContext) { 4623 Decl *FromTU = getTuDecl( 4624 R"( 4625 template <typename T> struct A { 4626 A(T); 4627 }; 4628 A a{(int)0}; 4629 )", 4630 Lang_CXX17, "input.cc"); 4631 // clang-format off 4632 /* 4633 |-ClassTemplateDecl 0x1fe5000 <input.cc:2:7, line:4:7> line:2:36 A 4634 | |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T 4635 | |-CXXRecordDecl 0x1fe4f70 <col:29, line:4:7> line:2:36 struct A definition 4636 4637 |-FunctionTemplateDecl 0x1fe5860 <line:2:7, line:3:12> col:9 implicit <deduction guide for A> 4638 | |-TemplateTypeParmDecl 0x1fe4eb0 <line:2:17, col:26> col:26 referenced typename depth 0 index 0 T 4639 | |-CXXDeductionGuideDecl 0x1fe57a8 <line:3:9, col:12> col:9 implicit <deduction guide for A> 'auto (T) -> A<T>' 4640 | | `-ParmVarDecl 0x1fe56b0 <col:11> col:12 'T' 4641 | `-CXXDeductionGuideDecl 0x20515d8 <col:9, col:12> col:9 implicit used <deduction guide for A> 'auto (int) -> A<int>' 4642 | |-TemplateArgument type 'int' 4643 | | `-BuiltinType 0x20587e0 'int' 4644 | `-ParmVarDecl 0x2051388 <col:11> col:12 'int':'int' 4645 `-FunctionTemplateDecl 0x1fe5a78 <line:2:7, col:36> col:36 implicit <deduction guide for A> 4646 |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T 4647 `-CXXDeductionGuideDecl 0x1fe59c0 <col:36> col:36 implicit <deduction guide for A> 'auto (A<T>) -> A<T>' 4648 `-ParmVarDecl 0x1fe5958 <col:36> col:36 'A<T>' 4649 */ 4650 // clang-format on 4651 auto *FromD1 = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 4652 FromTU, cxxDeductionGuideDecl()); 4653 auto *FromD2 = LastDeclMatcher<CXXDeductionGuideDecl>().match( 4654 FromTU, cxxDeductionGuideDecl()); 4655 4656 NamedDecl *P1 = 4657 FromD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam( 4658 0); 4659 NamedDecl *P2 = 4660 FromD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam( 4661 0); 4662 DeclContext *DC = P1->getDeclContext(); 4663 4664 ASSERT_EQ(P1, P2); 4665 ASSERT_TRUE(DC == FromD1 || DC == FromD2); 4666 4667 auto *ToD1 = Import(FromD1, Lang_CXX17); 4668 auto *ToD2 = Import(FromD2, Lang_CXX17); 4669 ASSERT_TRUE(ToD1 && ToD2); 4670 4671 P1 = ToD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam( 4672 0); 4673 P2 = ToD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam( 4674 0); 4675 DC = P1->getDeclContext(); 4676 4677 EXPECT_EQ(P1, P2); 4678 EXPECT_TRUE(DC == ToD1 || DC == ToD2); 4679 4680 ASTImporterLookupTable *Tbl = SharedStatePtr->getLookupTable(); 4681 if (Tbl->contains(ToD1, P1)) { 4682 EXPECT_FALSE(Tbl->contains(ToD2, P1)); 4683 } else { 4684 EXPECT_TRUE(Tbl->contains(ToD2, P1)); 4685 } 4686 } 4687 4688 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) { 4689 constexpr auto Code = 4690 R"( 4691 template<class T1, class T2> 4692 int X1; 4693 template<class T2> 4694 int X1<int, T2>; 4695 4696 namespace Ns { 4697 template<class T1, class T2> 4698 int X2; 4699 template<class T2> 4700 int X2<int, T2>; 4701 } 4702 )"; 4703 4704 Decl *FromTU = getTuDecl(Code, Lang_CXX14); 4705 4706 auto *FromD1 = FirstDeclMatcher<VarTemplateDecl>().match( 4707 FromTU, varTemplateDecl(hasName("X1"))); 4708 auto *FromD1Part = 4709 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match( 4710 FromTU, varTemplatePartialSpecializationDecl(hasName("X1"))); 4711 auto *FromD2 = FirstDeclMatcher<VarTemplateDecl>().match( 4712 FromTU, varTemplateDecl(hasName("X2"))); 4713 auto *FromD2Part = 4714 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match( 4715 FromTU, varTemplatePartialSpecializationDecl(hasName("X2"))); 4716 4717 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(), 4718 FromD1->getDeclContext()); 4719 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(), 4720 FromD2->getDeclContext()); 4721 4722 ASSERT_EQ(FromD1Part->getTemplateParameters()->getParam(0)->getDeclContext(), 4723 FromD1Part->getDeclContext()); 4724 // FIXME: VarTemplatePartialSpecializationDecl does not update ("adopt") 4725 // template parameter decl context 4726 // ASSERT_EQ(FromD2Part->getTemplateParameters()->getParam(0)->getDeclContext(), 4727 // FromD2Part->getDeclContext()); 4728 4729 auto *ToD1 = Import(FromD1, Lang_CXX14); 4730 auto *ToD2 = Import(FromD2, Lang_CXX14); 4731 4732 auto *ToD1Part = Import(FromD1Part, Lang_CXX14); 4733 auto *ToD2Part = Import(FromD2Part, Lang_CXX14); 4734 4735 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(), 4736 ToD1->getDeclContext()); 4737 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 4738 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0))); 4739 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(), 4740 ToD2->getDeclContext()); 4741 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 4742 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0))); 4743 4744 EXPECT_EQ(ToD1Part->getTemplateParameters()->getParam(0)->getDeclContext(), 4745 ToD1Part->getDeclContext()); 4746 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 4747 ToD1Part->getDeclContext(), 4748 ToD1Part->getTemplateParameters()->getParam(0))); 4749 // EXPECT_EQ(ToD2Part->getTemplateParameters()->getParam(0)->getDeclContext(), 4750 // ToD2Part->getDeclContext()); 4751 // EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 4752 // ToD2Part->getDeclContext(), 4753 // ToD2Part->getTemplateParameters()->getParam(0))); 4754 (void)ToD2Part; 4755 } 4756 4757 TEST_P(ASTImporterOptionSpecificTestBase, 4758 TypeAliasTemplateParameterDeclContext) { 4759 constexpr auto Code = 4760 R"( 4761 template<class T1, class T2> 4762 struct S {}; 4763 template<class T> using S1 = S<T, int>; 4764 namespace Ns { 4765 template<class T> using S2 = S<T, int>; 4766 } 4767 )"; 4768 4769 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 4770 4771 auto *FromD1 = FirstDeclMatcher<TypeAliasTemplateDecl>().match( 4772 FromTU, typeAliasTemplateDecl(hasName("S1"))); 4773 auto *FromD2 = FirstDeclMatcher<TypeAliasTemplateDecl>().match( 4774 FromTU, typeAliasTemplateDecl(hasName("S2"))); 4775 4776 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(), 4777 FromD1->getDeclContext()); 4778 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(), 4779 FromD2->getDeclContext()); 4780 4781 auto *ToD1 = Import(FromD1, Lang_CXX11); 4782 auto *ToD2 = Import(FromD2, Lang_CXX11); 4783 4784 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(), 4785 ToD1->getDeclContext()); 4786 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 4787 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0))); 4788 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(), 4789 ToD2->getDeclContext()); 4790 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 4791 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0))); 4792 } 4793 4794 const AstTypeMatcher<SubstTemplateTypeParmPackType> 4795 substTemplateTypeParmPackType; 4796 4797 TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmPackType) { 4798 constexpr auto Code = R"( 4799 template<typename ...T> struct D { 4800 template<typename... U> using B = int(int (*...p)(T, U)); 4801 template<typename U1, typename U2> D(B<U1, U2>*); 4802 }; 4803 int f(int(int, int), int(int, int)); 4804 4805 using asd = D<float, double, float>::B<int, long, int>; 4806 )"; 4807 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp"); 4808 auto *FromClass = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4809 FromTU, classTemplateSpecializationDecl()); 4810 4811 { 4812 ASTContext &FromCtx = FromTU->getASTContext(); 4813 const auto *FromSubstPack = selectFirst<SubstTemplateTypeParmPackType>( 4814 "pack", match(substTemplateTypeParmPackType().bind("pack"), FromCtx)); 4815 4816 ASSERT_TRUE(FromSubstPack); 4817 ASSERT_EQ(FromSubstPack->getIdentifier()->getName(), "T"); 4818 ArrayRef<TemplateArgument> FromArgPack = 4819 FromSubstPack->getArgumentPack().pack_elements(); 4820 ASSERT_EQ(FromArgPack.size(), 3u); 4821 ASSERT_EQ(FromArgPack[0].getAsType(), FromCtx.FloatTy); 4822 ASSERT_EQ(FromArgPack[1].getAsType(), FromCtx.DoubleTy); 4823 ASSERT_EQ(FromArgPack[2].getAsType(), FromCtx.FloatTy); 4824 } 4825 { 4826 // Let's do the import. 4827 ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11); 4828 ASTContext &ToCtx = ToClass->getASTContext(); 4829 4830 const auto *ToSubstPack = selectFirst<SubstTemplateTypeParmPackType>( 4831 "pack", match(substTemplateTypeParmPackType().bind("pack"), ToCtx)); 4832 4833 // Check if it meets the requirements. 4834 ASSERT_TRUE(ToSubstPack); 4835 ASSERT_EQ(ToSubstPack->getIdentifier()->getName(), "T"); 4836 ArrayRef<TemplateArgument> ToArgPack = 4837 ToSubstPack->getArgumentPack().pack_elements(); 4838 ASSERT_EQ(ToArgPack.size(), 3u); 4839 ASSERT_EQ(ToArgPack[0].getAsType(), ToCtx.FloatTy); 4840 ASSERT_EQ(ToArgPack[1].getAsType(), ToCtx.DoubleTy); 4841 ASSERT_EQ(ToArgPack[2].getAsType(), ToCtx.FloatTy); 4842 } 4843 } 4844 4845 struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {}; 4846 4847 TEST_P(ASTImporterLookupTableTest, OneDecl) { 4848 auto *ToTU = getToTuDecl("int a;", Lang_CXX03); 4849 auto *D = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("a"))); 4850 ASTImporterLookupTable LT(*ToTU); 4851 auto Res = LT.lookup(ToTU, D->getDeclName()); 4852 ASSERT_EQ(Res.size(), 1u); 4853 EXPECT_EQ(*Res.begin(), D); 4854 } 4855 4856 static Decl *findInDeclListOfDC(DeclContext *DC, DeclarationName Name) { 4857 for (Decl *D : DC->decls()) { 4858 if (auto *ND = dyn_cast<NamedDecl>(D)) 4859 if (ND->getDeclName() == Name) 4860 return ND; 4861 } 4862 return nullptr; 4863 } 4864 4865 TEST_P(ASTImporterLookupTableTest, 4866 FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup) { 4867 auto *Code = R"( 4868 template <class T> 4869 struct X { 4870 friend void foo(){} 4871 }; 4872 )"; 4873 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 4874 auto *X = FirstDeclMatcher<ClassTemplateDecl>().match( 4875 ToTU, classTemplateDecl(hasName("X"))); 4876 auto *Foo = FirstDeclMatcher<FunctionDecl>().match( 4877 ToTU, functionDecl(hasName("foo"))); 4878 DeclContext *FooDC = Foo->getDeclContext(); 4879 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext(); 4880 ASSERT_EQ(cast<Decl>(FooLexicalDC), X->getTemplatedDecl()); 4881 ASSERT_EQ(cast<Decl>(FooDC), ToTU); 4882 DeclarationName FooName = Foo->getDeclName(); 4883 4884 // Cannot find in the LookupTable of its DC (TUDecl) 4885 SmallVector<NamedDecl *, 2> FoundDecls; 4886 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 4887 EXPECT_EQ(FoundDecls.size(), 0u); 4888 4889 // Cannot find in the LookupTable of its LexicalDC (X) 4890 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 4891 EXPECT_EQ(FoundDecls.size(), 0u); 4892 4893 // Can't find in the list of Decls of the DC. 4894 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr); 4895 4896 // Can't find in the list of Decls of the LexicalDC 4897 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), nullptr); 4898 4899 // ASTImporter specific lookup finds it. 4900 ASTImporterLookupTable LT(*ToTU); 4901 auto Res = LT.lookup(FooDC, Foo->getDeclName()); 4902 ASSERT_EQ(Res.size(), 1u); 4903 EXPECT_EQ(*Res.begin(), Foo); 4904 } 4905 4906 TEST_P(ASTImporterLookupTableTest, 4907 FwdDeclStructShouldBeFoundByImporterSpecificLookup) { 4908 TranslationUnitDecl *ToTU = 4909 getToTuDecl("struct A { struct Foo *p; };", Lang_C99); 4910 auto *Foo = 4911 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("Foo"))); 4912 auto *A = 4913 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A"))); 4914 DeclContext *FooDC = Foo->getDeclContext(); 4915 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext(); 4916 ASSERT_EQ(cast<Decl>(FooLexicalDC), A); 4917 ASSERT_EQ(cast<Decl>(FooDC), ToTU); 4918 DeclarationName FooName = Foo->getDeclName(); 4919 4920 // Cannot find in the LookupTable of its DC (TUDecl). 4921 SmallVector<NamedDecl *, 2> FoundDecls; 4922 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 4923 EXPECT_EQ(FoundDecls.size(), 0u); 4924 4925 // Cannot find in the LookupTable of its LexicalDC (A). 4926 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 4927 EXPECT_EQ(FoundDecls.size(), 0u); 4928 4929 // Can't find in the list of Decls of the DC. 4930 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr); 4931 4932 // Can find in the list of Decls of the LexicalDC. 4933 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), Foo); 4934 4935 // ASTImporter specific lookup finds it. 4936 ASTImporterLookupTable LT(*ToTU); 4937 auto Res = LT.lookup(FooDC, Foo->getDeclName()); 4938 ASSERT_EQ(Res.size(), 1u); 4939 EXPECT_EQ(*Res.begin(), Foo); 4940 } 4941 4942 TEST_P(ASTImporterLookupTableTest, LookupFindsNamesInDifferentDC) { 4943 TranslationUnitDecl *ToTU = 4944 getToTuDecl("int V; struct A { int V; }; struct B { int V; };", Lang_C99); 4945 DeclarationName VName = FirstDeclMatcher<VarDecl>() 4946 .match(ToTU, varDecl(hasName("V"))) 4947 ->getDeclName(); 4948 auto *A = 4949 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A"))); 4950 auto *B = 4951 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("B"))); 4952 4953 ASTImporterLookupTable LT(*ToTU); 4954 4955 auto Res = LT.lookup(cast<DeclContext>(A), VName); 4956 ASSERT_EQ(Res.size(), 1u); 4957 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match( 4958 ToTU, fieldDecl(hasName("V"), 4959 hasParent(recordDecl(hasName("A")))))); 4960 Res = LT.lookup(cast<DeclContext>(B), VName); 4961 ASSERT_EQ(Res.size(), 1u); 4962 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match( 4963 ToTU, fieldDecl(hasName("V"), 4964 hasParent(recordDecl(hasName("B")))))); 4965 Res = LT.lookup(ToTU, VName); 4966 ASSERT_EQ(Res.size(), 1u); 4967 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<VarDecl>().match( 4968 ToTU, varDecl(hasName("V"), 4969 hasParent(translationUnitDecl())))); 4970 } 4971 4972 TEST_P(ASTImporterLookupTableTest, LookupFindsOverloadedNames) { 4973 TranslationUnitDecl *ToTU = getToTuDecl( 4974 R"( 4975 void foo(); 4976 void foo(int); 4977 void foo(int, int); 4978 )", 4979 Lang_CXX03); 4980 4981 ASTImporterLookupTable LT(*ToTU); 4982 auto *F0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl()); 4983 auto *F2 = LastDeclMatcher<FunctionDecl>().match(ToTU, functionDecl()); 4984 DeclarationName Name = F0->getDeclName(); 4985 auto Res = LT.lookup(ToTU, Name); 4986 EXPECT_EQ(Res.size(), 3u); 4987 EXPECT_EQ(Res.count(F0), 1u); 4988 EXPECT_EQ(Res.count(F2), 1u); 4989 } 4990 4991 TEST_P(ASTImporterLookupTableTest, 4992 DifferentOperatorsShouldHaveDifferentResultSet) { 4993 TranslationUnitDecl *ToTU = getToTuDecl( 4994 R"( 4995 struct X{}; 4996 void operator+(X, X); 4997 void operator-(X, X); 4998 )", 4999 Lang_CXX03); 5000 5001 ASTImporterLookupTable LT(*ToTU); 5002 auto *FPlus = FirstDeclMatcher<FunctionDecl>().match( 5003 ToTU, functionDecl(hasOverloadedOperatorName("+"))); 5004 auto *FMinus = FirstDeclMatcher<FunctionDecl>().match( 5005 ToTU, functionDecl(hasOverloadedOperatorName("-"))); 5006 DeclarationName NamePlus = FPlus->getDeclName(); 5007 auto ResPlus = LT.lookup(ToTU, NamePlus); 5008 EXPECT_EQ(ResPlus.size(), 1u); 5009 EXPECT_EQ(ResPlus.count(FPlus), 1u); 5010 EXPECT_EQ(ResPlus.count(FMinus), 0u); 5011 DeclarationName NameMinus = FMinus->getDeclName(); 5012 auto ResMinus = LT.lookup(ToTU, NameMinus); 5013 EXPECT_EQ(ResMinus.size(), 1u); 5014 EXPECT_EQ(ResMinus.count(FMinus), 1u); 5015 EXPECT_EQ(ResMinus.count(FPlus), 0u); 5016 EXPECT_NE(*ResMinus.begin(), *ResPlus.begin()); 5017 } 5018 5019 TEST_P(ASTImporterLookupTableTest, LookupDeclNamesFromDifferentTUs) { 5020 TranslationUnitDecl *ToTU = getToTuDecl( 5021 R"( 5022 struct X {}; 5023 void operator+(X, X); 5024 )", 5025 Lang_CXX03); 5026 auto *ToPlus = FirstDeclMatcher<FunctionDecl>().match( 5027 ToTU, functionDecl(hasOverloadedOperatorName("+"))); 5028 5029 Decl *FromTU = getTuDecl( 5030 R"( 5031 struct X {}; 5032 void operator+(X, X); 5033 )", 5034 Lang_CXX03); 5035 auto *FromPlus = FirstDeclMatcher<FunctionDecl>().match( 5036 FromTU, functionDecl(hasOverloadedOperatorName("+"))); 5037 5038 // FromPlus have a different TU, thus its DeclarationName is different too. 5039 ASSERT_NE(ToPlus->getDeclName(), FromPlus->getDeclName()); 5040 5041 ASTImporterLookupTable LT(*ToTU); 5042 auto Res = LT.lookup(ToTU, ToPlus->getDeclName()); 5043 ASSERT_EQ(Res.size(), 1u); 5044 EXPECT_EQ(*Res.begin(), ToPlus); 5045 5046 // FromPlus have a different TU, thus its DeclarationName is different too. 5047 Res = LT.lookup(ToTU, FromPlus->getDeclName()); 5048 ASSERT_EQ(Res.size(), 0u); 5049 } 5050 5051 TEST_P(ASTImporterLookupTableTest, 5052 LookupFindsFwdFriendClassDeclWithElaboratedType) { 5053 TranslationUnitDecl *ToTU = getToTuDecl( 5054 R"( 5055 class Y { friend class F; }; 5056 )", 5057 Lang_CXX03); 5058 5059 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent. 5060 // So we must dig up the underlying CXXRecordDecl. 5061 ASTImporterLookupTable LT(*ToTU); 5062 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 5063 const RecordDecl *RD = getRecordDeclOfFriend(FriendD); 5064 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match( 5065 ToTU, cxxRecordDecl(hasName("Y"))); 5066 5067 DeclarationName Name = RD->getDeclName(); 5068 auto Res = LT.lookup(ToTU, Name); 5069 EXPECT_EQ(Res.size(), 1u); 5070 EXPECT_EQ(*Res.begin(), RD); 5071 5072 Res = LT.lookup(Y, Name); 5073 EXPECT_EQ(Res.size(), 0u); 5074 } 5075 5076 TEST_P(ASTImporterLookupTableTest, 5077 LookupFindsFwdFriendClassDeclWithUnelaboratedType) { 5078 TranslationUnitDecl *ToTU = getToTuDecl( 5079 R"( 5080 class F; 5081 class Y { friend F; }; 5082 )", 5083 Lang_CXX11); 5084 5085 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent. 5086 // So we must dig up the underlying CXXRecordDecl. 5087 ASTImporterLookupTable LT(*ToTU); 5088 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 5089 const RecordDecl *RD = getRecordDeclOfFriend(FriendD); 5090 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, cxxRecordDecl(hasName("Y"))); 5091 5092 DeclarationName Name = RD->getDeclName(); 5093 auto Res = LT.lookup(ToTU, Name); 5094 EXPECT_EQ(Res.size(), 1u); 5095 EXPECT_EQ(*Res.begin(), RD); 5096 5097 Res = LT.lookup(Y, Name); 5098 EXPECT_EQ(Res.size(), 0u); 5099 } 5100 5101 TEST_P(ASTImporterLookupTableTest, 5102 LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert) { 5103 TranslationUnitDecl *ToTU = getToTuDecl( 5104 R"( 5105 class F; 5106 using alias_of_f = F; 5107 class Y { friend alias_of_f; }; 5108 )", 5109 Lang_CXX11); 5110 5111 // ASTImporterLookupTable constructor handles using declarations correctly, 5112 // no assert is expected. 5113 ASTImporterLookupTable LT(*ToTU); 5114 5115 auto *Alias = FirstDeclMatcher<TypeAliasDecl>().match( 5116 ToTU, typeAliasDecl(hasName("alias_of_f"))); 5117 DeclarationName Name = Alias->getDeclName(); 5118 auto Res = LT.lookup(ToTU, Name); 5119 EXPECT_EQ(Res.count(Alias), 1u); 5120 } 5121 5122 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassTemplateDecl) { 5123 TranslationUnitDecl *ToTU = getToTuDecl( 5124 R"( 5125 class Y { template <class T> friend class F; }; 5126 )", 5127 Lang_CXX03); 5128 5129 ASTImporterLookupTable LT(*ToTU); 5130 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match( 5131 ToTU, classTemplateDecl(hasName("F"))); 5132 DeclarationName Name = F->getDeclName(); 5133 auto Res = LT.lookup(ToTU, Name); 5134 EXPECT_EQ(Res.size(), 2u); 5135 EXPECT_EQ(Res.count(F), 1u); 5136 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 5137 } 5138 5139 TEST_P(ASTImporterLookupTableTest, DependentFriendClass) { 5140 TranslationUnitDecl *ToTU = getToTuDecl( 5141 R"( 5142 template <typename T> 5143 class F; 5144 5145 template <typename T> 5146 class Y { 5147 friend class F<T>; 5148 }; 5149 )", 5150 Lang_CXX03); 5151 5152 ASTImporterLookupTable LT(*ToTU); 5153 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match( 5154 ToTU, classTemplateDecl(hasName("F"))); 5155 DeclarationName Name = F->getDeclName(); 5156 auto Res = LT.lookup(ToTU, Name); 5157 EXPECT_EQ(Res.size(), 2u); 5158 EXPECT_EQ(Res.count(F), 1u); 5159 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 5160 } 5161 5162 TEST_P(ASTImporterLookupTableTest, FriendClassTemplateSpecialization) { 5163 TranslationUnitDecl *ToTU = getToTuDecl( 5164 R"( 5165 template <typename T> 5166 class F; 5167 5168 class Y { 5169 friend class F<int>; 5170 }; 5171 )", 5172 Lang_CXX03); 5173 5174 ASTImporterLookupTable LT(*ToTU); 5175 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match( 5176 ToTU, classTemplateDecl(hasName("F"))); 5177 DeclarationName Name = F->getDeclName(); 5178 auto Res = LT.lookup(ToTU, Name); 5179 ASSERT_EQ(Res.size(), 3u); 5180 EXPECT_EQ(Res.count(F), 1u); 5181 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 5182 EXPECT_EQ(Res.count(*F->spec_begin()), 1u); 5183 } 5184 5185 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionDecl) { 5186 TranslationUnitDecl *ToTU = getToTuDecl( 5187 R"( 5188 class Y { friend void F(); }; 5189 )", 5190 Lang_CXX03); 5191 5192 ASTImporterLookupTable LT(*ToTU); 5193 auto *F = 5194 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("F"))); 5195 DeclarationName Name = F->getDeclName(); 5196 auto Res = LT.lookup(ToTU, Name); 5197 EXPECT_EQ(Res.size(), 1u); 5198 EXPECT_EQ(*Res.begin(), F); 5199 } 5200 5201 TEST_P(ASTImporterLookupTableTest, 5202 LookupFindsDeclsInClassTemplateSpecialization) { 5203 TranslationUnitDecl *ToTU = getToTuDecl( 5204 R"( 5205 template <typename T> 5206 struct X { 5207 int F; 5208 }; 5209 void foo() { 5210 X<char> xc; 5211 } 5212 )", 5213 Lang_CXX03); 5214 5215 ASTImporterLookupTable LT(*ToTU); 5216 5217 auto *Template = FirstDeclMatcher<ClassTemplateDecl>().match( 5218 ToTU, classTemplateDecl(hasName("X"))); 5219 auto *FieldInTemplate = FirstDeclMatcher<FieldDecl>().match( 5220 ToTU, 5221 fieldDecl(hasParent(cxxRecordDecl(hasParent(classTemplateDecl()))))); 5222 5223 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 5224 ToTU, classTemplateSpecializationDecl(hasName("X"))); 5225 FieldDecl *FieldInSpec = *Spec->field_begin(); 5226 ASSERT_TRUE(FieldInSpec); 5227 5228 DeclarationName Name = FieldInSpec->getDeclName(); 5229 auto TemplateDC = cast<DeclContext>(Template->getTemplatedDecl()); 5230 5231 SmallVector<NamedDecl *, 2> FoundDecls; 5232 TemplateDC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); 5233 EXPECT_EQ(FoundDecls.size(), 1u); 5234 EXPECT_EQ(FoundDecls[0], FieldInTemplate); 5235 5236 auto Res = LT.lookup(TemplateDC, Name); 5237 ASSERT_EQ(Res.size(), 1u); 5238 EXPECT_EQ(*Res.begin(), FieldInTemplate); 5239 5240 cast<DeclContext>(Spec)->getRedeclContext()->localUncachedLookup(Name, 5241 FoundDecls); 5242 EXPECT_EQ(FoundDecls.size(), 1u); 5243 EXPECT_EQ(FoundDecls[0], FieldInSpec); 5244 5245 Res = LT.lookup(cast<DeclContext>(Spec), Name); 5246 ASSERT_EQ(Res.size(), 1u); 5247 EXPECT_EQ(*Res.begin(), FieldInSpec); 5248 } 5249 5250 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionTemplateDecl) { 5251 TranslationUnitDecl *ToTU = getToTuDecl( 5252 R"( 5253 class Y { template <class T> friend void F(); }; 5254 )", 5255 Lang_CXX03); 5256 5257 ASTImporterLookupTable LT(*ToTU); 5258 auto *F = FirstDeclMatcher<FunctionTemplateDecl>().match( 5259 ToTU, functionTemplateDecl(hasName("F"))); 5260 DeclarationName Name = F->getDeclName(); 5261 auto Res = LT.lookup(ToTU, Name); 5262 EXPECT_EQ(Res.size(), 2u); 5263 EXPECT_EQ(Res.count(F), 1u); 5264 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 5265 } 5266 5267 TEST_P(ASTImporterLookupTableTest, MultipleBefriendingClasses) { 5268 TranslationUnitDecl *ToTU = getToTuDecl( 5269 R"( 5270 struct X; 5271 struct A { 5272 friend struct X; 5273 }; 5274 struct B { 5275 friend struct X; 5276 }; 5277 )", 5278 Lang_CXX03); 5279 5280 ASTImporterLookupTable LT(*ToTU); 5281 auto *X = FirstDeclMatcher<CXXRecordDecl>().match( 5282 ToTU, cxxRecordDecl(hasName("X"))); 5283 auto *FriendD0 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 5284 auto *FriendD1 = LastDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 5285 const RecordDecl *RD0 = getRecordDeclOfFriend(FriendD0); 5286 const RecordDecl *RD1 = getRecordDeclOfFriend(FriendD1); 5287 ASSERT_EQ(RD0, RD1); 5288 ASSERT_EQ(RD1, X); 5289 5290 DeclarationName Name = X->getDeclName(); 5291 auto Res = LT.lookup(ToTU, Name); 5292 EXPECT_EQ(Res.size(), 1u); 5293 EXPECT_EQ(*Res.begin(), X); 5294 } 5295 5296 TEST_P(ASTImporterLookupTableTest, EnumConstantDecl) { 5297 TranslationUnitDecl *ToTU = getToTuDecl( 5298 R"( 5299 enum E { 5300 A, 5301 B 5302 }; 5303 )", 5304 Lang_C99); 5305 5306 ASTImporterLookupTable LT(*ToTU); 5307 auto *E = FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(hasName("E"))); 5308 auto *A = FirstDeclMatcher<EnumConstantDecl>().match( 5309 ToTU, enumConstantDecl(hasName("A"))); 5310 5311 DeclarationName Name = A->getDeclName(); 5312 // Redecl context is the TU. 5313 ASSERT_EQ(E->getRedeclContext(), ToTU); 5314 5315 SmallVector<NamedDecl *, 2> FoundDecls; 5316 // Normal lookup finds in the DC. 5317 E->localUncachedLookup(Name, FoundDecls); 5318 EXPECT_EQ(FoundDecls.size(), 1u); 5319 5320 // Normal lookup finds in the Redecl context. 5321 ToTU->localUncachedLookup(Name, FoundDecls); 5322 EXPECT_EQ(FoundDecls.size(), 1u); 5323 5324 // Import specific lookup finds in the DC. 5325 auto Res = LT.lookup(E, Name); 5326 ASSERT_EQ(Res.size(), 1u); 5327 EXPECT_EQ(*Res.begin(), A); 5328 5329 // Import specific lookup finds in the Redecl context. 5330 Res = LT.lookup(ToTU, Name); 5331 ASSERT_EQ(Res.size(), 1u); 5332 EXPECT_EQ(*Res.begin(), A); 5333 } 5334 5335 TEST_P(ASTImporterLookupTableTest, LookupSearchesInTheWholeRedeclChain) { 5336 TranslationUnitDecl *ToTU = getToTuDecl( 5337 R"( 5338 namespace N { 5339 int A; 5340 } 5341 namespace N { 5342 } 5343 )", 5344 Lang_CXX03); 5345 auto *N1 = 5346 LastDeclMatcher<NamespaceDecl>().match(ToTU, namespaceDecl(hasName("N"))); 5347 auto *A = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("A"))); 5348 DeclarationName Name = A->getDeclName(); 5349 5350 ASTImporterLookupTable LT(*ToTU); 5351 auto Res = LT.lookup(N1, Name); 5352 ASSERT_EQ(Res.size(), 1u); 5353 EXPECT_EQ(*Res.begin(), A); 5354 } 5355 5356 TEST_P(ASTImporterOptionSpecificTestBase, 5357 RedeclChainShouldBeCorrectAmongstNamespaces) { 5358 Decl *FromTU = getTuDecl( 5359 R"( 5360 namespace NS { 5361 struct X; 5362 struct Y { 5363 static const int I = 3; 5364 }; 5365 } 5366 namespace NS { 5367 struct X { // <--- To be imported 5368 void method(int i = Y::I) {} 5369 int f; 5370 }; 5371 } 5372 )", 5373 Lang_CXX03); 5374 auto *FromFwd = FirstDeclMatcher<CXXRecordDecl>().match( 5375 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit()))); 5376 auto *FromDef = LastDeclMatcher<CXXRecordDecl>().match( 5377 FromTU, 5378 cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit()))); 5379 ASSERT_NE(FromFwd, FromDef); 5380 ASSERT_FALSE(FromFwd->isThisDeclarationADefinition()); 5381 ASSERT_TRUE(FromDef->isThisDeclarationADefinition()); 5382 ASSERT_EQ(FromFwd->getCanonicalDecl(), FromDef->getCanonicalDecl()); 5383 5384 auto *ToDef = cast_or_null<CXXRecordDecl>(Import(FromDef, Lang_CXX03)); 5385 auto *ToFwd = cast_or_null<CXXRecordDecl>(Import(FromFwd, Lang_CXX03)); 5386 EXPECT_NE(ToFwd, ToDef); 5387 EXPECT_FALSE(ToFwd->isThisDeclarationADefinition()); 5388 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 5389 EXPECT_EQ(ToFwd->getCanonicalDecl(), ToDef->getCanonicalDecl()); 5390 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 5391 // We expect no (ODR) warning during the import. 5392 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 5393 } 5394 5395 struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {}; 5396 5397 TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) { 5398 Decl *ToTU = getToTuDecl( 5399 R"( 5400 class X { 5401 template <typename T> friend void foo(); 5402 }; 5403 )", 5404 Lang_CXX03); 5405 auto *Friend = FirstDeclMatcher<FunctionTemplateDecl>().match( 5406 ToTU, functionTemplateDecl(hasName("foo"))); 5407 5408 Decl *FromTU = getTuDecl( 5409 R"( 5410 template <typename T> void foo(); 5411 )", 5412 Lang_CXX03); 5413 auto *FromFoo = FirstDeclMatcher<FunctionTemplateDecl>().match( 5414 FromTU, functionTemplateDecl(hasName("foo"))); 5415 auto *Imported = Import(FromFoo, Lang_CXX03); 5416 5417 EXPECT_EQ(Imported->getPreviousDecl(), Friend); 5418 } 5419 5420 struct ASTImporterWithFakeErrors : ASTImporter { 5421 using ASTImporter::ASTImporter; 5422 bool returnWithErrorInTest() override { return true; } 5423 }; 5424 5425 struct ErrorHandlingTest : ASTImporterOptionSpecificTestBase { 5426 ErrorHandlingTest() { 5427 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 5428 ASTContext &FromContext, FileManager &FromFileManager, 5429 bool MinimalImport, 5430 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 5431 return new ASTImporterWithFakeErrors(ToContext, ToFileManager, 5432 FromContext, FromFileManager, 5433 MinimalImport, SharedState); 5434 }; 5435 } 5436 // In this test we purposely report an error (UnsupportedConstruct) when 5437 // importing the below stmt. 5438 static constexpr auto* ErroneousStmt = R"( asm(""); )"; 5439 }; 5440 5441 // Check a case when no new AST node is created in the AST before encountering 5442 // the error. 5443 TEST_P(ErrorHandlingTest, ErrorHappensBeforeCreatingANewNode) { 5444 TranslationUnitDecl *ToTU = getToTuDecl( 5445 R"( 5446 template <typename T> 5447 class X {}; 5448 template <> 5449 class X<int> { int a; }; 5450 )", 5451 Lang_CXX03); 5452 TranslationUnitDecl *FromTU = getTuDecl( 5453 R"( 5454 template <typename T> 5455 class X {}; 5456 template <> 5457 class X<int> { double b; }; 5458 )", 5459 Lang_CXX03); 5460 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 5461 FromTU, classTemplateSpecializationDecl(hasName("X"))); 5462 ClassTemplateSpecializationDecl *ImportedSpec = Import(FromSpec, Lang_CXX03); 5463 EXPECT_FALSE(ImportedSpec); 5464 5465 // The original Decl is kept, no new decl is created. 5466 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match( 5467 ToTU, classTemplateSpecializationDecl(hasName("X"))), 5468 1u); 5469 5470 // But an error is set to the counterpart in the "from" context. 5471 ASTImporter *Importer = findFromTU(FromSpec)->Importer.get(); 5472 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromSpec); 5473 ASSERT_TRUE(OptErr); 5474 EXPECT_EQ(OptErr->Error, ASTImportError::NameConflict); 5475 } 5476 5477 // Check a case when a new AST node is created but not linked to the AST before 5478 // encountering the error. 5479 TEST_P(ErrorHandlingTest, 5480 ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST) { 5481 TranslationUnitDecl *FromTU = getTuDecl( 5482 std::string("void foo() { ") + ErroneousStmt + " }", Lang_CXX03); 5483 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match( 5484 FromTU, functionDecl(hasName("foo"))); 5485 5486 FunctionDecl *ImportedFoo = Import(FromFoo, Lang_CXX03); 5487 EXPECT_FALSE(ImportedFoo); 5488 5489 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 5490 // Created, but not linked. 5491 EXPECT_EQ( 5492 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("foo"))), 5493 0u); 5494 5495 ASTImporter *Importer = findFromTU(FromFoo)->Importer.get(); 5496 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFoo); 5497 ASSERT_TRUE(OptErr); 5498 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5499 } 5500 5501 // Check a case when a new AST node is created and linked to the AST before 5502 // encountering the error. The error is set for the counterpart of the nodes in 5503 // the "from" context. 5504 TEST_P(ErrorHandlingTest, ErrorHappensAfterNodeIsCreatedAndLinked) { 5505 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5506 void f(); 5507 void f() { )") + ErroneousStmt + R"( } 5508 )", 5509 Lang_CXX03); 5510 auto *FromProto = FirstDeclMatcher<FunctionDecl>().match( 5511 FromTU, functionDecl(hasName("f"))); 5512 auto *FromDef = 5513 LastDeclMatcher<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))); 5514 FunctionDecl *ImportedProto = Import(FromProto, Lang_CXX03); 5515 EXPECT_FALSE(ImportedProto); // Could not import. 5516 // However, we created two nodes in the AST. 1) the fwd decl 2) the 5517 // definition. The definition is not added to its DC, but the fwd decl is 5518 // there. 5519 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 5520 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))), 5521 1u); 5522 // Match the fwd decl. 5523 auto *ToProto = 5524 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))); 5525 EXPECT_TRUE(ToProto); 5526 // An error is set to the counterpart in the "from" context both for the fwd 5527 // decl and the definition. 5528 ASTImporter *Importer = findFromTU(FromProto)->Importer.get(); 5529 Optional<ASTImportError> OptErr = 5530 Importer->getImportDeclErrorIfAny(FromProto); 5531 ASSERT_TRUE(OptErr); 5532 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5533 OptErr = Importer->getImportDeclErrorIfAny(FromDef); 5534 ASSERT_TRUE(OptErr); 5535 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5536 } 5537 5538 // An error should be set for a class if we cannot import one member. 5539 TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) { 5540 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5541 class X { 5542 void f() { )") + ErroneousStmt + R"( } // This member has the error 5543 // during import. 5544 void ok(); // The error should not prevent importing this. 5545 }; // An error will be set for X too. 5546 )", 5547 Lang_CXX03); 5548 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5549 FromTU, cxxRecordDecl(hasName("X"))); 5550 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 5551 5552 // An error is set for X. 5553 EXPECT_FALSE(ImportedX); 5554 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5555 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5556 ASSERT_TRUE(OptErr); 5557 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5558 5559 // An error is set for f(). 5560 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match( 5561 FromTU, cxxMethodDecl(hasName("f"))); 5562 OptErr = Importer->getImportDeclErrorIfAny(FromF); 5563 ASSERT_TRUE(OptErr); 5564 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5565 // And any subsequent import should fail. 5566 CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX03); 5567 EXPECT_FALSE(ImportedF); 5568 5569 // There is an error set for the other member too. 5570 auto *FromOK = FirstDeclMatcher<CXXMethodDecl>().match( 5571 FromTU, cxxMethodDecl(hasName("ok"))); 5572 OptErr = Importer->getImportDeclErrorIfAny(FromOK); 5573 EXPECT_TRUE(OptErr); 5574 // Cannot import the other member. 5575 CXXMethodDecl *ImportedOK = Import(FromOK, Lang_CXX03); 5576 EXPECT_FALSE(ImportedOK); 5577 } 5578 5579 // Check that an error propagates to the dependent AST nodes. 5580 // In the below code it means that an error in X should propagate to A. 5581 // And even to F since the containing A is erroneous. 5582 // And to all AST nodes which we visit during the import process which finally 5583 // ends up in a failure (in the error() function). 5584 TEST_P(ErrorHandlingTest, ErrorPropagatesThroughImportCycles) { 5585 Decl *FromTU = getTuDecl(std::string(R"( 5586 namespace NS { 5587 class A { 5588 template <int I> class F {}; 5589 class X { 5590 template <int I> friend class F; 5591 void error() { )") + 5592 ErroneousStmt + R"( } 5593 }; 5594 }; 5595 5596 class B {}; 5597 } // NS 5598 )", 5599 Lang_CXX03, "input0.cc"); 5600 5601 auto *FromFRD = FirstDeclMatcher<CXXRecordDecl>().match( 5602 FromTU, cxxRecordDecl(hasName("F"), isDefinition())); 5603 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 5604 FromTU, cxxRecordDecl(hasName("A"), isDefinition())); 5605 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match( 5606 FromTU, cxxRecordDecl(hasName("B"), isDefinition())); 5607 auto *FromNS = FirstDeclMatcher<NamespaceDecl>().match( 5608 FromTU, namespaceDecl(hasName("NS"))); 5609 5610 // Start by importing the templated CXXRecordDecl of F. 5611 // Import fails for that. 5612 EXPECT_FALSE(Import(FromFRD, Lang_CXX03)); 5613 // Import fails for A. 5614 EXPECT_FALSE(Import(FromA, Lang_CXX03)); 5615 // But we should be able to import the independent B. 5616 EXPECT_TRUE(Import(FromB, Lang_CXX03)); 5617 // And the namespace. 5618 EXPECT_TRUE(Import(FromNS, Lang_CXX03)); 5619 5620 // An error is set to the templated CXXRecordDecl of F. 5621 ASTImporter *Importer = findFromTU(FromFRD)->Importer.get(); 5622 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFRD); 5623 EXPECT_TRUE(OptErr); 5624 5625 // An error is set to A. 5626 OptErr = Importer->getImportDeclErrorIfAny(FromA); 5627 EXPECT_TRUE(OptErr); 5628 5629 // There is no error set to B. 5630 OptErr = Importer->getImportDeclErrorIfAny(FromB); 5631 EXPECT_FALSE(OptErr); 5632 5633 // There is no error set to NS. 5634 OptErr = Importer->getImportDeclErrorIfAny(FromNS); 5635 EXPECT_FALSE(OptErr); 5636 5637 // Check some of those decls whose ancestor is X, they all should have an 5638 // error set if we visited them during an import process which finally failed. 5639 // These decls are part of a cycle in an ImportPath. 5640 // There would not be any error set for these decls if we hadn't follow the 5641 // ImportPaths and the cycles. 5642 OptErr = Importer->getImportDeclErrorIfAny( 5643 FirstDeclMatcher<ClassTemplateDecl>().match( 5644 FromTU, classTemplateDecl(hasName("F")))); 5645 // An error is set to the 'F' ClassTemplateDecl. 5646 EXPECT_TRUE(OptErr); 5647 // An error is set to the FriendDecl. 5648 OptErr = Importer->getImportDeclErrorIfAny( 5649 FirstDeclMatcher<FriendDecl>().match( 5650 FromTU, friendDecl())); 5651 EXPECT_TRUE(OptErr); 5652 // An error is set to the implicit class of A. 5653 OptErr = 5654 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match( 5655 FromTU, cxxRecordDecl(hasName("A"), isImplicit()))); 5656 EXPECT_TRUE(OptErr); 5657 // An error is set to the implicit class of X. 5658 OptErr = 5659 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match( 5660 FromTU, cxxRecordDecl(hasName("X"), isImplicit()))); 5661 EXPECT_TRUE(OptErr); 5662 } 5663 5664 TEST_P(ErrorHandlingTest, ErrorIsNotPropagatedFromMemberToNamespace) { 5665 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5666 namespace X { 5667 void f() { )") + ErroneousStmt + R"( } // This member has the error 5668 // during import. 5669 void ok(); // The error should not prevent importing this. 5670 }; // An error will be set for X too. 5671 )", 5672 Lang_CXX03); 5673 auto *FromX = FirstDeclMatcher<NamespaceDecl>().match( 5674 FromTU, namespaceDecl(hasName("X"))); 5675 NamespaceDecl *ImportedX = Import(FromX, Lang_CXX03); 5676 5677 // There is no error set for X. 5678 EXPECT_TRUE(ImportedX); 5679 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5680 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5681 ASSERT_FALSE(OptErr); 5682 5683 // An error is set for f(). 5684 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 5685 FromTU, functionDecl(hasName("f"))); 5686 OptErr = Importer->getImportDeclErrorIfAny(FromF); 5687 ASSERT_TRUE(OptErr); 5688 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5689 // And any subsequent import should fail. 5690 FunctionDecl *ImportedF = Import(FromF, Lang_CXX03); 5691 EXPECT_FALSE(ImportedF); 5692 5693 // There is no error set for ok(). 5694 auto *FromOK = FirstDeclMatcher<FunctionDecl>().match( 5695 FromTU, functionDecl(hasName("ok"))); 5696 OptErr = Importer->getImportDeclErrorIfAny(FromOK); 5697 EXPECT_FALSE(OptErr); 5698 // And we should be able to import. 5699 FunctionDecl *ImportedOK = Import(FromOK, Lang_CXX03); 5700 EXPECT_TRUE(ImportedOK); 5701 } 5702 5703 TEST_P(ErrorHandlingTest, ODRViolationWithinTypedefDecls) { 5704 // Importing `z` should fail - instead of crashing - due to an ODR violation. 5705 // The `bar::e` typedef sets it's DeclContext after the import is done. 5706 // However, if the importation fails, it will be left as a nullptr. 5707 // During the cleanup of the failed import, we should check whether the 5708 // DeclContext is null or not - instead of dereferencing that unconditionally. 5709 constexpr auto ToTUCode = R"( 5710 namespace X { 5711 struct bar { 5712 int odr_violation; 5713 }; 5714 })"; 5715 constexpr auto FromTUCode = R"( 5716 namespace X { 5717 enum b {}; 5718 struct bar { 5719 typedef b e; 5720 static e d; 5721 }; 5722 } 5723 int z = X::bar::d; 5724 )"; 5725 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11); 5726 static_cast<void>(ToTU); 5727 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 5728 auto *FromZ = 5729 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("z"))); 5730 ASSERT_TRUE(FromZ); 5731 ASSERT_TRUE(FromZ->hasInit()); 5732 5733 auto *ImportedZ = Import(FromZ, Lang_CXX11); 5734 EXPECT_FALSE(ImportedZ); 5735 } 5736 5737 // An error should be set for a class if it had a previous import with an error 5738 // from another TU. 5739 TEST_P(ErrorHandlingTest, 5740 ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt) { 5741 // We already have a fwd decl. 5742 TranslationUnitDecl *ToTU = getToTuDecl("class X;", Lang_CXX03); 5743 // Then we import a definition. 5744 { 5745 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5746 class X { 5747 void f() { )") + ErroneousStmt + R"( } 5748 void ok(); 5749 }; 5750 )", 5751 Lang_CXX03); 5752 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5753 FromTU, cxxRecordDecl(hasName("X"))); 5754 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 5755 5756 // An error is set for X ... 5757 EXPECT_FALSE(ImportedX); 5758 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5759 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5760 ASSERT_TRUE(OptErr); 5761 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5762 } 5763 // ... but the node had been created. 5764 auto *ToXDef = FirstDeclMatcher<CXXRecordDecl>().match( 5765 ToTU, cxxRecordDecl(hasName("X"), isDefinition())); 5766 // An error is set for "ToXDef" in the shared state. 5767 Optional<ASTImportError> OptErr = 5768 SharedStatePtr->getImportDeclErrorIfAny(ToXDef); 5769 ASSERT_TRUE(OptErr); 5770 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5771 5772 auto *ToXFwd = FirstDeclMatcher<CXXRecordDecl>().match( 5773 ToTU, cxxRecordDecl(hasName("X"), unless(isDefinition()))); 5774 // An error is NOT set for the fwd Decl of X in the shared state. 5775 OptErr = SharedStatePtr->getImportDeclErrorIfAny(ToXFwd); 5776 ASSERT_FALSE(OptErr); 5777 5778 // Try to import X again but from another TU. 5779 { 5780 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5781 class X { 5782 void f() { )") + ErroneousStmt + R"( } 5783 void ok(); 5784 }; 5785 )", 5786 Lang_CXX03, "input1.cc"); 5787 5788 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5789 FromTU, cxxRecordDecl(hasName("X"))); 5790 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 5791 5792 // If we did not save the errors for the "to" context then the below checks 5793 // would fail, because the lookup finds the fwd Decl of the existing 5794 // definition in the "to" context. We can reach the existing definition via 5795 // the found fwd Decl. That existing definition is structurally equivalent 5796 // (we check only the fields) with this one we want to import, so we return 5797 // with the existing definition, which is erroneous (one method is missing). 5798 5799 // The import should fail. 5800 EXPECT_FALSE(ImportedX); 5801 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5802 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5803 // And an error is set for this new X in the "from" ctx. 5804 ASSERT_TRUE(OptErr); 5805 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5806 } 5807 } 5808 5809 TEST_P(ErrorHandlingTest, ImportOfOverriddenMethods) { 5810 auto MatchFooA = 5811 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A")))); 5812 auto MatchFooB = 5813 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B")))); 5814 auto MatchFooC = 5815 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("C")))); 5816 5817 // Provoke import of a method that has overridden methods with import error. 5818 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5819 struct C; 5820 struct A { 5821 virtual void foo(); 5822 void f1(C *); 5823 }; 5824 void A::foo() { 5825 )") + ErroneousStmt + R"( 5826 } 5827 struct B : public A { 5828 void foo() override; 5829 }; 5830 struct C : public B { 5831 void foo() override; 5832 }; 5833 )", 5834 Lang_CXX11); 5835 auto *FromFooA = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooA); 5836 auto *FromFooB = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooB); 5837 auto *FromFooC = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooC); 5838 5839 EXPECT_FALSE(Import(FromFooA, Lang_CXX11)); 5840 ASTImporter *Importer = findFromTU(FromFooA)->Importer.get(); 5841 auto CheckError = [&Importer](Decl *FromD) { 5842 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromD); 5843 ASSERT_TRUE(OptErr); 5844 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 5845 }; 5846 CheckError(FromFooA); 5847 EXPECT_FALSE(Import(FromFooB, Lang_CXX11)); 5848 CheckError(FromFooB); 5849 EXPECT_FALSE(Import(FromFooC, Lang_CXX11)); 5850 CheckError(FromFooC); 5851 } 5852 5853 TEST_P(ErrorHandlingTest, ODRViolationWithinParmVarDecls) { 5854 // Importing of 'f' and parameter 'P' should cause an ODR error. 5855 // The error happens after the ParmVarDecl for 'P' was already created. 5856 // This is a special case because the ParmVarDecl has a temporary DeclContext. 5857 // Expected is no crash at error handling of ASTImporter. 5858 constexpr auto ToTUCode = R"( 5859 struct X { 5860 char A; 5861 }; 5862 )"; 5863 constexpr auto FromTUCode = R"( 5864 struct X { 5865 enum Y { Z }; 5866 }; 5867 void f(int P = X::Z); 5868 )"; 5869 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11); 5870 static_cast<void>(ToTU); 5871 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 5872 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 5873 FromTU, functionDecl(hasName("f"))); 5874 ASSERT_TRUE(FromF); 5875 5876 auto *ImportedF = Import(FromF, Lang_CXX11); 5877 EXPECT_FALSE(ImportedF); 5878 } 5879 5880 TEST_P(ErrorHandlingTest, DoNotInheritErrorFromNonDependentChild) { 5881 // Declarations should not inherit an import error from a child object 5882 // if the declaration has no direct dependence to such a child. 5883 // For example a namespace should not get import error if one of the 5884 // declarations inside it fails to import. 5885 // There was a special case in error handling (when "import path circles" are 5886 // encountered) when this property was not held. This case is provoked by the 5887 // following code. 5888 constexpr auto ToTUCode = R"( 5889 namespace ns { 5890 struct Err { 5891 char A; 5892 }; 5893 } 5894 )"; 5895 constexpr auto FromTUCode = R"( 5896 namespace ns { 5897 struct A { 5898 using U = struct Err; 5899 }; 5900 } 5901 namespace ns { 5902 struct Err {}; // ODR violation 5903 void f(A) {} 5904 } 5905 )"; 5906 5907 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11); 5908 static_cast<void>(ToTU); 5909 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 5910 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 5911 FromTU, cxxRecordDecl(hasName("A"), hasDefinition())); 5912 ASSERT_TRUE(FromA); 5913 auto *ImportedA = Import(FromA, Lang_CXX11); 5914 // 'A' can not be imported: ODR error at 'Err' 5915 EXPECT_FALSE(ImportedA); 5916 // When import of 'A' failed there was a "saved import path circle" that 5917 // contained namespace 'ns' (A - U - Err - ns - f - A). This should not mean 5918 // that every object in this path fails to import. 5919 5920 Decl *FromNS = FirstDeclMatcher<NamespaceDecl>().match( 5921 FromTU, namespaceDecl(hasName("ns"))); 5922 EXPECT_TRUE(FromNS); 5923 auto *ImportedNS = Import(FromNS, Lang_CXX11); 5924 EXPECT_TRUE(ImportedNS); 5925 } 5926 5927 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) { 5928 Decl *FromTU = getTuDecl( 5929 R"( 5930 void f() { 5931 auto L = [](){}; 5932 } 5933 )", 5934 Lang_CXX11, "input0.cc"); 5935 auto Pattern = lambdaExpr(); 5936 CXXRecordDecl *FromL = 5937 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 5938 5939 auto ToL = Import(FromL, Lang_CXX11); 5940 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); 5941 unsigned FromLSize = 5942 std::distance(FromL->decls().begin(), FromL->decls().end()); 5943 EXPECT_NE(ToLSize, 0u); 5944 EXPECT_EQ(ToLSize, FromLSize); 5945 EXPECT_FALSE(FromL->isDependentLambda()); 5946 } 5947 5948 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) { 5949 Decl *FromTU = getTuDecl( 5950 R"( 5951 template <typename F> 5952 void f(F L = [](){}) {} 5953 )", 5954 Lang_CXX11, "input0.cc"); 5955 auto Pattern = lambdaExpr(); 5956 CXXRecordDecl *FromL = 5957 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 5958 5959 auto ToL = Import(FromL, Lang_CXX11); 5960 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); 5961 unsigned FromLSize = 5962 std::distance(FromL->decls().begin(), FromL->decls().end()); 5963 EXPECT_NE(ToLSize, 0u); 5964 EXPECT_EQ(ToLSize, FromLSize); 5965 EXPECT_TRUE(FromL->isDependentLambda()); 5966 } 5967 5968 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInGlobalScope) { 5969 Decl *FromTU = getTuDecl( 5970 R"( 5971 auto l1 = [](unsigned lp) { return 1; }; 5972 auto l2 = [](int lp) { return 2; }; 5973 int f(int p) { 5974 return l1(p) + l2(p); 5975 } 5976 )", 5977 Lang_CXX11, "input0.cc"); 5978 FunctionDecl *FromF = FirstDeclMatcher<FunctionDecl>().match( 5979 FromTU, functionDecl(hasName("f"))); 5980 FunctionDecl *ToF = Import(FromF, Lang_CXX11); 5981 EXPECT_TRUE(ToF); 5982 } 5983 5984 TEST_P(ASTImporterOptionSpecificTestBase, 5985 ImportExistingFriendClassTemplateDef) { 5986 auto Code = 5987 R"( 5988 template <class T1, class T2> 5989 struct Base { 5990 template <class U1, class U2> 5991 friend struct Class; 5992 }; 5993 template <class T1, class T2> 5994 struct Class { }; 5995 )"; 5996 5997 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 5998 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc"); 5999 6000 auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match( 6001 ToTU, classTemplateDecl(hasName("Class"))); 6002 auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match( 6003 ToTU, classTemplateDecl(hasName("Class"))); 6004 ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition()); 6005 ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition()); 6006 // Previous friend decl is not linked to it! 6007 ASSERT_FALSE(ToClassDef->getPreviousDecl()); 6008 ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef); 6009 ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto); 6010 6011 auto *FromClassProto = FirstDeclMatcher<ClassTemplateDecl>().match( 6012 FromTU, classTemplateDecl(hasName("Class"))); 6013 auto *FromClassDef = LastDeclMatcher<ClassTemplateDecl>().match( 6014 FromTU, classTemplateDecl(hasName("Class"))); 6015 ASSERT_FALSE(FromClassProto->isThisDeclarationADefinition()); 6016 ASSERT_TRUE(FromClassDef->isThisDeclarationADefinition()); 6017 ASSERT_FALSE(FromClassDef->getPreviousDecl()); 6018 ASSERT_EQ(FromClassDef->getMostRecentDecl(), FromClassDef); 6019 ASSERT_EQ(FromClassProto->getMostRecentDecl(), FromClassProto); 6020 6021 auto *ImportedDef = Import(FromClassDef, Lang_CXX03); 6022 // At import we should find the definition for 'Class' even if the 6023 // prototype (inside 'friend') for it comes first in the AST and is not 6024 // linked to the definition. 6025 EXPECT_EQ(ImportedDef, ToClassDef); 6026 } 6027 6028 struct LLDBLookupTest : ASTImporterOptionSpecificTestBase { 6029 LLDBLookupTest() { 6030 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 6031 ASTContext &FromContext, FileManager &FromFileManager, 6032 bool MinimalImport, 6033 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 6034 return new ASTImporter(ToContext, ToFileManager, FromContext, 6035 FromFileManager, MinimalImport, 6036 // We use the regular lookup. 6037 /*SharedState=*/nullptr); 6038 }; 6039 } 6040 }; 6041 6042 TEST_P(LLDBLookupTest, ImporterShouldFindInTransparentContext) { 6043 TranslationUnitDecl *ToTU = getToTuDecl( 6044 R"( 6045 extern "C" { 6046 class X{}; 6047 }; 6048 )", 6049 Lang_CXX03); 6050 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match( 6051 ToTU, cxxRecordDecl(hasName("X"))); 6052 6053 // Set up a stub external storage. 6054 ToTU->setHasExternalLexicalStorage(true); 6055 // Set up DeclContextBits.HasLazyExternalLexicalLookups to true. 6056 ToTU->setMustBuildLookupTable(); 6057 struct TestExternalASTSource : ExternalASTSource {}; 6058 ToTU->getASTContext().setExternalSource(new TestExternalASTSource()); 6059 6060 Decl *FromTU = getTuDecl( 6061 R"( 6062 class X; 6063 )", 6064 Lang_CXX03); 6065 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 6066 FromTU, cxxRecordDecl(hasName("X"))); 6067 auto *ImportedX = Import(FromX, Lang_CXX03); 6068 // The lookup must find the existing class definition in the LinkageSpecDecl. 6069 // Then the importer renders the existing and the new decl into one chain. 6070 EXPECT_EQ(ImportedX->getCanonicalDecl(), ToX->getCanonicalDecl()); 6071 } 6072 6073 struct SVEBuiltins : ASTImporterOptionSpecificTestBase {}; 6074 6075 TEST_P(SVEBuiltins, ImportTypes) { 6076 static const char *const TypeNames[] = { 6077 "__SVInt8_t", 6078 "__SVInt16_t", 6079 "__SVInt32_t", 6080 "__SVInt64_t", 6081 "__SVUint8_t", 6082 "__SVUint16_t", 6083 "__SVUint32_t", 6084 "__SVUint64_t", 6085 "__SVFloat16_t", 6086 "__SVBFloat16_t", 6087 "__SVFloat32_t", 6088 "__SVFloat64_t", 6089 "__SVBool_t" 6090 }; 6091 6092 TranslationUnitDecl *ToTU = getToTuDecl("", Lang_CXX03); 6093 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cc"); 6094 for (auto *TypeName : TypeNames) { 6095 auto *ToTypedef = FirstDeclMatcher<TypedefDecl>().match( 6096 ToTU, typedefDecl(hasName(TypeName))); 6097 QualType ToType = ToTypedef->getUnderlyingType(); 6098 6099 auto *FromTypedef = FirstDeclMatcher<TypedefDecl>().match( 6100 FromTU, typedefDecl(hasName(TypeName))); 6101 QualType FromType = FromTypedef->getUnderlyingType(); 6102 6103 QualType ImportedType = ImportType(FromType, FromTypedef, Lang_CXX03); 6104 EXPECT_EQ(ImportedType, ToType); 6105 } 6106 } 6107 6108 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfDefaultImplicitFunctions) { 6109 // Test that import of implicit functions works and the functions 6110 // are merged into one chain. 6111 auto GetDeclToImport = [this](StringRef File) { 6112 Decl *FromTU = getTuDecl( 6113 R"( 6114 struct X { }; 6115 // Force generating some implicit operator definitions for X. 6116 void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; } 6117 )", 6118 Lang_CXX11, File); 6119 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 6120 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit()))); 6121 // Destructor is picked as one example of implicit function. 6122 return FromD->getDestructor(); 6123 }; 6124 6125 auto *ToD1 = Import(GetDeclToImport("input1.cc"), Lang_CXX11); 6126 ASSERT_TRUE(ToD1); 6127 6128 auto *ToD2 = Import(GetDeclToImport("input2.cc"), Lang_CXX11); 6129 ASSERT_TRUE(ToD2); 6130 6131 EXPECT_EQ(ToD1->getCanonicalDecl(), ToD2->getCanonicalDecl()); 6132 } 6133 6134 TEST_P(ASTImporterOptionSpecificTestBase, 6135 ImportOfExplicitlyDefaultedOrDeleted) { 6136 Decl *FromTU = getTuDecl( 6137 R"( 6138 struct X { X() = default; X(const X&) = delete; }; 6139 )", 6140 Lang_CXX11); 6141 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 6142 FromTU, cxxRecordDecl(hasName("X"))); 6143 auto *ImportedX = Import(FromX, Lang_CXX11); 6144 auto *Constr1 = FirstDeclMatcher<CXXConstructorDecl>().match( 6145 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit()))); 6146 auto *Constr2 = LastDeclMatcher<CXXConstructorDecl>().match( 6147 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit()))); 6148 6149 ASSERT_TRUE(ImportedX); 6150 EXPECT_TRUE(Constr1->isDefaulted()); 6151 EXPECT_TRUE(Constr1->isExplicitlyDefaulted()); 6152 EXPECT_TRUE(Constr2->isDeletedAsWritten()); 6153 EXPECT_EQ(ImportedX->isAggregate(), FromX->isAggregate()); 6154 } 6155 6156 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, SVEBuiltins, 6157 ::testing::Values(std::vector<std::string>{ 6158 "-target", "aarch64-linux-gnu"})); 6159 6160 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, DeclContextTest, 6161 ::testing::Values(std::vector<std::string>())); 6162 6163 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CanonicalRedeclChain, 6164 ::testing::Values(std::vector<std::string>())); 6165 6166 TEST_P(ASTImporterOptionSpecificTestBase, LambdasAreDifferentiated) { 6167 Decl *FromTU = getTuDecl( 6168 R"( 6169 void f() { 6170 auto L0 = [](){}; 6171 auto L1 = [](){}; 6172 } 6173 )", 6174 Lang_CXX11, "input0.cc"); 6175 auto Pattern = lambdaExpr(); 6176 CXXRecordDecl *FromL0 = 6177 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 6178 CXXRecordDecl *FromL1 = 6179 LastDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 6180 ASSERT_NE(FromL0, FromL1); 6181 6182 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 6183 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 6184 EXPECT_NE(ToL0, ToL1); 6185 } 6186 6187 TEST_P(ASTImporterOptionSpecificTestBase, 6188 LambdasInFunctionParamsAreDifferentiated) { 6189 Decl *FromTU = getTuDecl( 6190 R"( 6191 template <typename F0, typename F1> 6192 void f(F0 L0 = [](){}, F1 L1 = [](){}) {} 6193 )", 6194 Lang_CXX11, "input0.cc"); 6195 auto Pattern = cxxRecordDecl(isLambda()); 6196 CXXRecordDecl *FromL0 = 6197 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 6198 CXXRecordDecl *FromL1 = 6199 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 6200 ASSERT_NE(FromL0, FromL1); 6201 6202 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 6203 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 6204 ASSERT_NE(ToL0, ToL1); 6205 } 6206 6207 TEST_P(ASTImporterOptionSpecificTestBase, 6208 LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed) { 6209 Decl *FromTU = getTuDecl( 6210 R"( 6211 #define LAMBDA [](){} 6212 template <typename F0, typename F1> 6213 void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {} 6214 )", 6215 Lang_CXX11, "input0.cc"); 6216 auto Pattern = cxxRecordDecl(isLambda()); 6217 CXXRecordDecl *FromL0 = 6218 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 6219 CXXRecordDecl *FromL1 = 6220 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 6221 ASSERT_NE(FromL0, FromL1); 6222 6223 Import(FromL0, Lang_CXX11); 6224 Import(FromL1, Lang_CXX11); 6225 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 6226 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 6227 ASSERT_NE(ToL0, ToL1); 6228 } 6229 6230 TEST_P(ASTImporterOptionSpecificTestBase, ImportAssignedLambda) { 6231 Decl *FromTU = getTuDecl( 6232 R"( 6233 void f() { 6234 auto x = []{} = {}; auto x2 = x; 6235 } 6236 )", 6237 Lang_CXX20, "input0.cc"); 6238 auto FromF = FirstDeclMatcher<FunctionDecl>().match( 6239 FromTU, functionDecl(hasName("f"))); 6240 // We have only one lambda class. 6241 ASSERT_EQ( 6242 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())), 6243 1u); 6244 6245 FunctionDecl *ToF = Import(FromF, Lang_CXX20); 6246 EXPECT_TRUE(ToF); 6247 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 6248 // We have only one lambda class after the import. 6249 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())), 6250 1u); 6251 } 6252 6253 TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) { 6254 Decl *FromTU = getTuDecl( 6255 R"( 6256 void f() { 6257 auto x = []{} = {}; 6258 auto xb = []{} = {}; 6259 } 6260 )", 6261 Lang_CXX20, "input0.cc"); 6262 auto FromF = FirstDeclMatcher<FunctionDecl>().match( 6263 FromTU, functionDecl(hasName("f"))); 6264 // We have two lambda classes. 6265 ASSERT_EQ( 6266 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())), 6267 2u); 6268 6269 FunctionDecl *ToF = Import(FromF, Lang_CXX20); 6270 EXPECT_TRUE(ToF); 6271 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 6272 // We have two lambda classes after the import. 6273 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())), 6274 2u); 6275 } 6276 6277 TEST_P(ASTImporterOptionSpecificTestBase, 6278 ImportFunctionDeclWithTypeSourceInfoWithSourceDecl) { 6279 // This code results in a lambda with implicit constructor. 6280 // The constructor's TypeSourceInfo points out the function prototype. 6281 // This prototype has an EST_Unevaluated in its exception information and a 6282 // SourceDecl that is the function declaration itself. 6283 // The test verifies that AST import of such AST does not crash. 6284 // (Here the function's TypeSourceInfo references the function itself.) 6285 Decl *FromTU = getTuDecl( 6286 R"( 6287 template<typename T> void f(T) { auto X = [](){}; } 6288 void g() { f(10); } 6289 )", 6290 Lang_CXX11, "input0.cc"); 6291 6292 // Use LastDeclMatcher to find the LambdaExpr in the template specialization. 6293 CXXRecordDecl *FromL = LastDeclMatcher<LambdaExpr>() 6294 .match(FromTU, lambdaExpr()) 6295 ->getLambdaClass(); 6296 6297 CXXConstructorDecl *FromCtor = *FromL->ctor_begin(); 6298 ASSERT_TRUE(FromCtor->isCopyConstructor()); 6299 ASSERT_TRUE(FromCtor->getTypeSourceInfo()); 6300 const auto *FromFPT = FromCtor->getType()->getAs<FunctionProtoType>(); 6301 ASSERT_TRUE(FromFPT); 6302 EXPECT_EQ(FromCtor->getTypeSourceInfo()->getType().getTypePtr(), FromFPT); 6303 FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo(); 6304 // If type is EST_Unevaluated, SourceDecl should be set to the parent Decl. 6305 EXPECT_EQ(FromEPI.ExceptionSpec.Type, EST_Unevaluated); 6306 EXPECT_EQ(FromEPI.ExceptionSpec.SourceDecl, FromCtor); 6307 6308 auto ToL = Import(FromL, Lang_CXX11); 6309 6310 // Check if the import was correct. 6311 CXXConstructorDecl *ToCtor = *ToL->ctor_begin(); 6312 EXPECT_TRUE(ToCtor->getTypeSourceInfo()); 6313 const auto *ToFPT = ToCtor->getType()->getAs<FunctionProtoType>(); 6314 ASSERT_TRUE(ToFPT); 6315 EXPECT_EQ(ToCtor->getTypeSourceInfo()->getType().getTypePtr(), ToFPT); 6316 FunctionProtoType::ExtProtoInfo ToEPI = ToFPT->getExtProtoInfo(); 6317 EXPECT_EQ(ToEPI.ExceptionSpec.Type, EST_Unevaluated); 6318 EXPECT_EQ(ToEPI.ExceptionSpec.SourceDecl, ToCtor); 6319 } 6320 6321 struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {}; 6322 6323 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithIntegerArgDeclaredInside) { 6324 Decl *FromTU = getTuDecl( 6325 R"( 6326 template<int> struct Tmpl {}; 6327 auto foo() { 6328 constexpr int X = 1; 6329 return Tmpl<X>(); 6330 } 6331 )", 6332 Lang_CXX14, "input0.cc"); 6333 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6334 FromTU, functionDecl(hasName("foo"))); 6335 6336 FunctionDecl *To = Import(From, Lang_CXX14); 6337 EXPECT_TRUE(To); 6338 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6339 } 6340 6341 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside1) { 6342 Decl *FromTU = getTuDecl( 6343 R"( 6344 template<class> struct Tmpl {}; 6345 auto foo() { 6346 struct X {}; 6347 return Tmpl<X>(); 6348 } 6349 )", 6350 Lang_CXX14, "input0.cc"); 6351 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6352 FromTU, functionDecl(hasName("foo"))); 6353 6354 FunctionDecl *To = Import(From, Lang_CXX14); 6355 EXPECT_TRUE(To); 6356 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6357 } 6358 6359 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside2) { 6360 Decl *FromTU = getTuDecl( 6361 R"( 6362 template<class> struct Tmpl {}; 6363 auto foo() { 6364 struct X {}; 6365 return Tmpl<Tmpl<X>>(); 6366 } 6367 )", 6368 Lang_CXX14, "input0.cc"); 6369 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6370 FromTU, functionDecl(hasName("foo"))); 6371 6372 FunctionDecl *To = Import(From, Lang_CXX14); 6373 EXPECT_TRUE(To); 6374 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6375 } 6376 6377 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTypedefDeclaredInside) { 6378 Decl *FromTU = getTuDecl( 6379 R"( 6380 template<class> struct Tmpl {}; 6381 auto foo() { 6382 struct X {}; 6383 using x_type = X; 6384 return Tmpl<x_type>(); 6385 } 6386 )", 6387 Lang_CXX14, "input0.cc"); 6388 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6389 FromTU, functionDecl(hasName("foo"))); 6390 6391 FunctionDecl *To = Import(From, Lang_CXX14); 6392 EXPECT_TRUE(To); 6393 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6394 } 6395 6396 TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) { 6397 Decl *FromTU = getTuDecl( 6398 R"( 6399 auto X = [](long l) { 6400 using int_type = long; 6401 auto dur = 13; 6402 return static_cast<int_type>(dur); 6403 }; 6404 )", 6405 Lang_CXX14, "input0.cc"); 6406 CXXMethodDecl *From = 6407 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, cxxMethodDecl()); 6408 6409 // Explicitly set the return type of the lambda's operator() to the TypeAlias. 6410 // Normally the return type would be the built-in 'long' type. However, there 6411 // are cases when Clang does not use the canonical type and the TypeAlias is 6412 // used. I could not create such an AST from regular source code, it requires 6413 // some special state in the preprocessor. I've found such an AST when Clang 6414 // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce 6415 // that with creduce, because after preprocessing, the AST no longer 6416 // contained the TypeAlias as a return type of the lambda. 6417 ASTContext &Ctx = From->getASTContext(); 6418 TypeAliasDecl *FromTA = 6419 FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl()); 6420 QualType TT = Ctx.getTypedefType(FromTA); 6421 const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType()); 6422 QualType NewFunType = 6423 Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo()); 6424 From->setType(NewFunType); 6425 6426 CXXMethodDecl *To = Import(From, Lang_CXX14); 6427 EXPECT_TRUE(To); 6428 EXPECT_TRUE(isa<TypedefType>(To->getReturnType())); 6429 } 6430 6431 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside) { 6432 Decl *FromTU = getTuDecl( 6433 R"( 6434 auto foo() { 6435 struct X {}; 6436 return X(); 6437 } 6438 )", 6439 Lang_CXX14, "input0.cc"); 6440 FunctionDecl *From = 6441 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 6442 6443 FunctionDecl *To = Import(From, Lang_CXX14); 6444 EXPECT_TRUE(To); 6445 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6446 } 6447 6448 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside2) { 6449 Decl *FromTU = getTuDecl( 6450 R"( 6451 auto foo() { 6452 struct X {}; 6453 return X(); 6454 } 6455 )", 6456 Lang_CXX14, "input0.cc"); 6457 FunctionDecl *From = 6458 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 6459 6460 // This time import the type directly. 6461 QualType ToT = ImportType(From->getType(), From, Lang_CXX14); 6462 const FunctionProtoType *FPT = cast<FunctionProtoType>(ToT); 6463 EXPECT_TRUE(isa<AutoType>(FPT->getReturnType())); 6464 } 6465 6466 TEST_P(ImportAutoFunctions, ReturnWithTypedefToStructDeclaredInside) { 6467 Decl *FromTU = getTuDecl( 6468 R"( 6469 auto foo() { 6470 struct X {}; 6471 using Y = X; 6472 return Y(); 6473 } 6474 )", 6475 Lang_CXX14, "input0.cc"); 6476 FunctionDecl *From = 6477 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 6478 6479 FunctionDecl *To = Import(From, Lang_CXX14); 6480 EXPECT_TRUE(To); 6481 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6482 } 6483 6484 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredNestedInside) { 6485 Decl *FromTU = getTuDecl( 6486 R"( 6487 auto foo() { 6488 struct X { struct Y{}; }; 6489 return X::Y(); 6490 } 6491 )", 6492 Lang_CXX14, "input0.cc"); 6493 FunctionDecl *From = 6494 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 6495 6496 FunctionDecl *To = Import(From, Lang_CXX14); 6497 EXPECT_TRUE(To); 6498 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6499 } 6500 6501 TEST_P(ImportAutoFunctions, ReturnWithInternalLambdaType) { 6502 Decl *FromTU = getTuDecl( 6503 R"( 6504 auto f() { 6505 auto l = []() { 6506 struct X {}; 6507 return X(); 6508 }; 6509 return l(); 6510 } 6511 )", 6512 Lang_CXX17, "input0.cc"); 6513 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6514 FromTU, functionDecl(hasName("f"))); 6515 6516 FunctionDecl *To = Import(From, Lang_CXX17); 6517 EXPECT_TRUE(To); 6518 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6519 } 6520 6521 TEST_P(ImportAutoFunctions, ReturnWithTypeInIf) { 6522 Decl *FromTU = getTuDecl( 6523 R"( 6524 auto f() { 6525 if (struct X {} x; true) 6526 return X(); 6527 else 6528 return X(); 6529 } 6530 )", 6531 Lang_CXX17, "input0.cc"); 6532 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6533 FromTU, functionDecl(hasName("f"))); 6534 6535 FunctionDecl *To = Import(From, Lang_CXX17); 6536 EXPECT_TRUE(To); 6537 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6538 } 6539 6540 TEST_P(ImportAutoFunctions, ReturnWithTypeInFor) { 6541 Decl *FromTU = getTuDecl( 6542 R"( 6543 auto f() { 6544 for (struct X {} x;;) 6545 return X(); 6546 } 6547 )", 6548 Lang_CXX17, "input0.cc"); 6549 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6550 FromTU, functionDecl(hasName("f"))); 6551 6552 FunctionDecl *To = Import(From, Lang_CXX17); 6553 EXPECT_TRUE(To); 6554 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6555 } 6556 6557 TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) { 6558 Decl *FromTU = getTuDecl( 6559 R"( 6560 auto f() { 6561 switch (struct X {} x; 10) { 6562 case 10: 6563 return X(); 6564 } 6565 } 6566 )", 6567 Lang_CXX17, "input0.cc"); 6568 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6569 FromTU, functionDecl(hasName("f"))); 6570 6571 FunctionDecl *To = Import(From, Lang_CXX17); 6572 EXPECT_TRUE(To); 6573 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6574 } 6575 6576 struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {}; 6577 6578 TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) { 6579 // Tests that the FileID tree structure (with the links being the include 6580 // chains) is preserved while importing other files (which need to be 6581 // added to this structure with fake include locations. 6582 6583 SourceLocation Location1; 6584 { 6585 auto Pattern = varDecl(hasName("X")); 6586 Decl *FromTU = getTuDecl("int X;", Lang_C99, "input0.c"); 6587 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 6588 6589 Location1 = Import(FromD, Lang_C99)->getLocation(); 6590 } 6591 SourceLocation Location2; 6592 { 6593 auto Pattern = varDecl(hasName("Y")); 6594 Decl *FromTU = getTuDecl("int Y;", Lang_C99, "input1.c"); 6595 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 6596 6597 Location2 = Import(FromD, Lang_C99)->getLocation(); 6598 } 6599 6600 SourceManager &ToSM = ToAST->getSourceManager(); 6601 FileID FileID1 = ToSM.getFileID(Location1); 6602 FileID FileID2 = ToSM.getFileID(Location2); 6603 6604 // Check that the imported files look like as if they were included from the 6605 // start of the main file. 6606 SourceLocation FileStart = ToSM.getLocForStartOfFile(ToSM.getMainFileID()); 6607 EXPECT_NE(FileID1, ToSM.getMainFileID()); 6608 EXPECT_NE(FileID2, ToSM.getMainFileID()); 6609 EXPECT_EQ(ToSM.getIncludeLoc(FileID1), FileStart); 6610 EXPECT_EQ(ToSM.getIncludeLoc(FileID2), FileStart); 6611 6612 // Let the SourceManager check the order of the locations. The order should 6613 // be the order in which the declarations are imported. 6614 EXPECT_TRUE(ToSM.isBeforeInTranslationUnit(Location1, Location2)); 6615 EXPECT_FALSE(ToSM.isBeforeInTranslationUnit(Location2, Location1)); 6616 } 6617 6618 TEST_P(ImportSourceLocations, NormalFileBuffer) { 6619 // Test importing normal file buffers. 6620 6621 std::string Path = "input0.c"; 6622 std::string Source = "int X;"; 6623 TranslationUnitDecl *FromTU = getTuDecl(Source, Lang_C99, Path); 6624 6625 SourceLocation ImportedLoc; 6626 { 6627 // Import the VarDecl to trigger the importing of the FileID. 6628 auto Pattern = varDecl(hasName("X")); 6629 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 6630 ImportedLoc = Import(FromD, Lang_C99)->getLocation(); 6631 } 6632 6633 // Make sure the imported buffer has the original contents. 6634 SourceManager &ToSM = ToAST->getSourceManager(); 6635 FileID ImportedID = ToSM.getFileID(ImportedLoc); 6636 EXPECT_EQ(Source, 6637 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer()); 6638 } 6639 6640 TEST_P(ImportSourceLocations, OverwrittenFileBuffer) { 6641 // Test importing overwritten file buffers. 6642 6643 std::string Path = "input0.c"; 6644 TranslationUnitDecl *FromTU = getTuDecl("int X;", Lang_C99, Path); 6645 6646 // Overwrite the file buffer for our input file with new content. 6647 const std::string Contents = "overwritten contents"; 6648 SourceLocation ImportedLoc; 6649 { 6650 SourceManager &FromSM = FromTU->getASTContext().getSourceManager(); 6651 clang::FileManager &FM = FromSM.getFileManager(); 6652 const clang::FileEntry &FE = 6653 *FM.getVirtualFile(Path, static_cast<off_t>(Contents.size()), 0); 6654 6655 llvm::SmallVector<char, 64> Buffer; 6656 Buffer.append(Contents.begin(), Contents.end()); 6657 auto FileContents = std::make_unique<llvm::SmallVectorMemoryBuffer>( 6658 std::move(Buffer), Path, /*RequiresNullTerminator=*/false); 6659 FromSM.overrideFileContents(&FE, std::move(FileContents)); 6660 6661 // Import the VarDecl to trigger the importing of the FileID. 6662 auto Pattern = varDecl(hasName("X")); 6663 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 6664 ImportedLoc = Import(FromD, Lang_C99)->getLocation(); 6665 } 6666 6667 // Make sure the imported buffer has the overwritten contents. 6668 SourceManager &ToSM = ToAST->getSourceManager(); 6669 FileID ImportedID = ToSM.getFileID(ImportedLoc); 6670 EXPECT_EQ(Contents, 6671 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer()); 6672 } 6673 6674 struct ImportAttributes : public ASTImporterOptionSpecificTestBase { 6675 void checkAttrImportCommon(const Attr *From, const Attr *To, 6676 const Decl *ToD) { 6677 6678 // Verify that dump does not crash because invalid data. 6679 ToD->dump(llvm::nulls()); 6680 6681 EXPECT_EQ(From->getParsedKind(), To->getParsedKind()); 6682 EXPECT_EQ(From->getSyntax(), To->getSyntax()); 6683 if (From->getAttrName()) { 6684 EXPECT_TRUE(To->getAttrName()); 6685 EXPECT_STREQ(From->getAttrName()->getNameStart(), 6686 To->getAttrName()->getNameStart()); 6687 } else { 6688 EXPECT_FALSE(To->getAttrName()); 6689 } 6690 if (From->getScopeName()) { 6691 EXPECT_TRUE(To->getScopeName()); 6692 EXPECT_STREQ(From->getScopeName()->getNameStart(), 6693 To->getScopeName()->getNameStart()); 6694 } else { 6695 EXPECT_FALSE(To->getScopeName()); 6696 } 6697 EXPECT_EQ(From->getSpellingListIndex(), To->getSpellingListIndex()); 6698 EXPECT_STREQ(From->getSpelling(), To->getSpelling()); 6699 EXPECT_EQ(From->isInherited(), To->isInherited()); 6700 EXPECT_EQ(From->isImplicit(), To->isImplicit()); 6701 EXPECT_EQ(From->isPackExpansion(), To->isPackExpansion()); 6702 EXPECT_EQ(From->isLateParsed(), To->isLateParsed()); 6703 } 6704 6705 template <class DT, class AT> 6706 void importAttr(const char *Code, AT *&FromAttr, AT *&ToAttr) { 6707 static_assert(std::is_base_of<Attr, AT>::value, "AT should be an Attr"); 6708 static_assert(std::is_base_of<Decl, DT>::value, "DT should be a Decl"); 6709 6710 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cc"); 6711 DT *FromD = 6712 FirstDeclMatcher<DT>().match(FromTU, namedDecl(hasName("test"))); 6713 ASSERT_TRUE(FromD); 6714 6715 DT *ToD = Import(FromD, Lang_CXX11); 6716 ASSERT_TRUE(ToD); 6717 6718 FromAttr = FromD->template getAttr<AT>(); 6719 ToAttr = ToD->template getAttr<AT>(); 6720 ASSERT_TRUE(FromAttr); 6721 EXPECT_TRUE(ToAttr); 6722 6723 checkAttrImportCommon(FromAttr, ToAttr, ToD); 6724 } 6725 6726 template <class T> void checkImported(const T *From, const T *To) { 6727 EXPECT_TRUE(To); 6728 EXPECT_NE(From, To); 6729 } 6730 6731 template <class T> 6732 void checkImportVariadicArg(const llvm::iterator_range<T **> &From, 6733 const llvm::iterator_range<T **> &To) { 6734 for (auto FromI = From.begin(), ToI = To.begin(); FromI != From.end(); 6735 ++FromI, ++ToI) { 6736 ASSERT_NE(ToI, To.end()); 6737 checkImported(*FromI, *ToI); 6738 } 6739 } 6740 }; 6741 6742 template <> 6743 void ImportAttributes::checkImported<Decl>(const Decl *From, const Decl *To) { 6744 EXPECT_TRUE(To); 6745 EXPECT_NE(From, To); 6746 EXPECT_EQ(To->getTranslationUnitDecl(), 6747 ToAST->getASTContext().getTranslationUnitDecl()); 6748 } 6749 6750 // FIXME: Use ImportAttributes for this test. 6751 TEST_P(ASTImporterOptionSpecificTestBase, ImportExprOfAlignmentAttr) { 6752 // Test if import of these packed and aligned attributes does not trigger an 6753 // error situation where source location from 'From' context is referenced in 6754 // 'To' context through evaluation of the alignof attribute. 6755 // This happens if the 'alignof(A)' expression is not imported correctly. 6756 Decl *FromTU = getTuDecl( 6757 R"( 6758 struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; }; 6759 struct alignas(alignof(A)) S {}; 6760 )", 6761 Lang_CXX11, "input.cc"); 6762 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 6763 FromTU, cxxRecordDecl(hasName("S"), unless(isImplicit()))); 6764 ASSERT_TRUE(FromD); 6765 6766 auto *ToD = Import(FromD, Lang_CXX11); 6767 ASSERT_TRUE(ToD); 6768 6769 auto *FromAttr = FromD->getAttr<AlignedAttr>(); 6770 auto *ToAttr = ToD->getAttr<AlignedAttr>(); 6771 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited()); 6772 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion()); 6773 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit()); 6774 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax()); 6775 EXPECT_EQ(FromAttr->getSemanticSpelling(), ToAttr->getSemanticSpelling()); 6776 EXPECT_TRUE(ToAttr->getAlignmentExpr()); 6777 6778 auto *ToA = FirstDeclMatcher<CXXRecordDecl>().match( 6779 ToD->getTranslationUnitDecl(), 6780 cxxRecordDecl(hasName("A"), unless(isImplicit()))); 6781 // Ensure that 'struct A' was imported (through reference from attribute of 6782 // 'S'). 6783 EXPECT_TRUE(ToA); 6784 } 6785 6786 // FIXME: Use ImportAttributes for this test. 6787 TEST_P(ASTImporterOptionSpecificTestBase, ImportFormatAttr) { 6788 Decl *FromTU = getTuDecl( 6789 R"( 6790 int foo(const char * fmt, ...) 6791 __attribute__ ((__format__ (__scanf__, 1, 2))); 6792 )", 6793 Lang_CXX03, "input.cc"); 6794 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 6795 FromTU, functionDecl(hasName("foo"))); 6796 ASSERT_TRUE(FromD); 6797 6798 auto *ToD = Import(FromD, Lang_CXX03); 6799 ASSERT_TRUE(ToD); 6800 ToD->dump(); // Should not crash! 6801 6802 auto *FromAttr = FromD->getAttr<FormatAttr>(); 6803 auto *ToAttr = ToD->getAttr<FormatAttr>(); 6804 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited()); 6805 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion()); 6806 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit()); 6807 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax()); 6808 EXPECT_EQ(FromAttr->getAttributeSpellingListIndex(), 6809 ToAttr->getAttributeSpellingListIndex()); 6810 EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName()); 6811 } 6812 6813 TEST_P(ImportAttributes, ImportEnableIf) { 6814 EnableIfAttr *FromAttr, *ToAttr; 6815 importAttr<FunctionDecl>( 6816 "void test(int A) __attribute__((enable_if(A == 1, \"message\")));", 6817 FromAttr, ToAttr); 6818 checkImported(FromAttr->getCond(), ToAttr->getCond()); 6819 EXPECT_EQ(FromAttr->getMessage(), ToAttr->getMessage()); 6820 } 6821 6822 TEST_P(ImportAttributes, ImportGuardedVar) { 6823 GuardedVarAttr *FromAttr, *ToAttr; 6824 importAttr<VarDecl>("int test __attribute__((guarded_var));", FromAttr, 6825 ToAttr); 6826 } 6827 6828 TEST_P(ImportAttributes, ImportPtGuardedVar) { 6829 PtGuardedVarAttr *FromAttr, *ToAttr; 6830 importAttr<VarDecl>("int *test __attribute__((pt_guarded_var));", FromAttr, 6831 ToAttr); 6832 } 6833 6834 TEST_P(ImportAttributes, ImportScopedLockable) { 6835 ScopedLockableAttr *FromAttr, *ToAttr; 6836 importAttr<CXXRecordDecl>("struct __attribute__((scoped_lockable)) test {};", 6837 FromAttr, ToAttr); 6838 } 6839 6840 TEST_P(ImportAttributes, ImportCapability) { 6841 CapabilityAttr *FromAttr, *ToAttr; 6842 importAttr<CXXRecordDecl>( 6843 "struct __attribute__((capability(\"cap\"))) test {};", FromAttr, ToAttr); 6844 EXPECT_EQ(FromAttr->getName(), ToAttr->getName()); 6845 } 6846 6847 TEST_P(ImportAttributes, ImportAssertCapability) { 6848 AssertCapabilityAttr *FromAttr, *ToAttr; 6849 importAttr<FunctionDecl>( 6850 "void test(int A1, int A2) __attribute__((assert_capability(A1, A2)));", 6851 FromAttr, ToAttr); 6852 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6853 } 6854 6855 TEST_P(ImportAttributes, ImportAcquireCapability) { 6856 AcquireCapabilityAttr *FromAttr, *ToAttr; 6857 importAttr<FunctionDecl>( 6858 "void test(int A1, int A2) __attribute__((acquire_capability(A1, A2)));", 6859 FromAttr, ToAttr); 6860 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6861 } 6862 6863 TEST_P(ImportAttributes, ImportTryAcquireCapability) { 6864 TryAcquireCapabilityAttr *FromAttr, *ToAttr; 6865 importAttr<FunctionDecl>( 6866 "void test(int A1, int A2) __attribute__((try_acquire_capability(1, A1, " 6867 "A2)));", 6868 FromAttr, ToAttr); 6869 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); 6870 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6871 } 6872 6873 TEST_P(ImportAttributes, ImportReleaseCapability) { 6874 ReleaseCapabilityAttr *FromAttr, *ToAttr; 6875 importAttr<FunctionDecl>( 6876 "void test(int A1, int A2) __attribute__((release_capability(A1, A2)));", 6877 FromAttr, ToAttr); 6878 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6879 } 6880 6881 TEST_P(ImportAttributes, ImportRequiresCapability) { 6882 RequiresCapabilityAttr *FromAttr, *ToAttr; 6883 importAttr<FunctionDecl>( 6884 "void test(int A1, int A2) __attribute__((requires_capability(A1, A2)));", 6885 FromAttr, ToAttr); 6886 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6887 } 6888 6889 TEST_P(ImportAttributes, ImportNoThreadSafetyAnalysis) { 6890 NoThreadSafetyAnalysisAttr *FromAttr, *ToAttr; 6891 importAttr<FunctionDecl>( 6892 "void test() __attribute__((no_thread_safety_analysis));", FromAttr, 6893 ToAttr); 6894 } 6895 6896 TEST_P(ImportAttributes, ImportGuardedBy) { 6897 GuardedByAttr *FromAttr, *ToAttr; 6898 importAttr<VarDecl>( 6899 R"( 6900 int G; 6901 int test __attribute__((guarded_by(G))); 6902 )", 6903 FromAttr, ToAttr); 6904 checkImported(FromAttr->getArg(), ToAttr->getArg()); 6905 } 6906 6907 TEST_P(ImportAttributes, ImportPtGuardedBy) { 6908 PtGuardedByAttr *FromAttr, *ToAttr; 6909 importAttr<VarDecl>( 6910 R"( 6911 int G; 6912 int *test __attribute__((pt_guarded_by(G))); 6913 )", 6914 FromAttr, ToAttr); 6915 checkImported(FromAttr->getArg(), ToAttr->getArg()); 6916 } 6917 6918 TEST_P(ImportAttributes, ImportAcquiredAfter) { 6919 AcquiredAfterAttr *FromAttr, *ToAttr; 6920 importAttr<VarDecl>( 6921 R"( 6922 struct __attribute__((lockable)) L {}; 6923 L A1; 6924 L A2; 6925 L test __attribute__((acquired_after(A1, A2))); 6926 )", 6927 FromAttr, ToAttr); 6928 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6929 } 6930 6931 TEST_P(ImportAttributes, ImportAcquiredBefore) { 6932 AcquiredBeforeAttr *FromAttr, *ToAttr; 6933 importAttr<VarDecl>( 6934 R"( 6935 struct __attribute__((lockable)) L {}; 6936 L A1; 6937 L A2; 6938 L test __attribute__((acquired_before(A1, A2))); 6939 )", 6940 FromAttr, ToAttr); 6941 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6942 } 6943 6944 TEST_P(ImportAttributes, ImportAssertExclusiveLock) { 6945 AssertExclusiveLockAttr *FromAttr, *ToAttr; 6946 importAttr<FunctionDecl>("void test(int A1, int A2) " 6947 "__attribute__((assert_exclusive_lock(A1, A2)));", 6948 FromAttr, ToAttr); 6949 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6950 } 6951 6952 TEST_P(ImportAttributes, ImportAssertSharedLock) { 6953 AssertSharedLockAttr *FromAttr, *ToAttr; 6954 importAttr<FunctionDecl>( 6955 "void test(int A1, int A2) __attribute__((assert_shared_lock(A1, A2)));", 6956 FromAttr, ToAttr); 6957 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6958 } 6959 6960 TEST_P(ImportAttributes, ImportExclusiveTrylockFunction) { 6961 ExclusiveTrylockFunctionAttr *FromAttr, *ToAttr; 6962 importAttr<FunctionDecl>( 6963 "void test(int A1, int A2) __attribute__((exclusive_trylock_function(1, " 6964 "A1, A2)));", 6965 FromAttr, ToAttr); 6966 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); 6967 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6968 } 6969 6970 TEST_P(ImportAttributes, ImportSharedTrylockFunction) { 6971 SharedTrylockFunctionAttr *FromAttr, *ToAttr; 6972 importAttr<FunctionDecl>( 6973 "void test(int A1, int A2) __attribute__((shared_trylock_function(1, A1, " 6974 "A2)));", 6975 FromAttr, ToAttr); 6976 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); 6977 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6978 } 6979 6980 TEST_P(ImportAttributes, ImportLockReturned) { 6981 LockReturnedAttr *FromAttr, *ToAttr; 6982 importAttr<FunctionDecl>( 6983 "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr, 6984 ToAttr); 6985 checkImported(FromAttr->getArg(), ToAttr->getArg()); 6986 } 6987 6988 TEST_P(ImportAttributes, ImportLocksExcluded) { 6989 LocksExcludedAttr *FromAttr, *ToAttr; 6990 importAttr<FunctionDecl>( 6991 "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));", 6992 FromAttr, ToAttr); 6993 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6994 } 6995 6996 template <typename T> 6997 auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) { 6998 auto Copy = Values; 6999 for (std::vector<std::string> &ArgV : Copy) { 7000 for (const std::string &Arg : Args) { 7001 ArgV.push_back(Arg); 7002 } 7003 } 7004 return ::testing::ValuesIn(Copy); 7005 } 7006 7007 struct ImportWithExternalSource : ASTImporterOptionSpecificTestBase { 7008 ImportWithExternalSource() { 7009 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 7010 ASTContext &FromContext, FileManager &FromFileManager, 7011 bool MinimalImport, 7012 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 7013 return new ASTImporter(ToContext, ToFileManager, FromContext, 7014 // Use minimal import for these tests. 7015 FromFileManager, /*MinimalImport=*/true, 7016 // We use the regular lookup. 7017 /*SharedState=*/nullptr); 7018 }; 7019 } 7020 }; 7021 7022 /// An ExternalASTSource that keeps track of the tags is completed. 7023 struct SourceWithCompletedTagList : clang::ExternalASTSource { 7024 std::vector<clang::TagDecl *> &CompletedTags; 7025 SourceWithCompletedTagList(std::vector<clang::TagDecl *> &CompletedTags) 7026 : CompletedTags(CompletedTags) {} 7027 void CompleteType(TagDecl *Tag) override { 7028 auto *Record = cast<CXXRecordDecl>(Tag); 7029 Record->startDefinition(); 7030 Record->completeDefinition(); 7031 CompletedTags.push_back(Tag); 7032 } 7033 using clang::ExternalASTSource::CompleteType; 7034 }; 7035 7036 TEST_P(ImportWithExternalSource, CompleteRecordBeforeImporting) { 7037 // Create an empty TU. 7038 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cpp"); 7039 7040 // Create and add the test ExternalASTSource. 7041 std::vector<clang::TagDecl *> CompletedTags; 7042 IntrusiveRefCntPtr<ExternalASTSource> source = 7043 new SourceWithCompletedTagList(CompletedTags); 7044 clang::ASTContext &Context = FromTU->getASTContext(); 7045 Context.setExternalSource(std::move(source)); 7046 7047 // Create a dummy class by hand with external lexical storage. 7048 IdentifierInfo &Ident = Context.Idents.get("test_class"); 7049 auto *Record = CXXRecordDecl::Create( 7050 Context, TTK_Class, FromTU, SourceLocation(), SourceLocation(), &Ident); 7051 Record->setHasExternalLexicalStorage(); 7052 FromTU->addDecl(Record); 7053 7054 // Do a minimal import of the created class. 7055 EXPECT_EQ(0U, CompletedTags.size()); 7056 Import(Record, Lang_CXX03); 7057 EXPECT_EQ(0U, CompletedTags.size()); 7058 7059 // Import the definition of the created class. 7060 llvm::Error Err = findFromTU(Record)->Importer->ImportDefinition(Record); 7061 EXPECT_FALSE((bool)Err); 7062 consumeError(std::move(Err)); 7063 7064 // Make sure the class was completed once. 7065 EXPECT_EQ(1U, CompletedTags.size()); 7066 EXPECT_EQ(Record, CompletedTags.front()); 7067 } 7068 7069 TEST_P(ImportFunctions, CTADImplicit) { 7070 Decl *FromTU = getTuDecl( 7071 R"( 7072 template <typename T> struct A { 7073 A(T); 7074 }; 7075 A a{(int)0}; 7076 )", 7077 Lang_CXX17, "input.cc"); 7078 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7079 FromTU, 7080 cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>"))))); 7081 auto *ToD = Import(FromD, Lang_CXX17); 7082 ASSERT_TRUE(ToD); 7083 EXPECT_TRUE(ToD->isCopyDeductionCandidate()); 7084 // Check that the deduced class template is also imported. 7085 EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull( 7086 FromD->getDeducedTemplate())); 7087 } 7088 7089 TEST_P(ImportFunctions, CTADUserDefinedExplicit) { 7090 Decl *FromTU = getTuDecl( 7091 R"( 7092 template <typename T> struct A { 7093 A(T); 7094 }; 7095 template <typename T> explicit A(T) -> A<float>; 7096 A a{(int)0}; // calls A<float>::A(float) 7097 )", 7098 Lang_CXX17, "input.cc"); 7099 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7100 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 7101 // Not-implicit: i.e. not compiler-generated, user defined. 7102 ASSERT_FALSE(FromD->isImplicit()); 7103 ASSERT_TRUE(FromD->isExplicit()); // Has the explicit keyword. 7104 auto *ToD = Import(FromD, Lang_CXX17); 7105 ASSERT_TRUE(ToD); 7106 EXPECT_FALSE(FromD->isImplicit()); 7107 EXPECT_TRUE(ToD->isExplicit()); 7108 } 7109 7110 TEST_P(ImportFunctions, CTADWithLocalTypedef) { 7111 Decl *TU = getTuDecl( 7112 R"( 7113 template <typename T> struct A { 7114 typedef T U; 7115 A(U); 7116 }; 7117 A a{(int)0}; 7118 )", 7119 Lang_CXX17, "input.cc"); 7120 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7121 TU, cxxDeductionGuideDecl()); 7122 auto *ToD = Import(FromD, Lang_CXX17); 7123 ASSERT_TRUE(ToD); 7124 } 7125 7126 TEST_P(ImportFunctions, ParmVarDeclDeclContext) { 7127 constexpr auto FromTUCode = R"( 7128 void f(int P); 7129 )"; 7130 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 7131 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 7132 FromTU, functionDecl(hasName("f"))); 7133 ASSERT_TRUE(FromF); 7134 7135 auto *ImportedF = Import(FromF, Lang_CXX11); 7136 EXPECT_TRUE(ImportedF); 7137 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 7138 ImportedF, ImportedF->getParamDecl(0))); 7139 } 7140 7141 // FIXME Move these tests out of ASTImporterTest. For that we need to factor 7142 // out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase 7143 // into a new test Fixture. Then we should lift up this Fixture to its own 7144 // implementation file and only then could we reuse the Fixture in other AST 7145 // unitttests. 7146 struct CTAD : ASTImporterOptionSpecificTestBase {}; 7147 7148 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) { 7149 Decl *TU = getTuDecl( 7150 R"( 7151 typedef int U; 7152 template <typename T> struct A { 7153 A(U, T); 7154 }; 7155 A a{(int)0, (int)0}; 7156 )", 7157 Lang_CXX17, "input.cc"); 7158 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7159 TU, cxxDeductionGuideDecl()); 7160 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 7161 TU, typedefNameDecl(hasName("U"))); 7162 ParmVarDecl *Param = Guide->getParamDecl(0); 7163 // The type of the first param (which is a typedef) should match the typedef 7164 // in the global scope. 7165 EXPECT_EQ(Param->getType()->castAs<TypedefType>()->getDecl(), Typedef); 7166 } 7167 7168 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) { 7169 Decl *TU = getTuDecl( 7170 R"( 7171 typedef int U; 7172 template <typename T> struct A { 7173 A(U*, T); 7174 }; 7175 A a{(int*)0, (int)0}; 7176 )", 7177 Lang_CXX17, "input.cc"); 7178 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7179 TU, cxxDeductionGuideDecl()); 7180 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 7181 TU, typedefNameDecl(hasName("U"))); 7182 ParmVarDecl *Param = Guide->getParamDecl(0); 7183 EXPECT_EQ(Param->getType() 7184 ->getAs<PointerType>() 7185 ->getPointeeType() 7186 ->getAs<TypedefType>() 7187 ->getDecl(), 7188 Typedef); 7189 } 7190 7191 TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) { 7192 Decl *TU = getTuDecl( 7193 R"( 7194 template <typename T> struct A { 7195 typedef T U; 7196 A(U, T); 7197 }; 7198 A a{(int)0, (int)0}; 7199 )", 7200 Lang_CXX17, "input.cc"); 7201 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7202 TU, cxxDeductionGuideDecl()); 7203 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 7204 TU, typedefNameDecl(hasName("U"))); 7205 ParmVarDecl *Param = Guide->getParamDecl(0); 7206 EXPECT_NE(Param->getType()->castAs<TypedefType>()->getDecl(), Typedef); 7207 } 7208 7209 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CTAD, 7210 DefaultTestValuesForRunOptions); 7211 7212 TEST_P(ASTImporterOptionSpecificTestBase, TypedefWithAttribute) { 7213 Decl *TU = getTuDecl( 7214 R"( 7215 namespace N { 7216 typedef int X __attribute__((annotate("A"))); 7217 } 7218 )", 7219 Lang_CXX17, "input.cc"); 7220 auto *FromD = 7221 FirstDeclMatcher<TypedefDecl>().match(TU, typedefDecl(hasName("X"))); 7222 auto *ToD = Import(FromD, Lang_CXX17); 7223 ASSERT_TRUE(ToD); 7224 ASSERT_EQ(ToD->getAttrs().size(), 1U); 7225 auto *ToAttr = dyn_cast<AnnotateAttr>(ToD->getAttrs()[0]); 7226 ASSERT_TRUE(ToAttr); 7227 EXPECT_EQ(ToAttr->getAnnotation(), "A"); 7228 } 7229 7230 TEST_P(ASTImporterOptionSpecificTestBase, 7231 ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) { 7232 Decl *FromTU = getTuDecl( 7233 R"( 7234 7235 namespace std { 7236 template<typename T> 7237 class basic_stringbuf; 7238 } 7239 namespace std { 7240 class char_traits; 7241 template<typename T = char_traits> 7242 class basic_stringbuf; 7243 } 7244 namespace std { 7245 template<typename T> 7246 class basic_stringbuf {}; 7247 } 7248 7249 )", 7250 Lang_CXX11); 7251 7252 auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match( 7253 FromTU, 7254 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); 7255 auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11)); 7256 EXPECT_TRUE(To1); 7257 7258 auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match( 7259 FromTU, 7260 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); 7261 auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11)); 7262 EXPECT_TRUE(To2); 7263 } 7264 7265 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfCapturedVLAType) { 7266 Decl *FromTU = getTuDecl( 7267 R"( 7268 void declToImport(int N) { 7269 int VLA[N]; 7270 [&VLA] {}; // FieldDecl inside the lambda. 7271 } 7272 )", 7273 Lang_CXX14); 7274 auto *FromFD = FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl()); 7275 ASSERT_TRUE(FromFD); 7276 ASSERT_TRUE(FromFD->hasCapturedVLAType()); 7277 7278 auto *ToFD = Import(FromFD, Lang_CXX14); 7279 EXPECT_TRUE(ToFD); 7280 EXPECT_TRUE(ToFD->hasCapturedVLAType()); 7281 EXPECT_NE(FromFD->getCapturedVLAType(), ToFD->getCapturedVLAType()); 7282 } 7283 7284 TEST_P(ASTImporterOptionSpecificTestBase, ImportEnumMemberSpecialization) { 7285 Decl *FromTU = getTuDecl( 7286 R"( 7287 template <class T> struct A { 7288 enum tagname { enumerator }; 7289 }; 7290 template struct A<int>; 7291 )", 7292 Lang_CXX03); 7293 auto *FromD = FirstDeclMatcher<EnumDecl>().match( 7294 FromTU, enumDecl(hasName("tagname"), 7295 hasParent(classTemplateSpecializationDecl()))); 7296 ASSERT_TRUE(FromD); 7297 ASSERT_TRUE(FromD->getMemberSpecializationInfo()); 7298 7299 auto *ToD = Import(FromD, Lang_CXX03); 7300 EXPECT_TRUE(ToD); 7301 EXPECT_TRUE(ToD->getMemberSpecializationInfo()); 7302 EXPECT_EQ(FromD->getTemplateSpecializationKind(), 7303 ToD->getTemplateSpecializationKind()); 7304 } 7305 7306 TEST_P(ASTImporterOptionSpecificTestBase, ImportIsInheritingConstructorBit) { 7307 Decl *FromTU = getTuDecl( 7308 R"( 7309 struct A { 7310 A(int); 7311 }; 7312 struct B : A { 7313 using A::A; // Inherited ctor. 7314 }; 7315 void f() { 7316 (B(0)); 7317 } 7318 )", 7319 Lang_CXX11); 7320 auto *FromD = FirstDeclMatcher<CXXConstructorDecl>().match( 7321 FromTU, cxxConstructorDecl(isInheritingConstructor())); 7322 ASSERT_TRUE(FromD); 7323 ASSERT_TRUE(FromD->isInheritingConstructor()); 7324 7325 auto *ToD = Import(FromD, Lang_CXX11); 7326 ASSERT_TRUE(ToD); 7327 EXPECT_TRUE(ToD->isInheritingConstructor()); 7328 } 7329 7330 TEST_P(ASTImporterOptionSpecificTestBase, ImportConstructorUsingShadow) { 7331 TranslationUnitDecl *FromTU = getTuDecl( 7332 R"( 7333 struct A { 7334 A(int, int); 7335 }; 7336 struct B : A { 7337 using A::A; 7338 }; 7339 struct C : B { 7340 using B::B; 7341 }; 7342 )", 7343 Lang_CXX11); 7344 7345 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordC) { 7346 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match( 7347 TU, cxxRecordDecl(hasName("A"))); 7348 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match( 7349 TU, cxxRecordDecl(hasName("B"))); 7350 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match( 7351 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)), 7352 parameterCountIs(2))); 7353 auto *ShadowBA = cast<ConstructorUsingShadowDecl>( 7354 FirstDeclMatcher<UsingShadowDecl>().match( 7355 TU, usingShadowDecl(hasParent(equalsNode(RecordB)), 7356 hasTargetDecl(equalsNode(ConstrA))))); 7357 auto *ShadowCA = cast<ConstructorUsingShadowDecl>( 7358 FirstDeclMatcher<UsingShadowDecl>().match( 7359 TU, usingShadowDecl(hasParent(equalsNode(RecordC)), 7360 hasTargetDecl(equalsNode(ConstrA))))); 7361 EXPECT_EQ(ShadowBA->getTargetDecl(), ConstrA); 7362 EXPECT_EQ(ShadowBA->getNominatedBaseClass(), RecordA); 7363 EXPECT_EQ(ShadowBA->getConstructedBaseClass(), RecordA); 7364 EXPECT_EQ(ShadowBA->getNominatedBaseClassShadowDecl(), nullptr); 7365 EXPECT_EQ(ShadowBA->getConstructedBaseClassShadowDecl(), nullptr); 7366 EXPECT_FALSE(ShadowBA->constructsVirtualBase()); 7367 EXPECT_EQ(ShadowCA->getTargetDecl(), ConstrA); 7368 EXPECT_EQ(ShadowCA->getNominatedBaseClass(), RecordB); 7369 EXPECT_EQ(ShadowCA->getConstructedBaseClass(), RecordB); 7370 EXPECT_EQ(ShadowCA->getNominatedBaseClassShadowDecl(), ShadowBA); 7371 EXPECT_EQ(ShadowCA->getConstructedBaseClassShadowDecl(), ShadowBA); 7372 EXPECT_FALSE(ShadowCA->constructsVirtualBase()); 7373 }; 7374 7375 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match( 7376 FromTU, cxxRecordDecl(hasName("C"))); 7377 7378 auto *ToC = Import(FromC, Lang_CXX11); 7379 TranslationUnitDecl *ToTU = ToC->getTranslationUnitDecl(); 7380 7381 CheckAST(FromTU, FromC); 7382 CheckAST(ToTU, ToC); 7383 } 7384 7385 AST_MATCHER_P(UsingShadowDecl, hasIntroducerDecl, internal::Matcher<NamedDecl>, 7386 InnerMatcher) { 7387 return InnerMatcher.matches(*Node.getIntroducer(), Finder, Builder); 7388 } 7389 7390 TEST_P(ASTImporterOptionSpecificTestBase, 7391 ImportConstructorUsingShadowVirtualBase) { 7392 TranslationUnitDecl *FromTU = getTuDecl( 7393 R"( 7394 struct A { A(int, int); }; 7395 struct B : A { using A::A; }; 7396 7397 struct V1 : virtual B { using B::B; }; 7398 struct V2 : virtual B { using B::B; }; 7399 7400 struct D2 : V1, V2 { 7401 using V1::V1; 7402 using V2::V2; 7403 }; 7404 )", 7405 Lang_CXX11); 7406 7407 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordD2) { 7408 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match( 7409 TU, cxxRecordDecl(hasName("A"))); 7410 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match( 7411 TU, cxxRecordDecl(hasName("B"))); 7412 auto *RecordV1 = FirstDeclMatcher<CXXRecordDecl>().match( 7413 TU, cxxRecordDecl(hasName("V1"))); 7414 auto *RecordV2 = FirstDeclMatcher<CXXRecordDecl>().match( 7415 TU, cxxRecordDecl(hasName("V2"))); 7416 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match( 7417 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)), 7418 parameterCountIs(2))); 7419 auto *ConstrB = FirstDeclMatcher<CXXConstructorDecl>().match( 7420 TU, cxxConstructorDecl(hasParent(equalsNode(RecordB)), 7421 isCopyConstructor())); 7422 auto *UsingD2V1 = FirstDeclMatcher<UsingDecl>().match( 7423 TU, usingDecl(hasParent(equalsNode(RecordD2)))); 7424 auto *UsingD2V2 = LastDeclMatcher<UsingDecl>().match( 7425 TU, usingDecl(hasParent(equalsNode(RecordD2)))); 7426 auto *ShadowBA = cast<ConstructorUsingShadowDecl>( 7427 FirstDeclMatcher<UsingShadowDecl>().match( 7428 TU, usingShadowDecl(hasParent(equalsNode(RecordB)), 7429 hasTargetDecl(equalsNode(ConstrA))))); 7430 auto *ShadowV1A = cast<ConstructorUsingShadowDecl>( 7431 FirstDeclMatcher<UsingShadowDecl>().match( 7432 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)), 7433 hasTargetDecl(equalsNode(ConstrA))))); 7434 auto *ShadowV1B = cast<ConstructorUsingShadowDecl>( 7435 FirstDeclMatcher<UsingShadowDecl>().match( 7436 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)), 7437 hasTargetDecl(equalsNode(ConstrB))))); 7438 auto *ShadowV2A = cast<ConstructorUsingShadowDecl>( 7439 FirstDeclMatcher<UsingShadowDecl>().match( 7440 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)), 7441 hasTargetDecl(equalsNode(ConstrA))))); 7442 auto *ShadowV2B = cast<ConstructorUsingShadowDecl>( 7443 FirstDeclMatcher<UsingShadowDecl>().match( 7444 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)), 7445 hasTargetDecl(equalsNode(ConstrB))))); 7446 auto *ShadowD2V1A = cast<ConstructorUsingShadowDecl>( 7447 FirstDeclMatcher<UsingShadowDecl>().match( 7448 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 7449 hasIntroducerDecl(equalsNode(UsingD2V1)), 7450 hasTargetDecl(equalsNode(ConstrA))))); 7451 auto *ShadowD2V1B = cast<ConstructorUsingShadowDecl>( 7452 FirstDeclMatcher<UsingShadowDecl>().match( 7453 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 7454 hasIntroducerDecl(equalsNode(UsingD2V1)), 7455 hasTargetDecl(equalsNode(ConstrB))))); 7456 auto *ShadowD2V2A = cast<ConstructorUsingShadowDecl>( 7457 FirstDeclMatcher<UsingShadowDecl>().match( 7458 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 7459 hasIntroducerDecl(equalsNode(UsingD2V2)), 7460 hasTargetDecl(equalsNode(ConstrA))))); 7461 auto *ShadowD2V2B = cast<ConstructorUsingShadowDecl>( 7462 FirstDeclMatcher<UsingShadowDecl>().match( 7463 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 7464 hasIntroducerDecl(equalsNode(UsingD2V2)), 7465 hasTargetDecl(equalsNode(ConstrB))))); 7466 7467 EXPECT_EQ(ShadowD2V1A->getTargetDecl(), ConstrA); 7468 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClassShadowDecl(), ShadowV1A); 7469 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClass(), RecordV1); 7470 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClassShadowDecl(), ShadowBA); 7471 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClass(), RecordB); 7472 EXPECT_TRUE(ShadowD2V1A->constructsVirtualBase()); 7473 EXPECT_EQ(ShadowD2V1B->getTargetDecl(), ConstrB); 7474 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClassShadowDecl(), ShadowV1B); 7475 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClass(), RecordV1); 7476 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClassShadowDecl(), nullptr); 7477 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClass(), RecordB); 7478 EXPECT_TRUE(ShadowD2V1B->constructsVirtualBase()); 7479 EXPECT_EQ(ShadowD2V2A->getTargetDecl(), ConstrA); 7480 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClassShadowDecl(), ShadowV2A); 7481 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClass(), RecordV2); 7482 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClassShadowDecl(), ShadowBA); 7483 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClass(), RecordB); 7484 EXPECT_TRUE(ShadowD2V2A->constructsVirtualBase()); 7485 EXPECT_EQ(ShadowD2V2B->getTargetDecl(), ConstrB); 7486 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClassShadowDecl(), ShadowV2B); 7487 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClass(), RecordV2); 7488 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClassShadowDecl(), nullptr); 7489 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClass(), RecordB); 7490 EXPECT_TRUE(ShadowD2V2B->constructsVirtualBase()); 7491 7492 EXPECT_TRUE(ShadowV1A->constructsVirtualBase()); 7493 EXPECT_TRUE(ShadowV1B->constructsVirtualBase()); 7494 EXPECT_TRUE(ShadowV2A->constructsVirtualBase()); 7495 EXPECT_TRUE(ShadowV2B->constructsVirtualBase()); 7496 EXPECT_FALSE(ShadowBA->constructsVirtualBase()); 7497 }; 7498 7499 auto *FromD2 = FirstDeclMatcher<CXXRecordDecl>().match( 7500 FromTU, cxxRecordDecl(hasName("D2"))); 7501 7502 auto *ToD2 = Import(FromD2, Lang_CXX11); 7503 TranslationUnitDecl *ToTU = ToD2->getTranslationUnitDecl(); 7504 7505 CheckAST(FromTU, FromD2); 7506 CheckAST(ToTU, ToD2); 7507 } 7508 7509 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingShadowList) { 7510 TranslationUnitDecl *FromTU = getTuDecl( 7511 R"( 7512 struct A { 7513 void f(); 7514 void f(int); 7515 }; 7516 struct B : A { 7517 using A::f; 7518 }; 7519 )", 7520 Lang_CXX11); 7521 7522 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match( 7523 FromTU, cxxRecordDecl(hasName("B"))); 7524 7525 auto *ToB = Import(FromB, Lang_CXX11); 7526 TranslationUnitDecl *ToTU = ToB->getTranslationUnitDecl(); 7527 7528 auto *ToUsing = FirstDeclMatcher<UsingDecl>().match( 7529 ToTU, usingDecl(hasParent(equalsNode(ToB)))); 7530 auto *ToUsingShadowF1 = FirstDeclMatcher<UsingShadowDecl>().match( 7531 ToTU, usingShadowDecl(hasTargetDecl( 7532 functionDecl(hasName("f"), parameterCountIs(0))))); 7533 auto *ToUsingShadowF2 = FirstDeclMatcher<UsingShadowDecl>().match( 7534 ToTU, usingShadowDecl(hasTargetDecl( 7535 functionDecl(hasName("f"), parameterCountIs(1))))); 7536 7537 EXPECT_EQ(ToUsing->shadow_size(), 2u); 7538 auto ShadowI = ToUsing->shadow_begin(); 7539 EXPECT_EQ(*ShadowI, ToUsingShadowF1); 7540 ++ShadowI; 7541 EXPECT_EQ(*ShadowI, ToUsingShadowF2); 7542 } 7543 7544 AST_MATCHER_P(FunctionTemplateDecl, templateParameterCountIs, unsigned, Cnt) { 7545 return Node.getTemplateParameters()->size() == Cnt; 7546 } 7547 7548 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuide) { 7549 TranslationUnitDecl *FromTU = getTuDecl( 7550 R"( 7551 template<class> class A { }; 7552 template<class T> class B { 7553 template<class T1, typename = A<T>> B(T1); 7554 }; 7555 template<class T> 7556 B(T, T) -> B<int>; 7557 )", 7558 Lang_CXX17); 7559 7560 // Get the implicit deduction guide for (non-default) constructor of 'B'. 7561 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 7562 FromTU, functionTemplateDecl(templateParameterCountIs(3))); 7563 // Implicit deduction guide for copy constructor of 'B'. 7564 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 7565 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit())); 7566 // User defined deduction guide. 7567 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7568 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 7569 7570 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters(); 7571 // Don't know why exactly but this is the DeclContext here. 7572 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(), 7573 FromDGCopyCtor->getTemplatedDecl()); 7574 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(), 7575 FromDGCtor->getTemplatedDecl()); 7576 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(), 7577 FromDGCtor->getTemplatedDecl()); 7578 EXPECT_EQ( 7579 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 7580 FromDGCopyCtor->getTemplatedDecl()); 7581 EXPECT_EQ(FromDGOther->getDescribedTemplate() 7582 ->getTemplateParameters() 7583 ->getParam(0) 7584 ->getDeclContext(), 7585 FromDGOther); 7586 7587 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17); 7588 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17); 7589 auto *ToDGOther = Import(FromDGOther, Lang_CXX17); 7590 ASSERT_TRUE(ToDGCtor); 7591 ASSERT_TRUE(ToDGCopyCtor); 7592 ASSERT_TRUE(ToDGOther); 7593 7594 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters(); 7595 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(), 7596 ToDGCopyCtor->getTemplatedDecl()); 7597 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(), 7598 ToDGCtor->getTemplatedDecl()); 7599 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(), 7600 ToDGCtor->getTemplatedDecl()); 7601 EXPECT_EQ( 7602 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 7603 ToDGCopyCtor->getTemplatedDecl()); 7604 EXPECT_EQ(ToDGOther->getDescribedTemplate() 7605 ->getTemplateParameters() 7606 ->getParam(0) 7607 ->getDeclContext(), 7608 ToDGOther); 7609 } 7610 7611 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuideDifferentOrder) { 7612 // This test demonstrates that the DeclContext of the imported object is 7613 // dependent on the order of import. The test is an exact copy of the previous 7614 // one except at the indicated locations. 7615 TranslationUnitDecl *FromTU = getTuDecl( 7616 R"( 7617 template<class> class A { }; 7618 template<class T> class B { 7619 template<class T1, typename = A<T>> B(T1); 7620 }; 7621 template<class T> 7622 B(T, T) -> B<int>; 7623 )", 7624 Lang_CXX17); 7625 7626 // Get the implicit deduction guide for (non-default) constructor of 'B'. 7627 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 7628 FromTU, functionTemplateDecl(templateParameterCountIs(3))); 7629 // Implicit deduction guide for copy constructor of 'B'. 7630 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 7631 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit())); 7632 // User defined deduction guide. 7633 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7634 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 7635 7636 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters(); 7637 // Don't know why exactly but this is the DeclContext here. 7638 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(), 7639 FromDGCopyCtor->getTemplatedDecl()); 7640 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(), 7641 FromDGCtor->getTemplatedDecl()); 7642 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(), 7643 FromDGCtor->getTemplatedDecl()); 7644 EXPECT_EQ( 7645 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 7646 FromDGCopyCtor->getTemplatedDecl()); 7647 EXPECT_EQ(FromDGOther->getDescribedTemplate() 7648 ->getTemplateParameters() 7649 ->getParam(0) 7650 ->getDeclContext(), 7651 FromDGOther); 7652 7653 // Here the import of 'ToDGCopyCtor' and 'ToDGCtor' is reversed relative to 7654 // the previous test. 7655 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17); 7656 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17); 7657 auto *ToDGOther = Import(FromDGOther, Lang_CXX17); 7658 ASSERT_TRUE(ToDGCtor); 7659 ASSERT_TRUE(ToDGCopyCtor); 7660 ASSERT_TRUE(ToDGOther); 7661 7662 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters(); 7663 // Next line: DeclContext is different relative to the previous test. 7664 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(), 7665 ToDGCtor->getTemplatedDecl()); 7666 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(), 7667 ToDGCtor->getTemplatedDecl()); 7668 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(), 7669 ToDGCtor->getTemplatedDecl()); 7670 // Next line: DeclContext is different relative to the previous test. 7671 EXPECT_EQ( 7672 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 7673 ToDGCtor->getTemplatedDecl()); 7674 EXPECT_EQ(ToDGOther->getDescribedTemplate() 7675 ->getTemplateParameters() 7676 ->getParam(0) 7677 ->getDeclContext(), 7678 ToDGOther); 7679 } 7680 7681 TEST_P(ASTImporterOptionSpecificTestBase, 7682 ImportRecordWithLayoutRequestingExpr) { 7683 TranslationUnitDecl *FromTU = getTuDecl( 7684 R"( 7685 struct A { 7686 int idx; 7687 static void foo(A x) { 7688 (void)&"text"[x.idx]; 7689 } 7690 }; 7691 )", 7692 Lang_CXX11); 7693 7694 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 7695 FromTU, cxxRecordDecl(hasName("A"))); 7696 7697 // Test that during import of 'foo' the record layout can be obtained without 7698 // crash. 7699 auto *ToA = Import(FromA, Lang_CXX11); 7700 EXPECT_TRUE(ToA); 7701 EXPECT_TRUE(ToA->isCompleteDefinition()); 7702 } 7703 7704 TEST_P(ASTImporterOptionSpecificTestBase, 7705 ImportRecordWithLayoutRequestingExprDifferentRecord) { 7706 TranslationUnitDecl *FromTU = getTuDecl( 7707 R"( 7708 struct B; 7709 struct A { 7710 int idx; 7711 B *b; 7712 }; 7713 struct B { 7714 static void foo(A x) { 7715 (void)&"text"[x.idx]; 7716 } 7717 }; 7718 )", 7719 Lang_CXX11); 7720 7721 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 7722 FromTU, cxxRecordDecl(hasName("A"))); 7723 7724 // Test that during import of 'foo' the record layout (of 'A') can be obtained 7725 // without crash. It is not possible to have all of the fields of 'A' imported 7726 // at that time (without big code changes). 7727 auto *ToA = Import(FromA, Lang_CXX11); 7728 EXPECT_TRUE(ToA); 7729 EXPECT_TRUE(ToA->isCompleteDefinition()); 7730 } 7731 7732 TEST_P(ASTImporterOptionSpecificTestBase, ImportInClassInitializerFromField) { 7733 // Encounter import of a field when the field already exists but has the 7734 // in-class initializer expression not yet set. Such case can occur in the AST 7735 // of generated template specializations. 7736 // The first code forces to create a template specialization of 7737 // `A<int>` but without implicit constructors. 7738 // The second ("From") code contains a variable of type `A<int>`, this 7739 // results in a template specialization that has constructors and 7740 // CXXDefaultInitExpr nodes. 7741 Decl *ToTU = getToTuDecl( 7742 R"( 7743 void f(); 7744 template<typename> struct A { int X = 1; }; 7745 struct B { A<int> Y; }; 7746 )", 7747 Lang_CXX11); 7748 auto *ToX = FirstDeclMatcher<FieldDecl>().match( 7749 ToTU, 7750 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl()))); 7751 ASSERT_TRUE(ToX->hasInClassInitializer()); 7752 ASSERT_FALSE(ToX->getInClassInitializer()); 7753 7754 Decl *FromTU = getTuDecl( 7755 R"( 7756 void f(); 7757 template<typename> struct A { int X = 1; }; 7758 struct B { A<int> Y; }; 7759 // 7760 A<int> Z; 7761 )", 7762 Lang_CXX11, "input1.cc"); 7763 auto *FromX = FirstDeclMatcher<FieldDecl>().match( 7764 FromTU, 7765 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl()))); 7766 7767 auto *ToXImported = Import(FromX, Lang_CXX11); 7768 EXPECT_EQ(ToXImported, ToX); 7769 EXPECT_TRUE(ToX->getInClassInitializer()); 7770 } 7771 7772 TEST_P(ASTImporterOptionSpecificTestBase, 7773 ImportInClassInitializerFromCXXDefaultInitExpr) { 7774 // Encounter AST import of a CXXDefaultInitExpr where the "to-field" 7775 // of it exists but has the in-class initializer not set yet. 7776 Decl *ToTU = getToTuDecl( 7777 R"( 7778 namespace N { 7779 template<typename> int b; 7780 struct X; 7781 } 7782 template<typename> struct A { N::X *X = nullptr; }; 7783 struct B { A<int> Y; }; 7784 )", 7785 Lang_CXX14); 7786 auto *ToX = FirstDeclMatcher<FieldDecl>().match( 7787 ToTU, 7788 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl()))); 7789 ASSERT_TRUE(ToX->hasInClassInitializer()); 7790 ASSERT_FALSE(ToX->getInClassInitializer()); 7791 7792 Decl *FromTU = getTuDecl( 7793 R"( 7794 namespace N { 7795 template<typename> int b; 7796 struct X; 7797 } 7798 template<typename> struct A { N::X *X = nullptr; }; 7799 struct B { A<int> Y; }; 7800 // 7801 void f() { 7802 (void)A<int>{}; 7803 } 7804 struct C { 7805 C(): attr(new A<int>{}){} 7806 A<int> *attr; 7807 const int value = N::b<C>; 7808 }; 7809 )", 7810 Lang_CXX14, "input1.cc"); 7811 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 7812 FromTU, functionDecl(hasName("f"), isDefinition())); 7813 auto *ToF = Import(FromF, Lang_CXX11); 7814 EXPECT_TRUE(ToF); 7815 EXPECT_TRUE(ToX->getInClassInitializer()); 7816 } 7817 7818 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) { 7819 Decl *FromTU = getTuDecl( 7820 R"( 7821 int bar() { 7822 return 0; 7823 } 7824 void other() { 7825 bar(); 7826 } 7827 )", 7828 Lang_CXX11); 7829 Decl *ToTU = getToTuDecl( 7830 R"( 7831 int bar() { 7832 return 0; 7833 } 7834 )", 7835 Lang_CXX11); 7836 auto *FromOther = FirstDeclMatcher<FunctionDecl>().match( 7837 FromTU, functionDecl(hasName("other"))); 7838 ASSERT_TRUE(FromOther); 7839 7840 auto *ToOther = Import(FromOther, Lang_CXX11); 7841 ASSERT_TRUE(ToOther); 7842 7843 auto *ToBar = FirstDeclMatcher<FunctionDecl>().match( 7844 ToTU, functionDecl(hasName("bar"))); 7845 7846 EXPECT_TRUE(SharedStatePtr->isNewDecl(ToOther)); 7847 EXPECT_FALSE(SharedStatePtr->isNewDecl(ToBar)); 7848 } 7849 7850 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest, 7851 DefaultTestValuesForRunOptions); 7852 7853 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportPath, 7854 ::testing::Values(std::vector<std::string>())); 7855 7856 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportExpr, 7857 DefaultTestValuesForRunOptions); 7858 7859 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFixedPointExpr, 7860 ExtendWithOptions(DefaultTestArrayForRunOptions, 7861 std::vector<std::string>{ 7862 "-ffixed-point"})); 7863 7864 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportBlock, 7865 ExtendWithOptions(DefaultTestArrayForRunOptions, 7866 std::vector<std::string>{ 7867 "-fblocks"})); 7868 7869 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportType, 7870 DefaultTestValuesForRunOptions); 7871 7872 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportDecl, 7873 DefaultTestValuesForRunOptions); 7874 7875 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterOptionSpecificTestBase, 7876 DefaultTestValuesForRunOptions); 7877 7878 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ErrorHandlingTest, 7879 DefaultTestValuesForRunOptions); 7880 7881 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, RedirectingImporterTest, 7882 DefaultTestValuesForRunOptions); 7883 7884 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctions, 7885 DefaultTestValuesForRunOptions); 7886 7887 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAutoFunctions, 7888 DefaultTestValuesForRunOptions); 7889 7890 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctionTemplates, 7891 DefaultTestValuesForRunOptions); 7892 7893 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctionTemplates, 7894 DefaultTestValuesForRunOptions); 7895 7896 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportClasses, 7897 DefaultTestValuesForRunOptions); 7898 7899 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctions, 7900 DefaultTestValuesForRunOptions); 7901 7902 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendClasses, 7903 DefaultTestValuesForRunOptions); 7904 7905 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, 7906 ImportFunctionTemplateSpecializations, 7907 DefaultTestValuesForRunOptions); 7908 7909 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportImplicitMethods, 7910 DefaultTestValuesForRunOptions); 7911 7912 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportVariables, 7913 DefaultTestValuesForRunOptions); 7914 7915 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, LLDBLookupTest, 7916 DefaultTestValuesForRunOptions); 7917 7918 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportSourceLocations, 7919 DefaultTestValuesForRunOptions); 7920 7921 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportWithExternalSource, 7922 DefaultTestValuesForRunOptions); 7923 7924 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAttributes, 7925 DefaultTestValuesForRunOptions); 7926 7927 } // end namespace ast_matchers 7928 } // end namespace clang 7929