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