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