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 ImportError &Error) { 3212 EXPECT_EQ(ImportError::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<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromSpec); 5473 ASSERT_TRUE(OptErr); 5474 EXPECT_EQ(OptErr->Error, ImportError::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<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFoo); 5497 ASSERT_TRUE(OptErr); 5498 EXPECT_EQ(OptErr->Error, ImportError::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<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromProto); 5530 ASSERT_TRUE(OptErr); 5531 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5532 OptErr = Importer->getImportDeclErrorIfAny(FromDef); 5533 ASSERT_TRUE(OptErr); 5534 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5535 } 5536 5537 // An error should be set for a class if we cannot import one member. 5538 TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) { 5539 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5540 class X { 5541 void f() { )") + ErroneousStmt + R"( } // This member has the error 5542 // during import. 5543 void ok(); // The error should not prevent importing this. 5544 }; // An error will be set for X too. 5545 )", 5546 Lang_CXX03); 5547 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5548 FromTU, cxxRecordDecl(hasName("X"))); 5549 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 5550 5551 // An error is set for X. 5552 EXPECT_FALSE(ImportedX); 5553 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5554 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5555 ASSERT_TRUE(OptErr); 5556 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5557 5558 // An error is set for f(). 5559 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match( 5560 FromTU, cxxMethodDecl(hasName("f"))); 5561 OptErr = Importer->getImportDeclErrorIfAny(FromF); 5562 ASSERT_TRUE(OptErr); 5563 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5564 // And any subsequent import should fail. 5565 CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX03); 5566 EXPECT_FALSE(ImportedF); 5567 5568 // There is an error set for the other member too. 5569 auto *FromOK = FirstDeclMatcher<CXXMethodDecl>().match( 5570 FromTU, cxxMethodDecl(hasName("ok"))); 5571 OptErr = Importer->getImportDeclErrorIfAny(FromOK); 5572 EXPECT_TRUE(OptErr); 5573 // Cannot import the other member. 5574 CXXMethodDecl *ImportedOK = Import(FromOK, Lang_CXX03); 5575 EXPECT_FALSE(ImportedOK); 5576 } 5577 5578 // Check that an error propagates to the dependent AST nodes. 5579 // In the below code it means that an error in X should propagate to A. 5580 // And even to F since the containing A is erroneous. 5581 // And to all AST nodes which we visit during the import process which finally 5582 // ends up in a failure (in the error() function). 5583 TEST_P(ErrorHandlingTest, ErrorPropagatesThroughImportCycles) { 5584 Decl *FromTU = getTuDecl(std::string(R"( 5585 namespace NS { 5586 class A { 5587 template <int I> class F {}; 5588 class X { 5589 template <int I> friend class F; 5590 void error() { )") + 5591 ErroneousStmt + R"( } 5592 }; 5593 }; 5594 5595 class B {}; 5596 } // NS 5597 )", 5598 Lang_CXX03, "input0.cc"); 5599 5600 auto *FromFRD = FirstDeclMatcher<CXXRecordDecl>().match( 5601 FromTU, cxxRecordDecl(hasName("F"), isDefinition())); 5602 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 5603 FromTU, cxxRecordDecl(hasName("A"), isDefinition())); 5604 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match( 5605 FromTU, cxxRecordDecl(hasName("B"), isDefinition())); 5606 auto *FromNS = FirstDeclMatcher<NamespaceDecl>().match( 5607 FromTU, namespaceDecl(hasName("NS"))); 5608 5609 // Start by importing the templated CXXRecordDecl of F. 5610 // Import fails for that. 5611 EXPECT_FALSE(Import(FromFRD, Lang_CXX03)); 5612 // Import fails for A. 5613 EXPECT_FALSE(Import(FromA, Lang_CXX03)); 5614 // But we should be able to import the independent B. 5615 EXPECT_TRUE(Import(FromB, Lang_CXX03)); 5616 // And the namespace. 5617 EXPECT_TRUE(Import(FromNS, Lang_CXX03)); 5618 5619 // An error is set to the templated CXXRecordDecl of F. 5620 ASTImporter *Importer = findFromTU(FromFRD)->Importer.get(); 5621 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFRD); 5622 EXPECT_TRUE(OptErr); 5623 5624 // An error is set to A. 5625 OptErr = Importer->getImportDeclErrorIfAny(FromA); 5626 EXPECT_TRUE(OptErr); 5627 5628 // There is no error set to B. 5629 OptErr = Importer->getImportDeclErrorIfAny(FromB); 5630 EXPECT_FALSE(OptErr); 5631 5632 // There is no error set to NS. 5633 OptErr = Importer->getImportDeclErrorIfAny(FromNS); 5634 EXPECT_FALSE(OptErr); 5635 5636 // Check some of those decls whose ancestor is X, they all should have an 5637 // error set if we visited them during an import process which finally failed. 5638 // These decls are part of a cycle in an ImportPath. 5639 // There would not be any error set for these decls if we hadn't follow the 5640 // ImportPaths and the cycles. 5641 OptErr = Importer->getImportDeclErrorIfAny( 5642 FirstDeclMatcher<ClassTemplateDecl>().match( 5643 FromTU, classTemplateDecl(hasName("F")))); 5644 // An error is set to the 'F' ClassTemplateDecl. 5645 EXPECT_TRUE(OptErr); 5646 // An error is set to the FriendDecl. 5647 OptErr = Importer->getImportDeclErrorIfAny( 5648 FirstDeclMatcher<FriendDecl>().match( 5649 FromTU, friendDecl())); 5650 EXPECT_TRUE(OptErr); 5651 // An error is set to the implicit class of A. 5652 OptErr = 5653 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match( 5654 FromTU, cxxRecordDecl(hasName("A"), isImplicit()))); 5655 EXPECT_TRUE(OptErr); 5656 // An error is set to the implicit class of X. 5657 OptErr = 5658 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match( 5659 FromTU, cxxRecordDecl(hasName("X"), isImplicit()))); 5660 EXPECT_TRUE(OptErr); 5661 } 5662 5663 TEST_P(ErrorHandlingTest, ErrorIsNotPropagatedFromMemberToNamespace) { 5664 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5665 namespace X { 5666 void f() { )") + ErroneousStmt + R"( } // This member has the error 5667 // during import. 5668 void ok(); // The error should not prevent importing this. 5669 }; // An error will be set for X too. 5670 )", 5671 Lang_CXX03); 5672 auto *FromX = FirstDeclMatcher<NamespaceDecl>().match( 5673 FromTU, namespaceDecl(hasName("X"))); 5674 NamespaceDecl *ImportedX = Import(FromX, Lang_CXX03); 5675 5676 // There is no error set for X. 5677 EXPECT_TRUE(ImportedX); 5678 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5679 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5680 ASSERT_FALSE(OptErr); 5681 5682 // An error is set for f(). 5683 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 5684 FromTU, functionDecl(hasName("f"))); 5685 OptErr = Importer->getImportDeclErrorIfAny(FromF); 5686 ASSERT_TRUE(OptErr); 5687 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5688 // And any subsequent import should fail. 5689 FunctionDecl *ImportedF = Import(FromF, Lang_CXX03); 5690 EXPECT_FALSE(ImportedF); 5691 5692 // There is no error set for ok(). 5693 auto *FromOK = FirstDeclMatcher<FunctionDecl>().match( 5694 FromTU, functionDecl(hasName("ok"))); 5695 OptErr = Importer->getImportDeclErrorIfAny(FromOK); 5696 EXPECT_FALSE(OptErr); 5697 // And we should be able to import. 5698 FunctionDecl *ImportedOK = Import(FromOK, Lang_CXX03); 5699 EXPECT_TRUE(ImportedOK); 5700 } 5701 5702 TEST_P(ErrorHandlingTest, ODRViolationWithinTypedefDecls) { 5703 // Importing `z` should fail - instead of crashing - due to an ODR violation. 5704 // The `bar::e` typedef sets it's DeclContext after the import is done. 5705 // However, if the importation fails, it will be left as a nullptr. 5706 // During the cleanup of the failed import, we should check whether the 5707 // DeclContext is null or not - instead of dereferencing that unconditionally. 5708 constexpr auto ToTUCode = R"( 5709 namespace X { 5710 struct bar { 5711 int odr_violation; 5712 }; 5713 })"; 5714 constexpr auto FromTUCode = R"( 5715 namespace X { 5716 enum b {}; 5717 struct bar { 5718 typedef b e; 5719 static e d; 5720 }; 5721 } 5722 int z = X::bar::d; 5723 )"; 5724 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11); 5725 static_cast<void>(ToTU); 5726 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 5727 auto *FromZ = 5728 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("z"))); 5729 ASSERT_TRUE(FromZ); 5730 ASSERT_TRUE(FromZ->hasInit()); 5731 5732 auto *ImportedZ = Import(FromZ, Lang_CXX11); 5733 EXPECT_FALSE(ImportedZ); 5734 } 5735 5736 // An error should be set for a class if it had a previous import with an error 5737 // from another TU. 5738 TEST_P(ErrorHandlingTest, 5739 ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt) { 5740 // We already have a fwd decl. 5741 TranslationUnitDecl *ToTU = getToTuDecl("class X;", Lang_CXX03); 5742 // Then we import a definition. 5743 { 5744 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5745 class X { 5746 void f() { )") + ErroneousStmt + R"( } 5747 void ok(); 5748 }; 5749 )", 5750 Lang_CXX03); 5751 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5752 FromTU, cxxRecordDecl(hasName("X"))); 5753 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 5754 5755 // An error is set for X ... 5756 EXPECT_FALSE(ImportedX); 5757 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5758 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5759 ASSERT_TRUE(OptErr); 5760 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5761 } 5762 // ... but the node had been created. 5763 auto *ToXDef = FirstDeclMatcher<CXXRecordDecl>().match( 5764 ToTU, cxxRecordDecl(hasName("X"), isDefinition())); 5765 // An error is set for "ToXDef" in the shared state. 5766 Optional<ImportError> OptErr = 5767 SharedStatePtr->getImportDeclErrorIfAny(ToXDef); 5768 ASSERT_TRUE(OptErr); 5769 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5770 5771 auto *ToXFwd = FirstDeclMatcher<CXXRecordDecl>().match( 5772 ToTU, cxxRecordDecl(hasName("X"), unless(isDefinition()))); 5773 // An error is NOT set for the fwd Decl of X in the shared state. 5774 OptErr = SharedStatePtr->getImportDeclErrorIfAny(ToXFwd); 5775 ASSERT_FALSE(OptErr); 5776 5777 // Try to import X again but from another TU. 5778 { 5779 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5780 class X { 5781 void f() { )") + ErroneousStmt + R"( } 5782 void ok(); 5783 }; 5784 )", 5785 Lang_CXX03, "input1.cc"); 5786 5787 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 5788 FromTU, cxxRecordDecl(hasName("X"))); 5789 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 5790 5791 // If we did not save the errors for the "to" context then the below checks 5792 // would fail, because the lookup finds the fwd Decl of the existing 5793 // definition in the "to" context. We can reach the existing definition via 5794 // the found fwd Decl. That existing definition is structurally equivalent 5795 // (we check only the fields) with this one we want to import, so we return 5796 // with the existing definition, which is erroneous (one method is missing). 5797 5798 // The import should fail. 5799 EXPECT_FALSE(ImportedX); 5800 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 5801 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); 5802 // And an error is set for this new X in the "from" ctx. 5803 ASSERT_TRUE(OptErr); 5804 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5805 } 5806 } 5807 5808 TEST_P(ErrorHandlingTest, ImportOfOverriddenMethods) { 5809 auto MatchFooA = 5810 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A")))); 5811 auto MatchFooB = 5812 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B")))); 5813 auto MatchFooC = 5814 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("C")))); 5815 5816 // Provoke import of a method that has overridden methods with import error. 5817 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 5818 struct C; 5819 struct A { 5820 virtual void foo(); 5821 void f1(C *); 5822 }; 5823 void A::foo() { 5824 )") + ErroneousStmt + R"( 5825 } 5826 struct B : public A { 5827 void foo() override; 5828 }; 5829 struct C : public B { 5830 void foo() override; 5831 }; 5832 )", 5833 Lang_CXX11); 5834 auto *FromFooA = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooA); 5835 auto *FromFooB = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooB); 5836 auto *FromFooC = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooC); 5837 5838 EXPECT_FALSE(Import(FromFooA, Lang_CXX11)); 5839 ASTImporter *Importer = findFromTU(FromFooA)->Importer.get(); 5840 auto CheckError = [&Importer](Decl *FromD) { 5841 Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromD); 5842 ASSERT_TRUE(OptErr); 5843 EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); 5844 }; 5845 CheckError(FromFooA); 5846 EXPECT_FALSE(Import(FromFooB, Lang_CXX11)); 5847 CheckError(FromFooB); 5848 EXPECT_FALSE(Import(FromFooC, Lang_CXX11)); 5849 CheckError(FromFooC); 5850 } 5851 5852 TEST_P(ErrorHandlingTest, ODRViolationWithinParmVarDecls) { 5853 // Importing of 'f' and parameter 'P' should cause an ODR error. 5854 // The error happens after the ParmVarDecl for 'P' was already created. 5855 // This is a special case because the ParmVarDecl has a temporary DeclContext. 5856 // Expected is no crash at error handling of ASTImporter. 5857 constexpr auto ToTUCode = R"( 5858 struct X { 5859 char A; 5860 }; 5861 )"; 5862 constexpr auto FromTUCode = R"( 5863 struct X { 5864 enum Y { Z }; 5865 }; 5866 void f(int P = X::Z); 5867 )"; 5868 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11); 5869 static_cast<void>(ToTU); 5870 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 5871 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 5872 FromTU, functionDecl(hasName("f"))); 5873 ASSERT_TRUE(FromF); 5874 5875 auto *ImportedF = Import(FromF, Lang_CXX11); 5876 EXPECT_FALSE(ImportedF); 5877 } 5878 5879 TEST_P(ErrorHandlingTest, DoNotInheritErrorFromNonDependentChild) { 5880 // Declarations should not inherit an import error from a child object 5881 // if the declaration has no direct dependence to such a child. 5882 // For example a namespace should not get import error if one of the 5883 // declarations inside it fails to import. 5884 // There was a special case in error handling (when "import path circles" are 5885 // encountered) when this property was not held. This case is provoked by the 5886 // following code. 5887 constexpr auto ToTUCode = R"( 5888 namespace ns { 5889 struct Err { 5890 char A; 5891 }; 5892 } 5893 )"; 5894 constexpr auto FromTUCode = R"( 5895 namespace ns { 5896 struct A { 5897 using U = struct Err; 5898 }; 5899 } 5900 namespace ns { 5901 struct Err {}; // ODR violation 5902 void f(A) {} 5903 } 5904 )"; 5905 5906 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11); 5907 static_cast<void>(ToTU); 5908 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 5909 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 5910 FromTU, cxxRecordDecl(hasName("A"), hasDefinition())); 5911 ASSERT_TRUE(FromA); 5912 auto *ImportedA = Import(FromA, Lang_CXX11); 5913 // 'A' can not be imported: ODR error at 'Err' 5914 EXPECT_FALSE(ImportedA); 5915 // When import of 'A' failed there was a "saved import path circle" that 5916 // contained namespace 'ns' (A - U - Err - ns - f - A). This should not mean 5917 // that every object in this path fails to import. 5918 5919 Decl *FromNS = FirstDeclMatcher<NamespaceDecl>().match( 5920 FromTU, namespaceDecl(hasName("ns"))); 5921 EXPECT_TRUE(FromNS); 5922 auto *ImportedNS = Import(FromNS, Lang_CXX11); 5923 EXPECT_TRUE(ImportedNS); 5924 } 5925 5926 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) { 5927 Decl *FromTU = getTuDecl( 5928 R"( 5929 void f() { 5930 auto L = [](){}; 5931 } 5932 )", 5933 Lang_CXX11, "input0.cc"); 5934 auto Pattern = lambdaExpr(); 5935 CXXRecordDecl *FromL = 5936 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 5937 5938 auto ToL = Import(FromL, Lang_CXX11); 5939 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); 5940 unsigned FromLSize = 5941 std::distance(FromL->decls().begin(), FromL->decls().end()); 5942 EXPECT_NE(ToLSize, 0u); 5943 EXPECT_EQ(ToLSize, FromLSize); 5944 EXPECT_FALSE(FromL->isDependentLambda()); 5945 } 5946 5947 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) { 5948 Decl *FromTU = getTuDecl( 5949 R"( 5950 template <typename F> 5951 void f(F L = [](){}) {} 5952 )", 5953 Lang_CXX11, "input0.cc"); 5954 auto Pattern = lambdaExpr(); 5955 CXXRecordDecl *FromL = 5956 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 5957 5958 auto ToL = Import(FromL, Lang_CXX11); 5959 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); 5960 unsigned FromLSize = 5961 std::distance(FromL->decls().begin(), FromL->decls().end()); 5962 EXPECT_NE(ToLSize, 0u); 5963 EXPECT_EQ(ToLSize, FromLSize); 5964 EXPECT_TRUE(FromL->isDependentLambda()); 5965 } 5966 5967 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInGlobalScope) { 5968 Decl *FromTU = getTuDecl( 5969 R"( 5970 auto l1 = [](unsigned lp) { return 1; }; 5971 auto l2 = [](int lp) { return 2; }; 5972 int f(int p) { 5973 return l1(p) + l2(p); 5974 } 5975 )", 5976 Lang_CXX11, "input0.cc"); 5977 FunctionDecl *FromF = FirstDeclMatcher<FunctionDecl>().match( 5978 FromTU, functionDecl(hasName("f"))); 5979 FunctionDecl *ToF = Import(FromF, Lang_CXX11); 5980 EXPECT_TRUE(ToF); 5981 } 5982 5983 TEST_P(ASTImporterOptionSpecificTestBase, 5984 ImportExistingFriendClassTemplateDef) { 5985 auto Code = 5986 R"( 5987 template <class T1, class T2> 5988 struct Base { 5989 template <class U1, class U2> 5990 friend struct Class; 5991 }; 5992 template <class T1, class T2> 5993 struct Class { }; 5994 )"; 5995 5996 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 5997 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc"); 5998 5999 auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match( 6000 ToTU, classTemplateDecl(hasName("Class"))); 6001 auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match( 6002 ToTU, classTemplateDecl(hasName("Class"))); 6003 ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition()); 6004 ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition()); 6005 // Previous friend decl is not linked to it! 6006 ASSERT_FALSE(ToClassDef->getPreviousDecl()); 6007 ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef); 6008 ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto); 6009 6010 auto *FromClassProto = FirstDeclMatcher<ClassTemplateDecl>().match( 6011 FromTU, classTemplateDecl(hasName("Class"))); 6012 auto *FromClassDef = LastDeclMatcher<ClassTemplateDecl>().match( 6013 FromTU, classTemplateDecl(hasName("Class"))); 6014 ASSERT_FALSE(FromClassProto->isThisDeclarationADefinition()); 6015 ASSERT_TRUE(FromClassDef->isThisDeclarationADefinition()); 6016 ASSERT_FALSE(FromClassDef->getPreviousDecl()); 6017 ASSERT_EQ(FromClassDef->getMostRecentDecl(), FromClassDef); 6018 ASSERT_EQ(FromClassProto->getMostRecentDecl(), FromClassProto); 6019 6020 auto *ImportedDef = Import(FromClassDef, Lang_CXX03); 6021 // At import we should find the definition for 'Class' even if the 6022 // prototype (inside 'friend') for it comes first in the AST and is not 6023 // linked to the definition. 6024 EXPECT_EQ(ImportedDef, ToClassDef); 6025 } 6026 6027 struct LLDBLookupTest : ASTImporterOptionSpecificTestBase { 6028 LLDBLookupTest() { 6029 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 6030 ASTContext &FromContext, FileManager &FromFileManager, 6031 bool MinimalImport, 6032 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 6033 return new ASTImporter(ToContext, ToFileManager, FromContext, 6034 FromFileManager, MinimalImport, 6035 // We use the regular lookup. 6036 /*SharedState=*/nullptr); 6037 }; 6038 } 6039 }; 6040 6041 TEST_P(LLDBLookupTest, ImporterShouldFindInTransparentContext) { 6042 TranslationUnitDecl *ToTU = getToTuDecl( 6043 R"( 6044 extern "C" { 6045 class X{}; 6046 }; 6047 )", 6048 Lang_CXX03); 6049 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match( 6050 ToTU, cxxRecordDecl(hasName("X"))); 6051 6052 // Set up a stub external storage. 6053 ToTU->setHasExternalLexicalStorage(true); 6054 // Set up DeclContextBits.HasLazyExternalLexicalLookups to true. 6055 ToTU->setMustBuildLookupTable(); 6056 struct TestExternalASTSource : ExternalASTSource {}; 6057 ToTU->getASTContext().setExternalSource(new TestExternalASTSource()); 6058 6059 Decl *FromTU = getTuDecl( 6060 R"( 6061 class X; 6062 )", 6063 Lang_CXX03); 6064 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 6065 FromTU, cxxRecordDecl(hasName("X"))); 6066 auto *ImportedX = Import(FromX, Lang_CXX03); 6067 // The lookup must find the existing class definition in the LinkageSpecDecl. 6068 // Then the importer renders the existing and the new decl into one chain. 6069 EXPECT_EQ(ImportedX->getCanonicalDecl(), ToX->getCanonicalDecl()); 6070 } 6071 6072 struct SVEBuiltins : ASTImporterOptionSpecificTestBase {}; 6073 6074 TEST_P(SVEBuiltins, ImportTypes) { 6075 static const char *const TypeNames[] = { 6076 "__SVInt8_t", 6077 "__SVInt16_t", 6078 "__SVInt32_t", 6079 "__SVInt64_t", 6080 "__SVUint8_t", 6081 "__SVUint16_t", 6082 "__SVUint32_t", 6083 "__SVUint64_t", 6084 "__SVFloat16_t", 6085 "__SVBFloat16_t", 6086 "__SVFloat32_t", 6087 "__SVFloat64_t", 6088 "__SVBool_t" 6089 }; 6090 6091 TranslationUnitDecl *ToTU = getToTuDecl("", Lang_CXX03); 6092 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cc"); 6093 for (auto *TypeName : TypeNames) { 6094 auto *ToTypedef = FirstDeclMatcher<TypedefDecl>().match( 6095 ToTU, typedefDecl(hasName(TypeName))); 6096 QualType ToType = ToTypedef->getUnderlyingType(); 6097 6098 auto *FromTypedef = FirstDeclMatcher<TypedefDecl>().match( 6099 FromTU, typedefDecl(hasName(TypeName))); 6100 QualType FromType = FromTypedef->getUnderlyingType(); 6101 6102 QualType ImportedType = ImportType(FromType, FromTypedef, Lang_CXX03); 6103 EXPECT_EQ(ImportedType, ToType); 6104 } 6105 } 6106 6107 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfDefaultImplicitFunctions) { 6108 // Test that import of implicit functions works and the functions 6109 // are merged into one chain. 6110 auto GetDeclToImport = [this](StringRef File) { 6111 Decl *FromTU = getTuDecl( 6112 R"( 6113 struct X { }; 6114 // Force generating some implicit operator definitions for X. 6115 void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; } 6116 )", 6117 Lang_CXX11, File); 6118 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 6119 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit()))); 6120 // Destructor is picked as one example of implicit function. 6121 return FromD->getDestructor(); 6122 }; 6123 6124 auto *ToD1 = Import(GetDeclToImport("input1.cc"), Lang_CXX11); 6125 ASSERT_TRUE(ToD1); 6126 6127 auto *ToD2 = Import(GetDeclToImport("input2.cc"), Lang_CXX11); 6128 ASSERT_TRUE(ToD2); 6129 6130 EXPECT_EQ(ToD1->getCanonicalDecl(), ToD2->getCanonicalDecl()); 6131 } 6132 6133 TEST_P(ASTImporterOptionSpecificTestBase, 6134 ImportOfExplicitlyDefaultedOrDeleted) { 6135 Decl *FromTU = getTuDecl( 6136 R"( 6137 struct X { X() = default; X(const X&) = delete; }; 6138 )", 6139 Lang_CXX11); 6140 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 6141 FromTU, cxxRecordDecl(hasName("X"))); 6142 auto *ImportedX = Import(FromX, Lang_CXX11); 6143 auto *Constr1 = FirstDeclMatcher<CXXConstructorDecl>().match( 6144 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit()))); 6145 auto *Constr2 = LastDeclMatcher<CXXConstructorDecl>().match( 6146 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit()))); 6147 6148 ASSERT_TRUE(ImportedX); 6149 EXPECT_TRUE(Constr1->isDefaulted()); 6150 EXPECT_TRUE(Constr1->isExplicitlyDefaulted()); 6151 EXPECT_TRUE(Constr2->isDeletedAsWritten()); 6152 EXPECT_EQ(ImportedX->isAggregate(), FromX->isAggregate()); 6153 } 6154 6155 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, SVEBuiltins, 6156 ::testing::Values(std::vector<std::string>{ 6157 "-target", "aarch64-linux-gnu"})); 6158 6159 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, DeclContextTest, 6160 ::testing::Values(std::vector<std::string>())); 6161 6162 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CanonicalRedeclChain, 6163 ::testing::Values(std::vector<std::string>())); 6164 6165 TEST_P(ASTImporterOptionSpecificTestBase, LambdasAreDifferentiated) { 6166 Decl *FromTU = getTuDecl( 6167 R"( 6168 void f() { 6169 auto L0 = [](){}; 6170 auto L1 = [](){}; 6171 } 6172 )", 6173 Lang_CXX11, "input0.cc"); 6174 auto Pattern = lambdaExpr(); 6175 CXXRecordDecl *FromL0 = 6176 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 6177 CXXRecordDecl *FromL1 = 6178 LastDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 6179 ASSERT_NE(FromL0, FromL1); 6180 6181 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 6182 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 6183 EXPECT_NE(ToL0, ToL1); 6184 } 6185 6186 TEST_P(ASTImporterOptionSpecificTestBase, 6187 LambdasInFunctionParamsAreDifferentiated) { 6188 Decl *FromTU = getTuDecl( 6189 R"( 6190 template <typename F0, typename F1> 6191 void f(F0 L0 = [](){}, F1 L1 = [](){}) {} 6192 )", 6193 Lang_CXX11, "input0.cc"); 6194 auto Pattern = cxxRecordDecl(isLambda()); 6195 CXXRecordDecl *FromL0 = 6196 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 6197 CXXRecordDecl *FromL1 = 6198 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 6199 ASSERT_NE(FromL0, FromL1); 6200 6201 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 6202 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 6203 ASSERT_NE(ToL0, ToL1); 6204 } 6205 6206 TEST_P(ASTImporterOptionSpecificTestBase, 6207 LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed) { 6208 Decl *FromTU = getTuDecl( 6209 R"( 6210 #define LAMBDA [](){} 6211 template <typename F0, typename F1> 6212 void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {} 6213 )", 6214 Lang_CXX11, "input0.cc"); 6215 auto Pattern = cxxRecordDecl(isLambda()); 6216 CXXRecordDecl *FromL0 = 6217 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 6218 CXXRecordDecl *FromL1 = 6219 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 6220 ASSERT_NE(FromL0, FromL1); 6221 6222 Import(FromL0, Lang_CXX11); 6223 Import(FromL1, Lang_CXX11); 6224 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 6225 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 6226 ASSERT_NE(ToL0, ToL1); 6227 } 6228 6229 TEST_P(ASTImporterOptionSpecificTestBase, ImportAssignedLambda) { 6230 Decl *FromTU = getTuDecl( 6231 R"( 6232 void f() { 6233 auto x = []{} = {}; auto x2 = x; 6234 } 6235 )", 6236 Lang_CXX20, "input0.cc"); 6237 auto FromF = FirstDeclMatcher<FunctionDecl>().match( 6238 FromTU, functionDecl(hasName("f"))); 6239 // We have only one lambda class. 6240 ASSERT_EQ( 6241 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())), 6242 1u); 6243 6244 FunctionDecl *ToF = Import(FromF, Lang_CXX20); 6245 EXPECT_TRUE(ToF); 6246 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 6247 // We have only one lambda class after the import. 6248 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())), 6249 1u); 6250 } 6251 6252 TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) { 6253 Decl *FromTU = getTuDecl( 6254 R"( 6255 void f() { 6256 auto x = []{} = {}; 6257 auto xb = []{} = {}; 6258 } 6259 )", 6260 Lang_CXX20, "input0.cc"); 6261 auto FromF = FirstDeclMatcher<FunctionDecl>().match( 6262 FromTU, functionDecl(hasName("f"))); 6263 // We have two lambda classes. 6264 ASSERT_EQ( 6265 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())), 6266 2u); 6267 6268 FunctionDecl *ToF = Import(FromF, Lang_CXX20); 6269 EXPECT_TRUE(ToF); 6270 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 6271 // We have two lambda classes after the import. 6272 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())), 6273 2u); 6274 } 6275 6276 TEST_P(ASTImporterOptionSpecificTestBase, 6277 ImportFunctionDeclWithTypeSourceInfoWithSourceDecl) { 6278 // This code results in a lambda with implicit constructor. 6279 // The constructor's TypeSourceInfo points out the function prototype. 6280 // This prototype has an EST_Unevaluated in its exception information and a 6281 // SourceDecl that is the function declaration itself. 6282 // The test verifies that AST import of such AST does not crash. 6283 // (Here the function's TypeSourceInfo references the function itself.) 6284 Decl *FromTU = getTuDecl( 6285 R"( 6286 template<typename T> void f(T) { auto X = [](){}; } 6287 void g() { f(10); } 6288 )", 6289 Lang_CXX11, "input0.cc"); 6290 6291 // Use LastDeclMatcher to find the LambdaExpr in the template specialization. 6292 CXXRecordDecl *FromL = LastDeclMatcher<LambdaExpr>() 6293 .match(FromTU, lambdaExpr()) 6294 ->getLambdaClass(); 6295 6296 CXXConstructorDecl *FromCtor = *FromL->ctor_begin(); 6297 ASSERT_TRUE(FromCtor->isCopyConstructor()); 6298 ASSERT_TRUE(FromCtor->getTypeSourceInfo()); 6299 const auto *FromFPT = FromCtor->getType()->getAs<FunctionProtoType>(); 6300 ASSERT_TRUE(FromFPT); 6301 EXPECT_EQ(FromCtor->getTypeSourceInfo()->getType().getTypePtr(), FromFPT); 6302 FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo(); 6303 // If type is EST_Unevaluated, SourceDecl should be set to the parent Decl. 6304 EXPECT_EQ(FromEPI.ExceptionSpec.Type, EST_Unevaluated); 6305 EXPECT_EQ(FromEPI.ExceptionSpec.SourceDecl, FromCtor); 6306 6307 auto ToL = Import(FromL, Lang_CXX11); 6308 6309 // Check if the import was correct. 6310 CXXConstructorDecl *ToCtor = *ToL->ctor_begin(); 6311 EXPECT_TRUE(ToCtor->getTypeSourceInfo()); 6312 const auto *ToFPT = ToCtor->getType()->getAs<FunctionProtoType>(); 6313 ASSERT_TRUE(ToFPT); 6314 EXPECT_EQ(ToCtor->getTypeSourceInfo()->getType().getTypePtr(), ToFPT); 6315 FunctionProtoType::ExtProtoInfo ToEPI = ToFPT->getExtProtoInfo(); 6316 EXPECT_EQ(ToEPI.ExceptionSpec.Type, EST_Unevaluated); 6317 EXPECT_EQ(ToEPI.ExceptionSpec.SourceDecl, ToCtor); 6318 } 6319 6320 struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {}; 6321 6322 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside1) { 6323 Decl *FromTU = getTuDecl( 6324 R"( 6325 template<class> struct Tmpl {}; 6326 auto foo() { 6327 struct X {}; 6328 return Tmpl<X>(); 6329 } 6330 )", 6331 Lang_CXX14, "input0.cc"); 6332 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6333 FromTU, functionDecl(hasName("foo"))); 6334 6335 FunctionDecl *To = Import(From, Lang_CXX14); 6336 EXPECT_TRUE(To); 6337 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6338 } 6339 6340 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside2) { 6341 Decl *FromTU = getTuDecl( 6342 R"( 6343 template<class> struct Tmpl {}; 6344 auto foo() { 6345 struct X {}; 6346 return Tmpl<Tmpl<X>>(); 6347 } 6348 )", 6349 Lang_CXX14, "input0.cc"); 6350 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6351 FromTU, functionDecl(hasName("foo"))); 6352 6353 FunctionDecl *To = Import(From, Lang_CXX14); 6354 EXPECT_TRUE(To); 6355 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6356 } 6357 6358 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTypedefDeclaredInside) { 6359 Decl *FromTU = getTuDecl( 6360 R"( 6361 template<class> struct Tmpl {}; 6362 auto foo() { 6363 struct X {}; 6364 using x_type = X; 6365 return Tmpl<x_type>(); 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, ReturnWithTypedefDeclaredInside) { 6378 Decl *FromTU = getTuDecl( 6379 R"( 6380 auto X = [](long l) { 6381 using int_type = long; 6382 auto dur = 13; 6383 return static_cast<int_type>(dur); 6384 }; 6385 )", 6386 Lang_CXX14, "input0.cc"); 6387 CXXMethodDecl *From = 6388 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, cxxMethodDecl()); 6389 6390 // Explicitly set the return type of the lambda's operator() to the TypeAlias. 6391 // Normally the return type would be the built-in 'long' type. However, there 6392 // are cases when Clang does not use the canonical type and the TypeAlias is 6393 // used. I could not create such an AST from regular source code, it requires 6394 // some special state in the preprocessor. I've found such an AST when Clang 6395 // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce 6396 // that with creduce, because after preprocessing, the AST no longer 6397 // contained the TypeAlias as a return type of the lambda. 6398 ASTContext &Ctx = From->getASTContext(); 6399 TypeAliasDecl *FromTA = 6400 FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl()); 6401 QualType TT = Ctx.getTypedefType(FromTA); 6402 const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType()); 6403 QualType NewFunType = 6404 Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo()); 6405 From->setType(NewFunType); 6406 6407 CXXMethodDecl *To = Import(From, Lang_CXX14); 6408 EXPECT_TRUE(To); 6409 EXPECT_TRUE(isa<TypedefType>(To->getReturnType())); 6410 } 6411 6412 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside) { 6413 Decl *FromTU = getTuDecl( 6414 R"( 6415 auto foo() { 6416 struct X {}; 6417 return X(); 6418 } 6419 )", 6420 Lang_CXX14, "input0.cc"); 6421 FunctionDecl *From = 6422 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 6423 6424 FunctionDecl *To = Import(From, Lang_CXX14); 6425 EXPECT_TRUE(To); 6426 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6427 } 6428 6429 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside2) { 6430 Decl *FromTU = getTuDecl( 6431 R"( 6432 auto foo() { 6433 struct X {}; 6434 return X(); 6435 } 6436 )", 6437 Lang_CXX14, "input0.cc"); 6438 FunctionDecl *From = 6439 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 6440 6441 // This time import the type directly. 6442 QualType ToT = ImportType(From->getType(), From, Lang_CXX14); 6443 const FunctionProtoType *FPT = cast<FunctionProtoType>(ToT); 6444 EXPECT_TRUE(isa<AutoType>(FPT->getReturnType())); 6445 } 6446 6447 TEST_P(ImportAutoFunctions, ReturnWithTypedefToStructDeclaredInside) { 6448 Decl *FromTU = getTuDecl( 6449 R"( 6450 auto foo() { 6451 struct X {}; 6452 using Y = X; 6453 return Y(); 6454 } 6455 )", 6456 Lang_CXX14, "input0.cc"); 6457 FunctionDecl *From = 6458 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 6459 6460 FunctionDecl *To = Import(From, Lang_CXX14); 6461 EXPECT_TRUE(To); 6462 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6463 } 6464 6465 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredNestedInside) { 6466 Decl *FromTU = getTuDecl( 6467 R"( 6468 auto foo() { 6469 struct X { struct Y{}; }; 6470 return X::Y(); 6471 } 6472 )", 6473 Lang_CXX14, "input0.cc"); 6474 FunctionDecl *From = 6475 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 6476 6477 FunctionDecl *To = Import(From, Lang_CXX14); 6478 EXPECT_TRUE(To); 6479 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6480 } 6481 6482 TEST_P(ImportAutoFunctions, ReturnWithInternalLambdaType) { 6483 Decl *FromTU = getTuDecl( 6484 R"( 6485 auto f() { 6486 auto l = []() { 6487 struct X {}; 6488 return X(); 6489 }; 6490 return l(); 6491 } 6492 )", 6493 Lang_CXX17, "input0.cc"); 6494 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6495 FromTU, functionDecl(hasName("f"))); 6496 6497 FunctionDecl *To = Import(From, Lang_CXX17); 6498 EXPECT_TRUE(To); 6499 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6500 } 6501 6502 TEST_P(ImportAutoFunctions, ReturnWithTypeInIf) { 6503 Decl *FromTU = getTuDecl( 6504 R"( 6505 auto f() { 6506 if (struct X {} x; true) 6507 return X(); 6508 else 6509 return X(); 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, ReturnWithTypeInFor) { 6522 Decl *FromTU = getTuDecl( 6523 R"( 6524 auto f() { 6525 for (struct X {} x;;) 6526 return X(); 6527 } 6528 )", 6529 Lang_CXX17, "input0.cc"); 6530 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 6531 FromTU, functionDecl(hasName("f"))); 6532 6533 FunctionDecl *To = Import(From, Lang_CXX17); 6534 EXPECT_TRUE(To); 6535 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 6536 } 6537 6538 TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) { 6539 Decl *FromTU = getTuDecl( 6540 R"( 6541 auto f() { 6542 switch (struct X {} x; 10) { 6543 case 10: 6544 return X(); 6545 } 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 struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {}; 6558 6559 TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) { 6560 // Tests that the FileID tree structure (with the links being the include 6561 // chains) is preserved while importing other files (which need to be 6562 // added to this structure with fake include locations. 6563 6564 SourceLocation Location1; 6565 { 6566 auto Pattern = varDecl(hasName("X")); 6567 Decl *FromTU = getTuDecl("int X;", Lang_C99, "input0.c"); 6568 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 6569 6570 Location1 = Import(FromD, Lang_C99)->getLocation(); 6571 } 6572 SourceLocation Location2; 6573 { 6574 auto Pattern = varDecl(hasName("Y")); 6575 Decl *FromTU = getTuDecl("int Y;", Lang_C99, "input1.c"); 6576 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 6577 6578 Location2 = Import(FromD, Lang_C99)->getLocation(); 6579 } 6580 6581 SourceManager &ToSM = ToAST->getSourceManager(); 6582 FileID FileID1 = ToSM.getFileID(Location1); 6583 FileID FileID2 = ToSM.getFileID(Location2); 6584 6585 // Check that the imported files look like as if they were included from the 6586 // start of the main file. 6587 SourceLocation FileStart = ToSM.getLocForStartOfFile(ToSM.getMainFileID()); 6588 EXPECT_NE(FileID1, ToSM.getMainFileID()); 6589 EXPECT_NE(FileID2, ToSM.getMainFileID()); 6590 EXPECT_EQ(ToSM.getIncludeLoc(FileID1), FileStart); 6591 EXPECT_EQ(ToSM.getIncludeLoc(FileID2), FileStart); 6592 6593 // Let the SourceManager check the order of the locations. The order should 6594 // be the order in which the declarations are imported. 6595 EXPECT_TRUE(ToSM.isBeforeInTranslationUnit(Location1, Location2)); 6596 EXPECT_FALSE(ToSM.isBeforeInTranslationUnit(Location2, Location1)); 6597 } 6598 6599 TEST_P(ImportSourceLocations, NormalFileBuffer) { 6600 // Test importing normal file buffers. 6601 6602 std::string Path = "input0.c"; 6603 std::string Source = "int X;"; 6604 TranslationUnitDecl *FromTU = getTuDecl(Source, Lang_C99, Path); 6605 6606 SourceLocation ImportedLoc; 6607 { 6608 // Import the VarDecl to trigger the importing of the FileID. 6609 auto Pattern = varDecl(hasName("X")); 6610 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 6611 ImportedLoc = Import(FromD, Lang_C99)->getLocation(); 6612 } 6613 6614 // Make sure the imported buffer has the original contents. 6615 SourceManager &ToSM = ToAST->getSourceManager(); 6616 FileID ImportedID = ToSM.getFileID(ImportedLoc); 6617 EXPECT_EQ(Source, 6618 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer()); 6619 } 6620 6621 TEST_P(ImportSourceLocations, OverwrittenFileBuffer) { 6622 // Test importing overwritten file buffers. 6623 6624 std::string Path = "input0.c"; 6625 TranslationUnitDecl *FromTU = getTuDecl("int X;", Lang_C99, Path); 6626 6627 // Overwrite the file buffer for our input file with new content. 6628 const std::string Contents = "overwritten contents"; 6629 SourceLocation ImportedLoc; 6630 { 6631 SourceManager &FromSM = FromTU->getASTContext().getSourceManager(); 6632 clang::FileManager &FM = FromSM.getFileManager(); 6633 const clang::FileEntry &FE = 6634 *FM.getVirtualFile(Path, static_cast<off_t>(Contents.size()), 0); 6635 6636 llvm::SmallVector<char, 64> Buffer; 6637 Buffer.append(Contents.begin(), Contents.end()); 6638 auto FileContents = std::make_unique<llvm::SmallVectorMemoryBuffer>( 6639 std::move(Buffer), Path, /*RequiresNullTerminator=*/false); 6640 FromSM.overrideFileContents(&FE, std::move(FileContents)); 6641 6642 // Import the VarDecl to trigger the importing of the FileID. 6643 auto Pattern = varDecl(hasName("X")); 6644 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 6645 ImportedLoc = Import(FromD, Lang_C99)->getLocation(); 6646 } 6647 6648 // Make sure the imported buffer has the overwritten contents. 6649 SourceManager &ToSM = ToAST->getSourceManager(); 6650 FileID ImportedID = ToSM.getFileID(ImportedLoc); 6651 EXPECT_EQ(Contents, 6652 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer()); 6653 } 6654 6655 struct ImportAttributes : public ASTImporterOptionSpecificTestBase { 6656 void checkAttrImportCommon(const Attr *From, const Attr *To, 6657 const Decl *ToD) { 6658 6659 // Verify that dump does not crash because invalid data. 6660 ToD->dump(llvm::nulls()); 6661 6662 EXPECT_EQ(From->getParsedKind(), To->getParsedKind()); 6663 EXPECT_EQ(From->getSyntax(), To->getSyntax()); 6664 if (From->getAttrName()) { 6665 EXPECT_TRUE(To->getAttrName()); 6666 EXPECT_STREQ(From->getAttrName()->getNameStart(), 6667 To->getAttrName()->getNameStart()); 6668 } else { 6669 EXPECT_FALSE(To->getAttrName()); 6670 } 6671 if (From->getScopeName()) { 6672 EXPECT_TRUE(To->getScopeName()); 6673 EXPECT_STREQ(From->getScopeName()->getNameStart(), 6674 To->getScopeName()->getNameStart()); 6675 } else { 6676 EXPECT_FALSE(To->getScopeName()); 6677 } 6678 EXPECT_EQ(From->getSpellingListIndex(), To->getSpellingListIndex()); 6679 EXPECT_STREQ(From->getSpelling(), To->getSpelling()); 6680 EXPECT_EQ(From->isInherited(), To->isInherited()); 6681 EXPECT_EQ(From->isImplicit(), To->isImplicit()); 6682 EXPECT_EQ(From->isPackExpansion(), To->isPackExpansion()); 6683 EXPECT_EQ(From->isLateParsed(), To->isLateParsed()); 6684 } 6685 6686 template <class DT, class AT> 6687 void importAttr(const char *Code, AT *&FromAttr, AT *&ToAttr) { 6688 static_assert(std::is_base_of<Attr, AT>::value, "AT should be an Attr"); 6689 static_assert(std::is_base_of<Decl, DT>::value, "DT should be a Decl"); 6690 6691 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cc"); 6692 DT *FromD = 6693 FirstDeclMatcher<DT>().match(FromTU, namedDecl(hasName("test"))); 6694 ASSERT_TRUE(FromD); 6695 6696 DT *ToD = Import(FromD, Lang_CXX11); 6697 ASSERT_TRUE(ToD); 6698 6699 FromAttr = FromD->template getAttr<AT>(); 6700 ToAttr = ToD->template getAttr<AT>(); 6701 ASSERT_TRUE(FromAttr); 6702 EXPECT_TRUE(ToAttr); 6703 6704 checkAttrImportCommon(FromAttr, ToAttr, ToD); 6705 } 6706 6707 template <class T> void checkImported(const T *From, const T *To) { 6708 EXPECT_TRUE(To); 6709 EXPECT_NE(From, To); 6710 } 6711 6712 template <class T> 6713 void checkImportVariadicArg(const llvm::iterator_range<T **> &From, 6714 const llvm::iterator_range<T **> &To) { 6715 for (auto FromI = From.begin(), ToI = To.begin(); FromI != From.end(); 6716 ++FromI, ++ToI) { 6717 ASSERT_NE(ToI, To.end()); 6718 checkImported(*FromI, *ToI); 6719 } 6720 } 6721 }; 6722 6723 template <> 6724 void ImportAttributes::checkImported<Decl>(const Decl *From, const Decl *To) { 6725 EXPECT_TRUE(To); 6726 EXPECT_NE(From, To); 6727 EXPECT_EQ(To->getTranslationUnitDecl(), 6728 ToAST->getASTContext().getTranslationUnitDecl()); 6729 } 6730 6731 // FIXME: Use ImportAttributes for this test. 6732 TEST_P(ASTImporterOptionSpecificTestBase, ImportExprOfAlignmentAttr) { 6733 // Test if import of these packed and aligned attributes does not trigger an 6734 // error situation where source location from 'From' context is referenced in 6735 // 'To' context through evaluation of the alignof attribute. 6736 // This happens if the 'alignof(A)' expression is not imported correctly. 6737 Decl *FromTU = getTuDecl( 6738 R"( 6739 struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; }; 6740 struct alignas(alignof(A)) S {}; 6741 )", 6742 Lang_CXX11, "input.cc"); 6743 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 6744 FromTU, cxxRecordDecl(hasName("S"), unless(isImplicit()))); 6745 ASSERT_TRUE(FromD); 6746 6747 auto *ToD = Import(FromD, Lang_CXX11); 6748 ASSERT_TRUE(ToD); 6749 6750 auto *FromAttr = FromD->getAttr<AlignedAttr>(); 6751 auto *ToAttr = ToD->getAttr<AlignedAttr>(); 6752 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited()); 6753 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion()); 6754 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit()); 6755 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax()); 6756 EXPECT_EQ(FromAttr->getSemanticSpelling(), ToAttr->getSemanticSpelling()); 6757 EXPECT_TRUE(ToAttr->getAlignmentExpr()); 6758 6759 auto *ToA = FirstDeclMatcher<CXXRecordDecl>().match( 6760 ToD->getTranslationUnitDecl(), 6761 cxxRecordDecl(hasName("A"), unless(isImplicit()))); 6762 // Ensure that 'struct A' was imported (through reference from attribute of 6763 // 'S'). 6764 EXPECT_TRUE(ToA); 6765 } 6766 6767 // FIXME: Use ImportAttributes for this test. 6768 TEST_P(ASTImporterOptionSpecificTestBase, ImportFormatAttr) { 6769 Decl *FromTU = getTuDecl( 6770 R"( 6771 int foo(const char * fmt, ...) 6772 __attribute__ ((__format__ (__scanf__, 1, 2))); 6773 )", 6774 Lang_CXX03, "input.cc"); 6775 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 6776 FromTU, functionDecl(hasName("foo"))); 6777 ASSERT_TRUE(FromD); 6778 6779 auto *ToD = Import(FromD, Lang_CXX03); 6780 ASSERT_TRUE(ToD); 6781 ToD->dump(); // Should not crash! 6782 6783 auto *FromAttr = FromD->getAttr<FormatAttr>(); 6784 auto *ToAttr = ToD->getAttr<FormatAttr>(); 6785 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited()); 6786 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion()); 6787 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit()); 6788 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax()); 6789 EXPECT_EQ(FromAttr->getAttributeSpellingListIndex(), 6790 ToAttr->getAttributeSpellingListIndex()); 6791 EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName()); 6792 } 6793 6794 TEST_P(ImportAttributes, ImportEnableIf) { 6795 EnableIfAttr *FromAttr, *ToAttr; 6796 importAttr<FunctionDecl>( 6797 "void test(int A) __attribute__((enable_if(A == 1, \"message\")));", 6798 FromAttr, ToAttr); 6799 checkImported(FromAttr->getCond(), ToAttr->getCond()); 6800 EXPECT_EQ(FromAttr->getMessage(), ToAttr->getMessage()); 6801 } 6802 6803 TEST_P(ImportAttributes, ImportGuardedVar) { 6804 GuardedVarAttr *FromAttr, *ToAttr; 6805 importAttr<VarDecl>("int test __attribute__((guarded_var));", FromAttr, 6806 ToAttr); 6807 } 6808 6809 TEST_P(ImportAttributes, ImportPtGuardedVar) { 6810 PtGuardedVarAttr *FromAttr, *ToAttr; 6811 importAttr<VarDecl>("int *test __attribute__((pt_guarded_var));", FromAttr, 6812 ToAttr); 6813 } 6814 6815 TEST_P(ImportAttributes, ImportScopedLockable) { 6816 ScopedLockableAttr *FromAttr, *ToAttr; 6817 importAttr<CXXRecordDecl>("struct __attribute__((scoped_lockable)) test {};", 6818 FromAttr, ToAttr); 6819 } 6820 6821 TEST_P(ImportAttributes, ImportCapability) { 6822 CapabilityAttr *FromAttr, *ToAttr; 6823 importAttr<CXXRecordDecl>( 6824 "struct __attribute__((capability(\"cap\"))) test {};", FromAttr, ToAttr); 6825 EXPECT_EQ(FromAttr->getName(), ToAttr->getName()); 6826 } 6827 6828 TEST_P(ImportAttributes, ImportAssertCapability) { 6829 AssertCapabilityAttr *FromAttr, *ToAttr; 6830 importAttr<FunctionDecl>( 6831 "void test(int A1, int A2) __attribute__((assert_capability(A1, A2)));", 6832 FromAttr, ToAttr); 6833 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6834 } 6835 6836 TEST_P(ImportAttributes, ImportAcquireCapability) { 6837 AcquireCapabilityAttr *FromAttr, *ToAttr; 6838 importAttr<FunctionDecl>( 6839 "void test(int A1, int A2) __attribute__((acquire_capability(A1, A2)));", 6840 FromAttr, ToAttr); 6841 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6842 } 6843 6844 TEST_P(ImportAttributes, ImportTryAcquireCapability) { 6845 TryAcquireCapabilityAttr *FromAttr, *ToAttr; 6846 importAttr<FunctionDecl>( 6847 "void test(int A1, int A2) __attribute__((try_acquire_capability(1, A1, " 6848 "A2)));", 6849 FromAttr, ToAttr); 6850 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); 6851 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6852 } 6853 6854 TEST_P(ImportAttributes, ImportReleaseCapability) { 6855 ReleaseCapabilityAttr *FromAttr, *ToAttr; 6856 importAttr<FunctionDecl>( 6857 "void test(int A1, int A2) __attribute__((release_capability(A1, A2)));", 6858 FromAttr, ToAttr); 6859 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6860 } 6861 6862 TEST_P(ImportAttributes, ImportRequiresCapability) { 6863 RequiresCapabilityAttr *FromAttr, *ToAttr; 6864 importAttr<FunctionDecl>( 6865 "void test(int A1, int A2) __attribute__((requires_capability(A1, A2)));", 6866 FromAttr, ToAttr); 6867 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6868 } 6869 6870 TEST_P(ImportAttributes, ImportNoThreadSafetyAnalysis) { 6871 NoThreadSafetyAnalysisAttr *FromAttr, *ToAttr; 6872 importAttr<FunctionDecl>( 6873 "void test() __attribute__((no_thread_safety_analysis));", FromAttr, 6874 ToAttr); 6875 } 6876 6877 TEST_P(ImportAttributes, ImportGuardedBy) { 6878 GuardedByAttr *FromAttr, *ToAttr; 6879 importAttr<VarDecl>( 6880 R"( 6881 int G; 6882 int test __attribute__((guarded_by(G))); 6883 )", 6884 FromAttr, ToAttr); 6885 checkImported(FromAttr->getArg(), ToAttr->getArg()); 6886 } 6887 6888 TEST_P(ImportAttributes, ImportPtGuardedBy) { 6889 PtGuardedByAttr *FromAttr, *ToAttr; 6890 importAttr<VarDecl>( 6891 R"( 6892 int G; 6893 int *test __attribute__((pt_guarded_by(G))); 6894 )", 6895 FromAttr, ToAttr); 6896 checkImported(FromAttr->getArg(), ToAttr->getArg()); 6897 } 6898 6899 TEST_P(ImportAttributes, ImportAcquiredAfter) { 6900 AcquiredAfterAttr *FromAttr, *ToAttr; 6901 importAttr<VarDecl>( 6902 R"( 6903 struct __attribute__((lockable)) L {}; 6904 L A1; 6905 L A2; 6906 L test __attribute__((acquired_after(A1, A2))); 6907 )", 6908 FromAttr, ToAttr); 6909 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6910 } 6911 6912 TEST_P(ImportAttributes, ImportAcquiredBefore) { 6913 AcquiredBeforeAttr *FromAttr, *ToAttr; 6914 importAttr<VarDecl>( 6915 R"( 6916 struct __attribute__((lockable)) L {}; 6917 L A1; 6918 L A2; 6919 L test __attribute__((acquired_before(A1, A2))); 6920 )", 6921 FromAttr, ToAttr); 6922 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6923 } 6924 6925 TEST_P(ImportAttributes, ImportAssertExclusiveLock) { 6926 AssertExclusiveLockAttr *FromAttr, *ToAttr; 6927 importAttr<FunctionDecl>("void test(int A1, int A2) " 6928 "__attribute__((assert_exclusive_lock(A1, A2)));", 6929 FromAttr, ToAttr); 6930 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6931 } 6932 6933 TEST_P(ImportAttributes, ImportAssertSharedLock) { 6934 AssertSharedLockAttr *FromAttr, *ToAttr; 6935 importAttr<FunctionDecl>( 6936 "void test(int A1, int A2) __attribute__((assert_shared_lock(A1, A2)));", 6937 FromAttr, ToAttr); 6938 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6939 } 6940 6941 TEST_P(ImportAttributes, ImportExclusiveTrylockFunction) { 6942 ExclusiveTrylockFunctionAttr *FromAttr, *ToAttr; 6943 importAttr<FunctionDecl>( 6944 "void test(int A1, int A2) __attribute__((exclusive_trylock_function(1, " 6945 "A1, A2)));", 6946 FromAttr, ToAttr); 6947 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); 6948 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6949 } 6950 6951 TEST_P(ImportAttributes, ImportSharedTrylockFunction) { 6952 SharedTrylockFunctionAttr *FromAttr, *ToAttr; 6953 importAttr<FunctionDecl>( 6954 "void test(int A1, int A2) __attribute__((shared_trylock_function(1, A1, " 6955 "A2)));", 6956 FromAttr, ToAttr); 6957 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); 6958 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6959 } 6960 6961 TEST_P(ImportAttributes, ImportLockReturned) { 6962 LockReturnedAttr *FromAttr, *ToAttr; 6963 importAttr<FunctionDecl>( 6964 "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr, 6965 ToAttr); 6966 checkImported(FromAttr->getArg(), ToAttr->getArg()); 6967 } 6968 6969 TEST_P(ImportAttributes, ImportLocksExcluded) { 6970 LocksExcludedAttr *FromAttr, *ToAttr; 6971 importAttr<FunctionDecl>( 6972 "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));", 6973 FromAttr, ToAttr); 6974 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 6975 } 6976 6977 template <typename T> 6978 auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) { 6979 auto Copy = Values; 6980 for (std::vector<std::string> &ArgV : Copy) { 6981 for (const std::string &Arg : Args) { 6982 ArgV.push_back(Arg); 6983 } 6984 } 6985 return ::testing::ValuesIn(Copy); 6986 } 6987 6988 struct ImportWithExternalSource : ASTImporterOptionSpecificTestBase { 6989 ImportWithExternalSource() { 6990 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 6991 ASTContext &FromContext, FileManager &FromFileManager, 6992 bool MinimalImport, 6993 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 6994 return new ASTImporter(ToContext, ToFileManager, FromContext, 6995 // Use minimal import for these tests. 6996 FromFileManager, /*MinimalImport=*/true, 6997 // We use the regular lookup. 6998 /*SharedState=*/nullptr); 6999 }; 7000 } 7001 }; 7002 7003 /// An ExternalASTSource that keeps track of the tags is completed. 7004 struct SourceWithCompletedTagList : clang::ExternalASTSource { 7005 std::vector<clang::TagDecl *> &CompletedTags; 7006 SourceWithCompletedTagList(std::vector<clang::TagDecl *> &CompletedTags) 7007 : CompletedTags(CompletedTags) {} 7008 void CompleteType(TagDecl *Tag) override { 7009 auto *Record = cast<CXXRecordDecl>(Tag); 7010 Record->startDefinition(); 7011 Record->completeDefinition(); 7012 CompletedTags.push_back(Tag); 7013 } 7014 using clang::ExternalASTSource::CompleteType; 7015 }; 7016 7017 TEST_P(ImportWithExternalSource, CompleteRecordBeforeImporting) { 7018 // Create an empty TU. 7019 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cpp"); 7020 7021 // Create and add the test ExternalASTSource. 7022 std::vector<clang::TagDecl *> CompletedTags; 7023 IntrusiveRefCntPtr<ExternalASTSource> source = 7024 new SourceWithCompletedTagList(CompletedTags); 7025 clang::ASTContext &Context = FromTU->getASTContext(); 7026 Context.setExternalSource(std::move(source)); 7027 7028 // Create a dummy class by hand with external lexical storage. 7029 IdentifierInfo &Ident = Context.Idents.get("test_class"); 7030 auto *Record = CXXRecordDecl::Create( 7031 Context, TTK_Class, FromTU, SourceLocation(), SourceLocation(), &Ident); 7032 Record->setHasExternalLexicalStorage(); 7033 FromTU->addDecl(Record); 7034 7035 // Do a minimal import of the created class. 7036 EXPECT_EQ(0U, CompletedTags.size()); 7037 Import(Record, Lang_CXX03); 7038 EXPECT_EQ(0U, CompletedTags.size()); 7039 7040 // Import the definition of the created class. 7041 llvm::Error Err = findFromTU(Record)->Importer->ImportDefinition(Record); 7042 EXPECT_FALSE((bool)Err); 7043 consumeError(std::move(Err)); 7044 7045 // Make sure the class was completed once. 7046 EXPECT_EQ(1U, CompletedTags.size()); 7047 EXPECT_EQ(Record, CompletedTags.front()); 7048 } 7049 7050 TEST_P(ImportFunctions, CTADImplicit) { 7051 Decl *FromTU = getTuDecl( 7052 R"( 7053 template <typename T> struct A { 7054 A(T); 7055 }; 7056 A a{(int)0}; 7057 )", 7058 Lang_CXX17, "input.cc"); 7059 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7060 FromTU, 7061 cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>"))))); 7062 auto *ToD = Import(FromD, Lang_CXX17); 7063 ASSERT_TRUE(ToD); 7064 EXPECT_TRUE(ToD->isCopyDeductionCandidate()); 7065 // Check that the deduced class template is also imported. 7066 EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull( 7067 FromD->getDeducedTemplate())); 7068 } 7069 7070 TEST_P(ImportFunctions, CTADUserDefinedExplicit) { 7071 Decl *FromTU = getTuDecl( 7072 R"( 7073 template <typename T> struct A { 7074 A(T); 7075 }; 7076 template <typename T> explicit A(T) -> A<float>; 7077 A a{(int)0}; // calls A<float>::A(float) 7078 )", 7079 Lang_CXX17, "input.cc"); 7080 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7081 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 7082 // Not-implicit: i.e. not compiler-generated, user defined. 7083 ASSERT_FALSE(FromD->isImplicit()); 7084 ASSERT_TRUE(FromD->isExplicit()); // Has the explicit keyword. 7085 auto *ToD = Import(FromD, Lang_CXX17); 7086 ASSERT_TRUE(ToD); 7087 EXPECT_FALSE(FromD->isImplicit()); 7088 EXPECT_TRUE(ToD->isExplicit()); 7089 } 7090 7091 TEST_P(ImportFunctions, CTADWithLocalTypedef) { 7092 Decl *TU = getTuDecl( 7093 R"( 7094 template <typename T> struct A { 7095 typedef T U; 7096 A(U); 7097 }; 7098 A a{(int)0}; 7099 )", 7100 Lang_CXX17, "input.cc"); 7101 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7102 TU, cxxDeductionGuideDecl()); 7103 auto *ToD = Import(FromD, Lang_CXX17); 7104 ASSERT_TRUE(ToD); 7105 } 7106 7107 TEST_P(ImportFunctions, ParmVarDeclDeclContext) { 7108 constexpr auto FromTUCode = R"( 7109 void f(int P); 7110 )"; 7111 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 7112 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 7113 FromTU, functionDecl(hasName("f"))); 7114 ASSERT_TRUE(FromF); 7115 7116 auto *ImportedF = Import(FromF, Lang_CXX11); 7117 EXPECT_TRUE(ImportedF); 7118 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 7119 ImportedF, ImportedF->getParamDecl(0))); 7120 } 7121 7122 // FIXME Move these tests out of ASTImporterTest. For that we need to factor 7123 // out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase 7124 // into a new test Fixture. Then we should lift up this Fixture to its own 7125 // implementation file and only then could we reuse the Fixture in other AST 7126 // unitttests. 7127 struct CTAD : ASTImporterOptionSpecificTestBase {}; 7128 7129 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) { 7130 Decl *TU = getTuDecl( 7131 R"( 7132 typedef int U; 7133 template <typename T> struct A { 7134 A(U, T); 7135 }; 7136 A a{(int)0, (int)0}; 7137 )", 7138 Lang_CXX17, "input.cc"); 7139 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7140 TU, cxxDeductionGuideDecl()); 7141 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 7142 TU, typedefNameDecl(hasName("U"))); 7143 ParmVarDecl *Param = Guide->getParamDecl(0); 7144 // The type of the first param (which is a typedef) should match the typedef 7145 // in the global scope. 7146 EXPECT_EQ(Param->getType()->castAs<TypedefType>()->getDecl(), Typedef); 7147 } 7148 7149 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) { 7150 Decl *TU = getTuDecl( 7151 R"( 7152 typedef int U; 7153 template <typename T> struct A { 7154 A(U*, T); 7155 }; 7156 A a{(int*)0, (int)0}; 7157 )", 7158 Lang_CXX17, "input.cc"); 7159 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7160 TU, cxxDeductionGuideDecl()); 7161 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 7162 TU, typedefNameDecl(hasName("U"))); 7163 ParmVarDecl *Param = Guide->getParamDecl(0); 7164 EXPECT_EQ(Param->getType() 7165 ->getAs<PointerType>() 7166 ->getPointeeType() 7167 ->getAs<TypedefType>() 7168 ->getDecl(), 7169 Typedef); 7170 } 7171 7172 TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) { 7173 Decl *TU = getTuDecl( 7174 R"( 7175 template <typename T> struct A { 7176 typedef T U; 7177 A(U, T); 7178 }; 7179 A a{(int)0, (int)0}; 7180 )", 7181 Lang_CXX17, "input.cc"); 7182 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7183 TU, cxxDeductionGuideDecl()); 7184 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 7185 TU, typedefNameDecl(hasName("U"))); 7186 ParmVarDecl *Param = Guide->getParamDecl(0); 7187 EXPECT_NE(Param->getType()->castAs<TypedefType>()->getDecl(), Typedef); 7188 } 7189 7190 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CTAD, 7191 DefaultTestValuesForRunOptions); 7192 7193 TEST_P(ASTImporterOptionSpecificTestBase, TypedefWithAttribute) { 7194 Decl *TU = getTuDecl( 7195 R"( 7196 namespace N { 7197 typedef int X __attribute__((annotate("A"))); 7198 } 7199 )", 7200 Lang_CXX17, "input.cc"); 7201 auto *FromD = 7202 FirstDeclMatcher<TypedefDecl>().match(TU, typedefDecl(hasName("X"))); 7203 auto *ToD = Import(FromD, Lang_CXX17); 7204 ASSERT_TRUE(ToD); 7205 ASSERT_EQ(ToD->getAttrs().size(), 1U); 7206 auto *ToAttr = dyn_cast<AnnotateAttr>(ToD->getAttrs()[0]); 7207 ASSERT_TRUE(ToAttr); 7208 EXPECT_EQ(ToAttr->getAnnotation(), "A"); 7209 } 7210 7211 TEST_P(ASTImporterOptionSpecificTestBase, 7212 ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) { 7213 Decl *FromTU = getTuDecl( 7214 R"( 7215 7216 namespace std { 7217 template<typename T> 7218 class basic_stringbuf; 7219 } 7220 namespace std { 7221 class char_traits; 7222 template<typename T = char_traits> 7223 class basic_stringbuf; 7224 } 7225 namespace std { 7226 template<typename T> 7227 class basic_stringbuf {}; 7228 } 7229 7230 )", 7231 Lang_CXX11); 7232 7233 auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match( 7234 FromTU, 7235 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); 7236 auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11)); 7237 EXPECT_TRUE(To1); 7238 7239 auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match( 7240 FromTU, 7241 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); 7242 auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11)); 7243 EXPECT_TRUE(To2); 7244 } 7245 7246 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfCapturedVLAType) { 7247 Decl *FromTU = getTuDecl( 7248 R"( 7249 void declToImport(int N) { 7250 int VLA[N]; 7251 [&VLA] {}; // FieldDecl inside the lambda. 7252 } 7253 )", 7254 Lang_CXX14); 7255 auto *FromFD = FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl()); 7256 ASSERT_TRUE(FromFD); 7257 ASSERT_TRUE(FromFD->hasCapturedVLAType()); 7258 7259 auto *ToFD = Import(FromFD, Lang_CXX14); 7260 EXPECT_TRUE(ToFD); 7261 EXPECT_TRUE(ToFD->hasCapturedVLAType()); 7262 EXPECT_NE(FromFD->getCapturedVLAType(), ToFD->getCapturedVLAType()); 7263 } 7264 7265 TEST_P(ASTImporterOptionSpecificTestBase, ImportEnumMemberSpecialization) { 7266 Decl *FromTU = getTuDecl( 7267 R"( 7268 template <class T> struct A { 7269 enum tagname { enumerator }; 7270 }; 7271 template struct A<int>; 7272 )", 7273 Lang_CXX03); 7274 auto *FromD = FirstDeclMatcher<EnumDecl>().match( 7275 FromTU, enumDecl(hasName("tagname"), 7276 hasParent(classTemplateSpecializationDecl()))); 7277 ASSERT_TRUE(FromD); 7278 ASSERT_TRUE(FromD->getMemberSpecializationInfo()); 7279 7280 auto *ToD = Import(FromD, Lang_CXX03); 7281 EXPECT_TRUE(ToD); 7282 EXPECT_TRUE(ToD->getMemberSpecializationInfo()); 7283 EXPECT_EQ(FromD->getTemplateSpecializationKind(), 7284 ToD->getTemplateSpecializationKind()); 7285 } 7286 7287 TEST_P(ASTImporterOptionSpecificTestBase, ImportIsInheritingConstructorBit) { 7288 Decl *FromTU = getTuDecl( 7289 R"( 7290 struct A { 7291 A(int); 7292 }; 7293 struct B : A { 7294 using A::A; // Inherited ctor. 7295 }; 7296 void f() { 7297 (B(0)); 7298 } 7299 )", 7300 Lang_CXX11); 7301 auto *FromD = FirstDeclMatcher<CXXConstructorDecl>().match( 7302 FromTU, cxxConstructorDecl(isInheritingConstructor())); 7303 ASSERT_TRUE(FromD); 7304 ASSERT_TRUE(FromD->isInheritingConstructor()); 7305 7306 auto *ToD = Import(FromD, Lang_CXX11); 7307 ASSERT_TRUE(ToD); 7308 EXPECT_TRUE(ToD->isInheritingConstructor()); 7309 } 7310 7311 TEST_P(ASTImporterOptionSpecificTestBase, ImportConstructorUsingShadow) { 7312 TranslationUnitDecl *FromTU = getTuDecl( 7313 R"( 7314 struct A { 7315 A(int, int); 7316 }; 7317 struct B : A { 7318 using A::A; 7319 }; 7320 struct C : B { 7321 using B::B; 7322 }; 7323 )", 7324 Lang_CXX11); 7325 7326 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordC) { 7327 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match( 7328 TU, cxxRecordDecl(hasName("A"))); 7329 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match( 7330 TU, cxxRecordDecl(hasName("B"))); 7331 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match( 7332 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)), 7333 parameterCountIs(2))); 7334 auto *ShadowBA = cast<ConstructorUsingShadowDecl>( 7335 FirstDeclMatcher<UsingShadowDecl>().match( 7336 TU, usingShadowDecl(hasParent(equalsNode(RecordB)), 7337 hasTargetDecl(equalsNode(ConstrA))))); 7338 auto *ShadowCA = cast<ConstructorUsingShadowDecl>( 7339 FirstDeclMatcher<UsingShadowDecl>().match( 7340 TU, usingShadowDecl(hasParent(equalsNode(RecordC)), 7341 hasTargetDecl(equalsNode(ConstrA))))); 7342 EXPECT_EQ(ShadowBA->getTargetDecl(), ConstrA); 7343 EXPECT_EQ(ShadowBA->getNominatedBaseClass(), RecordA); 7344 EXPECT_EQ(ShadowBA->getConstructedBaseClass(), RecordA); 7345 EXPECT_EQ(ShadowBA->getNominatedBaseClassShadowDecl(), nullptr); 7346 EXPECT_EQ(ShadowBA->getConstructedBaseClassShadowDecl(), nullptr); 7347 EXPECT_FALSE(ShadowBA->constructsVirtualBase()); 7348 EXPECT_EQ(ShadowCA->getTargetDecl(), ConstrA); 7349 EXPECT_EQ(ShadowCA->getNominatedBaseClass(), RecordB); 7350 EXPECT_EQ(ShadowCA->getConstructedBaseClass(), RecordB); 7351 EXPECT_EQ(ShadowCA->getNominatedBaseClassShadowDecl(), ShadowBA); 7352 EXPECT_EQ(ShadowCA->getConstructedBaseClassShadowDecl(), ShadowBA); 7353 EXPECT_FALSE(ShadowCA->constructsVirtualBase()); 7354 }; 7355 7356 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match( 7357 FromTU, cxxRecordDecl(hasName("C"))); 7358 7359 auto *ToC = Import(FromC, Lang_CXX11); 7360 TranslationUnitDecl *ToTU = ToC->getTranslationUnitDecl(); 7361 7362 CheckAST(FromTU, FromC); 7363 CheckAST(ToTU, ToC); 7364 } 7365 7366 AST_MATCHER_P(UsingShadowDecl, hasIntroducerDecl, internal::Matcher<NamedDecl>, 7367 InnerMatcher) { 7368 return InnerMatcher.matches(*Node.getIntroducer(), Finder, Builder); 7369 } 7370 7371 TEST_P(ASTImporterOptionSpecificTestBase, 7372 ImportConstructorUsingShadowVirtualBase) { 7373 TranslationUnitDecl *FromTU = getTuDecl( 7374 R"( 7375 struct A { A(int, int); }; 7376 struct B : A { using A::A; }; 7377 7378 struct V1 : virtual B { using B::B; }; 7379 struct V2 : virtual B { using B::B; }; 7380 7381 struct D2 : V1, V2 { 7382 using V1::V1; 7383 using V2::V2; 7384 }; 7385 )", 7386 Lang_CXX11); 7387 7388 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordD2) { 7389 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match( 7390 TU, cxxRecordDecl(hasName("A"))); 7391 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match( 7392 TU, cxxRecordDecl(hasName("B"))); 7393 auto *RecordV1 = FirstDeclMatcher<CXXRecordDecl>().match( 7394 TU, cxxRecordDecl(hasName("V1"))); 7395 auto *RecordV2 = FirstDeclMatcher<CXXRecordDecl>().match( 7396 TU, cxxRecordDecl(hasName("V2"))); 7397 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match( 7398 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)), 7399 parameterCountIs(2))); 7400 auto *ConstrB = FirstDeclMatcher<CXXConstructorDecl>().match( 7401 TU, cxxConstructorDecl(hasParent(equalsNode(RecordB)), 7402 isCopyConstructor())); 7403 auto *UsingD2V1 = FirstDeclMatcher<UsingDecl>().match( 7404 TU, usingDecl(hasParent(equalsNode(RecordD2)))); 7405 auto *UsingD2V2 = LastDeclMatcher<UsingDecl>().match( 7406 TU, usingDecl(hasParent(equalsNode(RecordD2)))); 7407 auto *ShadowBA = cast<ConstructorUsingShadowDecl>( 7408 FirstDeclMatcher<UsingShadowDecl>().match( 7409 TU, usingShadowDecl(hasParent(equalsNode(RecordB)), 7410 hasTargetDecl(equalsNode(ConstrA))))); 7411 auto *ShadowV1A = cast<ConstructorUsingShadowDecl>( 7412 FirstDeclMatcher<UsingShadowDecl>().match( 7413 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)), 7414 hasTargetDecl(equalsNode(ConstrA))))); 7415 auto *ShadowV1B = cast<ConstructorUsingShadowDecl>( 7416 FirstDeclMatcher<UsingShadowDecl>().match( 7417 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)), 7418 hasTargetDecl(equalsNode(ConstrB))))); 7419 auto *ShadowV2A = cast<ConstructorUsingShadowDecl>( 7420 FirstDeclMatcher<UsingShadowDecl>().match( 7421 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)), 7422 hasTargetDecl(equalsNode(ConstrA))))); 7423 auto *ShadowV2B = cast<ConstructorUsingShadowDecl>( 7424 FirstDeclMatcher<UsingShadowDecl>().match( 7425 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)), 7426 hasTargetDecl(equalsNode(ConstrB))))); 7427 auto *ShadowD2V1A = cast<ConstructorUsingShadowDecl>( 7428 FirstDeclMatcher<UsingShadowDecl>().match( 7429 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 7430 hasIntroducerDecl(equalsNode(UsingD2V1)), 7431 hasTargetDecl(equalsNode(ConstrA))))); 7432 auto *ShadowD2V1B = cast<ConstructorUsingShadowDecl>( 7433 FirstDeclMatcher<UsingShadowDecl>().match( 7434 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 7435 hasIntroducerDecl(equalsNode(UsingD2V1)), 7436 hasTargetDecl(equalsNode(ConstrB))))); 7437 auto *ShadowD2V2A = cast<ConstructorUsingShadowDecl>( 7438 FirstDeclMatcher<UsingShadowDecl>().match( 7439 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 7440 hasIntroducerDecl(equalsNode(UsingD2V2)), 7441 hasTargetDecl(equalsNode(ConstrA))))); 7442 auto *ShadowD2V2B = cast<ConstructorUsingShadowDecl>( 7443 FirstDeclMatcher<UsingShadowDecl>().match( 7444 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 7445 hasIntroducerDecl(equalsNode(UsingD2V2)), 7446 hasTargetDecl(equalsNode(ConstrB))))); 7447 7448 EXPECT_EQ(ShadowD2V1A->getTargetDecl(), ConstrA); 7449 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClassShadowDecl(), ShadowV1A); 7450 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClass(), RecordV1); 7451 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClassShadowDecl(), ShadowBA); 7452 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClass(), RecordB); 7453 EXPECT_TRUE(ShadowD2V1A->constructsVirtualBase()); 7454 EXPECT_EQ(ShadowD2V1B->getTargetDecl(), ConstrB); 7455 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClassShadowDecl(), ShadowV1B); 7456 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClass(), RecordV1); 7457 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClassShadowDecl(), nullptr); 7458 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClass(), RecordB); 7459 EXPECT_TRUE(ShadowD2V1B->constructsVirtualBase()); 7460 EXPECT_EQ(ShadowD2V2A->getTargetDecl(), ConstrA); 7461 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClassShadowDecl(), ShadowV2A); 7462 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClass(), RecordV2); 7463 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClassShadowDecl(), ShadowBA); 7464 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClass(), RecordB); 7465 EXPECT_TRUE(ShadowD2V2A->constructsVirtualBase()); 7466 EXPECT_EQ(ShadowD2V2B->getTargetDecl(), ConstrB); 7467 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClassShadowDecl(), ShadowV2B); 7468 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClass(), RecordV2); 7469 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClassShadowDecl(), nullptr); 7470 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClass(), RecordB); 7471 EXPECT_TRUE(ShadowD2V2B->constructsVirtualBase()); 7472 7473 EXPECT_TRUE(ShadowV1A->constructsVirtualBase()); 7474 EXPECT_TRUE(ShadowV1B->constructsVirtualBase()); 7475 EXPECT_TRUE(ShadowV2A->constructsVirtualBase()); 7476 EXPECT_TRUE(ShadowV2B->constructsVirtualBase()); 7477 EXPECT_FALSE(ShadowBA->constructsVirtualBase()); 7478 }; 7479 7480 auto *FromD2 = FirstDeclMatcher<CXXRecordDecl>().match( 7481 FromTU, cxxRecordDecl(hasName("D2"))); 7482 7483 auto *ToD2 = Import(FromD2, Lang_CXX11); 7484 TranslationUnitDecl *ToTU = ToD2->getTranslationUnitDecl(); 7485 7486 CheckAST(FromTU, FromD2); 7487 CheckAST(ToTU, ToD2); 7488 } 7489 7490 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingShadowList) { 7491 TranslationUnitDecl *FromTU = getTuDecl( 7492 R"( 7493 struct A { 7494 void f(); 7495 void f(int); 7496 }; 7497 struct B : A { 7498 using A::f; 7499 }; 7500 )", 7501 Lang_CXX11); 7502 7503 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match( 7504 FromTU, cxxRecordDecl(hasName("B"))); 7505 7506 auto *ToB = Import(FromB, Lang_CXX11); 7507 TranslationUnitDecl *ToTU = ToB->getTranslationUnitDecl(); 7508 7509 auto *ToUsing = FirstDeclMatcher<UsingDecl>().match( 7510 ToTU, usingDecl(hasParent(equalsNode(ToB)))); 7511 auto *ToUsingShadowF1 = FirstDeclMatcher<UsingShadowDecl>().match( 7512 ToTU, usingShadowDecl(hasTargetDecl( 7513 functionDecl(hasName("f"), parameterCountIs(0))))); 7514 auto *ToUsingShadowF2 = FirstDeclMatcher<UsingShadowDecl>().match( 7515 ToTU, usingShadowDecl(hasTargetDecl( 7516 functionDecl(hasName("f"), parameterCountIs(1))))); 7517 7518 EXPECT_EQ(ToUsing->shadow_size(), 2u); 7519 auto ShadowI = ToUsing->shadow_begin(); 7520 EXPECT_EQ(*ShadowI, ToUsingShadowF1); 7521 ++ShadowI; 7522 EXPECT_EQ(*ShadowI, ToUsingShadowF2); 7523 } 7524 7525 AST_MATCHER_P(FunctionTemplateDecl, templateParameterCountIs, unsigned, Cnt) { 7526 return Node.getTemplateParameters()->size() == Cnt; 7527 } 7528 7529 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuide) { 7530 TranslationUnitDecl *FromTU = getTuDecl( 7531 R"( 7532 template<class> class A { }; 7533 template<class T> class B { 7534 template<class T1, typename = A<T>> B(T1); 7535 }; 7536 template<class T> 7537 B(T, T) -> B<int>; 7538 )", 7539 Lang_CXX17); 7540 7541 // Get the implicit deduction guide for (non-default) constructor of 'B'. 7542 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 7543 FromTU, functionTemplateDecl(templateParameterCountIs(3))); 7544 // Implicit deduction guide for copy constructor of 'B'. 7545 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 7546 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit())); 7547 // User defined deduction guide. 7548 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7549 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 7550 7551 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters(); 7552 // Don't know why exactly but this is the DeclContext here. 7553 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(), 7554 FromDGCopyCtor->getTemplatedDecl()); 7555 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(), 7556 FromDGCtor->getTemplatedDecl()); 7557 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(), 7558 FromDGCtor->getTemplatedDecl()); 7559 EXPECT_EQ( 7560 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 7561 FromDGCopyCtor->getTemplatedDecl()); 7562 EXPECT_EQ(FromDGOther->getDescribedTemplate() 7563 ->getTemplateParameters() 7564 ->getParam(0) 7565 ->getDeclContext(), 7566 FromDGOther); 7567 7568 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17); 7569 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17); 7570 auto *ToDGOther = Import(FromDGOther, Lang_CXX17); 7571 ASSERT_TRUE(ToDGCtor); 7572 ASSERT_TRUE(ToDGCopyCtor); 7573 ASSERT_TRUE(ToDGOther); 7574 7575 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters(); 7576 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(), 7577 ToDGCopyCtor->getTemplatedDecl()); 7578 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(), 7579 ToDGCtor->getTemplatedDecl()); 7580 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(), 7581 ToDGCtor->getTemplatedDecl()); 7582 EXPECT_EQ( 7583 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 7584 ToDGCopyCtor->getTemplatedDecl()); 7585 EXPECT_EQ(ToDGOther->getDescribedTemplate() 7586 ->getTemplateParameters() 7587 ->getParam(0) 7588 ->getDeclContext(), 7589 ToDGOther); 7590 } 7591 7592 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuideDifferentOrder) { 7593 // This test demonstrates that the DeclContext of the imported object is 7594 // dependent on the order of import. The test is an exact copy of the previous 7595 // one except at the indicated locations. 7596 TranslationUnitDecl *FromTU = getTuDecl( 7597 R"( 7598 template<class> class A { }; 7599 template<class T> class B { 7600 template<class T1, typename = A<T>> B(T1); 7601 }; 7602 template<class T> 7603 B(T, T) -> B<int>; 7604 )", 7605 Lang_CXX17); 7606 7607 // Get the implicit deduction guide for (non-default) constructor of 'B'. 7608 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 7609 FromTU, functionTemplateDecl(templateParameterCountIs(3))); 7610 // Implicit deduction guide for copy constructor of 'B'. 7611 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 7612 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit())); 7613 // User defined deduction guide. 7614 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 7615 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 7616 7617 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters(); 7618 // Don't know why exactly but this is the DeclContext here. 7619 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(), 7620 FromDGCopyCtor->getTemplatedDecl()); 7621 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(), 7622 FromDGCtor->getTemplatedDecl()); 7623 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(), 7624 FromDGCtor->getTemplatedDecl()); 7625 EXPECT_EQ( 7626 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 7627 FromDGCopyCtor->getTemplatedDecl()); 7628 EXPECT_EQ(FromDGOther->getDescribedTemplate() 7629 ->getTemplateParameters() 7630 ->getParam(0) 7631 ->getDeclContext(), 7632 FromDGOther); 7633 7634 // Here the import of 'ToDGCopyCtor' and 'ToDGCtor' is reversed relative to 7635 // the previous test. 7636 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17); 7637 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17); 7638 auto *ToDGOther = Import(FromDGOther, Lang_CXX17); 7639 ASSERT_TRUE(ToDGCtor); 7640 ASSERT_TRUE(ToDGCopyCtor); 7641 ASSERT_TRUE(ToDGOther); 7642 7643 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters(); 7644 // Next line: DeclContext is different relative to the previous test. 7645 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(), 7646 ToDGCtor->getTemplatedDecl()); 7647 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(), 7648 ToDGCtor->getTemplatedDecl()); 7649 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(), 7650 ToDGCtor->getTemplatedDecl()); 7651 // Next line: DeclContext is different relative to the previous test. 7652 EXPECT_EQ( 7653 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 7654 ToDGCtor->getTemplatedDecl()); 7655 EXPECT_EQ(ToDGOther->getDescribedTemplate() 7656 ->getTemplateParameters() 7657 ->getParam(0) 7658 ->getDeclContext(), 7659 ToDGOther); 7660 } 7661 7662 TEST_P(ASTImporterOptionSpecificTestBase, 7663 ImportRecordWithLayoutRequestingExpr) { 7664 TranslationUnitDecl *FromTU = getTuDecl( 7665 R"( 7666 struct A { 7667 int idx; 7668 static void foo(A x) { 7669 (void)&"text"[x.idx]; 7670 } 7671 }; 7672 )", 7673 Lang_CXX11); 7674 7675 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 7676 FromTU, cxxRecordDecl(hasName("A"))); 7677 7678 // Test that during import of 'foo' the record layout can be obtained without 7679 // crash. 7680 auto *ToA = Import(FromA, Lang_CXX11); 7681 EXPECT_TRUE(ToA); 7682 EXPECT_TRUE(ToA->isCompleteDefinition()); 7683 } 7684 7685 TEST_P(ASTImporterOptionSpecificTestBase, 7686 ImportRecordWithLayoutRequestingExprDifferentRecord) { 7687 TranslationUnitDecl *FromTU = getTuDecl( 7688 R"( 7689 struct B; 7690 struct A { 7691 int idx; 7692 B *b; 7693 }; 7694 struct B { 7695 static void foo(A x) { 7696 (void)&"text"[x.idx]; 7697 } 7698 }; 7699 )", 7700 Lang_CXX11); 7701 7702 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 7703 FromTU, cxxRecordDecl(hasName("A"))); 7704 7705 // Test that during import of 'foo' the record layout (of 'A') can be obtained 7706 // without crash. It is not possible to have all of the fields of 'A' imported 7707 // at that time (without big code changes). 7708 auto *ToA = Import(FromA, Lang_CXX11); 7709 EXPECT_TRUE(ToA); 7710 EXPECT_TRUE(ToA->isCompleteDefinition()); 7711 } 7712 7713 TEST_P(ASTImporterOptionSpecificTestBase, ImportInClassInitializerFromField) { 7714 // Encounter import of a field when the field already exists but has the 7715 // in-class initializer expression not yet set. Such case can occur in the AST 7716 // of generated template specializations. 7717 // The first code forces to create a template specialization of 7718 // `A<int>` but without implicit constructors. 7719 // The second ("From") code contains a variable of type `A<int>`, this 7720 // results in a template specialization that has constructors and 7721 // CXXDefaultInitExpr nodes. 7722 Decl *ToTU = getToTuDecl( 7723 R"( 7724 void f(); 7725 template<typename> struct A { int X = 1; }; 7726 struct B { A<int> Y; }; 7727 )", 7728 Lang_CXX11); 7729 auto *ToX = FirstDeclMatcher<FieldDecl>().match( 7730 ToTU, 7731 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl()))); 7732 ASSERT_TRUE(ToX->hasInClassInitializer()); 7733 ASSERT_FALSE(ToX->getInClassInitializer()); 7734 7735 Decl *FromTU = getTuDecl( 7736 R"( 7737 void f(); 7738 template<typename> struct A { int X = 1; }; 7739 struct B { A<int> Y; }; 7740 // 7741 A<int> Z; 7742 )", 7743 Lang_CXX11, "input1.cc"); 7744 auto *FromX = FirstDeclMatcher<FieldDecl>().match( 7745 FromTU, 7746 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl()))); 7747 7748 auto *ToXImported = Import(FromX, Lang_CXX11); 7749 EXPECT_EQ(ToXImported, ToX); 7750 EXPECT_TRUE(ToX->getInClassInitializer()); 7751 } 7752 7753 TEST_P(ASTImporterOptionSpecificTestBase, 7754 ImportInClassInitializerFromCXXDefaultInitExpr) { 7755 // Encounter AST import of a CXXDefaultInitExpr where the "to-field" 7756 // of it exists but has the in-class initializer not set yet. 7757 Decl *ToTU = getToTuDecl( 7758 R"( 7759 namespace N { 7760 template<typename> int b; 7761 struct X; 7762 } 7763 template<typename> struct A { N::X *X = nullptr; }; 7764 struct B { A<int> Y; }; 7765 )", 7766 Lang_CXX14); 7767 auto *ToX = FirstDeclMatcher<FieldDecl>().match( 7768 ToTU, 7769 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl()))); 7770 ASSERT_TRUE(ToX->hasInClassInitializer()); 7771 ASSERT_FALSE(ToX->getInClassInitializer()); 7772 7773 Decl *FromTU = getTuDecl( 7774 R"( 7775 namespace N { 7776 template<typename> int b; 7777 struct X; 7778 } 7779 template<typename> struct A { N::X *X = nullptr; }; 7780 struct B { A<int> Y; }; 7781 // 7782 void f() { 7783 (void)A<int>{}; 7784 } 7785 struct C { 7786 C(): attr(new A<int>{}){} 7787 A<int> *attr; 7788 const int value = N::b<C>; 7789 }; 7790 )", 7791 Lang_CXX14, "input1.cc"); 7792 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 7793 FromTU, functionDecl(hasName("f"), isDefinition())); 7794 auto *ToF = Import(FromF, Lang_CXX11); 7795 EXPECT_TRUE(ToF); 7796 EXPECT_TRUE(ToX->getInClassInitializer()); 7797 } 7798 7799 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) { 7800 Decl *FromTU = getTuDecl( 7801 R"( 7802 int bar() { 7803 return 0; 7804 } 7805 void other() { 7806 bar(); 7807 } 7808 )", 7809 Lang_CXX11); 7810 Decl *ToTU = getToTuDecl( 7811 R"( 7812 int bar() { 7813 return 0; 7814 } 7815 )", 7816 Lang_CXX11); 7817 auto *FromOther = FirstDeclMatcher<FunctionDecl>().match( 7818 FromTU, functionDecl(hasName("other"))); 7819 ASSERT_TRUE(FromOther); 7820 7821 auto *ToOther = Import(FromOther, Lang_CXX11); 7822 ASSERT_TRUE(ToOther); 7823 7824 auto *ToBar = FirstDeclMatcher<FunctionDecl>().match( 7825 ToTU, functionDecl(hasName("bar"))); 7826 7827 EXPECT_TRUE(SharedStatePtr->isNewDecl(ToOther)); 7828 EXPECT_FALSE(SharedStatePtr->isNewDecl(ToBar)); 7829 } 7830 7831 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest, 7832 DefaultTestValuesForRunOptions); 7833 7834 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportPath, 7835 ::testing::Values(std::vector<std::string>())); 7836 7837 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportExpr, 7838 DefaultTestValuesForRunOptions); 7839 7840 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFixedPointExpr, 7841 ExtendWithOptions(DefaultTestArrayForRunOptions, 7842 std::vector<std::string>{ 7843 "-ffixed-point"})); 7844 7845 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportBlock, 7846 ExtendWithOptions(DefaultTestArrayForRunOptions, 7847 std::vector<std::string>{ 7848 "-fblocks"})); 7849 7850 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportType, 7851 DefaultTestValuesForRunOptions); 7852 7853 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportDecl, 7854 DefaultTestValuesForRunOptions); 7855 7856 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterOptionSpecificTestBase, 7857 DefaultTestValuesForRunOptions); 7858 7859 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ErrorHandlingTest, 7860 DefaultTestValuesForRunOptions); 7861 7862 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, RedirectingImporterTest, 7863 DefaultTestValuesForRunOptions); 7864 7865 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctions, 7866 DefaultTestValuesForRunOptions); 7867 7868 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAutoFunctions, 7869 DefaultTestValuesForRunOptions); 7870 7871 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctionTemplates, 7872 DefaultTestValuesForRunOptions); 7873 7874 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctionTemplates, 7875 DefaultTestValuesForRunOptions); 7876 7877 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportClasses, 7878 DefaultTestValuesForRunOptions); 7879 7880 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctions, 7881 DefaultTestValuesForRunOptions); 7882 7883 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendClasses, 7884 DefaultTestValuesForRunOptions); 7885 7886 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, 7887 ImportFunctionTemplateSpecializations, 7888 DefaultTestValuesForRunOptions); 7889 7890 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportImplicitMethods, 7891 DefaultTestValuesForRunOptions); 7892 7893 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportVariables, 7894 DefaultTestValuesForRunOptions); 7895 7896 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, LLDBLookupTest, 7897 DefaultTestValuesForRunOptions); 7898 7899 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportSourceLocations, 7900 DefaultTestValuesForRunOptions); 7901 7902 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportWithExternalSource, 7903 DefaultTestValuesForRunOptions); 7904 7905 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAttributes, 7906 DefaultTestValuesForRunOptions); 7907 7908 } // end namespace ast_matchers 7909 } // end namespace clang 7910