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/AST/RecordLayout.h" 14 #include "clang/ASTMatchers/ASTMatchers.h" 15 #include "clang/Testing/CommandLineArgs.h" 16 #include "llvm/Support/SmallVectorMemoryBuffer.h" 17 18 #include "clang/AST/DeclContextInternals.h" 19 #include "gtest/gtest.h" 20 21 #include "ASTImporterFixtures.h" 22 #include <optional> 23 24 namespace clang { 25 namespace ast_matchers { 26 27 using internal::Matcher; 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_FILE_NAME(); }", Lang_CXX03, 262 "", Lang_CXX03, Verifier, 263 functionDecl(hasDescendant( 264 sourceLocExpr(hasBuiltinStr("__builtin_FILE_NAME"))))); 265 testImport("void declToImport() { (void)__builtin_COLUMN(); }", Lang_CXX03, 266 "", Lang_CXX03, Verifier, 267 functionDecl(hasDescendant( 268 sourceLocExpr(hasBuiltinStr("__builtin_COLUMN"))))); 269 } 270 271 TEST_P(ImportExpr, ImportStringLiteral) { 272 MatchVerifier<Decl> Verifier; 273 testImport("void declToImport() { (void)\"foo\"; }", Lang_CXX03, "", 274 Lang_CXX03, Verifier, 275 functionDecl(hasDescendant( 276 stringLiteral(hasType(asString("const char[4]")))))); 277 testImport("void declToImport() { (void)L\"foo\"; }", Lang_CXX03, "", 278 Lang_CXX03, Verifier, 279 functionDecl(hasDescendant( 280 stringLiteral(hasType(asString("const wchar_t[4]")))))); 281 testImport("void declToImport() { (void) \"foo\" \"bar\"; }", Lang_CXX03, "", 282 Lang_CXX03, Verifier, 283 functionDecl(hasDescendant( 284 stringLiteral(hasType(asString("const char[7]")))))); 285 } 286 287 TEST_P(ImportExpr, ImportChooseExpr) { 288 MatchVerifier<Decl> Verifier; 289 290 // This case tests C code that is not condition-dependent and has a true 291 // condition. 292 testImport("void declToImport() { (void)__builtin_choose_expr(1, 2, 3); }", 293 Lang_C99, "", Lang_C99, Verifier, 294 functionDecl(hasDescendant(chooseExpr()))); 295 } 296 297 const internal::VariadicDynCastAllOfMatcher<Stmt, ShuffleVectorExpr> 298 shuffleVectorExpr; 299 300 TEST_P(ImportExpr, ImportShuffleVectorExpr) { 301 MatchVerifier<Decl> Verifier; 302 constexpr auto Code = R"code( 303 typedef double vector4double __attribute__((__vector_size__(32))); 304 vector4double declToImport(vector4double a, vector4double b) { 305 return __builtin_shufflevector(a, b, 0, 1, 2, 3); 306 } 307 )code"; 308 const auto Pattern = functionDecl(hasDescendant(shuffleVectorExpr( 309 allOf(has(declRefExpr(to(parmVarDecl(hasName("a"))))), 310 has(declRefExpr(to(parmVarDecl(hasName("b"))))), 311 has(integerLiteral(equals(0))), has(integerLiteral(equals(1))), 312 has(integerLiteral(equals(2))), has(integerLiteral(equals(3))))))); 313 testImport(Code, Lang_C99, "", Lang_C99, Verifier, Pattern); 314 } 315 316 TEST_P(ImportExpr, ImportGNUNullExpr) { 317 MatchVerifier<Decl> Verifier; 318 testImport("void declToImport() { (void)__null; }", Lang_CXX03, "", 319 Lang_CXX03, Verifier, 320 functionDecl(hasDescendant(gnuNullExpr(hasType(isInteger()))))); 321 } 322 323 TEST_P(ImportExpr, ImportGenericSelectionExpr) { 324 MatchVerifier<Decl> Verifier; 325 326 testImport( 327 "void declToImport() { int x; (void)_Generic(x, int: 0, float: 1); }", 328 Lang_C99, "", Lang_C99, Verifier, 329 functionDecl(hasDescendant(genericSelectionExpr()))); 330 } 331 332 TEST_P(ImportExpr, ImportCXXNullPtrLiteralExpr) { 333 MatchVerifier<Decl> Verifier; 334 testImport( 335 "void declToImport() { (void)nullptr; }", 336 Lang_CXX11, "", Lang_CXX11, Verifier, 337 functionDecl(hasDescendant(cxxNullPtrLiteralExpr()))); 338 } 339 340 341 TEST_P(ImportExpr, ImportFloatinglLiteralExpr) { 342 MatchVerifier<Decl> Verifier; 343 testImport("void declToImport() { (void)1.0; }", Lang_C99, "", Lang_C99, 344 Verifier, 345 functionDecl(hasDescendant( 346 floatLiteral(equals(1.0), hasType(asString("double")))))); 347 testImport("void declToImport() { (void)1.0e-5f; }", Lang_C99, "", Lang_C99, 348 Verifier, 349 functionDecl(hasDescendant( 350 floatLiteral(equals(1.0e-5f), hasType(asString("float")))))); 351 } 352 353 TEST_P(ImportFixedPointExpr, ImportFixedPointerLiteralExpr) { 354 MatchVerifier<Decl> Verifier; 355 testImport("void declToImport() { (void)1.0k; }", Lang_C99, "", Lang_C99, 356 Verifier, functionDecl(hasDescendant(fixedPointLiteral()))); 357 testImport("void declToImport() { (void)0.75r; }", Lang_C99, "", Lang_C99, 358 Verifier, functionDecl(hasDescendant(fixedPointLiteral()))); 359 } 360 361 TEST_P(ImportExpr, ImportImaginaryLiteralExpr) { 362 MatchVerifier<Decl> Verifier; 363 testImport( 364 "void declToImport() { (void)1.0i; }", 365 Lang_CXX14, "", Lang_CXX14, Verifier, 366 functionDecl(hasDescendant(imaginaryLiteral()))); 367 } 368 369 TEST_P(ImportExpr, ImportCompoundLiteralExpr) { 370 MatchVerifier<Decl> Verifier; 371 testImport("void declToImport() {" 372 " struct s { int x; long y; unsigned z; }; " 373 " (void)(struct s){ 42, 0L, 1U }; }", 374 Lang_CXX03, "", Lang_CXX03, Verifier, 375 functionDecl(hasDescendant(compoundLiteralExpr( 376 hasType(asString("struct s")), 377 has(initListExpr( 378 hasType(asString("struct s")), 379 has(integerLiteral(equals(42), hasType(asString("int")))), 380 has(integerLiteral(equals(0), hasType(asString("long")))), 381 has(integerLiteral( 382 equals(1), hasType(asString("unsigned int")))))))))); 383 } 384 385 TEST_P(ImportExpr, ImportCXXThisExpr) { 386 MatchVerifier<Decl> Verifier; 387 testImport("class declToImport { void f() { (void)this; } };", Lang_CXX03, "", 388 Lang_CXX03, Verifier, 389 cxxRecordDecl(hasMethod(hasDescendant( 390 cxxThisExpr(hasType(asString("class declToImport *"))))))); 391 } 392 393 TEST_P(ImportExpr, ImportAtomicExpr) { 394 MatchVerifier<Decl> Verifier; 395 testImport("void declToImport() { int *ptr; __atomic_load_n(ptr, 1); }", 396 Lang_C99, "", Lang_C99, Verifier, 397 functionDecl(hasDescendant(atomicExpr( 398 has(ignoringParenImpCasts( 399 declRefExpr(hasDeclaration(varDecl(hasName("ptr"))), 400 hasType(asString("int *"))))), 401 has(integerLiteral(equals(1), hasType(asString("int")))))))); 402 } 403 404 TEST_P(ImportExpr, ImportLabelDeclAndAddrLabelExpr) { 405 MatchVerifier<Decl> Verifier; 406 testImport("void declToImport() { loop: goto loop; (void)&&loop; }", Lang_C99, 407 "", Lang_C99, Verifier, 408 functionDecl(hasDescendant(labelStmt( 409 hasDeclaration(labelDecl(hasName("loop"))))), 410 hasDescendant(addrLabelExpr( 411 hasDeclaration(labelDecl(hasName("loop"))))))); 412 } 413 414 AST_MATCHER_P(TemplateDecl, hasTemplateDecl, 415 internal::Matcher<NamedDecl>, InnerMatcher) { 416 const NamedDecl *Template = Node.getTemplatedDecl(); 417 return Template && InnerMatcher.matches(*Template, Finder, Builder); 418 } 419 420 TEST_P(ImportExpr, ImportParenListExpr) { 421 MatchVerifier<Decl> Verifier; 422 testImport( 423 "template<typename T> class dummy { void f() { dummy X(*this); } };" 424 "typedef dummy<int> declToImport;" 425 "template class dummy<int>;", 426 Lang_CXX03, "", Lang_CXX03, Verifier, 427 typedefDecl(hasType(elaboratedType(namesType(templateSpecializationType( 428 hasDeclaration(classTemplateSpecializationDecl(hasSpecializedTemplate( 429 classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod( 430 allOf(hasName("f"), 431 hasBody(compoundStmt(has(declStmt(hasSingleDecl(varDecl( 432 hasInitializer(parenListExpr(has(unaryOperator( 433 hasOperatorName("*"), 434 hasUnaryOperand( 435 cxxThisExpr()))))))))))))))))))))))))); 436 } 437 438 TEST_P(ImportExpr, ImportSwitch) { 439 MatchVerifier<Decl> Verifier; 440 testImport("void declToImport() { int b; switch (b) { case 1: break; } }", 441 Lang_C99, "", Lang_C99, Verifier, 442 functionDecl(hasDescendant( 443 switchStmt(has(compoundStmt(has(caseStmt()))))))); 444 } 445 446 TEST_P(ImportExpr, ImportStmtExpr) { 447 MatchVerifier<Decl> Verifier; 448 testImport( 449 "void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }", 450 Lang_C99, "", Lang_C99, Verifier, 451 traverse(TK_AsIs, 452 functionDecl(hasDescendant(varDecl( 453 hasName("C"), hasType(asString("int")), 454 hasInitializer(stmtExpr( 455 hasAnySubstatement(declStmt(hasSingleDecl(varDecl( 456 hasName("X"), hasType(asString("int")), 457 hasInitializer(integerLiteral(equals(4))))))), 458 hasDescendant(implicitCastExpr())))))))); 459 } 460 461 TEST_P(ImportExpr, ImportConditionalOperator) { 462 MatchVerifier<Decl> Verifier; 463 testImport("void declToImport() { (void)(true ? 1 : -5); }", Lang_CXX03, "", 464 Lang_CXX03, Verifier, 465 functionDecl(hasDescendant(conditionalOperator( 466 hasCondition(cxxBoolLiteral(equals(true))), 467 hasTrueExpression(integerLiteral(equals(1))), 468 hasFalseExpression(unaryOperator( 469 hasUnaryOperand(integerLiteral(equals(5))))))))); 470 } 471 472 TEST_P(ImportExpr, ImportBinaryConditionalOperator) { 473 MatchVerifier<Decl> Verifier; 474 testImport( 475 "void declToImport() { (void)(1 ?: -5); }", Lang_CXX03, "", Lang_CXX03, 476 Verifier, 477 traverse(TK_AsIs, 478 functionDecl(hasDescendant(binaryConditionalOperator( 479 hasCondition(implicitCastExpr( 480 hasSourceExpression(opaqueValueExpr( 481 hasSourceExpression(integerLiteral(equals(1))))), 482 hasType(booleanType()))), 483 hasTrueExpression(opaqueValueExpr( 484 hasSourceExpression(integerLiteral(equals(1))))), 485 hasFalseExpression(unaryOperator( 486 hasOperatorName("-"), 487 hasUnaryOperand(integerLiteral(equals(5)))))))))); 488 } 489 490 TEST_P(ImportExpr, ImportDesignatedInitExpr) { 491 MatchVerifier<Decl> Verifier; 492 testImport( 493 "void declToImport() {" 494 " struct point { double x; double y; };" 495 " struct point ptarray[10] = " 496 "{ [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }", 497 Lang_C99, "", Lang_C99, Verifier, 498 functionDecl(hasDescendant(initListExpr( 499 has(designatedInitExpr(designatorCountIs(2), 500 hasDescendant(floatLiteral(equals(1.0))), 501 hasDescendant(integerLiteral(equals(2))))), 502 has(designatedInitExpr(designatorCountIs(2), 503 hasDescendant(floatLiteral(equals(2.0))), 504 hasDescendant(integerLiteral(equals(2))))), 505 has(designatedInitExpr(designatorCountIs(2), 506 hasDescendant(floatLiteral(equals(1.0))), 507 hasDescendant(integerLiteral(equals(0))))))))); 508 } 509 510 TEST_P(ImportExpr, ImportPredefinedExpr) { 511 MatchVerifier<Decl> Verifier; 512 // __func__ expands as StringLiteral("declToImport") 513 testImport("void declToImport() { (void)__func__; }", Lang_CXX03, "", 514 Lang_CXX03, Verifier, 515 functionDecl(hasDescendant(predefinedExpr( 516 hasType(asString("const char[13]")), 517 has(stringLiteral(hasType(asString("const char[13]")))))))); 518 } 519 520 TEST_P(ImportExpr, ImportInitListExpr) { 521 MatchVerifier<Decl> Verifier; 522 testImport("void declToImport() {" 523 " struct point { double x; double y; };" 524 " point ptarray[10] = { [2].y = 1.0, [2].x = 2.0," 525 " [0].x = 1.0 }; }", 526 Lang_CXX03, "", Lang_CXX03, Verifier, 527 functionDecl(hasDescendant(initListExpr( 528 has(cxxConstructExpr(requiresZeroInitialization())), 529 has(initListExpr( 530 hasType(asString("point")), has(floatLiteral(equals(1.0))), 531 has(implicitValueInitExpr(hasType(asString("double")))))), 532 has(initListExpr(hasType(asString("point")), 533 has(floatLiteral(equals(2.0))), 534 has(floatLiteral(equals(1.0))))))))); 535 } 536 537 const internal::VariadicDynCastAllOfMatcher<Expr, CXXDefaultInitExpr> 538 cxxDefaultInitExpr; 539 540 TEST_P(ImportExpr, ImportCXXDefaultInitExpr) { 541 MatchVerifier<Decl> Verifier; 542 testImport("class declToImport { int DefInit = 5; }; declToImport X;", 543 Lang_CXX11, "", Lang_CXX11, Verifier, 544 cxxRecordDecl(hasDescendant(cxxConstructorDecl( 545 hasAnyConstructorInitializer(cxxCtorInitializer( 546 withInitializer(cxxDefaultInitExpr()))))))); 547 testImport( 548 "struct X { int A = 5; }; X declToImport{};", Lang_CXX17, "", Lang_CXX17, 549 Verifier, 550 varDecl(hasInitializer(initListExpr(hasInit(0, cxxDefaultInitExpr()))))); 551 } 552 553 const internal::VariadicDynCastAllOfMatcher<Expr, VAArgExpr> vaArgExpr; 554 555 TEST_P(ImportExpr, ImportVAArgExpr) { 556 MatchVerifier<Decl> Verifier; 557 testImport("void declToImport(__builtin_va_list list, ...) {" 558 " (void)__builtin_va_arg(list, int); }", 559 Lang_CXX03, "", Lang_CXX03, Verifier, 560 functionDecl(hasDescendant( 561 cStyleCastExpr(hasSourceExpression(vaArgExpr()))))); 562 } 563 564 const internal::VariadicDynCastAllOfMatcher<Stmt, BuiltinBitCastExpr> 565 builtinBitCastExpr; 566 567 TEST_P(ImportExpr, ImportBuiltinBitCastExpr) { 568 MatchVerifier<Decl> Verifier; 569 testImport("void declToImport(int X) {" 570 " (void)__builtin_bit_cast(float, X); }", 571 Lang_CXX20, "", Lang_CXX20, Verifier, 572 functionDecl(hasDescendant( 573 cStyleCastExpr(hasSourceExpression(builtinBitCastExpr()))))); 574 } 575 576 TEST_P(ImportExpr, CXXTemporaryObjectExpr) { 577 MatchVerifier<Decl> Verifier; 578 testImport( 579 "struct C {};" 580 "void declToImport() { C c = C(); }", 581 Lang_CXX03, "", Lang_CXX03, Verifier, 582 traverse(TK_AsIs, 583 functionDecl(hasDescendant(exprWithCleanups(has(cxxConstructExpr( 584 has(materializeTemporaryExpr(has(implicitCastExpr( 585 has(cxxTemporaryObjectExpr())))))))))))); 586 } 587 588 TEST_P(ImportType, ImportAtomicType) { 589 MatchVerifier<Decl> Verifier; 590 testImport( 591 "void declToImport() { typedef _Atomic(int) a_int; }", 592 Lang_CXX11, "", Lang_CXX11, Verifier, 593 functionDecl(hasDescendant(typedefDecl(has(atomicType()))))); 594 } 595 596 TEST_P(ImportType, ImportBitIntType) { 597 const AstTypeMatcher<BitIntType> bitIntType; 598 MatchVerifier<Decl> Verifier; 599 testImport("_BitInt(10) declToImport;", Lang_CXX11, "", Lang_CXX11, Verifier, 600 varDecl(hasType(bitIntType()))); 601 } 602 603 TEST_P(ImportType, ImportDependentBitIntType) { 604 const AstTypeMatcher<DependentBitIntType> dependentBitIntType; 605 MatchVerifier<Decl> Verifier; 606 testImport("template<int Width> using declToImport = _BitInt(Width);", 607 Lang_CXX11, "", Lang_CXX11, Verifier, 608 typeAliasTemplateDecl( 609 has(typeAliasDecl(hasType(dependentBitIntType()))))); 610 } 611 612 TEST_P(ImportType, ImportDependentAddressSpaceType) { 613 const AstTypeMatcher<DependentAddressSpaceType> dependentAddressSpaceType; 614 MatchVerifier<Decl> Verifier; 615 testImport( 616 R"( 617 template<typename T, int AddrSpace> 618 using declToImport = T __attribute__((address_space(AddrSpace))); 619 )", 620 Lang_CXX11, "", Lang_CXX11, Verifier, 621 typeAliasTemplateDecl( 622 has(typeAliasDecl(hasType(dependentAddressSpaceType()))))); 623 } 624 625 TEST_P(ImportType, ImportVectorType) { 626 const AstTypeMatcher<VectorType> vectorType; 627 MatchVerifier<Decl> Verifier; 628 testImport("typedef int __attribute__((vector_size(12))) declToImport;", 629 Lang_CXX11, "", Lang_CXX11, Verifier, 630 typedefDecl(hasType(vectorType()))); 631 } 632 633 TEST_P(ImportType, ImportDependentVectorType) { 634 const AstTypeMatcher<DependentVectorType> dependentVectorType; 635 MatchVerifier<Decl> Verifier; 636 testImport( 637 R"( 638 template<typename T, int Size> 639 using declToImport = T __attribute__((vector_size(Size))); 640 )", 641 Lang_CXX11, "", Lang_CXX11, Verifier, 642 typeAliasTemplateDecl( 643 has(typeAliasDecl(hasType(dependentVectorType()))))); 644 } 645 646 struct ImportOpenCLPipe : ImportType { 647 std::vector<std::string> getExtraArgs() const override { 648 return {"-x", "cl", "-cl-no-stdinc", "-cl-std=CL2.0"}; 649 } 650 }; 651 652 TEST_P(ImportOpenCLPipe, ImportPipeType) { 653 const AstTypeMatcher<PipeType> pipeType; 654 MatchVerifier<Decl> Verifier; 655 testImport("typedef pipe int declToImport;", Lang_OpenCL, "", Lang_OpenCL, 656 Verifier, typedefDecl(hasType(pipeType()))); 657 } 658 659 struct ImportMatrixType : ImportType { 660 std::vector<std::string> getExtraArgs() const override { 661 return {"-fenable-matrix"}; 662 } 663 }; 664 665 TEST_P(ImportMatrixType, ImportConstantMatrixType) { 666 const AstTypeMatcher<ConstantMatrixType> constantMatrixType; 667 MatchVerifier<Decl> Verifier; 668 testImport("typedef int __attribute__((matrix_type(5, 5))) declToImport;", 669 Lang_CXX11, "", Lang_CXX11, Verifier, 670 typedefDecl(hasType(constantMatrixType()))); 671 } 672 673 TEST_P(ImportMatrixType, ImportDependentSizedMatrixType) { 674 const AstTypeMatcher<DependentSizedMatrixType> dependentSizedMatrixType; 675 MatchVerifier<Decl> Verifier; 676 testImport( 677 R"( 678 template<typename T, int Rows, int Cols> 679 using declToImport = T __attribute__((matrix_type(Rows, Cols))); 680 )", 681 Lang_CXX11, "", Lang_CXX11, Verifier, 682 typeAliasTemplateDecl( 683 has(typeAliasDecl(hasType(dependentSizedMatrixType()))))); 684 } 685 686 TEST_P(ImportType, ImportUsingType) { 687 MatchVerifier<Decl> Verifier; 688 testImport("struct C {};" 689 "void declToImport() { using ::C; new C{}; }", 690 Lang_CXX11, "", Lang_CXX11, Verifier, 691 functionDecl(hasDescendant(cxxNewExpr(hasType(pointerType( 692 pointee(elaboratedType(namesType(usingType()))))))))); 693 } 694 695 TEST_P(ImportDecl, ImportFunctionTemplateDecl) { 696 MatchVerifier<Decl> Verifier; 697 testImport("template <typename T> void declToImport() { };", Lang_CXX03, "", 698 Lang_CXX03, Verifier, functionTemplateDecl()); 699 } 700 701 TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) { 702 MatchVerifier<Decl> Verifier; 703 testImport("template <typename T> struct C { T t; };" 704 "template <typename T> void declToImport() {" 705 " C<T> d;" 706 " (void)d.t;" 707 "}" 708 "void instantiate() { declToImport<int>(); }", 709 Lang_CXX03, "", Lang_CXX03, Verifier, 710 functionTemplateDecl(hasDescendant( 711 cStyleCastExpr(has(cxxDependentScopeMemberExpr()))))); 712 testImport("template <typename T> struct C { T t; };" 713 "template <typename T> void declToImport() {" 714 " C<T> d;" 715 " (void)(&d)->t;" 716 "}" 717 "void instantiate() { declToImport<int>(); }", 718 Lang_CXX03, "", Lang_CXX03, Verifier, 719 functionTemplateDecl(hasDescendant( 720 cStyleCastExpr(has(cxxDependentScopeMemberExpr()))))); 721 } 722 723 TEST_P(ImportType, ImportTypeAliasTemplate) { 724 MatchVerifier<Decl> Verifier; 725 testImport( 726 "template <int K>" 727 "struct dummy { static const int i = K; };" 728 "template <int K> using dummy2 = dummy<K>;" 729 "int declToImport() { return dummy2<3>::i; }", 730 Lang_CXX11, "", Lang_CXX11, Verifier, 731 traverse(TK_AsIs, 732 functionDecl(hasDescendant(implicitCastExpr(has(declRefExpr()))), 733 unless(hasAncestor( 734 translationUnitDecl(has(typeAliasDecl()))))))); 735 } 736 737 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateSpecializationDecl> 738 varTemplateSpecializationDecl; 739 740 TEST_P(ImportDecl, ImportVarTemplate) { 741 MatchVerifier<Decl> Verifier; 742 testImport( 743 "template <typename T>" 744 "T pi = T(3.1415926535897932385L);" 745 "void declToImport() { (void)pi<int>; }", 746 Lang_CXX14, "", Lang_CXX14, Verifier, 747 functionDecl( 748 hasDescendant(declRefExpr(to(varTemplateSpecializationDecl()))), 749 unless(hasAncestor(translationUnitDecl(has(varDecl( 750 hasName("pi"), unless(varTemplateSpecializationDecl())))))))); 751 } 752 753 TEST_P(ImportType, ImportPackExpansion) { 754 MatchVerifier<Decl> Verifier; 755 testImport("template <typename... Args>" 756 "struct dummy {" 757 " dummy(Args... args) {}" 758 " static const int i = 4;" 759 "};" 760 "int declToImport() { return dummy<int>::i; }", 761 Lang_CXX11, "", Lang_CXX11, Verifier, 762 traverse(TK_AsIs, functionDecl(hasDescendant(returnStmt(has( 763 implicitCastExpr(has(declRefExpr())))))))); 764 } 765 766 TEST_P(ImportType, ImportDependentTemplateSpecialization) { 767 MatchVerifier<Decl> Verifier; 768 testImport("template<typename T>" 769 "struct A;" 770 "template<typename T>" 771 "struct declToImport {" 772 " typename A<T>::template B<T> a;" 773 "};", 774 Lang_CXX03, "", Lang_CXX03, Verifier, 775 classTemplateDecl(has(cxxRecordDecl(has( 776 fieldDecl(hasType(dependentTemplateSpecializationType()))))))); 777 } 778 779 TEST_P(ImportType, ImportDeducedTemplateSpecialization) { 780 MatchVerifier<Decl> Verifier; 781 testImport("template <typename T>" 782 "class C { public: C(T); };" 783 "C declToImport(123);", 784 Lang_CXX17, "", Lang_CXX17, Verifier, 785 varDecl(hasType(elaboratedType( 786 namesType(deducedTemplateSpecializationType()))))); 787 } 788 789 const internal::VariadicDynCastAllOfMatcher<Stmt, SizeOfPackExpr> 790 sizeOfPackExpr; 791 792 TEST_P(ImportExpr, ImportSizeOfPackExpr) { 793 MatchVerifier<Decl> Verifier; 794 testImport( 795 "template <typename... Ts>" 796 "void declToImport() {" 797 " const int i = sizeof...(Ts);" 798 "};" 799 "void g() { declToImport<int>(); }", 800 Lang_CXX11, "", Lang_CXX11, Verifier, 801 functionTemplateDecl(hasDescendant(sizeOfPackExpr()))); 802 testImport( 803 "template <typename... Ts>" 804 "using X = int[sizeof...(Ts)];" 805 "template <typename... Us>" 806 "struct Y {" 807 " X<Us..., int, double, int, Us...> f;" 808 "};" 809 "Y<float, int> declToImport;", 810 Lang_CXX11, "", Lang_CXX11, Verifier, 811 varDecl(hasType(classTemplateSpecializationDecl(has(fieldDecl(hasType( 812 hasUnqualifiedDesugaredType(constantArrayType(hasSize(7)))))))))); 813 } 814 815 TEST_P(ImportExpr, ImportCXXFoldExpr) { 816 auto Match1 = cxxFoldExpr(hasOperatorName("+"), isLeftFold(), 817 unless(hasFoldInit(expr()))); 818 auto Match2 = 819 cxxFoldExpr(hasOperatorName("-"), isLeftFold(), hasFoldInit(expr())); 820 auto Match3 = cxxFoldExpr(hasOperatorName("*"), isRightFold(), 821 unless(hasFoldInit(expr()))); 822 auto Match4 = 823 cxxFoldExpr(hasOperatorName("/"), isRightFold(), hasFoldInit(expr())); 824 825 MatchVerifier<Decl> Verifier; 826 testImport("template <typename... Ts>" 827 "void declToImport(Ts... args) {" 828 " const int i1 = (... + args);" 829 " const int i2 = (1 - ... - args);" 830 " const int i3 = (args * ...);" 831 " const int i4 = (args / ... / 1);" 832 "};" 833 "void g() { declToImport(1, 2, 3, 4, 5); }", 834 Lang_CXX17, "", Lang_CXX17, Verifier, 835 functionTemplateDecl(hasDescendant(Match1), hasDescendant(Match2), 836 hasDescendant(Match3), 837 hasDescendant(Match4))); 838 } 839 840 /// \brief Matches __builtin_types_compatible_p: 841 /// GNU extension to check equivalent types 842 /// Given 843 /// \code 844 /// __builtin_types_compatible_p(int, int) 845 /// \endcode 846 // will generate TypeTraitExpr <...> 'int' 847 const internal::VariadicDynCastAllOfMatcher<Stmt, TypeTraitExpr> typeTraitExpr; 848 849 TEST_P(ImportExpr, ImportTypeTraitExpr) { 850 MatchVerifier<Decl> Verifier; 851 testImport( 852 "void declToImport() { " 853 " (void)__builtin_types_compatible_p(int, int);" 854 "}", 855 Lang_C99, "", Lang_C99, Verifier, 856 functionDecl(hasDescendant(typeTraitExpr(hasType(asString("int")))))); 857 } 858 859 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr> cxxTypeidExpr; 860 861 TEST_P(ImportExpr, ImportCXXTypeidExpr) { 862 MatchVerifier<Decl> Verifier; 863 testImport( 864 "namespace std { class type_info {}; }" 865 "void declToImport() {" 866 " int x;" 867 " auto a = typeid(int); auto b = typeid(x);" 868 "}", 869 Lang_CXX11, "", Lang_CXX11, Verifier, 870 traverse( 871 TK_AsIs, 872 functionDecl( 873 hasDescendant(varDecl(hasName("a"), hasInitializer(hasDescendant( 874 cxxTypeidExpr())))), 875 hasDescendant(varDecl(hasName("b"), hasInitializer(hasDescendant( 876 cxxTypeidExpr()))))))); 877 } 878 879 TEST_P(ImportExpr, ImportTypeTraitExprValDep) { 880 MatchVerifier<Decl> Verifier; 881 testImport( 882 "template<typename T> struct declToImport {" 883 " void m() { (void)__is_pod(T); }" 884 "};" 885 "void f() { declToImport<int>().m(); }", 886 Lang_CXX11, "", Lang_CXX11, Verifier, 887 classTemplateDecl(has(cxxRecordDecl(has( 888 functionDecl(hasDescendant( 889 typeTraitExpr(hasType(booleanType()))))))))); 890 } 891 892 TEST_P(ImportDecl, ImportRecordDeclInFunc) { 893 MatchVerifier<Decl> Verifier; 894 testImport("int declToImport() { " 895 " struct data_t {int a;int b;};" 896 " struct data_t d;" 897 " return 0;" 898 "}", 899 Lang_C99, "", Lang_C99, Verifier, 900 functionDecl(hasBody(compoundStmt( 901 has(declStmt(hasSingleDecl(varDecl(hasName("d"))))))))); 902 } 903 904 TEST_P(ImportDecl, ImportedVarDeclPreservesThreadLocalStorage) { 905 MatchVerifier<Decl> Verifier; 906 testImport("thread_local int declToImport;", Lang_CXX11, "", Lang_CXX11, 907 Verifier, varDecl(hasThreadStorageDuration())); 908 } 909 910 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) { 911 Decl *FromTU = getTuDecl("int declToImport() { " 912 " struct data_t {int a;int b;};" 913 " struct data_t d;" 914 " return 0;" 915 "}", 916 Lang_C99, "input.c"); 917 auto *FromVar = 918 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("d"))); 919 ASSERT_TRUE(FromVar); 920 auto ToType = 921 ImportType(FromVar->getType().getCanonicalType(), FromVar, Lang_C99); 922 EXPECT_FALSE(ToType.isNull()); 923 } 924 925 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncParams) { 926 // This construct is not supported by ASTImporter. 927 Decl *FromTU = getTuDecl( 928 "int declToImport(struct data_t{int a;int b;} ***d){ return 0; }", 929 Lang_C99, "input.c"); 930 auto *From = FirstDeclMatcher<FunctionDecl>().match( 931 FromTU, functionDecl(hasName("declToImport"))); 932 ASSERT_TRUE(From); 933 auto *To = Import(From, Lang_C99); 934 EXPECT_EQ(To, nullptr); 935 } 936 937 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncFromMacro) { 938 Decl *FromTU = 939 getTuDecl("#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n" 940 "int declToImport(){ return NONAME_SIZEOF(int); }", 941 Lang_C99, "input.c"); 942 auto *From = FirstDeclMatcher<FunctionDecl>().match( 943 FromTU, functionDecl(hasName("declToImport"))); 944 ASSERT_TRUE(From); 945 auto *To = Import(From, Lang_C99); 946 ASSERT_TRUE(To); 947 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match( 948 To, functionDecl(hasName("declToImport"), 949 hasDescendant(unaryExprOrTypeTraitExpr())))); 950 } 951 952 TEST_P(ASTImporterOptionSpecificTestBase, 953 ImportRecordDeclInFuncParamsFromMacro) { 954 // This construct is not supported by ASTImporter. 955 Decl *FromTU = 956 getTuDecl("#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n" 957 "int declToImport(PAIR_STRUCT(int) ***d){ return 0; }", 958 Lang_C99, "input.c"); 959 auto *From = FirstDeclMatcher<FunctionDecl>().match( 960 FromTU, functionDecl(hasName("declToImport"))); 961 ASSERT_TRUE(From); 962 auto *To = Import(From, Lang_C99); 963 EXPECT_EQ(To, nullptr); 964 } 965 966 const internal::VariadicDynCastAllOfMatcher<Expr, CXXPseudoDestructorExpr> 967 cxxPseudoDestructorExpr; 968 969 TEST_P(ImportExpr, ImportCXXPseudoDestructorExpr) { 970 MatchVerifier<Decl> Verifier; 971 testImport( 972 "typedef int T;" 973 "void declToImport(int *p) {" 974 " T t;" 975 " p->T::~T();" 976 "}", 977 Lang_CXX03, "", Lang_CXX03, Verifier, 978 functionDecl(hasDescendant(callExpr(has(cxxPseudoDestructorExpr()))))); 979 } 980 981 TEST_P(ImportDecl, ImportUsingDecl) { 982 MatchVerifier<Decl> Verifier; 983 testImport("namespace foo { int bar; }" 984 "void declToImport() { using foo::bar; }", 985 Lang_CXX03, "", Lang_CXX03, Verifier, 986 functionDecl(hasDescendant(usingDecl(hasName("bar"))))); 987 } 988 989 TEST_P(ImportDecl, ImportUsingTemplate) { 990 MatchVerifier<Decl> Verifier; 991 testImport("namespace ns { template <typename T> struct S {}; }" 992 "template <template <typename> class T> class X {};" 993 "void declToImport() {" 994 "using ns::S; X<S> xi; }", 995 Lang_CXX11, "", Lang_CXX11, Verifier, 996 functionDecl(hasDescendant(varDecl(hasTypeLoc(elaboratedTypeLoc( 997 hasNamedTypeLoc(templateSpecializationTypeLoc( 998 hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))))); 999 } 1000 1001 TEST_P(ImportDecl, ImportUsingEnumDecl) { 1002 MatchVerifier<Decl> Verifier; 1003 testImport("namespace foo { enum bar { baz, toto, quux }; }" 1004 "void declToImport() { using enum foo::bar; }", 1005 Lang_CXX20, "", Lang_CXX20, Verifier, 1006 functionDecl(hasDescendant(usingEnumDecl(hasName("bar"))))); 1007 } 1008 1009 const internal::VariadicDynCastAllOfMatcher<Decl, UsingPackDecl> usingPackDecl; 1010 1011 TEST_P(ImportDecl, ImportUsingPackDecl) { 1012 MatchVerifier<Decl> Verifier; 1013 testImport( 1014 "struct A { int operator()() { return 1; } };" 1015 "struct B { int operator()() { return 2; } };" 1016 "template<typename ...T> struct C : T... { using T::operator()...; };" 1017 "C<A, B> declToImport;", 1018 Lang_CXX20, "", Lang_CXX20, Verifier, 1019 varDecl(hasType(elaboratedType(namesType(templateSpecializationType( 1020 hasDeclaration(classTemplateSpecializationDecl( 1021 hasDescendant(usingPackDecl()))))))))); 1022 } 1023 1024 /// \brief Matches shadow declarations introduced into a scope by a 1025 /// (resolved) using declaration. 1026 /// 1027 /// Given 1028 /// \code 1029 /// namespace n { int f; } 1030 /// namespace declToImport { using n::f; } 1031 /// \endcode 1032 /// usingShadowDecl() 1033 /// matches \code f \endcode 1034 const internal::VariadicDynCastAllOfMatcher<Decl, 1035 UsingShadowDecl> usingShadowDecl; 1036 1037 TEST_P(ImportDecl, ImportUsingShadowDecl) { 1038 MatchVerifier<Decl> Verifier; 1039 // from using-decl 1040 testImport("namespace foo { int bar; }" 1041 "namespace declToImport { using foo::bar; }", 1042 Lang_CXX03, "", Lang_CXX03, Verifier, 1043 namespaceDecl(has(usingShadowDecl(hasName("bar"))))); 1044 // from using-enum-decl 1045 testImport("namespace foo { enum bar {baz, toto, quux }; }" 1046 "namespace declToImport { using enum foo::bar; }", 1047 Lang_CXX20, "", Lang_CXX20, Verifier, 1048 namespaceDecl(has(usingShadowDecl(hasName("baz"))))); 1049 } 1050 1051 TEST_P(ImportExpr, ImportUnresolvedLookupExpr) { 1052 MatchVerifier<Decl> Verifier; 1053 testImport("template<typename T> int foo();" 1054 "template <typename T> void declToImport() {" 1055 " (void)::foo<T>;" 1056 " (void)::template foo<T>;" 1057 "}" 1058 "void instantiate() { declToImport<int>(); }", 1059 Lang_CXX03, "", Lang_CXX03, Verifier, 1060 functionTemplateDecl(hasDescendant(unresolvedLookupExpr()))); 1061 } 1062 1063 TEST_P(ImportExpr, ImportCXXUnresolvedConstructExpr) { 1064 MatchVerifier<Decl> Verifier; 1065 testImport("template <typename T> struct C { T t; };" 1066 "template <typename T> void declToImport() {" 1067 " C<T> d;" 1068 " d.t = T();" 1069 "}" 1070 "void instantiate() { declToImport<int>(); }", 1071 Lang_CXX03, "", Lang_CXX03, Verifier, 1072 functionTemplateDecl(hasDescendant( 1073 binaryOperator(has(cxxUnresolvedConstructExpr()))))); 1074 testImport("template <typename T> struct C { T t; };" 1075 "template <typename T> void declToImport() {" 1076 " C<T> d;" 1077 " (&d)->t = T();" 1078 "}" 1079 "void instantiate() { declToImport<int>(); }", 1080 Lang_CXX03, "", Lang_CXX03, Verifier, 1081 functionTemplateDecl(hasDescendant( 1082 binaryOperator(has(cxxUnresolvedConstructExpr()))))); 1083 } 1084 1085 /// Check that function "declToImport()" (which is the templated function 1086 /// for corresponding FunctionTemplateDecl) is not added into DeclContext. 1087 /// Same for class template declarations. 1088 TEST_P(ImportDecl, ImportTemplatedDeclForTemplate) { 1089 MatchVerifier<Decl> Verifier; 1090 testImport("template <typename T> void declToImport() { T a = 1; }" 1091 "void instantiate() { declToImport<int>(); }", 1092 Lang_CXX03, "", Lang_CXX03, Verifier, 1093 functionTemplateDecl(hasAncestor(translationUnitDecl( 1094 unless(has(functionDecl(hasName("declToImport")))))))); 1095 testImport("template <typename T> struct declToImport { T t; };" 1096 "void instantiate() { declToImport<int>(); }", 1097 Lang_CXX03, "", Lang_CXX03, Verifier, 1098 classTemplateDecl(hasAncestor(translationUnitDecl( 1099 unless(has(cxxRecordDecl(hasName("declToImport")))))))); 1100 } 1101 1102 TEST_P(ImportDecl, ImportClassTemplatePartialSpecialization) { 1103 MatchVerifier<Decl> Verifier; 1104 auto Code = 1105 R"s( 1106 struct declToImport { 1107 template <typename T0> struct X; 1108 template <typename T0> struct X<T0 *> {}; 1109 }; 1110 )s"; 1111 testImport(Code, Lang_CXX03, "", Lang_CXX03, Verifier, 1112 recordDecl(has(classTemplateDecl()), 1113 has(classTemplateSpecializationDecl()))); 1114 } 1115 1116 TEST_P(ImportExpr, CXXOperatorCallExpr) { 1117 MatchVerifier<Decl> Verifier; 1118 testImport( 1119 "class declToImport {" 1120 " void f() { *this = declToImport(); }" 1121 "};", 1122 Lang_CXX03, "", Lang_CXX03, Verifier, 1123 cxxRecordDecl(has(cxxMethodDecl(hasDescendant(cxxOperatorCallExpr()))))); 1124 } 1125 1126 TEST_P(ImportExpr, DependentSizedArrayType) { 1127 MatchVerifier<Decl> Verifier; 1128 testImport("template<typename T, int Size> class declToImport {" 1129 " T data[Size];" 1130 "};", 1131 Lang_CXX03, "", Lang_CXX03, Verifier, 1132 classTemplateDecl(has(cxxRecordDecl( 1133 has(fieldDecl(hasType(dependentSizedArrayType()))))))); 1134 } 1135 1136 TEST_P(ImportExpr, DependentSizedExtVectorType) { 1137 MatchVerifier<Decl> Verifier; 1138 testImport("template<typename T, int Size>" 1139 "class declToImport {" 1140 " typedef T __attribute__((ext_vector_type(Size))) type;" 1141 "};", 1142 Lang_CXX03, "", Lang_CXX03, Verifier, 1143 classTemplateDecl(has(cxxRecordDecl( 1144 has(typedefDecl(hasType(dependentSizedExtVectorType()))))))); 1145 } 1146 1147 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingPackDecl) { 1148 Decl *FromTU = getTuDecl( 1149 "struct A { int operator()() { return 1; } };" 1150 "struct B { int operator()() { return 2; } };" 1151 "template<typename ...T> struct C : T... { using T::operator()...; };" 1152 "C<A, B> Var;", 1153 Lang_CXX20); 1154 1155 auto From = FirstDeclMatcher<UsingPackDecl>().match(FromTU, usingPackDecl()); 1156 ASSERT_TRUE(From); 1157 auto To = cast<UsingPackDecl>(Import(From, Lang_CXX20)); 1158 ASSERT_TRUE(To); 1159 1160 ArrayRef<NamedDecl *> FromExpansions = From->expansions(); 1161 ArrayRef<NamedDecl *> ToExpansions = To->expansions(); 1162 ASSERT_EQ(FromExpansions.size(), ToExpansions.size()); 1163 for (unsigned int I = 0; I < FromExpansions.size(); ++I) { 1164 auto ImportedExpansion = Import(FromExpansions[I], Lang_CXX20); 1165 EXPECT_EQ(ImportedExpansion, ToExpansions[I]); 1166 } 1167 1168 auto ImportedDC = cast<Decl>(Import(From->getDeclContext(), Lang_CXX20)); 1169 EXPECT_EQ(ImportedDC, cast<Decl>(To->getDeclContext())); 1170 } 1171 1172 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclNoDefaultArg) { 1173 Decl *FromTU = getTuDecl("template<typename T> struct X {};", Lang_CXX03); 1174 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match( 1175 FromTU, templateTypeParmDecl(hasName("T"))); 1176 TemplateTypeParmDecl *To = Import(From, Lang_CXX03); 1177 ASSERT_FALSE(To->hasDefaultArgument()); 1178 } 1179 1180 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclDefaultArg) { 1181 Decl *FromTU = 1182 getTuDecl("template<typename T = int> struct X {};", Lang_CXX03); 1183 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match( 1184 FromTU, templateTypeParmDecl(hasName("T"))); 1185 TemplateTypeParmDecl *To = Import(From, Lang_CXX03); 1186 ASSERT_TRUE(To->hasDefaultArgument()); 1187 QualType ToArg = To->getDefaultArgument().getArgument().getAsType(); 1188 ASSERT_EQ(ToArg, QualType(To->getASTContext().IntTy)); 1189 } 1190 1191 TEST_P(ASTImporterOptionSpecificTestBase, ImportBeginLocOfDeclRefExpr) { 1192 Decl *FromTU = 1193 getTuDecl("class A { public: static int X; }; void f() { (void)A::X; }", 1194 Lang_CXX03); 1195 auto From = FirstDeclMatcher<FunctionDecl>().match( 1196 FromTU, functionDecl(hasName("f"))); 1197 ASSERT_TRUE(From); 1198 ASSERT_TRUE( 1199 cast<CStyleCastExpr>(cast<CompoundStmt>(From->getBody())->body_front()) 1200 ->getSubExpr() 1201 ->getBeginLoc() 1202 .isValid()); 1203 FunctionDecl *To = Import(From, Lang_CXX03); 1204 ASSERT_TRUE(To); 1205 ASSERT_TRUE( 1206 cast<CStyleCastExpr>(cast<CompoundStmt>(To->getBody())->body_front()) 1207 ->getSubExpr() 1208 ->getBeginLoc() 1209 .isValid()); 1210 } 1211 1212 TEST_P(ASTImporterOptionSpecificTestBase, 1213 TemplateTemplateParmDeclNoDefaultArg) { 1214 Decl *FromTU = getTuDecl(R"( 1215 template<template<typename> typename TT> struct Y {}; 1216 )", 1217 Lang_CXX17); 1218 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match( 1219 FromTU, templateTemplateParmDecl(hasName("TT"))); 1220 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17); 1221 ASSERT_FALSE(To->hasDefaultArgument()); 1222 } 1223 1224 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTemplateParmDeclDefaultArg) { 1225 Decl *FromTU = getTuDecl(R"( 1226 template<typename T> struct X {}; 1227 template<template<typename> typename TT = X> struct Y {}; 1228 )", 1229 Lang_CXX17); 1230 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match( 1231 FromTU, templateTemplateParmDecl(hasName("TT"))); 1232 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17); 1233 ASSERT_TRUE(To->hasDefaultArgument()); 1234 const TemplateArgument &ToDefaultArg = To->getDefaultArgument().getArgument(); 1235 ASSERT_TRUE(To->isTemplateDecl()); 1236 TemplateDecl *ToTemplate = ToDefaultArg.getAsTemplate().getAsTemplateDecl(); 1237 1238 // Find the default argument template 'X' in the AST and compare it against 1239 // the default argument we got. 1240 auto ToExpectedDecl = FirstDeclMatcher<ClassTemplateDecl>().match( 1241 To->getTranslationUnitDecl(), classTemplateDecl(hasName("X"))); 1242 ASSERT_EQ(ToTemplate, ToExpectedDecl); 1243 } 1244 1245 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclNoDefaultArg) { 1246 Decl *FromTU = getTuDecl("template<int N> struct X {};", Lang_CXX03); 1247 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match( 1248 FromTU, nonTypeTemplateParmDecl(hasName("N"))); 1249 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03); 1250 ASSERT_FALSE(To->hasDefaultArgument()); 1251 } 1252 1253 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclDefaultArg) { 1254 Decl *FromTU = getTuDecl("template<int S = 1> struct X {};", Lang_CXX03); 1255 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match( 1256 FromTU, nonTypeTemplateParmDecl(hasName("S"))); 1257 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03); 1258 ASSERT_TRUE(To->hasDefaultArgument()); 1259 Stmt *ToArg = To->getDefaultArgument().getArgument().getAsExpr(); 1260 ASSERT_TRUE(isa<IntegerLiteral>(ToArg)); 1261 ASSERT_EQ(cast<IntegerLiteral>(ToArg)->getValue().getLimitedValue(), 1U); 1262 } 1263 1264 TEST_P(ASTImporterOptionSpecificTestBase, TemplateArgumentsDefaulted) { 1265 Decl *FromTU = getTuDecl(R"( 1266 template<typename T> struct X {}; 1267 template<typename TP = double, 1268 int NTTP = 50, 1269 template<typename> typename TT = X> struct S {}; 1270 S<> s; 1271 )", 1272 Lang_CXX17); 1273 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 1274 FromTU, classTemplateSpecializationDecl(hasName("S"))); 1275 ASSERT_TRUE(FromSpec); 1276 auto *ToSpec = Import(FromSpec, Lang_CXX03); 1277 ASSERT_TRUE(ToSpec); 1278 auto const &TList = ToSpec->getTemplateArgs(); 1279 for (auto const &Arg : TList.asArray()) { 1280 ASSERT_TRUE(Arg.getIsDefaulted()); 1281 } 1282 } 1283 1284 TEST_P(ASTImporterOptionSpecificTestBase, 1285 ImportOfTemplatedDeclOfClassTemplateDecl) { 1286 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03); 1287 auto From = 1288 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl()); 1289 ASSERT_TRUE(From); 1290 auto To = cast<ClassTemplateDecl>(Import(From, Lang_CXX03)); 1291 ASSERT_TRUE(To); 1292 Decl *ToTemplated = To->getTemplatedDecl(); 1293 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03); 1294 EXPECT_TRUE(ToTemplated1); 1295 EXPECT_EQ(ToTemplated1, ToTemplated); 1296 } 1297 1298 TEST_P(ASTImporterOptionSpecificTestBase, 1299 ImportOfTemplatedDeclOfFunctionTemplateDecl) { 1300 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03); 1301 auto From = FirstDeclMatcher<FunctionTemplateDecl>().match( 1302 FromTU, functionTemplateDecl()); 1303 ASSERT_TRUE(From); 1304 auto To = cast<FunctionTemplateDecl>(Import(From, Lang_CXX03)); 1305 ASSERT_TRUE(To); 1306 Decl *ToTemplated = To->getTemplatedDecl(); 1307 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03); 1308 EXPECT_TRUE(ToTemplated1); 1309 EXPECT_EQ(ToTemplated1, ToTemplated); 1310 } 1311 1312 TEST_P(ASTImporterOptionSpecificTestBase, 1313 ImportOfTemplatedDeclShouldImportTheClassTemplateDecl) { 1314 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03); 1315 auto FromFT = 1316 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl()); 1317 ASSERT_TRUE(FromFT); 1318 1319 auto ToTemplated = 1320 cast<CXXRecordDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03)); 1321 EXPECT_TRUE(ToTemplated); 1322 auto ToTU = ToTemplated->getTranslationUnitDecl(); 1323 auto ToFT = 1324 FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, classTemplateDecl()); 1325 EXPECT_TRUE(ToFT); 1326 } 1327 1328 TEST_P(ASTImporterOptionSpecificTestBase, 1329 ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) { 1330 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03); 1331 auto FromFT = FirstDeclMatcher<FunctionTemplateDecl>().match( 1332 FromTU, functionTemplateDecl()); 1333 ASSERT_TRUE(FromFT); 1334 1335 auto ToTemplated = 1336 cast<FunctionDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03)); 1337 EXPECT_TRUE(ToTemplated); 1338 auto ToTU = ToTemplated->getTranslationUnitDecl(); 1339 auto ToFT = FirstDeclMatcher<FunctionTemplateDecl>().match( 1340 ToTU, functionTemplateDecl()); 1341 EXPECT_TRUE(ToFT); 1342 } 1343 1344 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) { 1345 auto Code = 1346 R"( 1347 namespace x { 1348 template<class X> struct S1{}; 1349 template<class X> struct S2{}; 1350 template<class X> struct S3{}; 1351 } 1352 )"; 1353 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 1354 auto FromNs = 1355 FirstDeclMatcher<NamespaceDecl>().match(FromTU, namespaceDecl()); 1356 auto ToNs = cast<NamespaceDecl>(Import(FromNs, Lang_CXX03)); 1357 ASSERT_TRUE(ToNs); 1358 auto From = 1359 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, 1360 classTemplateDecl( 1361 hasName("S2"))); 1362 auto To = 1363 FirstDeclMatcher<ClassTemplateDecl>().match(ToNs, 1364 classTemplateDecl( 1365 hasName("S2"))); 1366 ASSERT_TRUE(From); 1367 ASSERT_TRUE(To); 1368 auto ToTemplated = To->getTemplatedDecl(); 1369 auto ToTemplated1 = 1370 cast<CXXRecordDecl>(Import(From->getTemplatedDecl(), Lang_CXX03)); 1371 EXPECT_TRUE(ToTemplated1); 1372 ASSERT_EQ(ToTemplated1, ToTemplated); 1373 } 1374 1375 TEST_P(ASTImporterOptionSpecificTestBase, 1376 ImportTemplateSpecializationStaticMember) { 1377 auto FromCode = 1378 R"( 1379 template <typename H> class Test{ 1380 public: 1381 static const unsigned int length; 1382 }; 1383 1384 template<> const unsigned int Test<int>::length; 1385 template<> const unsigned int Test<int>::length = 0; 1386 )"; 1387 auto ToCode = 1388 R"( 1389 template <typename H> class Test { 1390 public: 1391 static const unsigned int length; 1392 }; 1393 1394 template <> const unsigned int Test<int>::length; 1395 1396 void foo() { int i = 1 / Test<int>::length; } 1397 )"; 1398 Decl *FromTU = getTuDecl(FromCode, Lang_CXX14); 1399 auto FromDecl = FirstDeclMatcher<VarDecl>().match( 1400 FromTU, varDecl(hasName("length"), isDefinition())); 1401 Decl *ToTu = getToTuDecl(ToCode, Lang_CXX14); 1402 auto ToX = Import(FromDecl, Lang_CXX03); 1403 auto ToDecl = FirstDeclMatcher<VarDecl>().match( 1404 ToTu, varDecl(hasName("length"), isDefinition())); 1405 EXPECT_TRUE(ToX); 1406 EXPECT_EQ(ToX, ToDecl); 1407 } 1408 1409 TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) { 1410 // This tests the import of isConditionTrue directly to make sure the importer 1411 // gets it right. 1412 Decl *From, *To; 1413 std::tie(From, To) = getImportedDecl( 1414 "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }", Lang_C99, 1415 "", Lang_C99); 1416 1417 auto ToResults = match(chooseExpr().bind("choose"), To->getASTContext()); 1418 auto FromResults = match(chooseExpr().bind("choose"), From->getASTContext()); 1419 1420 const ChooseExpr *FromChooseExpr = 1421 selectFirst<ChooseExpr>("choose", FromResults); 1422 ASSERT_TRUE(FromChooseExpr); 1423 1424 const ChooseExpr *ToChooseExpr = selectFirst<ChooseExpr>("choose", ToResults); 1425 ASSERT_TRUE(ToChooseExpr); 1426 1427 EXPECT_EQ(FromChooseExpr->isConditionTrue(), ToChooseExpr->isConditionTrue()); 1428 EXPECT_EQ(FromChooseExpr->isConditionDependent(), 1429 ToChooseExpr->isConditionDependent()); 1430 } 1431 1432 TEST_P(ASTImporterOptionSpecificTestBase, ImportConvertVectorExpr) { 1433 Decl *From, *To; 1434 std::tie(From, To) = getImportedDecl( 1435 "typedef double v4double __attribute__((__vector_size__(32)));" 1436 "typedef float v4float __attribute__((__vector_size__(16)));" 1437 "v4float vf;" 1438 "void declToImport() { (void)__builtin_convertvector(vf, v4double); }", 1439 Lang_CXX03, "", Lang_CXX03); 1440 1441 auto ToResults = 1442 match(convertVectorExpr().bind("convert"), To->getASTContext()); 1443 auto FromResults = 1444 match(convertVectorExpr().bind("convert"), From->getASTContext()); 1445 1446 const ConvertVectorExpr *FromConvertVectorExpr = 1447 selectFirst<ConvertVectorExpr>("convert", FromResults); 1448 ASSERT_TRUE(FromConvertVectorExpr); 1449 1450 const ConvertVectorExpr *ToConvertVectorExpr = 1451 selectFirst<ConvertVectorExpr>("convert", ToResults); 1452 ASSERT_TRUE(ToConvertVectorExpr); 1453 } 1454 1455 TEST_P(ASTImporterOptionSpecificTestBase, ImportGenericSelectionExpr) { 1456 Decl *From, *To; 1457 std::tie(From, To) = getImportedDecl( 1458 R"( 1459 int declToImport() { 1460 int x; 1461 return _Generic(x, int: 0, default: 1); 1462 } 1463 )", 1464 Lang_C99, "", Lang_C99); 1465 1466 auto ToResults = 1467 match(genericSelectionExpr().bind("expr"), To->getASTContext()); 1468 auto FromResults = 1469 match(genericSelectionExpr().bind("expr"), From->getASTContext()); 1470 1471 const GenericSelectionExpr *FromGenericSelectionExpr = 1472 selectFirst<GenericSelectionExpr>("expr", FromResults); 1473 ASSERT_TRUE(FromGenericSelectionExpr); 1474 1475 const GenericSelectionExpr *ToGenericSelectionExpr = 1476 selectFirst<GenericSelectionExpr>("expr", ToResults); 1477 ASSERT_TRUE(ToGenericSelectionExpr); 1478 1479 EXPECT_EQ(FromGenericSelectionExpr->isResultDependent(), 1480 ToGenericSelectionExpr->isResultDependent()); 1481 EXPECT_EQ(FromGenericSelectionExpr->getResultIndex(), 1482 ToGenericSelectionExpr->getResultIndex()); 1483 } 1484 1485 TEST_P(ASTImporterOptionSpecificTestBase, 1486 ImportFunctionWithBackReferringParameter) { 1487 Decl *From, *To; 1488 std::tie(From, To) = getImportedDecl( 1489 R"( 1490 template <typename T> struct X {}; 1491 1492 void declToImport(int y, X<int> &x) {} 1493 1494 template <> struct X<int> { 1495 void g() { 1496 X<int> x; 1497 declToImport(0, x); 1498 } 1499 }; 1500 )", 1501 Lang_CXX03, "", Lang_CXX03); 1502 1503 MatchVerifier<Decl> Verifier; 1504 auto Matcher = functionDecl(hasName("declToImport"), 1505 parameterCountIs(2), 1506 hasParameter(0, hasName("y")), 1507 hasParameter(1, hasName("x")), 1508 hasParameter(1, hasType(asString("X<int> &")))); 1509 ASSERT_TRUE(Verifier.match(From, Matcher)); 1510 EXPECT_TRUE(Verifier.match(To, Matcher)); 1511 } 1512 1513 TEST_P(ASTImporterOptionSpecificTestBase, 1514 TUshouldNotContainTemplatedDeclOfFunctionTemplates) { 1515 Decl *From, *To; 1516 std::tie(From, To) = 1517 getImportedDecl("template <typename T> void declToImport() { T a = 1; }" 1518 "void instantiate() { declToImport<int>(); }", 1519 Lang_CXX03, "", Lang_CXX03); 1520 1521 auto Check = [](Decl *D) -> bool { 1522 auto TU = D->getTranslationUnitDecl(); 1523 for (auto Child : TU->decls()) { 1524 if (auto *FD = dyn_cast<FunctionDecl>(Child)) { 1525 if (FD->getNameAsString() == "declToImport") { 1526 GTEST_NONFATAL_FAILURE_( 1527 "TU should not contain any FunctionDecl with name declToImport"); 1528 return false; 1529 } 1530 } 1531 } 1532 return true; 1533 }; 1534 1535 ASSERT_TRUE(Check(From)); 1536 EXPECT_TRUE(Check(To)); 1537 } 1538 1539 TEST_P(ASTImporterOptionSpecificTestBase, 1540 TUshouldNotContainTemplatedDeclOfClassTemplates) { 1541 Decl *From, *To; 1542 std::tie(From, To) = 1543 getImportedDecl("template <typename T> struct declToImport { T t; };" 1544 "void instantiate() { declToImport<int>(); }", 1545 Lang_CXX03, "", Lang_CXX03); 1546 1547 auto Check = [](Decl *D) -> bool { 1548 auto TU = D->getTranslationUnitDecl(); 1549 for (auto Child : TU->decls()) { 1550 if (auto *RD = dyn_cast<CXXRecordDecl>(Child)) { 1551 if (RD->getNameAsString() == "declToImport") { 1552 GTEST_NONFATAL_FAILURE_( 1553 "TU should not contain any CXXRecordDecl with name declToImport"); 1554 return false; 1555 } 1556 } 1557 } 1558 return true; 1559 }; 1560 1561 ASSERT_TRUE(Check(From)); 1562 EXPECT_TRUE(Check(To)); 1563 } 1564 1565 TEST_P(ASTImporterOptionSpecificTestBase, 1566 TUshouldNotContainTemplatedDeclOfTypeAlias) { 1567 Decl *From, *To; 1568 std::tie(From, To) = 1569 getImportedDecl( 1570 "template <typename T> struct X {};" 1571 "template <typename T> using declToImport = X<T>;" 1572 "void instantiate() { declToImport<int> a; }", 1573 Lang_CXX11, "", Lang_CXX11); 1574 1575 auto Check = [](Decl *D) -> bool { 1576 auto TU = D->getTranslationUnitDecl(); 1577 for (auto Child : TU->decls()) { 1578 if (auto *AD = dyn_cast<TypeAliasDecl>(Child)) { 1579 if (AD->getNameAsString() == "declToImport") { 1580 GTEST_NONFATAL_FAILURE_( 1581 "TU should not contain any TypeAliasDecl with name declToImport"); 1582 return false; 1583 } 1584 } 1585 } 1586 return true; 1587 }; 1588 1589 ASSERT_TRUE(Check(From)); 1590 EXPECT_TRUE(Check(To)); 1591 } 1592 1593 TEST_P(ASTImporterOptionSpecificTestBase, 1594 TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) { 1595 1596 Decl *From, *To; 1597 std::tie(From, To) = getImportedDecl( 1598 R"( 1599 template<class T> 1600 class Base {}; 1601 class declToImport : public Base<declToImport> {}; 1602 )", 1603 Lang_CXX03, "", Lang_CXX03); 1604 1605 // Check that the ClassTemplateSpecializationDecl is NOT the child of the TU. 1606 auto Pattern = 1607 translationUnitDecl(unless(has(classTemplateSpecializationDecl()))); 1608 ASSERT_TRUE( 1609 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1610 EXPECT_TRUE( 1611 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1612 1613 // Check that the ClassTemplateSpecializationDecl is the child of the 1614 // ClassTemplateDecl. 1615 Pattern = translationUnitDecl(has(classTemplateDecl( 1616 hasName("Base"), has(classTemplateSpecializationDecl())))); 1617 ASSERT_TRUE( 1618 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1619 EXPECT_TRUE( 1620 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1621 } 1622 1623 AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) { 1624 size_t Index = 0; 1625 for (Decl *D : Node.decls()) { 1626 if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) { 1627 auto *ND = cast<NamedDecl>(D); 1628 if (Index == Order.size()) 1629 return false; 1630 if (ND->getName() != Order[Index]) 1631 return false; 1632 ++Index; 1633 } 1634 } 1635 return Index == Order.size(); 1636 } 1637 1638 TEST_P(ASTImporterOptionSpecificTestBase, 1639 TUshouldContainClassTemplateSpecializationOfExplicitInstantiation) { 1640 Decl *From, *To; 1641 std::tie(From, To) = getImportedDecl( 1642 R"( 1643 namespace NS { 1644 template<class T> 1645 class X {}; 1646 template class X<int>; 1647 } 1648 )", 1649 Lang_CXX03, "", Lang_CXX03, "NS"); 1650 1651 // Check that the ClassTemplateSpecializationDecl is NOT the child of the 1652 // ClassTemplateDecl. 1653 auto Pattern = namespaceDecl(has(classTemplateDecl( 1654 hasName("X"), unless(has(classTemplateSpecializationDecl()))))); 1655 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern)); 1656 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern)); 1657 1658 // Check that the ClassTemplateSpecializationDecl is the child of the 1659 // NamespaceDecl. 1660 Pattern = namespaceDecl(has(classTemplateSpecializationDecl(hasName("X")))); 1661 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern)); 1662 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern)); 1663 } 1664 1665 TEST_P(ASTImporterOptionSpecificTestBase, 1666 CXXRecordDeclFieldsShouldBeInCorrectOrder) { 1667 Decl *From, *To; 1668 std::tie(From, To) = 1669 getImportedDecl( 1670 "struct declToImport { int a; int b; };", 1671 Lang_CXX11, "", Lang_CXX11); 1672 1673 MatchVerifier<Decl> Verifier; 1674 ASSERT_TRUE(Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b"})))); 1675 EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b"})))); 1676 } 1677 1678 TEST_P(ASTImporterOptionSpecificTestBase, 1679 CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) { 1680 Decl *From, *To; 1681 std::tie(From, To) = getImportedDecl( 1682 // The original recursive algorithm of ASTImporter first imports 'c' then 1683 // 'b' and lastly 'a'. Therefore we must restore the order somehow. 1684 R"s( 1685 struct declToImport { 1686 int a = c + b; 1687 int b = 1; 1688 int c = 2; 1689 }; 1690 )s", 1691 Lang_CXX11, "", Lang_CXX11); 1692 1693 MatchVerifier<Decl> Verifier; 1694 ASSERT_TRUE( 1695 Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b", "c"})))); 1696 EXPECT_TRUE( 1697 Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"})))); 1698 } 1699 1700 TEST_P(ASTImporterOptionSpecificTestBase, 1701 CXXRecordDeclFieldAndIndirectFieldOrder) { 1702 Decl *From, *To; 1703 std::tie(From, To) = getImportedDecl( 1704 // First field is "a", then the field for unnamed union, then "b" and "c" 1705 // from it (indirect fields), then "d". 1706 R"s( 1707 struct declToImport { 1708 int a = d; 1709 union { 1710 int b; 1711 int c; 1712 }; 1713 int d; 1714 }; 1715 )s", 1716 Lang_CXX11, "", Lang_CXX11); 1717 1718 MatchVerifier<Decl> Verifier; 1719 ASSERT_TRUE(Verifier.match( 1720 From, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"})))); 1721 EXPECT_TRUE(Verifier.match( 1722 To, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"})))); 1723 } 1724 1725 TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) { 1726 Decl *From, *To; 1727 std::tie(From, To) = getImportedDecl( 1728 R"( 1729 struct declToImport { 1730 }; 1731 )", 1732 Lang_CXX03, "", Lang_CXX03); 1733 1734 MatchVerifier<Decl> Verifier; 1735 // Match the implicit Decl. 1736 auto Matcher = cxxRecordDecl(has(cxxRecordDecl())); 1737 ASSERT_TRUE(Verifier.match(From, Matcher)); 1738 EXPECT_TRUE(Verifier.match(To, Matcher)); 1739 } 1740 1741 TEST_P(ASTImporterOptionSpecificTestBase, 1742 ShouldImportImplicitCXXRecordDeclOfClassTemplate) { 1743 Decl *From, *To; 1744 std::tie(From, To) = getImportedDecl( 1745 R"( 1746 template <typename U> 1747 struct declToImport { 1748 }; 1749 )", 1750 Lang_CXX03, "", Lang_CXX03); 1751 1752 MatchVerifier<Decl> Verifier; 1753 // Match the implicit Decl. 1754 auto Matcher = classTemplateDecl(has(cxxRecordDecl(has(cxxRecordDecl())))); 1755 ASSERT_TRUE(Verifier.match(From, Matcher)); 1756 EXPECT_TRUE(Verifier.match(To, Matcher)); 1757 } 1758 1759 TEST_P(ASTImporterOptionSpecificTestBase, 1760 ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) { 1761 Decl *From, *To; 1762 std::tie(From, To) = getImportedDecl( 1763 R"( 1764 template<class T> 1765 class Base {}; 1766 class declToImport : public Base<declToImport> {}; 1767 )", 1768 Lang_CXX03, "", Lang_CXX03); 1769 1770 auto hasImplicitClass = has(cxxRecordDecl()); 1771 auto Pattern = translationUnitDecl(has(classTemplateDecl( 1772 hasName("Base"), 1773 has(classTemplateSpecializationDecl(hasImplicitClass))))); 1774 ASSERT_TRUE( 1775 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1776 EXPECT_TRUE( 1777 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1778 } 1779 1780 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOrdinary) { 1781 Decl *From, *To; 1782 std::tie(From, To) = 1783 getImportedDecl("void declToImport() {}", Lang_CXX03, "", Lang_CXX03); 1784 1785 MatchVerifier<Decl> Verifier; 1786 auto Matcher = functionDecl(); 1787 ASSERT_TRUE(Verifier.match(From, Matcher)); 1788 EXPECT_TRUE(Verifier.match(To, Matcher)); 1789 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace()); 1790 } 1791 1792 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOfNonmemberOperator) { 1793 Decl *FromTU = getTuDecl( 1794 R"( 1795 struct X {}; 1796 void operator<<(int, X); 1797 )", 1798 Lang_CXX03); 1799 Decl *From = LastDeclMatcher<Decl>{}.match(FromTU, functionDecl()); 1800 const Decl *To = Import(From, Lang_CXX03); 1801 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace()); 1802 } 1803 1804 TEST_P(ASTImporterOptionSpecificTestBase, 1805 ShouldImportMembersOfClassTemplateSpecializationDecl) { 1806 Decl *From, *To; 1807 std::tie(From, To) = getImportedDecl( 1808 R"( 1809 template<class T> 1810 class Base { int a; }; 1811 class declToImport : Base<declToImport> {}; 1812 )", 1813 Lang_CXX03, "", Lang_CXX03); 1814 1815 auto Pattern = translationUnitDecl(has(classTemplateDecl( 1816 hasName("Base"), 1817 has(classTemplateSpecializationDecl(has(fieldDecl(hasName("a")))))))); 1818 ASSERT_TRUE( 1819 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern)); 1820 EXPECT_TRUE( 1821 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); 1822 } 1823 1824 TEST_P(ASTImporterOptionSpecificTestBase, 1825 ImportDefinitionOfClassTemplateAfterFwdDecl) { 1826 { 1827 Decl *FromTU = getTuDecl( 1828 R"( 1829 template <typename T> 1830 struct B; 1831 )", 1832 Lang_CXX03, "input0.cc"); 1833 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 1834 FromTU, classTemplateDecl(hasName("B"))); 1835 1836 Import(FromD, Lang_CXX03); 1837 } 1838 1839 { 1840 Decl *FromTU = getTuDecl( 1841 R"( 1842 template <typename T> 1843 struct B { 1844 void f(); 1845 }; 1846 )", 1847 Lang_CXX03, "input1.cc"); 1848 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match( 1849 FromTU, functionDecl(hasName("f"))); 1850 Import(FromD, Lang_CXX03); 1851 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match( 1852 FromTU, classTemplateDecl(hasName("B"))); 1853 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03)); 1854 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition()); 1855 } 1856 } 1857 1858 TEST_P(ASTImporterOptionSpecificTestBase, 1859 ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition) { 1860 Decl *ToTU = getToTuDecl( 1861 R"( 1862 template <typename T> 1863 struct B { 1864 void f(); 1865 }; 1866 1867 template <typename T> 1868 struct B; 1869 )", 1870 Lang_CXX03); 1871 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>( 1872 [](const ClassTemplateDecl *T) { 1873 return T->isThisDeclarationADefinition(); 1874 }) 1875 .match(ToTU, classTemplateDecl())); 1876 1877 Decl *FromTU = getTuDecl( 1878 R"( 1879 template <typename T> 1880 struct B { 1881 void f(); 1882 }; 1883 )", 1884 Lang_CXX03, "input1.cc"); 1885 ClassTemplateDecl *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 1886 FromTU, classTemplateDecl(hasName("B"))); 1887 1888 Import(FromD, Lang_CXX03); 1889 1890 // We should have only one definition. 1891 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>( 1892 [](const ClassTemplateDecl *T) { 1893 return T->isThisDeclarationADefinition(); 1894 }) 1895 .match(ToTU, classTemplateDecl())); 1896 } 1897 1898 TEST_P(ASTImporterOptionSpecificTestBase, 1899 ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition) { 1900 Decl *ToTU = getToTuDecl( 1901 R"( 1902 struct B { 1903 void f(); 1904 }; 1905 1906 struct B; 1907 )", 1908 Lang_CXX03); 1909 ASSERT_EQ(2u, DeclCounter<CXXRecordDecl>().match( 1910 ToTU, cxxRecordDecl(unless(isImplicit())))); 1911 1912 Decl *FromTU = getTuDecl( 1913 R"( 1914 struct B { 1915 void f(); 1916 }; 1917 )", 1918 Lang_CXX03, "input1.cc"); 1919 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 1920 FromTU, cxxRecordDecl(hasName("B"))); 1921 1922 Import(FromD, Lang_CXX03); 1923 1924 EXPECT_EQ(2u, DeclCounter<CXXRecordDecl>().match( 1925 ToTU, cxxRecordDecl(unless(isImplicit())))); 1926 } 1927 1928 static void CompareSourceLocs(FullSourceLoc Loc1, FullSourceLoc Loc2) { 1929 EXPECT_EQ(Loc1.getExpansionLineNumber(), Loc2.getExpansionLineNumber()); 1930 EXPECT_EQ(Loc1.getExpansionColumnNumber(), Loc2.getExpansionColumnNumber()); 1931 EXPECT_EQ(Loc1.getSpellingLineNumber(), Loc2.getSpellingLineNumber()); 1932 EXPECT_EQ(Loc1.getSpellingColumnNumber(), Loc2.getSpellingColumnNumber()); 1933 } 1934 static void CompareSourceRanges(SourceRange Range1, SourceRange Range2, 1935 SourceManager &SM1, SourceManager &SM2) { 1936 CompareSourceLocs(FullSourceLoc{ Range1.getBegin(), SM1 }, 1937 FullSourceLoc{ Range2.getBegin(), SM2 }); 1938 CompareSourceLocs(FullSourceLoc{ Range1.getEnd(), SM1 }, 1939 FullSourceLoc{ Range2.getEnd(), SM2 }); 1940 } 1941 TEST_P(ASTImporterOptionSpecificTestBase, ImportSourceLocs) { 1942 Decl *FromTU = getTuDecl( 1943 R"( 1944 #define MFOO(arg) arg = arg + 1 1945 1946 void foo() { 1947 int a = 5; 1948 MFOO(a); 1949 } 1950 )", 1951 Lang_CXX03); 1952 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 1953 auto ToD = Import(FromD, Lang_CXX03); 1954 1955 auto ToLHS = LastDeclMatcher<DeclRefExpr>().match(ToD, declRefExpr()); 1956 auto FromLHS = LastDeclMatcher<DeclRefExpr>().match(FromTU, declRefExpr()); 1957 auto ToRHS = LastDeclMatcher<IntegerLiteral>().match(ToD, integerLiteral()); 1958 auto FromRHS = 1959 LastDeclMatcher<IntegerLiteral>().match(FromTU, integerLiteral()); 1960 1961 SourceManager &ToSM = ToAST->getASTContext().getSourceManager(); 1962 SourceManager &FromSM = FromD->getASTContext().getSourceManager(); 1963 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM, 1964 FromSM); 1965 CompareSourceRanges(ToLHS->getSourceRange(), FromLHS->getSourceRange(), ToSM, 1966 FromSM); 1967 CompareSourceRanges(ToRHS->getSourceRange(), FromRHS->getSourceRange(), ToSM, 1968 FromSM); 1969 } 1970 1971 TEST_P(ASTImporterOptionSpecificTestBase, ImportNestedMacro) { 1972 Decl *FromTU = getTuDecl( 1973 R"( 1974 #define FUNC_INT void declToImport 1975 #define FUNC FUNC_INT 1976 FUNC(int a); 1977 )", 1978 Lang_CXX03); 1979 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 1980 auto ToD = Import(FromD, Lang_CXX03); 1981 1982 SourceManager &ToSM = ToAST->getASTContext().getSourceManager(); 1983 SourceManager &FromSM = FromD->getASTContext().getSourceManager(); 1984 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM, 1985 FromSM); 1986 } 1987 1988 TEST_P( 1989 ASTImporterOptionSpecificTestBase, 1990 ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition) { 1991 Decl *ToTU = getToTuDecl( 1992 R"( 1993 template <typename T> 1994 struct B; 1995 1996 template <> 1997 struct B<int> {}; 1998 1999 template <> 2000 struct B<int>; 2001 )", 2002 Lang_CXX03); 2003 // We should have only one definition. 2004 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>( 2005 [](const ClassTemplateSpecializationDecl *T) { 2006 return T->isThisDeclarationADefinition(); 2007 }) 2008 .match(ToTU, classTemplateSpecializationDecl())); 2009 2010 Decl *FromTU = getTuDecl( 2011 R"( 2012 template <typename T> 2013 struct B; 2014 2015 template <> 2016 struct B<int> {}; 2017 )", 2018 Lang_CXX03, "input1.cc"); 2019 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 2020 FromTU, classTemplateSpecializationDecl(hasName("B"))); 2021 2022 Import(FromD, Lang_CXX03); 2023 2024 // We should have only one definition. 2025 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>( 2026 [](const ClassTemplateSpecializationDecl *T) { 2027 return T->isThisDeclarationADefinition(); 2028 }) 2029 .match(ToTU, classTemplateSpecializationDecl())); 2030 } 2031 2032 TEST_P(ASTImporterOptionSpecificTestBase, ObjectsWithUnnamedStructType) { 2033 Decl *FromTU = getTuDecl( 2034 R"( 2035 struct { int a; int b; } object0 = { 2, 3 }; 2036 struct { int x; int y; int z; } object1; 2037 )", 2038 Lang_CXX03, "input0.cc"); 2039 2040 auto *Obj0 = 2041 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object0"))); 2042 auto *From0 = getRecordDecl(Obj0); 2043 auto *Obj1 = 2044 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object1"))); 2045 auto *From1 = getRecordDecl(Obj1); 2046 2047 auto *To0 = Import(From0, Lang_CXX03); 2048 auto *To1 = Import(From1, Lang_CXX03); 2049 2050 EXPECT_TRUE(To0); 2051 EXPECT_TRUE(To1); 2052 EXPECT_NE(To0, To1); 2053 EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl()); 2054 } 2055 2056 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecords) { 2057 auto *Code = 2058 R"( 2059 struct X { 2060 struct { int a; }; 2061 struct { int b; }; 2062 }; 2063 )"; 2064 Decl *FromTU0 = getTuDecl(Code, Lang_C99, "input0.c"); 2065 2066 Decl *FromTU1 = getTuDecl(Code, Lang_C99, "input1.c"); 2067 2068 auto *X0 = 2069 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X"))); 2070 auto *X1 = 2071 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X"))); 2072 Import(X0, Lang_C99); 2073 Import(X1, Lang_C99); 2074 2075 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2076 // We expect no (ODR) warning during the import. 2077 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 2078 EXPECT_EQ(1u, 2079 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X")))); 2080 } 2081 2082 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecordsReversed) { 2083 Decl *FromTU0 = getTuDecl( 2084 R"( 2085 struct X { 2086 struct { int a; }; 2087 struct { int b; }; 2088 }; 2089 )", 2090 Lang_C99, "input0.c"); 2091 2092 Decl *FromTU1 = getTuDecl( 2093 R"( 2094 struct X { // reversed order 2095 struct { int b; }; 2096 struct { int a; }; 2097 }; 2098 )", 2099 Lang_C99, "input1.c"); 2100 2101 auto *X0 = 2102 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X"))); 2103 auto *X1 = 2104 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X"))); 2105 Import(X0, Lang_C99); 2106 Import(X1, Lang_C99); 2107 2108 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2109 // We expect one (ODR) warning during the import. 2110 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 2111 EXPECT_EQ(1u, 2112 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X")))); 2113 } 2114 2115 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag) { 2116 auto Pattern = varDecl(hasName("x")); 2117 VarDecl *Imported1; 2118 { 2119 Decl *FromTU = getTuDecl("extern int x;", Lang_CXX03, "input0.cc"); 2120 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 2121 Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 2122 } 2123 VarDecl *Imported2; 2124 { 2125 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input1.cc"); 2126 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 2127 Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 2128 } 2129 EXPECT_EQ(Imported1->getCanonicalDecl(), Imported2->getCanonicalDecl()); 2130 EXPECT_FALSE(Imported2->isUsed(false)); 2131 { 2132 Decl *FromTU = getTuDecl("extern int x; int f() { return x; }", Lang_CXX03, 2133 "input2.cc"); 2134 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2135 FromTU, functionDecl(hasName("f"))); 2136 Import(FromD, Lang_CXX03); 2137 } 2138 EXPECT_TRUE(Imported2->isUsed(false)); 2139 } 2140 2141 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag2) { 2142 auto Pattern = varDecl(hasName("x")); 2143 VarDecl *ExistingD; 2144 { 2145 Decl *ToTU = getToTuDecl("int x = 1;", Lang_CXX03); 2146 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern); 2147 } 2148 EXPECT_FALSE(ExistingD->isUsed(false)); 2149 { 2150 Decl *FromTU = 2151 getTuDecl("int x = 1; int f() { return x; }", Lang_CXX03, "input1.cc"); 2152 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2153 FromTU, functionDecl(hasName("f"))); 2154 Import(FromD, Lang_CXX03); 2155 } 2156 EXPECT_TRUE(ExistingD->isUsed(false)); 2157 } 2158 2159 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag3) { 2160 auto Pattern = varDecl(hasName("a")); 2161 VarDecl *ExistingD; 2162 { 2163 Decl *ToTU = getToTuDecl( 2164 R"( 2165 struct A { 2166 static const int a = 1; 2167 }; 2168 )", 2169 Lang_CXX03); 2170 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern); 2171 } 2172 EXPECT_FALSE(ExistingD->isUsed(false)); 2173 { 2174 Decl *FromTU = getTuDecl( 2175 R"( 2176 struct A { 2177 static const int a = 1; 2178 }; 2179 const int *f() { return &A::a; } // requires storage, 2180 // thus used flag will be set 2181 )", 2182 Lang_CXX03, "input1.cc"); 2183 auto *FromFunD = FirstDeclMatcher<FunctionDecl>().match( 2184 FromTU, functionDecl(hasName("f"))); 2185 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 2186 ASSERT_TRUE(FromD->isUsed(false)); 2187 Import(FromFunD, Lang_CXX03); 2188 } 2189 EXPECT_TRUE(ExistingD->isUsed(false)); 2190 } 2191 2192 TEST_P(ASTImporterOptionSpecificTestBase, ReimportWithUsedFlag) { 2193 auto Pattern = varDecl(hasName("x")); 2194 2195 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input0.cc"); 2196 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 2197 2198 auto *Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 2199 2200 ASSERT_FALSE(Imported1->isUsed(false)); 2201 2202 FromD->setIsUsed(); 2203 auto *Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03)); 2204 2205 EXPECT_EQ(Imported1, Imported2); 2206 EXPECT_TRUE(Imported2->isUsed(false)); 2207 } 2208 2209 struct ImportFunctions : ASTImporterOptionSpecificTestBase {}; 2210 2211 TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) { 2212 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03); 2213 auto Pattern = functionDecl(hasName("f")); 2214 auto *From = 2215 FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Proto 2216 2217 Decl *ImportedD = Import(From, Lang_CXX03); 2218 Decl *ToTU = ImportedD->getTranslationUnitDecl(); 2219 2220 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2221 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2222 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2223 EXPECT_TRUE(ImportedD == To0); 2224 EXPECT_FALSE(To0->doesThisDeclarationHaveABody()); 2225 EXPECT_TRUE(To1->doesThisDeclarationHaveABody()); 2226 EXPECT_EQ(To1->getPreviousDecl(), To0); 2227 } 2228 2229 TEST_P(ImportFunctions, ImportDefinitionOfRecursiveFunction) { 2230 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03); 2231 auto Pattern = functionDecl(hasName("f")); 2232 auto *From = 2233 LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Def 2234 2235 Decl *ImportedD = Import(From, Lang_CXX03); 2236 Decl *ToTU = ImportedD->getTranslationUnitDecl(); 2237 2238 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2239 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2240 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2241 EXPECT_TRUE(ImportedD == To1); 2242 EXPECT_FALSE(To0->doesThisDeclarationHaveABody()); 2243 EXPECT_TRUE(To1->doesThisDeclarationHaveABody()); 2244 EXPECT_EQ(To1->getPreviousDecl(), To0); 2245 } 2246 2247 TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) { 2248 auto Code = 2249 R"( 2250 struct B { virtual void f(); }; 2251 void B::f() {} 2252 struct D : B { void f(); }; 2253 )"; 2254 auto Pattern = 2255 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2256 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 2257 CXXMethodDecl *Proto = 2258 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern); 2259 2260 ASSERT_EQ(Proto->size_overridden_methods(), 1u); 2261 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03)); 2262 EXPECT_EQ(To->size_overridden_methods(), 1u); 2263 } 2264 2265 TEST_P(ImportFunctions, VirtualFlagShouldBePreservedWhenImportingPrototype) { 2266 auto Code = 2267 R"( 2268 struct B { virtual void f(); }; 2269 void B::f() {} 2270 )"; 2271 auto Pattern = 2272 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2273 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 2274 CXXMethodDecl *Proto = 2275 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern); 2276 CXXMethodDecl *Def = LastDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern); 2277 2278 ASSERT_TRUE(Proto->isVirtual()); 2279 ASSERT_TRUE(Def->isVirtual()); 2280 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03)); 2281 EXPECT_TRUE(To->isVirtual()); 2282 } 2283 2284 TEST_P(ImportFunctions, 2285 ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl) { 2286 Decl *ToTU = getToTuDecl( 2287 R"( 2288 void f() {} 2289 void f(); 2290 )", 2291 Lang_CXX03); 2292 ASSERT_EQ(1u, 2293 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) { 2294 return FD->doesThisDeclarationHaveABody(); 2295 }).match(ToTU, functionDecl())); 2296 2297 Decl *FromTU = getTuDecl("void f() {}", Lang_CXX03, "input0.cc"); 2298 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 2299 2300 Import(FromD, Lang_CXX03); 2301 2302 EXPECT_EQ(1u, 2303 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) { 2304 return FD->doesThisDeclarationHaveABody(); 2305 }).match(ToTU, functionDecl())); 2306 } 2307 2308 TEST_P(ImportFunctions, ImportOverriddenMethodTwice) { 2309 auto Code = 2310 R"( 2311 struct B { virtual void f(); }; 2312 struct D:B { void f(); }; 2313 )"; 2314 auto BFP = 2315 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2316 auto DFP = 2317 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2318 2319 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03); 2320 auto *DF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP); 2321 Import(DF, Lang_CXX03); 2322 2323 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2324 auto *BF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP); 2325 Import(BF, Lang_CXX03); 2326 2327 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2328 2329 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2330 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u); 2331 } 2332 2333 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceDefinitionFirst) { 2334 auto CodeWithoutDef = 2335 R"( 2336 struct B { virtual void f(); }; 2337 struct D:B { void f(); }; 2338 )"; 2339 auto CodeWithDef = 2340 R"( 2341 struct B { virtual void f(){}; }; 2342 struct D:B { void f(){}; }; 2343 )"; 2344 auto BFP = 2345 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2346 auto DFP = 2347 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2348 auto BFDefP = cxxMethodDecl( 2349 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition()); 2350 auto DFDefP = cxxMethodDecl( 2351 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition()); 2352 auto FDefAllP = cxxMethodDecl(hasName("f"), isDefinition()); 2353 2354 { 2355 Decl *FromTU = getTuDecl(CodeWithDef, Lang_CXX03, "input0.cc"); 2356 auto *FromD = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, DFP); 2357 Import(FromD, Lang_CXX03); 2358 } 2359 { 2360 Decl *FromTU = getTuDecl(CodeWithoutDef, Lang_CXX03, "input1.cc"); 2361 auto *FromB = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, BFP); 2362 Import(FromB, Lang_CXX03); 2363 } 2364 2365 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2366 2367 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2368 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u); 2369 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 1u); 2370 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 1u); 2371 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FDefAllP), 2u); 2372 } 2373 2374 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceOutOfClassDef) { 2375 auto Code = 2376 R"( 2377 struct B { virtual void f(); }; 2378 struct D:B { void f(); }; 2379 void B::f(){}; 2380 )"; 2381 2382 auto BFP = 2383 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2384 auto BFDefP = cxxMethodDecl( 2385 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition()); 2386 auto DFP = cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), 2387 unless(isDefinition())); 2388 2389 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03); 2390 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP); 2391 Import(D, Lang_CXX03); 2392 2393 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2394 auto *B = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP); 2395 Import(B, Lang_CXX03); 2396 2397 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2398 2399 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2400 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u); 2401 2402 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match( 2403 ToTU, cxxRecordDecl(hasName("B"))); 2404 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP); 2405 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match( 2406 ToTU, cxxMethodDecl(hasName("f"), isDefinition())); 2407 2408 // The definition should be out-of-class. 2409 EXPECT_NE(ToBFInClass, ToBFOutOfClass); 2410 EXPECT_NE(ToBFInClass->getLexicalDeclContext(), 2411 ToBFOutOfClass->getLexicalDeclContext()); 2412 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB); 2413 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU); 2414 2415 // Check that the redecl chain is intact. 2416 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass); 2417 } 2418 2419 TEST_P(ImportFunctions, 2420 ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode) { 2421 auto CodeTU0 = 2422 R"( 2423 struct B { virtual void f(); }; 2424 struct D:B { void f(); }; 2425 )"; 2426 auto CodeTU1 = 2427 R"( 2428 struct B { virtual void f(); }; 2429 struct D:B { void f(); }; 2430 void B::f(){} 2431 void D::f(){} 2432 void foo(B &b, D &d) { b.f(); d.f(); } 2433 )"; 2434 2435 auto BFP = 2436 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B")))); 2437 auto BFDefP = cxxMethodDecl( 2438 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition()); 2439 auto DFP = 2440 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D")))); 2441 auto DFDefP = cxxMethodDecl( 2442 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition()); 2443 auto FooDef = functionDecl(hasName("foo")); 2444 2445 { 2446 Decl *FromTU0 = getTuDecl(CodeTU0, Lang_CXX03, "input0.cc"); 2447 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP); 2448 Import(D, Lang_CXX03); 2449 } 2450 2451 { 2452 Decl *FromTU1 = getTuDecl(CodeTU1, Lang_CXX03, "input1.cc"); 2453 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(FromTU1, FooDef); 2454 Import(Foo, Lang_CXX03); 2455 } 2456 2457 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2458 2459 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u); 2460 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u); 2461 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u); 2462 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 0u); 2463 2464 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match( 2465 ToTU, cxxRecordDecl(hasName("B"))); 2466 auto *ToD = FirstDeclMatcher<CXXRecordDecl>().match( 2467 ToTU, cxxRecordDecl(hasName("D"))); 2468 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP); 2469 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match( 2470 ToTU, cxxMethodDecl(hasName("f"), isDefinition())); 2471 auto *ToDFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, DFP); 2472 auto *ToDFOutOfClass = LastDeclMatcher<CXXMethodDecl>().match( 2473 ToTU, cxxMethodDecl(hasName("f"), isDefinition())); 2474 2475 // The definition should be out-of-class. 2476 EXPECT_NE(ToBFInClass, ToBFOutOfClass); 2477 EXPECT_NE(ToBFInClass->getLexicalDeclContext(), 2478 ToBFOutOfClass->getLexicalDeclContext()); 2479 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB); 2480 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU); 2481 2482 EXPECT_NE(ToDFInClass, ToDFOutOfClass); 2483 EXPECT_NE(ToDFInClass->getLexicalDeclContext(), 2484 ToDFOutOfClass->getLexicalDeclContext()); 2485 EXPECT_EQ(ToDFOutOfClass->getDeclContext(), ToD); 2486 EXPECT_EQ(ToDFOutOfClass->getLexicalDeclContext(), ToTU); 2487 2488 // Check that the redecl chain is intact. 2489 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass); 2490 EXPECT_EQ(ToDFOutOfClass->getPreviousDecl(), ToDFInClass); 2491 } 2492 2493 TEST_P(ASTImporterOptionSpecificTestBase, 2494 ImportVirtualOverriddenMethodOnALoop) { 2495 // B::f() calls => f1() ==> C ==> C::f() 2496 // \ 2497 // \---- A::f() 2498 // 2499 // C::f()'s ImportOverriddenMethods() asserts B::isVirtual(), so B::f()'s 2500 // ImportOverriddenMethods() should be completed before B::f()'s body 2501 const char *Code = 2502 R"( 2503 void f1(); 2504 class A { 2505 virtual void f(){} 2506 }; 2507 class B: public A { 2508 void f() override { 2509 f1(); 2510 } 2511 }; 2512 class C: public B { 2513 void f() override {} 2514 }; 2515 void f1() { C c; } 2516 )"; 2517 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 2518 2519 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match( 2520 FromTU, cxxMethodDecl(hasName("B::f"))); 2521 2522 auto *ToBF = Import(FromF, Lang_CXX11); 2523 EXPECT_TRUE(ToBF->isVirtual()); 2524 2525 auto *ToCF = FirstDeclMatcher<CXXMethodDecl>().match( 2526 ToBF->getTranslationUnitDecl(), cxxMethodDecl(hasName("C::f"))); 2527 EXPECT_TRUE(ToCF->isVirtual()); 2528 } 2529 2530 TEST_P(ASTImporterOptionSpecificTestBase, ImportVariableChainInC) { 2531 std::string Code = "static int v; static int v = 0;"; 2532 auto Pattern = varDecl(hasName("v")); 2533 2534 TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_C99, "input0.c"); 2535 2536 auto *From0 = FirstDeclMatcher<VarDecl>().match(FromTu, Pattern); 2537 auto *From1 = LastDeclMatcher<VarDecl>().match(FromTu, Pattern); 2538 2539 auto *To0 = Import(From0, Lang_C99); 2540 auto *To1 = Import(From1, Lang_C99); 2541 2542 EXPECT_TRUE(To0); 2543 ASSERT_TRUE(To1); 2544 EXPECT_NE(To0, To1); 2545 EXPECT_EQ(To1->getPreviousDecl(), To0); 2546 } 2547 2548 TEST_P(ImportFunctions, ImportFromDifferentScopedAnonNamespace) { 2549 TranslationUnitDecl *FromTu = 2550 getTuDecl("namespace NS0 { namespace { void f(); } }" 2551 "namespace NS1 { namespace { void f(); } }", 2552 Lang_CXX03, "input0.cc"); 2553 auto Pattern = functionDecl(hasName("f")); 2554 2555 auto *FromF0 = FirstDeclMatcher<FunctionDecl>().match(FromTu, Pattern); 2556 auto *FromF1 = LastDeclMatcher<FunctionDecl>().match(FromTu, Pattern); 2557 2558 auto *ToF0 = Import(FromF0, Lang_CXX03); 2559 auto *ToF1 = Import(FromF1, Lang_CXX03); 2560 2561 EXPECT_TRUE(ToF0); 2562 ASSERT_TRUE(ToF1); 2563 EXPECT_NE(ToF0, ToF1); 2564 EXPECT_FALSE(ToF1->getPreviousDecl()); 2565 } 2566 2567 TEST_P(ImportFunctions, ImportFunctionFromUnnamedNamespace) { 2568 { 2569 Decl *FromTU = getTuDecl("namespace { void f() {} } void g0() { f(); }", 2570 Lang_CXX03, "input0.cc"); 2571 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2572 FromTU, functionDecl(hasName("g0"))); 2573 2574 Import(FromD, Lang_CXX03); 2575 } 2576 { 2577 Decl *FromTU = 2578 getTuDecl("namespace { void f() { int a; } } void g1() { f(); }", 2579 Lang_CXX03, "input1.cc"); 2580 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2581 FromTU, functionDecl(hasName("g1"))); 2582 Import(FromD, Lang_CXX03); 2583 } 2584 2585 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2586 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))), 2587 2u); 2588 } 2589 2590 TEST_P(ImportFunctions, ImportImplicitFunctionsInLambda) { 2591 Decl *FromTU = getTuDecl( 2592 R"( 2593 void foo() { 2594 (void)[]() { ; }; 2595 } 2596 )", 2597 Lang_CXX11); 2598 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2599 FromTU, functionDecl(hasName("foo"))); 2600 auto *ToD = Import(FromD, Lang_CXX03); 2601 EXPECT_TRUE(ToD); 2602 CXXRecordDecl *LambdaRec = 2603 cast<LambdaExpr>(cast<CStyleCastExpr>( 2604 *cast<CompoundStmt>(ToD->getBody())->body_begin()) 2605 ->getSubExpr()) 2606 ->getLambdaClass(); 2607 EXPECT_TRUE(LambdaRec->getDestructor()); 2608 } 2609 2610 TEST_P(ImportFunctions, 2611 CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) { 2612 Decl *FromTU = getTuDecl( 2613 R"( 2614 struct X { 2615 template <typename T> 2616 void foo(){} 2617 }; 2618 void f() { 2619 X x; 2620 x.foo<int>(); 2621 } 2622 )", 2623 Lang_CXX03); 2624 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2625 FromTU, functionDecl(hasName("f"))); 2626 auto *ToD = Import(FromD, Lang_CXX03); 2627 EXPECT_TRUE(ToD); 2628 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match( 2629 ToD, functionDecl(hasName("f"), hasDescendant(declRefExpr())))); 2630 } 2631 2632 TEST_P(ImportFunctions, 2633 DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) { 2634 Decl *FromTU = getTuDecl( 2635 R"( 2636 struct X { 2637 template <typename T> 2638 void foo(){} 2639 }; 2640 template <typename T> 2641 void f() { 2642 X x; 2643 x.foo<T>(); 2644 } 2645 void g() { 2646 f<int>(); 2647 } 2648 )", 2649 Lang_CXX03); 2650 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2651 FromTU, functionDecl(hasName("g"))); 2652 auto *ToD = Import(FromD, Lang_CXX03); 2653 EXPECT_TRUE(ToD); 2654 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2655 EXPECT_TRUE(MatchVerifier<TranslationUnitDecl>().match( 2656 ToTU, translationUnitDecl(hasDescendant( 2657 functionDecl(hasName("f"), hasDescendant(declRefExpr())))))); 2658 } 2659 2660 struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {}; 2661 2662 TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) { 2663 auto Code = 2664 R"( 2665 class X { 2666 template <class T> 2667 void f(T t); 2668 }; 2669 )"; 2670 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2671 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2672 FromTU1, functionTemplateDecl(hasName("f"))); 2673 auto *ToD1 = Import(FromD1, Lang_CXX03); 2674 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc"); 2675 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2676 FromTU2, functionTemplateDecl(hasName("f"))); 2677 auto *ToD2 = Import(FromD2, Lang_CXX03); 2678 EXPECT_EQ(ToD1, ToD2); 2679 } 2680 2681 TEST_P(ImportFunctionTemplates, 2682 ImportFunctionTemplateWithDefInRecordDeclTwice) { 2683 auto Code = 2684 R"( 2685 class X { 2686 template <class T> 2687 void f(T t); 2688 }; 2689 template <class T> 2690 void X::f(T t) {}; 2691 )"; 2692 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc"); 2693 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2694 FromTU1, functionTemplateDecl(hasName("f"))); 2695 auto *ToD1 = Import(FromD1, Lang_CXX03); 2696 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc"); 2697 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match( 2698 FromTU2, functionTemplateDecl(hasName("f"))); 2699 auto *ToD2 = Import(FromD2, Lang_CXX03); 2700 EXPECT_EQ(ToD1, ToD2); 2701 } 2702 2703 TEST_P(ImportFunctionTemplates, 2704 ImportFunctionWhenThereIsAFunTemplateWithSameName) { 2705 getToTuDecl( 2706 R"( 2707 template <typename T> 2708 void foo(T) {} 2709 void foo(); 2710 )", 2711 Lang_CXX03); 2712 Decl *FromTU = getTuDecl("void foo();", Lang_CXX03); 2713 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 2714 FromTU, functionDecl(hasName("foo"))); 2715 auto *ImportedD = Import(FromD, Lang_CXX03); 2716 EXPECT_TRUE(ImportedD); 2717 } 2718 2719 TEST_P(ImportFunctionTemplates, 2720 ImportConstructorWhenThereIsAFunTemplateWithSameName) { 2721 auto Code = 2722 R"( 2723 struct Foo { 2724 template <typename T> 2725 Foo(T) {} 2726 Foo(); 2727 }; 2728 )"; 2729 getToTuDecl(Code, Lang_CXX03); 2730 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 2731 auto *FromD = 2732 LastDeclMatcher<CXXConstructorDecl>().match(FromTU, cxxConstructorDecl()); 2733 auto *ImportedD = Import(FromD, Lang_CXX03); 2734 EXPECT_TRUE(ImportedD); 2735 } 2736 2737 TEST_P(ImportFunctionTemplates, 2738 ImportOperatorWhenThereIsAFunTemplateWithSameName) { 2739 getToTuDecl( 2740 R"( 2741 template <typename T> 2742 void operator<(T,T) {} 2743 struct X{}; 2744 void operator<(X, X); 2745 )", 2746 Lang_CXX03); 2747 Decl *FromTU = getTuDecl( 2748 R"( 2749 struct X{}; 2750 void operator<(X, X); 2751 )", 2752 Lang_CXX03); 2753 auto *FromD = LastDeclMatcher<FunctionDecl>().match( 2754 FromTU, functionDecl(hasOverloadedOperatorName("<"))); 2755 auto *ImportedD = Import(FromD, Lang_CXX03); 2756 EXPECT_TRUE(ImportedD); 2757 } 2758 2759 struct ImportFriendFunctions : ImportFunctions {}; 2760 2761 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) { 2762 auto Pattern = functionDecl(hasName("f")); 2763 2764 Decl *FromTU = getTuDecl("struct X { friend void f(); };" 2765 "void f();", 2766 Lang_CXX03, "input0.cc"); 2767 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2768 2769 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2770 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2771 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2772 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2773 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2774 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody()); 2775 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2776 } 2777 2778 TEST_P(ImportFriendFunctions, 2779 ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst) { 2780 auto Pattern = functionDecl(hasName("f")); 2781 2782 Decl *FromTU = getTuDecl("void f();" 2783 "struct X { friend void f(); };", 2784 Lang_CXX03, "input0.cc"); 2785 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2786 2787 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2788 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2789 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2790 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2791 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2792 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody()); 2793 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2794 } 2795 2796 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDef) { 2797 auto Pattern = functionDecl(hasName("f")); 2798 2799 Decl *FromTU = getTuDecl("struct X { friend void f(){} };" 2800 "void f();", 2801 Lang_CXX03, "input0.cc"); 2802 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2803 2804 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2805 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2806 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2807 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody()); 2808 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2809 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody()); 2810 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2811 } 2812 2813 TEST_P(ImportFriendFunctions, 2814 ImportFriendFunctionRedeclChainDef_OutOfClassDef) { 2815 auto Pattern = functionDecl(hasName("f")); 2816 2817 Decl *FromTU = getTuDecl("struct X { friend void f(); };" 2818 "void f(){}", 2819 Lang_CXX03, "input0.cc"); 2820 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2821 2822 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2823 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2824 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2825 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2826 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern); 2827 EXPECT_TRUE(ToFD->doesThisDeclarationHaveABody()); 2828 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD); 2829 } 2830 2831 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDefWithClass) { 2832 auto Pattern = functionDecl(hasName("f")); 2833 2834 Decl *FromTU = getTuDecl( 2835 R"( 2836 class X; 2837 void f(X *x){} 2838 class X{ 2839 friend void f(X *x); 2840 }; 2841 )", 2842 Lang_CXX03, "input0.cc"); 2843 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2844 2845 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2846 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2847 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2848 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody()); 2849 auto *InClassFD = cast<FunctionDecl>(FirstDeclMatcher<FriendDecl>() 2850 .match(ToTU, friendDecl()) 2851 ->getFriendDecl()); 2852 EXPECT_FALSE(InClassFD->doesThisDeclarationHaveABody()); 2853 EXPECT_EQ(InClassFD->getPreviousDecl(), ImportedD); 2854 // The parameters must refer the same type 2855 EXPECT_EQ((*InClassFD->param_begin())->getOriginalType(), 2856 (*ImportedD->param_begin())->getOriginalType()); 2857 } 2858 2859 TEST_P(ImportFriendFunctions, 2860 ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) { 2861 auto Pattern = functionDecl(hasName("f")); 2862 2863 Decl *FromTU = getTuDecl( 2864 R"( 2865 class X; 2866 void f(X *x){} 2867 class X{ 2868 friend void f(X *x); 2869 }; 2870 )", 2871 Lang_CXX03, "input0.cc"); 2872 auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2873 2874 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2875 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2876 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2877 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody()); 2878 auto *OutOfClassFD = FirstDeclMatcher<FunctionDecl>().match( 2879 ToTU, functionDecl(unless(hasParent(friendDecl())))); 2880 2881 EXPECT_TRUE(OutOfClassFD->doesThisDeclarationHaveABody()); 2882 EXPECT_EQ(ImportedD->getPreviousDecl(), OutOfClassFD); 2883 // The parameters must refer the same type 2884 EXPECT_EQ((*OutOfClassFD->param_begin())->getOriginalType(), 2885 (*ImportedD->param_begin())->getOriginalType()); 2886 } 2887 2888 TEST_P(ImportFriendFunctions, ImportFriendFunctionFromMultipleTU) { 2889 auto Pattern = functionDecl(hasName("f")); 2890 2891 FunctionDecl *ImportedD; 2892 { 2893 Decl *FromTU = 2894 getTuDecl("struct X { friend void f(){} };", Lang_CXX03, "input0.cc"); 2895 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2896 ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2897 } 2898 FunctionDecl *ImportedD1; 2899 { 2900 Decl *FromTU = getTuDecl("void f();", Lang_CXX03, "input1.cc"); 2901 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); 2902 ImportedD1 = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2903 } 2904 2905 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2906 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 2907 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody()); 2908 EXPECT_FALSE(ImportedD1->doesThisDeclarationHaveABody()); 2909 EXPECT_EQ(ImportedD1->getPreviousDecl(), ImportedD); 2910 } 2911 2912 TEST_P(ImportFriendFunctions, Lookup) { 2913 auto FunctionPattern = functionDecl(hasName("f")); 2914 auto ClassPattern = cxxRecordDecl(hasName("X")); 2915 2916 TranslationUnitDecl *FromTU = 2917 getTuDecl("struct X { friend void f(); };", Lang_CXX03, "input0.cc"); 2918 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2919 ASSERT_TRUE(FromD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2920 ASSERT_FALSE(FromD->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2921 { 2922 auto FromName = FromD->getDeclName(); 2923 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern); 2924 auto LookupRes = Class->noload_lookup(FromName); 2925 ASSERT_TRUE(LookupRes.empty()); 2926 LookupRes = FromTU->noload_lookup(FromName); 2927 ASSERT_TRUE(LookupRes.isSingleResult()); 2928 } 2929 2930 auto *ToD = cast<FunctionDecl>(Import(FromD, Lang_CXX03)); 2931 auto ToName = ToD->getDeclName(); 2932 2933 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2934 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern); 2935 auto LookupRes = Class->noload_lookup(ToName); 2936 EXPECT_TRUE(LookupRes.empty()); 2937 LookupRes = ToTU->noload_lookup(ToName); 2938 EXPECT_TRUE(LookupRes.isSingleResult()); 2939 2940 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 1u); 2941 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2942 EXPECT_TRUE(To0->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2943 EXPECT_FALSE(To0->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2944 } 2945 2946 TEST_P(ImportFriendFunctions, LookupWithProtoAfter) { 2947 auto FunctionPattern = functionDecl(hasName("f")); 2948 auto ClassPattern = cxxRecordDecl(hasName("X")); 2949 2950 TranslationUnitDecl *FromTU = 2951 getTuDecl("struct X { friend void f(); };" 2952 // This proto decl makes f available to normal 2953 // lookup, otherwise it is hidden. 2954 // Normal C++ lookup (implemented in 2955 // `clang::Sema::CppLookupName()` and in `LookupDirect()`) 2956 // returns the found `NamedDecl` only if the set IDNS is matched 2957 "void f();", 2958 Lang_CXX03, "input0.cc"); 2959 auto *FromFriend = 2960 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2961 auto *FromNormal = 2962 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 2963 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2964 ASSERT_FALSE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2965 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2966 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2967 2968 auto FromName = FromFriend->getDeclName(); 2969 auto *FromClass = 2970 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern); 2971 auto LookupRes = FromClass->noload_lookup(FromName); 2972 ASSERT_TRUE(LookupRes.empty()); 2973 LookupRes = FromTU->noload_lookup(FromName); 2974 ASSERT_TRUE(LookupRes.isSingleResult()); 2975 2976 auto *ToFriend = cast<FunctionDecl>(Import(FromFriend, Lang_CXX03)); 2977 auto ToName = ToFriend->getDeclName(); 2978 2979 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 2980 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern); 2981 LookupRes = ToClass->noload_lookup(ToName); 2982 EXPECT_TRUE(LookupRes.empty()); 2983 LookupRes = ToTU->noload_lookup(ToName); 2984 // Test is disabled because this result is 2. 2985 EXPECT_TRUE(LookupRes.isSingleResult()); 2986 2987 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u); 2988 ToFriend = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2989 auto *ToNormal = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 2990 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2991 EXPECT_FALSE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2992 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 2993 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 2994 } 2995 2996 TEST_P(ImportFriendFunctions, LookupWithProtoBefore) { 2997 auto FunctionPattern = functionDecl(hasName("f")); 2998 auto ClassPattern = cxxRecordDecl(hasName("X")); 2999 3000 TranslationUnitDecl *FromTU = getTuDecl("void f();" 3001 "struct X { friend void f(); };", 3002 Lang_CXX03, "input0.cc"); 3003 auto *FromNormal = 3004 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 3005 auto *FromFriend = 3006 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern); 3007 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 3008 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 3009 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 3010 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 3011 3012 auto FromName = FromNormal->getDeclName(); 3013 auto *FromClass = 3014 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern); 3015 auto LookupRes = FromClass->noload_lookup(FromName); 3016 ASSERT_TRUE(LookupRes.empty()); 3017 LookupRes = FromTU->noload_lookup(FromName); 3018 ASSERT_TRUE(LookupRes.isSingleResult()); 3019 3020 auto *ToNormal = cast<FunctionDecl>(Import(FromNormal, Lang_CXX03)); 3021 auto ToName = ToNormal->getDeclName(); 3022 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 3023 3024 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern); 3025 LookupRes = ToClass->noload_lookup(ToName); 3026 EXPECT_TRUE(LookupRes.empty()); 3027 LookupRes = ToTU->noload_lookup(ToName); 3028 EXPECT_TRUE(LookupRes.isSingleResult()); 3029 3030 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u); 3031 ToNormal = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 3032 auto *ToFriend = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern); 3033 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 3034 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 3035 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 3036 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 3037 } 3038 3039 TEST_P(ImportFriendFunctions, ImportFriendChangesLookup) { 3040 auto Pattern = functionDecl(hasName("f")); 3041 3042 TranslationUnitDecl *FromNormalTU = 3043 getTuDecl("void f();", Lang_CXX03, "input0.cc"); 3044 auto *FromNormalF = 3045 FirstDeclMatcher<FunctionDecl>().match(FromNormalTU, Pattern); 3046 TranslationUnitDecl *FromFriendTU = 3047 getTuDecl("class X { friend void f(); };", Lang_CXX03, "input1.cc"); 3048 auto *FromFriendF = 3049 FirstDeclMatcher<FunctionDecl>().match(FromFriendTU, Pattern); 3050 auto FromNormalName = FromNormalF->getDeclName(); 3051 auto FromFriendName = FromFriendF->getDeclName(); 3052 3053 ASSERT_TRUE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 3054 ASSERT_FALSE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 3055 ASSERT_FALSE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 3056 ASSERT_TRUE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 3057 auto LookupRes = FromNormalTU->noload_lookup(FromNormalName); 3058 ASSERT_TRUE(LookupRes.isSingleResult()); 3059 LookupRes = FromFriendTU->noload_lookup(FromFriendName); 3060 ASSERT_TRUE(LookupRes.isSingleResult()); 3061 3062 auto *ToNormalF = cast<FunctionDecl>(Import(FromNormalF, Lang_CXX03)); 3063 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 3064 auto ToName = ToNormalF->getDeclName(); 3065 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 3066 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 3067 LookupRes = ToTU->noload_lookup(ToName); 3068 EXPECT_TRUE(LookupRes.isSingleResult()); 3069 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u); 3070 3071 auto *ToFriendF = cast<FunctionDecl>(Import(FromFriendF, Lang_CXX03)); 3072 LookupRes = ToTU->noload_lookup(ToName); 3073 EXPECT_TRUE(LookupRes.isSingleResult()); 3074 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u); 3075 3076 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 3077 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 3078 3079 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary)); 3080 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)); 3081 } 3082 3083 TEST_P(ImportFriendFunctions, ImportFriendList) { 3084 TranslationUnitDecl *FromTU = getTuDecl("struct X { friend void f(); };" 3085 "void f();", 3086 Lang_CXX03, "input0.cc"); 3087 auto *FromFriendF = FirstDeclMatcher<FunctionDecl>().match( 3088 FromTU, functionDecl(hasName("f"))); 3089 3090 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( 3091 FromTU, cxxRecordDecl(hasName("X"))); 3092 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl()); 3093 auto FromFriends = FromClass->friends(); 3094 unsigned int FrN = 0; 3095 for (auto Fr : FromFriends) { 3096 ASSERT_EQ(Fr, FromFriend); 3097 ++FrN; 3098 } 3099 ASSERT_EQ(FrN, 1u); 3100 3101 Import(FromFriendF, Lang_CXX03); 3102 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 3103 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match( 3104 ToTU, cxxRecordDecl(hasName("X"))); 3105 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 3106 auto ToFriends = ToClass->friends(); 3107 FrN = 0; 3108 for (auto Fr : ToFriends) { 3109 EXPECT_EQ(Fr, ToFriend); 3110 ++FrN; 3111 } 3112 EXPECT_EQ(FrN, 1u); 3113 } 3114 3115 AST_MATCHER_P(TagDecl, hasTypedefForAnonDecl, Matcher<TypedefNameDecl>, 3116 InnerMatcher) { 3117 if (auto *Typedef = Node.getTypedefNameForAnonDecl()) 3118 return InnerMatcher.matches(*Typedef, Finder, Builder); 3119 return false; 3120 } 3121 3122 TEST_P(ImportDecl, ImportEnumSequential) { 3123 CodeFiles Samples{{"main.c", 3124 {"void foo();" 3125 "void moo();" 3126 "int main() { foo(); moo(); }", 3127 Lang_C99}}, 3128 3129 {"foo.c", 3130 {"typedef enum { THING_VALUE } thing_t;" 3131 "void conflict(thing_t type);" 3132 "void foo() { (void)THING_VALUE; }" 3133 "void conflict(thing_t type) {}", 3134 Lang_C99}}, 3135 3136 {"moo.c", 3137 {"typedef enum { THING_VALUE } thing_t;" 3138 "void conflict(thing_t type);" 3139 "void moo() { conflict(THING_VALUE); }", 3140 Lang_C99}}}; 3141 3142 auto VerificationMatcher = 3143 enumDecl(has(enumConstantDecl(hasName("THING_VALUE"))), 3144 hasTypedefForAnonDecl(hasName("thing_t"))); 3145 3146 ImportAction ImportFoo{"foo.c", "main.c", functionDecl(hasName("foo"))}, 3147 ImportMoo{"moo.c", "main.c", functionDecl(hasName("moo"))}; 3148 3149 testImportSequence( 3150 Samples, {ImportFoo, ImportMoo}, // "foo", them "moo". 3151 // Just check that there is only one enum decl in the result AST. 3152 "main.c", enumDecl(), VerificationMatcher); 3153 3154 // For different import order, result should be the same. 3155 testImportSequence( 3156 Samples, {ImportMoo, ImportFoo}, // "moo", them "foo". 3157 // Check that there is only one enum decl in the result AST. 3158 "main.c", enumDecl(), VerificationMatcher); 3159 } 3160 3161 TEST_P(ImportDecl, ImportFieldOrder) { 3162 MatchVerifier<Decl> Verifier; 3163 testImport("struct declToImport {" 3164 " int b = a + 2;" 3165 " int a = 5;" 3166 "};", 3167 Lang_CXX11, "", Lang_CXX11, Verifier, 3168 recordDecl(hasFieldOrder({"b", "a"}))); 3169 } 3170 3171 TEST_P(ImportExpr, DependentScopeDeclRefExpr) { 3172 MatchVerifier<Decl> Verifier; 3173 testImport("template <typename T> struct S { static T foo; };" 3174 "template <typename T> void declToImport() {" 3175 " (void) S<T>::foo;" 3176 "}" 3177 "void instantiate() { declToImport<int>(); }" 3178 "template <typename T> T S<T>::foo;", 3179 Lang_CXX11, "", Lang_CXX11, Verifier, 3180 functionTemplateDecl(has(functionDecl(has(compoundStmt( 3181 has(cStyleCastExpr(has(dependentScopeDeclRefExpr()))))))))); 3182 3183 testImport("template <typename T> struct S {" 3184 "template<typename S> static void foo(){};" 3185 "};" 3186 "template <typename T> void declToImport() {" 3187 " S<T>::template foo<T>();" 3188 "}" 3189 "void instantiate() { declToImport<int>(); }", 3190 Lang_CXX11, "", Lang_CXX11, Verifier, 3191 functionTemplateDecl(has(functionDecl(has(compoundStmt( 3192 has(callExpr(has(dependentScopeDeclRefExpr()))))))))); 3193 } 3194 3195 TEST_P(ImportExpr, DependentNameType) { 3196 MatchVerifier<Decl> Verifier; 3197 testImport("template <typename T> struct declToImport {" 3198 " typedef typename T::type dependent_name;" 3199 "};", 3200 Lang_CXX11, "", Lang_CXX11, Verifier, 3201 classTemplateDecl(has( 3202 cxxRecordDecl(has(typedefDecl(has(dependentNameType()))))))); 3203 } 3204 3205 TEST_P(ImportExpr, UnresolvedMemberExpr) { 3206 MatchVerifier<Decl> Verifier; 3207 testImport("struct S { template <typename T> void mem(); };" 3208 "template <typename U> void declToImport() {" 3209 " S s;" 3210 " s.mem<U>();" 3211 "}" 3212 "void instantiate() { declToImport<int>(); }", 3213 Lang_CXX11, "", Lang_CXX11, Verifier, 3214 functionTemplateDecl(has(functionDecl(has( 3215 compoundStmt(has(callExpr(has(unresolvedMemberExpr()))))))))); 3216 } 3217 3218 class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase { 3219 public: 3220 static constexpr auto DefaultCode = R"( 3221 struct A { int x; }; 3222 void f() { 3223 A a; 3224 A a1(a); 3225 A a2(A{}); 3226 a = a1; 3227 a = A{}; 3228 a.~A(); 3229 })"; 3230 3231 template <typename MatcherType> 3232 void testImportOf( 3233 const MatcherType &MethodMatcher, const char *Code = DefaultCode) { 3234 test(MethodMatcher, Code, /*ExpectedCount=*/1u); 3235 } 3236 3237 template <typename MatcherType> 3238 void testNoImportOf( 3239 const MatcherType &MethodMatcher, const char *Code = DefaultCode) { 3240 test(MethodMatcher, Code, /*ExpectedCount=*/0u); 3241 } 3242 3243 private: 3244 template <typename MatcherType> 3245 void test(const MatcherType &MethodMatcher, 3246 const char *Code, unsigned int ExpectedCount) { 3247 auto ClassMatcher = cxxRecordDecl(unless(isImplicit())); 3248 3249 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3250 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match( 3251 ToTU, ClassMatcher); 3252 3253 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 1u); 3254 3255 { 3256 CXXMethodDecl *Method = 3257 FirstDeclMatcher<CXXMethodDecl>().match(ToClass, MethodMatcher); 3258 ToClass->removeDecl(Method); 3259 SharedStatePtr->getLookupTable()->remove(Method); 3260 } 3261 3262 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 0u); 3263 3264 Decl *ImportedClass = nullptr; 3265 { 3266 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input1.cc"); 3267 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( 3268 FromTU, ClassMatcher); 3269 ImportedClass = Import(FromClass, Lang_CXX11); 3270 } 3271 3272 EXPECT_EQ(ToClass, ImportedClass); 3273 EXPECT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 3274 ExpectedCount); 3275 } 3276 }; 3277 3278 TEST_P(ImportImplicitMethods, DefaultConstructor) { 3279 testImportOf(cxxConstructorDecl(isDefaultConstructor())); 3280 } 3281 3282 TEST_P(ImportImplicitMethods, CopyConstructor) { 3283 testImportOf(cxxConstructorDecl(isCopyConstructor())); 3284 } 3285 3286 TEST_P(ImportImplicitMethods, MoveConstructor) { 3287 testImportOf(cxxConstructorDecl(isMoveConstructor())); 3288 } 3289 3290 TEST_P(ImportImplicitMethods, Destructor) { 3291 testImportOf(cxxDestructorDecl()); 3292 } 3293 3294 TEST_P(ImportImplicitMethods, CopyAssignment) { 3295 testImportOf(cxxMethodDecl(isCopyAssignmentOperator())); 3296 } 3297 3298 TEST_P(ImportImplicitMethods, MoveAssignment) { 3299 testImportOf(cxxMethodDecl(isMoveAssignmentOperator())); 3300 } 3301 3302 TEST_P(ImportImplicitMethods, DoNotImportUserProvided) { 3303 auto Code = R"( 3304 struct A { A() { int x; } }; 3305 )"; 3306 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); 3307 } 3308 3309 TEST_P(ImportImplicitMethods, DoNotImportDefault) { 3310 auto Code = R"( 3311 struct A { A() = default; }; 3312 )"; 3313 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); 3314 } 3315 3316 TEST_P(ImportImplicitMethods, DoNotImportDeleted) { 3317 auto Code = R"( 3318 struct A { A() = delete; }; 3319 )"; 3320 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); 3321 } 3322 3323 TEST_P(ImportImplicitMethods, DoNotImportOtherMethod) { 3324 auto Code = R"( 3325 struct A { void f() { } }; 3326 )"; 3327 testNoImportOf(cxxMethodDecl(hasName("f")), Code); 3328 } 3329 3330 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentRecord) { 3331 Decl *ToR1; 3332 { 3333 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input0.cc"); 3334 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3335 FromTU, cxxRecordDecl(hasName("A"))); 3336 3337 ToR1 = Import(FromR, Lang_CXX03); 3338 } 3339 3340 Decl *ToR2; 3341 { 3342 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input1.cc"); 3343 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3344 FromTU, cxxRecordDecl(hasName("A"))); 3345 3346 ToR2 = Import(FromR, Lang_CXX03); 3347 } 3348 3349 EXPECT_EQ(ToR1, ToR2); 3350 } 3351 3352 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentRecord) { 3353 Decl *ToR1; 3354 { 3355 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc"); 3356 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3357 FromTU, cxxRecordDecl(hasName("A"))); 3358 ToR1 = Import(FromR, Lang_CXX03); 3359 } 3360 Decl *ToR2; 3361 { 3362 Decl *FromTU = 3363 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc"); 3364 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 3365 FromTU, cxxRecordDecl(hasName("A"))); 3366 ToR2 = Import(FromR, Lang_CXX03); 3367 } 3368 EXPECT_NE(ToR1, ToR2); 3369 } 3370 3371 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentField) { 3372 Decl *ToF1; 3373 { 3374 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc"); 3375 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3376 FromTU, fieldDecl(hasName("x"))); 3377 ToF1 = Import(FromF, Lang_CXX03); 3378 } 3379 Decl *ToF2; 3380 { 3381 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input1.cc"); 3382 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3383 FromTU, fieldDecl(hasName("x"))); 3384 ToF2 = Import(FromF, Lang_CXX03); 3385 } 3386 EXPECT_EQ(ToF1, ToF2); 3387 } 3388 3389 TEST_P(ASTImporterOptionSpecificTestBase, ImportBitfields) { 3390 Decl *FromTU = getTuDecl("struct A { unsigned x : 3; };", Lang_CXX03); 3391 auto *FromF = 3392 FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("x"))); 3393 3394 ASSERT_TRUE(FromF->isBitField()); 3395 ASSERT_EQ(3u, FromF->getBitWidthValue()); 3396 auto *ToField = Import(FromF, Lang_CXX03); 3397 3398 EXPECT_TRUE(ToField->isBitField()); 3399 EXPECT_EQ(3u, ToField->getBitWidthValue()); 3400 3401 const auto *FromBT = FromF->getBitWidth()->getType()->getAs<BuiltinType>(); 3402 const auto *ToBT = ToField->getBitWidth()->getType()->getAs<BuiltinType>(); 3403 ASSERT_TRUE(FromBT); 3404 ASSERT_EQ(BuiltinType::Int, FromBT->getKind()); 3405 EXPECT_TRUE(ToBT); 3406 EXPECT_EQ(BuiltinType::Int, ToBT->getKind()); 3407 } 3408 3409 struct ImportBlock : ASTImporterOptionSpecificTestBase {}; 3410 TEST_P(ImportBlock, ImportBlocksAreUnsupported) { 3411 const auto *Code = R"( 3412 void test_block__capture_null() { 3413 int *p = 0; 3414 ^(){ 3415 *p = 1; 3416 }(); 3417 })"; 3418 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 3419 auto *FromBlock = FirstDeclMatcher<BlockDecl>().match(FromTU, blockDecl()); 3420 ASSERT_TRUE(FromBlock); 3421 3422 auto ToBlockOrError = importOrError(FromBlock, Lang_CXX03); 3423 3424 const auto ExpectUnsupportedConstructError = [](const ASTImportError &Error) { 3425 EXPECT_EQ(ASTImportError::UnsupportedConstruct, Error.Error); 3426 }; 3427 llvm::handleAllErrors(ToBlockOrError.takeError(), 3428 ExpectUnsupportedConstructError); 3429 } 3430 3431 TEST_P(ASTImporterOptionSpecificTestBase, ImportParmVarDecl) { 3432 const auto *Code = R"( 3433 template <typename T> struct Wrapper { 3434 Wrapper(T Value = {}) {} 3435 }; 3436 template class Wrapper<int>; 3437 )"; 3438 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3439 auto *FromVar = FirstDeclMatcher<ParmVarDecl>().match( 3440 FromTU, parmVarDecl(hasType(asString("int")))); 3441 ASSERT_TRUE(FromVar); 3442 ASSERT_TRUE(FromVar->hasUninstantiatedDefaultArg()); 3443 ASSERT_TRUE(FromVar->getUninstantiatedDefaultArg()); 3444 ASSERT_FALSE(FromVar->isExplicitObjectParameter()); 3445 3446 const auto *ToVar = Import(FromVar, Lang_CXX11); 3447 EXPECT_TRUE(ToVar); 3448 EXPECT_TRUE(ToVar->hasUninstantiatedDefaultArg()); 3449 EXPECT_TRUE(ToVar->getUninstantiatedDefaultArg()); 3450 EXPECT_NE(FromVar->getUninstantiatedDefaultArg(), 3451 ToVar->getUninstantiatedDefaultArg()); 3452 EXPECT_FALSE(ToVar->isExplicitObjectParameter()); 3453 } 3454 3455 TEST_P(ASTImporterOptionSpecificTestBase, ImportParmVarDecl_Explicit) { 3456 const auto *Code = R"( 3457 struct Wrapper { 3458 void func(this Wrapper) {} 3459 }; 3460 )"; 3461 Decl *FromTU = getTuDecl(Code, Lang_CXX23); 3462 auto *FromVar = FirstDeclMatcher<ParmVarDecl>().match(FromTU, parmVarDecl()); 3463 ASSERT_TRUE(FromVar); 3464 ASSERT_TRUE(FromVar->isExplicitObjectParameter()); 3465 3466 const auto *ToVar = Import(FromVar, Lang_CXX23); 3467 EXPECT_TRUE(ToVar); 3468 EXPECT_TRUE(ToVar->isExplicitObjectParameter()); 3469 EXPECT_NE(ToVar->getExplicitObjectParamThisLoc(), 3470 FromVar->getExplicitObjectParamThisLoc()); 3471 } 3472 3473 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentField) { 3474 Decl *ToF1; 3475 { 3476 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc"); 3477 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3478 FromTU, fieldDecl(hasName("x"))); 3479 ToF1 = Import(FromF, Lang_CXX03); 3480 } 3481 Decl *ToF2; 3482 { 3483 Decl *FromTU = 3484 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc"); 3485 auto *FromF = FirstDeclMatcher<FieldDecl>().match( 3486 FromTU, fieldDecl(hasName("x"))); 3487 ToF2 = Import(FromF, Lang_CXX03); 3488 } 3489 EXPECT_NE(ToF1, ToF2); 3490 } 3491 3492 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentMethod) { 3493 Decl *ToM1; 3494 { 3495 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }", 3496 Lang_CXX03, "input0.cc"); 3497 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3498 FromTU, functionDecl(hasName("x"), isDefinition())); 3499 ToM1 = Import(FromM, Lang_CXX03); 3500 } 3501 Decl *ToM2; 3502 { 3503 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }", 3504 Lang_CXX03, "input1.cc"); 3505 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3506 FromTU, functionDecl(hasName("x"), isDefinition())); 3507 ToM2 = Import(FromM, Lang_CXX03); 3508 } 3509 EXPECT_EQ(ToM1, ToM2); 3510 } 3511 3512 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentMethod) { 3513 Decl *ToM1; 3514 { 3515 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }", 3516 Lang_CXX03, "input0.cc"); 3517 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3518 FromTU, functionDecl(hasName("x"), isDefinition())); 3519 ToM1 = Import(FromM, Lang_CXX03); 3520 } 3521 Decl *ToM2; 3522 { 3523 Decl *FromTU = 3524 getTuDecl("struct A { void x() const; }; void A::x() const { }", 3525 Lang_CXX03, "input1.cc"); 3526 auto *FromM = FirstDeclMatcher<FunctionDecl>().match( 3527 FromTU, functionDecl(hasName("x"), isDefinition())); 3528 ToM2 = Import(FromM, Lang_CXX03); 3529 } 3530 EXPECT_NE(ToM1, ToM2); 3531 } 3532 3533 TEST_P(ASTImporterOptionSpecificTestBase, 3534 ImportUnnamedStructsWithRecursingField) { 3535 Decl *FromTU = getTuDecl( 3536 R"( 3537 struct A { 3538 struct { 3539 struct A *next; 3540 } entry0; 3541 struct { 3542 struct A *next; 3543 } entry1; 3544 }; 3545 )", 3546 Lang_C99, "input0.cc"); 3547 auto *From = 3548 FirstDeclMatcher<RecordDecl>().match(FromTU, recordDecl(hasName("A"))); 3549 3550 Import(From, Lang_C99); 3551 3552 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 3553 auto *Entry0 = 3554 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0"))); 3555 auto *Entry1 = 3556 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry1"))); 3557 auto *R0 = getRecordDecl(Entry0); 3558 auto *R1 = getRecordDecl(Entry1); 3559 EXPECT_NE(R0, R1); 3560 EXPECT_TRUE(MatchVerifier<RecordDecl>().match( 3561 R0, recordDecl(has(fieldDecl(hasName("next")))))); 3562 EXPECT_TRUE(MatchVerifier<RecordDecl>().match( 3563 R1, recordDecl(has(fieldDecl(hasName("next")))))); 3564 } 3565 3566 TEST_P(ASTImporterOptionSpecificTestBase, ImportUnnamedFieldsInCorrectOrder) { 3567 Decl *FromTU = getTuDecl( 3568 R"( 3569 void f(int X, int Y, bool Z) { 3570 (void)[X, Y, Z] { (void)Z; }; 3571 } 3572 )", 3573 Lang_CXX11, "input0.cc"); 3574 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 3575 FromTU, functionDecl(hasName("f"))); 3576 auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11)); 3577 EXPECT_TRUE(ToF); 3578 3579 CXXRecordDecl *FromLambda = 3580 cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>( 3581 FromF->getBody())->body_front())->getSubExpr())->getLambdaClass(); 3582 3583 auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11)); 3584 EXPECT_TRUE(ToLambda); 3585 3586 // Check if the fields of the lambda class are imported in correct order. 3587 unsigned FromIndex = 0u; 3588 for (auto *FromField : FromLambda->fields()) { 3589 ASSERT_FALSE(FromField->getDeclName()); 3590 auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11)); 3591 EXPECT_TRUE(ToField); 3592 std::optional<unsigned> ToIndex = ASTImporter::getFieldIndex(ToField); 3593 EXPECT_TRUE(ToIndex); 3594 EXPECT_EQ(*ToIndex, FromIndex); 3595 ++FromIndex; 3596 } 3597 3598 EXPECT_EQ(FromIndex, 3u); 3599 } 3600 3601 TEST_P(ASTImporterOptionSpecificTestBase, 3602 MergeFieldDeclsOfClassTemplateSpecialization) { 3603 std::string ClassTemplate = 3604 R"( 3605 template <typename T> 3606 struct X { 3607 int a{0}; // FieldDecl with InitListExpr 3608 X(char) : a(3) {} // (1) 3609 X(int) {} // (2) 3610 }; 3611 )"; 3612 Decl *ToTU = getToTuDecl(ClassTemplate + 3613 R"( 3614 void foo() { 3615 // ClassTemplateSpec with ctor (1): FieldDecl without InitlistExpr 3616 X<char> xc('c'); 3617 } 3618 )", Lang_CXX11); 3619 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3620 ToTU, classTemplateSpecializationDecl(hasName("X"))); 3621 // FieldDecl without InitlistExpr: 3622 auto *ToField = *ToSpec->field_begin(); 3623 ASSERT_TRUE(ToField); 3624 ASSERT_FALSE(ToField->getInClassInitializer()); 3625 Decl *FromTU = getTuDecl(ClassTemplate + 3626 R"( 3627 void bar() { 3628 // ClassTemplateSpec with ctor (2): FieldDecl WITH InitlistExpr 3629 X<char> xc(1); 3630 } 3631 )", Lang_CXX11); 3632 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3633 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3634 // FieldDecl with InitlistExpr: 3635 auto *FromField = *FromSpec->field_begin(); 3636 ASSERT_TRUE(FromField); 3637 ASSERT_TRUE(FromField->getInClassInitializer()); 3638 3639 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3640 ASSERT_TRUE(ImportedSpec); 3641 EXPECT_EQ(ImportedSpec, ToSpec); 3642 // After the import, the FieldDecl has to be merged, thus it should have the 3643 // InitListExpr. 3644 EXPECT_TRUE(ToField->getInClassInitializer()); 3645 } 3646 3647 TEST_P(ASTImporterOptionSpecificTestBase, 3648 MergeFunctionOfClassTemplateSpecialization) { 3649 std::string ClassTemplate = 3650 R"( 3651 template <typename T> 3652 struct X { 3653 void f() {} 3654 void g() {} 3655 }; 3656 )"; 3657 Decl *ToTU = getToTuDecl(ClassTemplate + 3658 R"( 3659 void foo() { 3660 X<char> x; 3661 x.f(); 3662 } 3663 )", Lang_CXX11); 3664 Decl *FromTU = getTuDecl(ClassTemplate + 3665 R"( 3666 void bar() { 3667 X<char> x; 3668 x.g(); 3669 } 3670 )", Lang_CXX11); 3671 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3672 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3673 auto FunPattern = functionDecl(hasName("g"), 3674 hasParent(classTemplateSpecializationDecl())); 3675 auto *FromFun = 3676 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunPattern); 3677 auto *ToFun = 3678 FirstDeclMatcher<FunctionDecl>().match(ToTU, FunPattern); 3679 ASSERT_TRUE(FromFun->hasBody()); 3680 ASSERT_FALSE(ToFun->hasBody()); 3681 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3682 ASSERT_TRUE(ImportedSpec); 3683 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3684 ToTU, classTemplateSpecializationDecl(hasName("X"))); 3685 EXPECT_EQ(ImportedSpec, ToSpec); 3686 EXPECT_TRUE(ToFun->hasBody()); 3687 } 3688 3689 TEST_P(ASTImporterOptionSpecificTestBase, MergeTemplateSpecWithForwardDecl) { 3690 std::string ClassTemplate = 3691 R"( 3692 template<typename T> 3693 struct X { int m; }; 3694 template<> 3695 struct X<int> { int m; }; 3696 )"; 3697 // Append a forward decl for our template specialization. 3698 getToTuDecl(ClassTemplate + "template<> struct X<int>;", Lang_CXX11); 3699 Decl *FromTU = getTuDecl(ClassTemplate, Lang_CXX11); 3700 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3701 FromTU, classTemplateSpecializationDecl(hasName("X"), isDefinition())); 3702 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3703 // Check that our definition got merged with the existing definition. 3704 EXPECT_TRUE(FromSpec->isThisDeclarationADefinition()); 3705 EXPECT_TRUE(ImportedSpec->isThisDeclarationADefinition()); 3706 } 3707 3708 TEST_P(ASTImporterOptionSpecificTestBase, 3709 ODRViolationOfClassTemplateSpecializationsShouldBeReported) { 3710 std::string ClassTemplate = 3711 R"( 3712 template <typename T> 3713 struct X {}; 3714 )"; 3715 Decl *ToTU = getToTuDecl(ClassTemplate + 3716 R"( 3717 template <> 3718 struct X<char> { 3719 int a; 3720 }; 3721 void foo() { 3722 X<char> x; 3723 } 3724 )", 3725 Lang_CXX11); 3726 Decl *FromTU = getTuDecl(ClassTemplate + 3727 R"( 3728 template <> 3729 struct X<char> { 3730 int b; 3731 }; 3732 void foo() { 3733 X<char> x; 3734 } 3735 )", 3736 Lang_CXX11); 3737 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3738 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3739 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3740 3741 // We expect one (ODR) warning during the import. 3742 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 3743 3744 // The second specialization is different from the first, thus it violates 3745 // ODR, consequently we expect to keep the first specialization only, which is 3746 // already in the "To" context. 3747 EXPECT_FALSE(ImportedSpec); 3748 EXPECT_EQ(1u, 3749 DeclCounter<ClassTemplateSpecializationDecl>().match( 3750 ToTU, classTemplateSpecializationDecl(hasName("X")))); 3751 } 3752 3753 TEST_P(ASTImporterOptionSpecificTestBase, 3754 MergeCtorOfClassTemplateSpecialization) { 3755 std::string ClassTemplate = 3756 R"( 3757 template <typename T> 3758 struct X { 3759 X(char) {} 3760 X(int) {} 3761 }; 3762 )"; 3763 Decl *ToTU = getToTuDecl(ClassTemplate + 3764 R"( 3765 void foo() { 3766 X<char> x('c'); 3767 } 3768 )", Lang_CXX11); 3769 Decl *FromTU = getTuDecl(ClassTemplate + 3770 R"( 3771 void bar() { 3772 X<char> x(1); 3773 } 3774 )", Lang_CXX11); 3775 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3776 FromTU, classTemplateSpecializationDecl(hasName("X"))); 3777 // Match the void(int) ctor. 3778 auto CtorPattern = 3779 cxxConstructorDecl(hasParameter(0, varDecl(hasType(asString("int")))), 3780 hasParent(classTemplateSpecializationDecl())); 3781 auto *FromCtor = 3782 FirstDeclMatcher<CXXConstructorDecl>().match(FromTU, CtorPattern); 3783 auto *ToCtor = 3784 FirstDeclMatcher<CXXConstructorDecl>().match(ToTU, CtorPattern); 3785 ASSERT_TRUE(FromCtor->hasBody()); 3786 ASSERT_FALSE(ToCtor->hasBody()); 3787 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3788 ASSERT_TRUE(ImportedSpec); 3789 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3790 ToTU, classTemplateSpecializationDecl(hasName("X"))); 3791 EXPECT_EQ(ImportedSpec, ToSpec); 3792 EXPECT_TRUE(ToCtor->hasBody()); 3793 } 3794 3795 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateFriendDecl) { 3796 const auto *Code = 3797 R"( 3798 template <class T> class X { friend T; }; 3799 struct Y {}; 3800 template class X<Y>; 3801 )"; 3802 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3803 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3804 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3805 FromTU, classTemplateSpecializationDecl()); 3806 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3807 ToTU, classTemplateSpecializationDecl()); 3808 3809 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3810 EXPECT_EQ(ImportedSpec, ToSpec); 3811 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match( 3812 ToTU, classTemplateSpecializationDecl())); 3813 } 3814 3815 TEST_P(ASTImporterOptionSpecificTestBase, 3816 ClassTemplatePartialSpecializationsShouldNotBeDuplicated) { 3817 auto Code = 3818 R"( 3819 // primary template 3820 template<class T1, class T2, int I> 3821 class A {}; 3822 3823 // partial specialization 3824 template<class T, int I> 3825 class A<T, T*, I> {}; 3826 )"; 3827 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3828 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3829 auto *FromSpec = 3830 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match( 3831 FromTU, classTemplatePartialSpecializationDecl()); 3832 auto *ToSpec = 3833 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match( 3834 ToTU, classTemplatePartialSpecializationDecl()); 3835 3836 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3837 EXPECT_EQ(ImportedSpec, ToSpec); 3838 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match( 3839 ToTU, classTemplatePartialSpecializationDecl())); 3840 } 3841 3842 TEST_P(ASTImporterOptionSpecificTestBase, 3843 ClassTemplateSpecializationsShouldNotBeDuplicated) { 3844 auto Code = 3845 R"( 3846 // primary template 3847 template<class T1, class T2, int I> 3848 class A {}; 3849 3850 // full specialization 3851 template<> 3852 class A<int, int, 1> {}; 3853 )"; 3854 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 3855 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 3856 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3857 FromTU, classTemplateSpecializationDecl()); 3858 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3859 ToTU, classTemplateSpecializationDecl()); 3860 3861 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3862 EXPECT_EQ(ImportedSpec, ToSpec); 3863 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match( 3864 ToTU, classTemplateSpecializationDecl())); 3865 } 3866 3867 TEST_P(ASTImporterOptionSpecificTestBase, 3868 ClassTemplateFullAndPartialSpecsShouldNotBeMixed) { 3869 std::string PrimaryTemplate = 3870 R"( 3871 template<class T1, class T2, int I> 3872 class A {}; 3873 )"; 3874 auto PartialSpec = 3875 R"( 3876 template<class T, int I> 3877 class A<T, T*, I> {}; 3878 )"; 3879 auto FullSpec = 3880 R"( 3881 template<> 3882 class A<int, int, 1> {}; 3883 )"; 3884 Decl *ToTU = getToTuDecl(PrimaryTemplate + FullSpec, Lang_CXX11); 3885 Decl *FromTU = getTuDecl(PrimaryTemplate + PartialSpec, Lang_CXX11); 3886 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 3887 FromTU, classTemplateSpecializationDecl()); 3888 3889 auto *ImportedSpec = Import(FromSpec, Lang_CXX11); 3890 EXPECT_TRUE(ImportedSpec); 3891 // Check the number of partial specializations. 3892 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match( 3893 ToTU, classTemplatePartialSpecializationDecl())); 3894 // Check the number of full specializations. 3895 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match( 3896 ToTU, classTemplateSpecializationDecl( 3897 unless(classTemplatePartialSpecializationDecl())))); 3898 } 3899 3900 TEST_P(ASTImporterOptionSpecificTestBase, 3901 InitListExprValueKindShouldBeImported) { 3902 Decl *TU = getTuDecl( 3903 R"( 3904 const int &init(); 3905 void foo() { const int &a{init()}; } 3906 )", Lang_CXX11, "input0.cc"); 3907 auto *FromD = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("a"))); 3908 ASSERT_TRUE(FromD->getAnyInitializer()); 3909 auto *InitExpr = FromD->getAnyInitializer(); 3910 ASSERT_TRUE(InitExpr); 3911 ASSERT_TRUE(InitExpr->isGLValue()); 3912 3913 auto *ToD = Import(FromD, Lang_CXX11); 3914 EXPECT_TRUE(ToD); 3915 auto *ToInitExpr = cast<VarDecl>(ToD)->getAnyInitializer(); 3916 EXPECT_TRUE(ToInitExpr); 3917 EXPECT_TRUE(ToInitExpr->isGLValue()); 3918 } 3919 3920 struct ImportVariables : ASTImporterOptionSpecificTestBase {}; 3921 3922 TEST_P(ImportVariables, ImportOfOneDeclBringsInTheWholeChain) { 3923 Decl *FromTU = getTuDecl( 3924 R"( 3925 struct A { 3926 static const int a = 1 + 2; 3927 }; 3928 const int A::a; 3929 )", 3930 Lang_CXX03, "input1.cc"); 3931 3932 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match( 3933 FromTU, varDecl(hasName("a"))); // Decl with init 3934 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match( 3935 FromTU, varDecl(hasName("a"))); // Decl with definition 3936 ASSERT_NE(FromDWithInit, FromDWithDef); 3937 ASSERT_EQ(FromDWithDef->getPreviousDecl(), FromDWithInit); 3938 3939 auto *ToD0 = cast<VarDecl>(Import(FromDWithInit, Lang_CXX11)); 3940 auto *ToD1 = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11)); 3941 ASSERT_TRUE(ToD0); 3942 ASSERT_TRUE(ToD1); 3943 EXPECT_NE(ToD0, ToD1); 3944 EXPECT_EQ(ToD1->getPreviousDecl(), ToD0); 3945 } 3946 3947 TEST_P(ImportVariables, InitAndDefinitionAreInDifferentTUs) { 3948 auto StructA = 3949 R"( 3950 struct A { 3951 static const int a = 1 + 2; 3952 }; 3953 )"; 3954 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03); 3955 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a;", Lang_CXX03, 3956 "input1.cc"); 3957 3958 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match( 3959 FromTU, varDecl(hasName("a"))); // Decl with init 3960 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match( 3961 FromTU, varDecl(hasName("a"))); // Decl with definition 3962 ASSERT_EQ(FromDWithInit, FromDWithDef->getPreviousDecl()); 3963 ASSERT_TRUE(FromDWithInit->getInit()); 3964 ASSERT_FALSE(FromDWithInit->isThisDeclarationADefinition()); 3965 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition()); 3966 ASSERT_FALSE(FromDWithDef->getInit()); 3967 3968 auto *ToD = FirstDeclMatcher<VarDecl>().match( 3969 ToTU, varDecl(hasName("a"))); // Decl with init 3970 ASSERT_TRUE(ToD->getInit()); 3971 ASSERT_FALSE(ToD->getDefinition()); 3972 3973 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11)); 3974 EXPECT_TRUE(ImportedD->getAnyInitializer()); 3975 EXPECT_TRUE(ImportedD->getDefinition()); 3976 } 3977 3978 TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) { 3979 auto StructA = 3980 R"( 3981 struct A { 3982 static const int a; 3983 }; 3984 )"; 3985 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03); 3986 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a = 1 + 2;", 3987 Lang_CXX03, "input1.cc"); 3988 3989 auto *FromDDeclarationOnly = FirstDeclMatcher<VarDecl>().match( 3990 FromTU, varDecl(hasName("a"))); 3991 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match( 3992 FromTU, varDecl(hasName("a"))); // Decl with definition and with init. 3993 ASSERT_EQ(FromDDeclarationOnly, FromDWithDef->getPreviousDecl()); 3994 ASSERT_FALSE(FromDDeclarationOnly->getInit()); 3995 ASSERT_FALSE(FromDDeclarationOnly->isThisDeclarationADefinition()); 3996 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition()); 3997 ASSERT_TRUE(FromDWithDef->getInit()); 3998 3999 auto *ToD = FirstDeclMatcher<VarDecl>().match( 4000 ToTU, varDecl(hasName("a"))); 4001 ASSERT_FALSE(ToD->getInit()); 4002 ASSERT_FALSE(ToD->getDefinition()); 4003 4004 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11)); 4005 EXPECT_TRUE(ImportedD->getAnyInitializer()); 4006 EXPECT_TRUE(ImportedD->getDefinition()); 4007 } 4008 4009 TEST_P(ImportVariables, ImportBindingDecl) { 4010 Decl *From, *To; 4011 std::tie(From, To) = getImportedDecl( 4012 R"( 4013 void declToImport() { 4014 int a[2] = {1,2}; 4015 auto [x1,y1] = a; 4016 auto& [x2,y2] = a; 4017 4018 struct S { 4019 mutable int x1 : 2; 4020 volatile double y1; 4021 }; 4022 S b; 4023 const auto [x3, y3] = b; 4024 }; 4025 )", 4026 Lang_CXX17, "", Lang_CXX17); 4027 4028 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl(); 4029 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 4030 FromTU, functionDecl(hasName("declToImport"))); 4031 auto *ToF = Import(FromF, Lang_CXX17); 4032 EXPECT_TRUE(ToF); 4033 4034 auto VerifyImport = [&](llvm::StringRef BindName) { 4035 auto *FromB = FirstDeclMatcher<BindingDecl>().match( 4036 FromF, bindingDecl(hasName(BindName))); 4037 ASSERT_TRUE(FromB); 4038 auto *ToB = Import(FromB, Lang_CXX17); 4039 EXPECT_TRUE(ToB); 4040 EXPECT_EQ(FromB->getBinding() != nullptr, ToB->getBinding() != nullptr); 4041 EXPECT_EQ(FromB->getDecomposedDecl() != nullptr, 4042 ToB->getDecomposedDecl() != nullptr); 4043 EXPECT_EQ(FromB->getHoldingVar() != nullptr, 4044 ToB->getHoldingVar() != nullptr); 4045 }; 4046 4047 VerifyImport("x1"); 4048 VerifyImport("y1"); 4049 VerifyImport("x2"); 4050 VerifyImport("y2"); 4051 VerifyImport("x3"); 4052 VerifyImport("y3"); 4053 } 4054 4055 TEST_P(ImportVariables, ImportDecompositionDeclArray) { 4056 Decl *From, *To; 4057 std::tie(From, To) = getImportedDecl( 4058 R"( 4059 void declToImport() { 4060 int a[2] = {1,2}; 4061 auto [x1,y1] = a; 4062 }; 4063 )", 4064 Lang_CXX17, "", Lang_CXX17); 4065 4066 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl(); 4067 auto *FromDecomp = 4068 FirstDeclMatcher<DecompositionDecl>().match(FromTU, decompositionDecl()); 4069 auto *ToDecomp = Import(FromDecomp, Lang_CXX17); 4070 EXPECT_TRUE(ToDecomp); 4071 4072 ArrayRef<BindingDecl *> FromB = FromDecomp->bindings(); 4073 ArrayRef<BindingDecl *> ToB = ToDecomp->bindings(); 4074 EXPECT_EQ(FromB.size(), ToB.size()); 4075 for (unsigned int I = 0; I < FromB.size(); ++I) { 4076 auto *ToBI = Import(FromB[I], Lang_CXX17); 4077 EXPECT_EQ(ToBI, ToB[I]); 4078 } 4079 } 4080 4081 struct ImportClasses : ASTImporterOptionSpecificTestBase {}; 4082 4083 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) { 4084 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C99); 4085 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc"); 4086 auto Pattern = recordDecl(hasName("X"), unless(isImplicit())); 4087 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern); 4088 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern); 4089 4090 Decl *ImportedDef = Import(FromDef, Lang_C99); 4091 4092 EXPECT_NE(ImportedDef, ToProto); 4093 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u); 4094 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern); 4095 EXPECT_TRUE(ImportedDef == ToDef); 4096 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 4097 EXPECT_FALSE(ToProto->isThisDeclarationADefinition()); 4098 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto); 4099 } 4100 4101 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContextCXX) { 4102 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_CXX03); 4103 Decl *FromTU1 = getTuDecl("struct X {};", Lang_CXX03, "input1.cc"); 4104 auto Pattern = recordDecl(hasName("X"), unless(isImplicit())); 4105 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern); 4106 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern); 4107 4108 Decl *ImportedDef = Import(FromDef, Lang_CXX03); 4109 4110 EXPECT_NE(ImportedDef, ToProto); 4111 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u); 4112 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern); 4113 EXPECT_TRUE(ImportedDef == ToDef); 4114 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 4115 EXPECT_FALSE(ToProto->isThisDeclarationADefinition()); 4116 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto); 4117 } 4118 4119 TEST_P(ImportClasses, ImportNestedPrototypeThenDefinition) { 4120 Decl *FromTU0 = 4121 getTuDecl("struct A { struct X *Xp; };", Lang_C99, "input0.cc"); 4122 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc"); 4123 auto Pattern = recordDecl(hasName("X"), unless(isImplicit())); 4124 auto FromProto = FirstDeclMatcher<RecordDecl>().match(FromTU0, Pattern); 4125 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern); 4126 4127 Decl *ImportedProto = Import(FromProto, Lang_C99); 4128 Decl *ImportedDef = Import(FromDef, Lang_C99); 4129 Decl *ToTU = ImportedDef->getTranslationUnitDecl(); 4130 4131 EXPECT_NE(ImportedDef, ImportedProto); 4132 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u); 4133 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern); 4134 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern); 4135 EXPECT_TRUE(ImportedDef == ToDef); 4136 EXPECT_TRUE(ImportedProto == ToProto); 4137 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 4138 EXPECT_FALSE(ToProto->isThisDeclarationADefinition()); 4139 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto); 4140 } 4141 4142 struct ImportFriendClasses : ASTImporterOptionSpecificTestBase { 4143 void testRecursiveFriendClassTemplate(Decl *FromTu) { 4144 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 4145 FromTu, classTemplateDecl()); 4146 4147 auto Pattern = classTemplateDecl( 4148 has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl())))))); 4149 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern)); 4150 4151 auto *FromFriend = 4152 FirstDeclMatcher<FriendDecl>().match(FromD, friendDecl()); 4153 auto *FromRecordOfFriend = 4154 cast<ClassTemplateDecl>(FromFriend->getFriendDecl()) 4155 ->getTemplatedDecl(); 4156 EXPECT_NE(FromRecordOfFriend, FromD->getTemplatedDecl()); 4157 EXPECT_TRUE(FromRecordOfFriend->getPreviousDecl() == nullptr); 4158 4159 auto *FromDC = FromRecordOfFriend->getDeclContext(); 4160 auto *FromLexicalDC = FromRecordOfFriend->getLexicalDeclContext(); 4161 ASSERT_EQ(FromDC, cast<DeclContext>(FromTu)); 4162 ASSERT_EQ(FromLexicalDC, cast<DeclContext>(FromD->getTemplatedDecl())); 4163 4164 ASSERT_FALSE(FromDC->containsDecl(FromRecordOfFriend)); 4165 ASSERT_FALSE(FromLexicalDC->containsDecl(FromRecordOfFriend)); 4166 ASSERT_FALSE(cast<RecordDecl>(FromRecordOfFriend) 4167 ->getLookupParent() 4168 ->lookup(FromRecordOfFriend->getDeclName()) 4169 .empty()); 4170 4171 auto *ToD = Import(FromD, Lang_CXX03); 4172 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern)); 4173 4174 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToD, friendDecl()); 4175 auto *ToRecordOfFriend = 4176 cast<ClassTemplateDecl>(ToFriend->getFriendDecl())->getTemplatedDecl(); 4177 4178 EXPECT_NE(ToRecordOfFriend, ToD->getTemplatedDecl()); 4179 EXPECT_TRUE(ToRecordOfFriend->getPreviousDecl() == nullptr); 4180 4181 auto *ToDC = ToRecordOfFriend->getDeclContext(); 4182 auto *ToLexicalDC = ToRecordOfFriend->getLexicalDeclContext(); 4183 ASSERT_EQ(ToDC, cast<DeclContext>(ToD->getTranslationUnitDecl())); 4184 ASSERT_EQ(ToLexicalDC, cast<DeclContext>(ToD->getTemplatedDecl())); 4185 4186 ASSERT_FALSE(ToDC->containsDecl(ToRecordOfFriend)); 4187 ASSERT_FALSE(ToLexicalDC->containsDecl(ToRecordOfFriend)); 4188 ASSERT_FALSE(cast<RecordDecl>(ToRecordOfFriend) 4189 ->getLookupParent() 4190 ->lookup(ToRecordOfFriend->getDeclName()) 4191 .empty()); 4192 } 4193 4194 void testRepeatedFriendImport(const char *Code) { 4195 Decl *ToTu = getToTuDecl(Code, Lang_CXX03); 4196 Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc"); 4197 4198 auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4199 auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4200 auto *FromFriend1 = 4201 FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4202 auto *FromFriend2 = 4203 LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4204 4205 FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03); 4206 FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03); 4207 4208 EXPECT_NE(ToImportedFriend1, ToImportedFriend2); 4209 EXPECT_EQ(ToFriend1, ToImportedFriend1); 4210 EXPECT_EQ(ToFriend2, ToImportedFriend2); 4211 } 4212 }; 4213 4214 TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) { 4215 Decl *FromTU = getTuDecl( 4216 R"( 4217 class A { 4218 template <int I> class F {}; 4219 class X { 4220 template <int I> friend class F; 4221 }; 4222 }; 4223 )", 4224 Lang_CXX03, "input0.cc"); 4225 4226 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( 4227 FromTU, cxxRecordDecl(hasName("F"), isDefinition())); 4228 auto *FromFriendClass = LastDeclMatcher<CXXRecordDecl>().match( 4229 FromTU, cxxRecordDecl(hasName("F"))); 4230 4231 ASSERT_TRUE(FromClass); 4232 ASSERT_TRUE(FromFriendClass); 4233 ASSERT_NE(FromClass, FromFriendClass); 4234 ASSERT_EQ(FromFriendClass->getDefinition(), FromClass); 4235 ASSERT_EQ(FromFriendClass->getPreviousDecl(), FromClass); 4236 ASSERT_EQ(FromFriendClass->getDescribedClassTemplate()->getPreviousDecl(), 4237 FromClass->getDescribedClassTemplate()); 4238 4239 auto *ToClass = cast<CXXRecordDecl>(Import(FromClass, Lang_CXX03)); 4240 auto *ToFriendClass = 4241 cast<CXXRecordDecl>(Import(FromFriendClass, Lang_CXX03)); 4242 4243 EXPECT_TRUE(ToClass); 4244 EXPECT_TRUE(ToFriendClass); 4245 EXPECT_NE(ToClass, ToFriendClass); 4246 EXPECT_EQ(ToFriendClass->getDefinition(), ToClass); 4247 EXPECT_EQ(ToFriendClass->getPreviousDecl(), ToClass); 4248 EXPECT_EQ(ToFriendClass->getDescribedClassTemplate()->getPreviousDecl(), 4249 ToClass->getDescribedClassTemplate()); 4250 } 4251 4252 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClass) { 4253 Decl *FromTu = getTuDecl( 4254 R"( 4255 class declToImport { 4256 friend class declToImport; 4257 }; 4258 )", 4259 Lang_CXX03, "input.cc"); 4260 4261 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 4262 FromTu, cxxRecordDecl(hasName("declToImport"))); 4263 auto *ToD = Import(FromD, Lang_CXX03); 4264 auto Pattern = cxxRecordDecl(has(friendDecl())); 4265 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern)); 4266 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern)); 4267 } 4268 4269 TEST_P(ImportFriendClasses, UndeclaredFriendClassShouldNotBeVisible) { 4270 Decl *FromTu = 4271 getTuDecl("class X { friend class Y; };", Lang_CXX03, "from.cc"); 4272 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 4273 FromTu, cxxRecordDecl(hasName("X"))); 4274 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl()); 4275 RecordDecl *FromRecordOfFriend = 4276 const_cast<RecordDecl *>(getRecordDeclOfFriend(FromFriend)); 4277 4278 ASSERT_EQ(FromRecordOfFriend->getDeclContext(), cast<DeclContext>(FromTu)); 4279 ASSERT_EQ(FromRecordOfFriend->getLexicalDeclContext(), 4280 cast<DeclContext>(FromX)); 4281 ASSERT_FALSE( 4282 FromRecordOfFriend->getDeclContext()->containsDecl(FromRecordOfFriend)); 4283 ASSERT_FALSE(FromRecordOfFriend->getLexicalDeclContext()->containsDecl( 4284 FromRecordOfFriend)); 4285 ASSERT_FALSE(FromRecordOfFriend->getLookupParent() 4286 ->lookup(FromRecordOfFriend->getDeclName()) 4287 .empty()); 4288 4289 auto *ToX = Import(FromX, Lang_CXX03); 4290 ASSERT_TRUE(ToX); 4291 4292 Decl *ToTu = ToX->getTranslationUnitDecl(); 4293 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl()); 4294 RecordDecl *ToRecordOfFriend = 4295 const_cast<RecordDecl *>(getRecordDeclOfFriend(ToFriend)); 4296 4297 ASSERT_EQ(ToRecordOfFriend->getDeclContext(), cast<DeclContext>(ToTu)); 4298 ASSERT_EQ(ToRecordOfFriend->getLexicalDeclContext(), cast<DeclContext>(ToX)); 4299 EXPECT_FALSE( 4300 ToRecordOfFriend->getDeclContext()->containsDecl(ToRecordOfFriend)); 4301 EXPECT_FALSE(ToRecordOfFriend->getLexicalDeclContext()->containsDecl( 4302 ToRecordOfFriend)); 4303 EXPECT_FALSE(ToRecordOfFriend->getLookupParent() 4304 ->lookup(ToRecordOfFriend->getDeclName()) 4305 .empty()); 4306 } 4307 4308 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClassTemplate) { 4309 Decl *FromTu = getTuDecl( 4310 R"( 4311 template<class A> class declToImport { 4312 template<class A1> friend class declToImport; 4313 }; 4314 )", 4315 Lang_CXX03, "input.cc"); 4316 4317 testRecursiveFriendClassTemplate(FromTu); 4318 } 4319 4320 TEST_P(ImportFriendClasses, 4321 ImportOfRecursiveFriendClassTemplateWithNonTypeParm) { 4322 Decl *FromTu = getTuDecl( 4323 R"( 4324 template<class A1, A1 A> class declToImport { 4325 template<class B1, B1> friend class declToImport; 4326 }; 4327 )", 4328 Lang_CXX03, "input.cc"); 4329 testRecursiveFriendClassTemplate(FromTu); 4330 } 4331 4332 TEST_P(ImportFriendClasses, ProperPrevDeclForClassTemplateDecls) { 4333 auto Pattern = classTemplateSpecializationDecl(hasName("X")); 4334 4335 ClassTemplateSpecializationDecl *Imported1; 4336 { 4337 Decl *FromTU = getTuDecl("template<class T> class X;" 4338 "struct Y { friend class X<int>; };", 4339 Lang_CXX03, "input0.cc"); 4340 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4341 FromTU, Pattern); 4342 4343 Imported1 = 4344 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03)); 4345 } 4346 ClassTemplateSpecializationDecl *Imported2; 4347 { 4348 Decl *FromTU = getTuDecl("template<class T> class X;" 4349 "template<> class X<int>{};" 4350 "struct Z { friend class X<int>; };", 4351 Lang_CXX03, "input1.cc"); 4352 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4353 FromTU, Pattern); 4354 4355 Imported2 = 4356 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03)); 4357 } 4358 4359 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4360 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(ToTU, Pattern), 4361 2u); 4362 ASSERT_TRUE(Imported2->getPreviousDecl()); 4363 EXPECT_EQ(Imported2->getPreviousDecl(), Imported1); 4364 } 4365 4366 TEST_P(ImportFriendClasses, TypeForDeclShouldBeSetInTemplated) { 4367 Decl *FromTU0 = getTuDecl( 4368 R"( 4369 class X { 4370 class Y; 4371 }; 4372 class X::Y { 4373 template <typename T> 4374 friend class F; // The decl context of F is the global namespace. 4375 }; 4376 )", 4377 Lang_CXX03, "input0.cc"); 4378 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match( 4379 FromTU0, classTemplateDecl(hasName("F"))); 4380 auto *Imported0 = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03)); 4381 Decl *FromTU1 = getTuDecl( 4382 R"( 4383 template <typename T> 4384 class F {}; 4385 )", 4386 Lang_CXX03, "input1.cc"); 4387 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match( 4388 FromTU1, classTemplateDecl(hasName("F"))); 4389 auto *Imported1 = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03)); 4390 EXPECT_EQ(Imported0->getTemplatedDecl()->getTypeForDecl(), 4391 Imported1->getTemplatedDecl()->getTypeForDecl()); 4392 } 4393 4394 TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) { 4395 Decl *From, *To; 4396 std::tie(From, To) = 4397 getImportedDecl("class declToImport {};", Lang_CXX03, 4398 "class Y { friend class declToImport; };", Lang_CXX03); 4399 auto *Imported = cast<CXXRecordDecl>(To); 4400 4401 EXPECT_TRUE(Imported->getPreviousDecl()); 4402 } 4403 4404 TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) { 4405 Decl *ToTU = getToTuDecl( 4406 R"( 4407 template <class T, T U> 4408 class A; 4409 4410 template <class T, T U> 4411 class A { 4412 public: 4413 template <class P, P Q> 4414 friend class A; 4415 4416 A(T x) :x(x) {} 4417 4418 private: 4419 T x; 4420 }; 4421 )", 4422 Lang_CXX11); 4423 4424 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match( 4425 ToTU, 4426 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A"))))); 4427 Decl *FromTU = getTuDecl( 4428 R"( 4429 template <class T, T U> 4430 class A; 4431 4432 template <class T, T U> 4433 class A { 4434 public: 4435 template <class P, P Q> 4436 friend class A; 4437 4438 A(T x) : x(x) {} 4439 4440 private: 4441 T x; 4442 }; 4443 4444 A<int,3> a1(0); 4445 )", 4446 Lang_CXX11, "input1.cc"); 4447 auto *FromA = FirstDeclMatcher<ClassTemplateDecl>().match( 4448 FromTU, 4449 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A"))))); 4450 auto *ToA = Import(FromA, Lang_CXX11); 4451 EXPECT_TRUE(ToA); 4452 EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(), 4453 ToA->getTemplatedDecl()->getTypeForDecl()); 4454 } 4455 4456 TEST_P(ImportFriendClasses, 4457 ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) { 4458 Decl *ToTU = getToTuDecl( 4459 R"( 4460 class X { 4461 class Y; 4462 }; 4463 class X::Y { 4464 template <typename T> 4465 friend class F; // The decl context of F is the global namespace. 4466 }; 4467 )", 4468 Lang_CXX03); 4469 auto *ToDecl = FirstDeclMatcher<ClassTemplateDecl>().match( 4470 ToTU, classTemplateDecl(hasName("F"))); 4471 Decl *FromTU = getTuDecl( 4472 R"( 4473 template <typename T> 4474 class F {}; 4475 )", 4476 Lang_CXX03, "input0.cc"); 4477 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match( 4478 FromTU, classTemplateDecl(hasName("F"))); 4479 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03)); 4480 EXPECT_TRUE(ImportedDef->getPreviousDecl()); 4481 EXPECT_EQ(ToDecl, ImportedDef->getPreviousDecl()); 4482 EXPECT_EQ(ToDecl->getTemplatedDecl(), 4483 ImportedDef->getTemplatedDecl()->getPreviousDecl()); 4484 } 4485 4486 TEST_P(ImportFriendClasses, 4487 ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked) { 4488 Decl *FromTU0 = getTuDecl( 4489 R"( 4490 class X { 4491 class Y; 4492 }; 4493 class X::Y { 4494 template <typename T> 4495 friend class F; // The decl context of F is the global namespace. 4496 }; 4497 )", 4498 Lang_CXX03, "input0.cc"); 4499 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match( 4500 FromTU0, classTemplateDecl(hasName("F"))); 4501 auto *ImportedFwd = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03)); 4502 Decl *FromTU1 = getTuDecl( 4503 R"( 4504 template <typename T> 4505 class F {}; 4506 )", 4507 Lang_CXX03, "input1.cc"); 4508 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match( 4509 FromTU1, classTemplateDecl(hasName("F"))); 4510 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03)); 4511 EXPECT_TRUE(ImportedDef->getPreviousDecl()); 4512 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl()); 4513 EXPECT_EQ(ImportedFwd->getTemplatedDecl(), 4514 ImportedDef->getTemplatedDecl()->getPreviousDecl()); 4515 } 4516 4517 TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) { 4518 Decl *FromTU0 = getTuDecl( 4519 R"( 4520 class X { 4521 class Y; 4522 }; 4523 class X::Y { 4524 friend class F; // The decl context of F is the global namespace. 4525 }; 4526 )", 4527 Lang_CXX03, "input0.cc"); 4528 auto *Friend = FirstDeclMatcher<FriendDecl>().match(FromTU0, friendDecl()); 4529 QualType FT = Friend->getFriendType()->getType(); 4530 FT = FromTU0->getASTContext().getCanonicalType(FT); 4531 auto *Fwd = cast<TagType>(FT)->getDecl(); 4532 auto *ImportedFwd = Import(Fwd, Lang_CXX03); 4533 Decl *FromTU1 = getTuDecl( 4534 R"( 4535 class F {}; 4536 )", 4537 Lang_CXX03, "input1.cc"); 4538 auto *Definition = FirstDeclMatcher<CXXRecordDecl>().match( 4539 FromTU1, cxxRecordDecl(hasName("F"))); 4540 auto *ImportedDef = Import(Definition, Lang_CXX03); 4541 EXPECT_TRUE(ImportedDef->getPreviousDecl()); 4542 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl()); 4543 } 4544 4545 TEST_P(ImportFriendClasses, 4546 ImportFriendTemplatesInDependentContext_DefToFriend) { 4547 Decl *ToTU = getToTuDecl( 4548 R"( 4549 template<class T1> 4550 struct X { 4551 template<class T2> 4552 friend struct Y; 4553 }; 4554 )", 4555 Lang_CXX03); 4556 auto *ToYFriend = FirstDeclMatcher<ClassTemplateDecl>().match( 4557 ToTU, classTemplateDecl(hasName("Y"))); 4558 Decl *FromTU = getTuDecl( 4559 R"( 4560 template<class T1> 4561 struct Y {}; 4562 )", 4563 Lang_CXX03, "input0.cc"); 4564 auto *FromYDef = FirstDeclMatcher<ClassTemplateDecl>().match( 4565 FromTU, classTemplateDecl(hasName("Y"))); 4566 auto *ImportedYDef = Import(FromYDef, Lang_CXX03); 4567 EXPECT_TRUE(ImportedYDef); 4568 EXPECT_FALSE(ImportedYDef->getPreviousDecl()); 4569 EXPECT_NE(ImportedYDef, ToYFriend); 4570 } 4571 4572 TEST_P(ImportFriendClasses, 4573 ImportFriendTemplatesInDependentContext_DefToFriend_NE) { 4574 getToTuDecl( 4575 R"( 4576 template<class T1> 4577 struct X { 4578 template<class T2> 4579 friend struct Y; 4580 }; 4581 )", 4582 Lang_CXX03); 4583 Decl *FromTU = getTuDecl( 4584 R"( 4585 template<class T1, class T2> 4586 struct Y {}; 4587 )", 4588 Lang_CXX03, "input0.cc"); 4589 auto *FromYDef = FirstDeclMatcher<ClassTemplateDecl>().match( 4590 FromTU, classTemplateDecl(hasName("Y"))); 4591 auto *ImportedYDef = Import(FromYDef, Lang_CXX03); 4592 EXPECT_FALSE(ImportedYDef); 4593 } 4594 4595 TEST_P(ImportFriendClasses, 4596 ImportFriendTemplatesInDependentContext_FriendToFriend) { 4597 Decl *ToTU = getToTuDecl( 4598 R"( 4599 template<class T1> 4600 struct X { 4601 template<class T2> 4602 friend struct Y; 4603 }; 4604 )", 4605 Lang_CXX03); 4606 auto *ToYFriend = FirstDeclMatcher<ClassTemplateDecl>().match( 4607 ToTU, classTemplateDecl(hasName("Y"))); 4608 Decl *FromTU = getTuDecl( 4609 R"( 4610 template<class T1> 4611 struct X { 4612 template<class T2> 4613 friend struct Y; 4614 }; 4615 )", 4616 Lang_CXX03, "input0.cc"); 4617 auto *FromYFriend = FirstDeclMatcher<ClassTemplateDecl>().match( 4618 FromTU, classTemplateDecl(hasName("Y"))); 4619 auto *ImportedYFriend = Import(FromYFriend, Lang_CXX03); 4620 EXPECT_TRUE(ImportedYFriend); 4621 EXPECT_FALSE(ImportedYFriend->getPreviousDecl()); 4622 EXPECT_NE(ImportedYFriend, ToYFriend); 4623 } 4624 4625 TEST_P(ImportFriendClasses, 4626 ImportFriendTemplatesInDependentContext_FriendToFriend_NE) { 4627 getToTuDecl( 4628 R"( 4629 template<class T1> 4630 struct X { 4631 template<class T2> 4632 friend struct Y; 4633 }; 4634 )", 4635 Lang_CXX03); 4636 Decl *FromTU = getTuDecl( 4637 R"( 4638 template<class T1> 4639 struct X { 4640 template<class T2, class T3> 4641 friend struct Y; 4642 }; 4643 )", 4644 Lang_CXX03, "input0.cc"); 4645 auto *FromYFriend = FirstDeclMatcher<ClassTemplateDecl>().match( 4646 FromTU, classTemplateDecl(hasName("Y"))); 4647 auto *ImportedYFriend = Import(FromYFriend, Lang_CXX03); 4648 EXPECT_FALSE(ImportedYFriend); 4649 } 4650 4651 TEST_P(ImportFriendClasses, 4652 ImportFriendTemplatesInDependentContext_FriendToDef) { 4653 Decl *ToTU = getToTuDecl( 4654 R"( 4655 template<class T1> 4656 struct Y {}; 4657 )", 4658 Lang_CXX03); 4659 auto *ToYDef = FirstDeclMatcher<ClassTemplateDecl>().match( 4660 ToTU, classTemplateDecl(hasName("Y"))); 4661 Decl *FromTU = getTuDecl( 4662 R"( 4663 template<class T1> 4664 struct X { 4665 template<class T2> 4666 friend struct Y; 4667 }; 4668 )", 4669 Lang_CXX03, "input0.cc"); 4670 auto *FromYFriend = FirstDeclMatcher<ClassTemplateDecl>().match( 4671 FromTU, classTemplateDecl(hasName("Y"))); 4672 auto *ImportedYFriend = Import(FromYFriend, Lang_CXX03); 4673 EXPECT_TRUE(ImportedYFriend); 4674 EXPECT_FALSE(ImportedYFriend->getPreviousDecl()); 4675 EXPECT_NE(ImportedYFriend, ToYDef); 4676 } 4677 4678 TEST_P(ImportFriendClasses, 4679 ImportFriendTemplatesInDependentContext_FriendToDef_NE) { 4680 getToTuDecl( 4681 R"( 4682 template<class T1> 4683 struct Y {}; 4684 )", 4685 Lang_CXX03); 4686 Decl *FromTU = getTuDecl( 4687 R"( 4688 template<class T1> 4689 struct X { 4690 template<class T2, class T3> 4691 friend struct Y; 4692 }; 4693 )", 4694 Lang_CXX03, "input0.cc"); 4695 auto *FromYFriend = FirstDeclMatcher<ClassTemplateDecl>().match( 4696 FromTU, classTemplateDecl(hasName("Y"))); 4697 auto *ImportedYFriend = Import(FromYFriend, Lang_CXX03); 4698 EXPECT_FALSE(ImportedYFriend); 4699 } 4700 4701 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendType) { 4702 const char *Code = 4703 R"( 4704 class Container { 4705 friend class X; 4706 friend class X; 4707 }; 4708 )"; 4709 testRepeatedFriendImport(Code); 4710 } 4711 4712 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendDecl) { 4713 const char *Code = 4714 R"( 4715 class Container { 4716 friend void f(); 4717 friend void f(); 4718 }; 4719 )"; 4720 testRepeatedFriendImport(Code); 4721 } 4722 4723 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendFunctionTemplateDecl) { 4724 const char *Code = 4725 R"( 4726 template <class T> 4727 class Container { 4728 template <class U> friend void m(); 4729 template <class U> friend void m(); 4730 }; 4731 )"; 4732 testRepeatedFriendImport(Code); 4733 } 4734 4735 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendClassTemplateDecl) { 4736 const char *Code = 4737 R"( 4738 template <class T> 4739 class Container { 4740 template <class U> friend class X; 4741 template <class U> friend class X; 4742 }; 4743 )"; 4744 testRepeatedFriendImport(Code); 4745 } 4746 4747 TEST_P(ASTImporterOptionSpecificTestBase, FriendFunInClassTemplate) { 4748 auto *Code = R"( 4749 template <class T> 4750 struct X { 4751 friend void foo(){} 4752 }; 4753 )"; 4754 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 4755 auto *ToFoo = FirstDeclMatcher<FunctionDecl>().match( 4756 ToTU, functionDecl(hasName("foo"))); 4757 4758 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc"); 4759 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match( 4760 FromTU, functionDecl(hasName("foo"))); 4761 auto *ImportedFoo = Import(FromFoo, Lang_CXX03); 4762 EXPECT_EQ(ImportedFoo, ToFoo); 4763 } 4764 4765 struct DeclContextTest : ASTImporterOptionSpecificTestBase {}; 4766 4767 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) { 4768 Decl *TU = getTuDecl( 4769 R"( 4770 namespace NS { 4771 4772 template <typename T> 4773 struct S {}; 4774 template struct S<int>; 4775 4776 inline namespace INS { 4777 template <typename T> 4778 struct S {}; 4779 template struct S<int>; 4780 } 4781 4782 } 4783 )", Lang_CXX11, "input0.cc"); 4784 auto *NS = FirstDeclMatcher<NamespaceDecl>().match( 4785 TU, namespaceDecl()); 4786 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 4787 TU, classTemplateSpecializationDecl()); 4788 ASSERT_TRUE(NS->containsDecl(Spec)); 4789 4790 NS->removeDecl(Spec); 4791 EXPECT_FALSE(NS->containsDecl(Spec)); 4792 } 4793 4794 TEST_P(DeclContextTest, 4795 removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage) { 4796 Decl *TU = getTuDecl("extern int A; int A;", Lang_CXX03); 4797 auto *A0 = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A"))); 4798 auto *A1 = LastDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A"))); 4799 4800 // Investigate the list. 4801 auto *DC = A0->getDeclContext(); 4802 ASSERT_TRUE(DC->containsDecl(A0)); 4803 ASSERT_TRUE(DC->containsDecl(A1)); 4804 4805 // Investigate the lookup table. 4806 auto *Map = DC->getLookupPtr(); 4807 ASSERT_TRUE(Map); 4808 auto I = Map->find(A0->getDeclName()); 4809 ASSERT_NE(I, Map->end()); 4810 StoredDeclsList &L = I->second; 4811 // The lookup table contains the most recent decl of A. 4812 ASSERT_NE(L.getAsDecl(), A0); 4813 ASSERT_EQ(L.getAsDecl(), A1); 4814 4815 ASSERT_TRUE(L.getAsDecl()); 4816 // Simulate the private function DeclContext::reconcileExternalVisibleStorage. 4817 // We do not have a list with one element. 4818 L.setHasExternalDecls(); 4819 ASSERT_FALSE(L.getAsList()); 4820 auto Results = L.getLookupResult(); 4821 ASSERT_EQ(1u, std::distance(Results.begin(), Results.end())); 4822 4823 // This asserts in the old implementation. 4824 DC->removeDecl(A0); 4825 EXPECT_FALSE(DC->containsDecl(A0)); 4826 4827 // Make sure we do not leave a StoredDeclsList with no entries. 4828 DC->removeDecl(A1); 4829 ASSERT_EQ(Map->find(A1->getDeclName()), Map->end()); 4830 } 4831 4832 struct ImportFunctionTemplateSpecializations 4833 : ASTImporterOptionSpecificTestBase {}; 4834 4835 TEST_P(ImportFunctionTemplateSpecializations, 4836 TUshouldNotContainFunctionTemplateImplicitInstantiation) { 4837 4838 Decl *FromTU = getTuDecl( 4839 R"( 4840 template<class T> 4841 int f() { return 0; } 4842 void foo() { f<int>(); } 4843 )", 4844 Lang_CXX03, "input0.cc"); 4845 4846 // Check that the function template instantiation is NOT the child of the TU. 4847 auto Pattern = translationUnitDecl( 4848 unless(has(functionDecl(hasName("f"), isTemplateInstantiation())))); 4849 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern)); 4850 4851 auto *Foo = FirstDeclMatcher<FunctionDecl>().match( 4852 FromTU, functionDecl(hasName("foo"))); 4853 ASSERT_TRUE(Import(Foo, Lang_CXX03)); 4854 4855 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4856 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern)); 4857 } 4858 4859 TEST_P(ImportFunctionTemplateSpecializations, 4860 TUshouldNotContainFunctionTemplateExplicitInstantiation) { 4861 4862 Decl *FromTU = getTuDecl( 4863 R"( 4864 template<class T> 4865 int f() { return 0; } 4866 template int f<int>(); 4867 )", 4868 Lang_CXX03, "input0.cc"); 4869 4870 // Check that the function template instantiation is NOT the child of the TU. 4871 auto Instantiation = functionDecl(hasName("f"), isTemplateInstantiation()); 4872 auto Pattern = translationUnitDecl(unless(has(Instantiation))); 4873 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern)); 4874 4875 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Instantiation), 4876 Lang_CXX03)); 4877 4878 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4879 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern)); 4880 } 4881 4882 TEST_P(ImportFunctionTemplateSpecializations, 4883 TUshouldContainFunctionTemplateSpecialization) { 4884 4885 Decl *FromTU = getTuDecl( 4886 R"( 4887 template<class T> 4888 int f() { return 0; } 4889 template <> int f<int>() { return 4; } 4890 )", 4891 Lang_CXX03, "input0.cc"); 4892 4893 // Check that the function template specialization is the child of the TU. 4894 auto Specialization = 4895 functionDecl(hasName("f"), isExplicitTemplateSpecialization()); 4896 auto Pattern = translationUnitDecl(has(Specialization)); 4897 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern)); 4898 4899 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Specialization), 4900 Lang_CXX03)); 4901 4902 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4903 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern)); 4904 } 4905 4906 TEST_P(ImportFunctionTemplateSpecializations, 4907 FunctionTemplateSpecializationRedeclChain) { 4908 4909 Decl *FromTU = getTuDecl( 4910 R"( 4911 template<class T> 4912 int f() { return 0; } 4913 template <> int f<int>() { return 4; } 4914 )", 4915 Lang_CXX03, "input0.cc"); 4916 4917 auto Spec = functionDecl(hasName("f"), isExplicitTemplateSpecialization(), 4918 hasParent(translationUnitDecl())); 4919 auto *FromSpecD = FirstDeclMatcher<Decl>().match(FromTU, Spec); 4920 { 4921 auto *TU = FromTU; 4922 auto *SpecD = FromSpecD; 4923 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match( 4924 TU, functionTemplateDecl()); 4925 auto *FirstSpecD = *(TemplateD->spec_begin()); 4926 ASSERT_EQ(SpecD, FirstSpecD); 4927 ASSERT_TRUE(SpecD->getPreviousDecl()); 4928 ASSERT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl()) 4929 ->doesThisDeclarationHaveABody()); 4930 } 4931 4932 ASSERT_TRUE(Import(FromSpecD, Lang_CXX03)); 4933 4934 { 4935 auto *TU = ToAST->getASTContext().getTranslationUnitDecl(); 4936 auto *SpecD = FirstDeclMatcher<Decl>().match(TU, Spec); 4937 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match( 4938 TU, functionTemplateDecl()); 4939 auto *FirstSpecD = *(TemplateD->spec_begin()); 4940 EXPECT_EQ(SpecD, FirstSpecD); 4941 ASSERT_TRUE(SpecD->getPreviousDecl()); 4942 EXPECT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl()) 4943 ->doesThisDeclarationHaveABody()); 4944 } 4945 } 4946 4947 TEST_P(ImportFunctionTemplateSpecializations, 4948 MatchNumberOfFunctionTemplateSpecializations) { 4949 4950 Decl *FromTU = getTuDecl( 4951 R"( 4952 template <typename T> constexpr int f() { return 0; } 4953 template <> constexpr int f<int>() { return 4; } 4954 void foo() { 4955 static_assert(f<char>() == 0, ""); 4956 static_assert(f<int>() == 4, ""); 4957 } 4958 )", 4959 Lang_CXX11, "input0.cc"); 4960 auto *FromD = FirstDeclMatcher<FunctionDecl>().match( 4961 FromTU, functionDecl(hasName("foo"))); 4962 4963 Import(FromD, Lang_CXX11); 4964 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 4965 EXPECT_EQ( 4966 DeclCounter<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))), 4967 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f")))); 4968 } 4969 4970 TEST_P(ASTImporterOptionSpecificTestBase, 4971 ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) { 4972 { 4973 Decl *FromTU = getTuDecl( 4974 R"( 4975 template <typename T> 4976 struct B; 4977 )", 4978 Lang_CXX03, "input0.cc"); 4979 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 4980 FromTU, classTemplateDecl(hasName("B"))); 4981 4982 Import(FromD, Lang_CXX03); 4983 } 4984 4985 { 4986 Decl *FromTU = getTuDecl( 4987 R"( 4988 template <typename T> 4989 struct B { 4990 void f(); 4991 B* b; 4992 }; 4993 )", 4994 Lang_CXX03, "input1.cc"); 4995 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match( 4996 FromTU, functionDecl(hasName("f"))); 4997 Import(FromD, Lang_CXX03); 4998 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match( 4999 FromTU, classTemplateDecl(hasName("B"))); 5000 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03)); 5001 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition()); 5002 5003 // We expect no (ODR) warning during the import. 5004 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 5005 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 5006 } 5007 } 5008 5009 TEST_P(ASTImporterOptionSpecificTestBase, 5010 ImportingTypedefShouldImportTheCompleteType) { 5011 // We already have an incomplete underlying type in the "To" context. 5012 auto Code = 5013 R"( 5014 template <typename T> 5015 struct S { 5016 void foo(); 5017 }; 5018 using U = S<int>; 5019 )"; 5020 Decl *ToTU = getToTuDecl(Code, Lang_CXX11); 5021 auto *ToD = FirstDeclMatcher<TypedefNameDecl>().match(ToTU, 5022 typedefNameDecl(hasName("U"))); 5023 ASSERT_TRUE(ToD->getUnderlyingType()->isIncompleteType()); 5024 5025 // The "From" context has the same typedef, but the underlying type is 5026 // complete this time. 5027 Decl *FromTU = getTuDecl(std::string(Code) + 5028 R"( 5029 void foo(U* u) { 5030 u->foo(); 5031 } 5032 )", Lang_CXX11); 5033 auto *FromD = FirstDeclMatcher<TypedefNameDecl>().match(FromTU, 5034 typedefNameDecl(hasName("U"))); 5035 ASSERT_FALSE(FromD->getUnderlyingType()->isIncompleteType()); 5036 5037 // The imported type should be complete. 5038 auto *ImportedD = cast<TypedefNameDecl>(Import(FromD, Lang_CXX11)); 5039 EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType()); 5040 } 5041 5042 TEST_P(ASTImporterOptionSpecificTestBase, ImportTemplateParameterLists) { 5043 auto Code = 5044 R"( 5045 template<class T> 5046 int f() { return 0; } 5047 template <> int f<int>() { return 4; } 5048 )"; 5049 5050 Decl *FromTU = getTuDecl(Code, Lang_CXX03); 5051 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, 5052 functionDecl(hasName("f"), isExplicitTemplateSpecialization())); 5053 ASSERT_EQ(FromD->getNumTemplateParameterLists(), 1u); 5054 5055 auto *ToD = Import(FromD, Lang_CXX03); 5056 // The template parameter list should exist. 5057 EXPECT_EQ(ToD->getNumTemplateParameterLists(), 1u); 5058 } 5059 5060 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl> 5061 varTemplateDecl; 5062 5063 const internal::VariadicDynCastAllOfMatcher< 5064 Decl, VarTemplatePartialSpecializationDecl> 5065 varTemplatePartialSpecializationDecl; 5066 5067 TEST_P(ASTImporterOptionSpecificTestBase, 5068 FunctionTemplateParameterDeclContext) { 5069 constexpr auto Code = 5070 R"( 5071 template<class T> 5072 void f() {}; 5073 )"; 5074 5075 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 5076 5077 auto *FromD = FirstDeclMatcher<FunctionTemplateDecl>().match( 5078 FromTU, functionTemplateDecl(hasName("f"))); 5079 5080 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(), 5081 FromD->getTemplatedDecl()); 5082 5083 auto *ToD = Import(FromD, Lang_CXX11); 5084 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(), 5085 ToD->getTemplatedDecl()); 5086 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 5087 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0))); 5088 } 5089 5090 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateParameterDeclContext) { 5091 constexpr auto Code = 5092 R"( 5093 template<class T1, class T2> 5094 struct S {}; 5095 template<class T2> 5096 struct S<int, T2> {}; 5097 )"; 5098 5099 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 5100 5101 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 5102 FromTU, classTemplateDecl(hasName("S"))); 5103 auto *FromDPart = 5104 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match( 5105 FromTU, classTemplatePartialSpecializationDecl(hasName("S"))); 5106 5107 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(), 5108 FromD->getTemplatedDecl()); 5109 ASSERT_EQ(FromDPart->getTemplateParameters()->getParam(0)->getDeclContext(), 5110 FromDPart); 5111 5112 auto *ToD = Import(FromD, Lang_CXX11); 5113 auto *ToDPart = Import(FromDPart, Lang_CXX11); 5114 5115 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(), 5116 ToD->getTemplatedDecl()); 5117 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 5118 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0))); 5119 5120 EXPECT_EQ(ToDPart->getTemplateParameters()->getParam(0)->getDeclContext(), 5121 ToDPart); 5122 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 5123 ToDPart, ToDPart->getTemplateParameters()->getParam(0))); 5124 } 5125 5126 TEST_P(ASTImporterOptionSpecificTestBase, 5127 CXXDeductionGuideTemplateParameterDeclContext) { 5128 Decl *FromTU = getTuDecl( 5129 R"( 5130 template <typename T> struct A { 5131 A(T); 5132 }; 5133 A a{(int)0}; 5134 )", 5135 Lang_CXX17, "input.cc"); 5136 // clang-format off 5137 /* 5138 |-ClassTemplateDecl 0x1fe5000 <input.cc:2:7, line:4:7> line:2:36 A 5139 | |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T 5140 | |-CXXRecordDecl 0x1fe4f70 <col:29, line:4:7> line:2:36 struct A definition 5141 5142 |-FunctionTemplateDecl 0x1fe5860 <line:2:7, line:3:12> col:9 implicit <deduction guide for A> 5143 | |-TemplateTypeParmDecl 0x1fe4eb0 <line:2:17, col:26> col:26 referenced typename depth 0 index 0 T 5144 | |-CXXDeductionGuideDecl 0x1fe57a8 <line:3:9, col:12> col:9 implicit <deduction guide for A> 'auto (T) -> A<T>' 5145 | | `-ParmVarDecl 0x1fe56b0 <col:11> col:12 'T' 5146 | `-CXXDeductionGuideDecl 0x20515d8 <col:9, col:12> col:9 implicit used <deduction guide for A> 'auto (int) -> A<int>' 5147 | |-TemplateArgument type 'int' 5148 | | `-BuiltinType 0x20587e0 'int' 5149 | `-ParmVarDecl 0x2051388 <col:11> col:12 'int' 5150 `-FunctionTemplateDecl 0x1fe5a78 <line:2:7, col:36> col:36 implicit <deduction guide for A> 5151 |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T 5152 `-CXXDeductionGuideDecl 0x1fe59c0 <col:36> col:36 implicit <deduction guide for A> 'auto (A<T>) -> A<T>' 5153 `-ParmVarDecl 0x1fe5958 <col:36> col:36 'A<T>' 5154 */ 5155 // clang-format on 5156 auto *FromD1 = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 5157 FromTU, cxxDeductionGuideDecl()); 5158 auto *FromD2 = LastDeclMatcher<CXXDeductionGuideDecl>().match( 5159 FromTU, cxxDeductionGuideDecl()); 5160 5161 NamedDecl *P1 = 5162 FromD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam( 5163 0); 5164 NamedDecl *P2 = 5165 FromD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam( 5166 0); 5167 DeclContext *DC = P1->getDeclContext(); 5168 5169 ASSERT_EQ(P1, P2); 5170 ASSERT_TRUE(DC == FromD1 || DC == FromD2); 5171 5172 auto *ToD1 = Import(FromD1, Lang_CXX17); 5173 auto *ToD2 = Import(FromD2, Lang_CXX17); 5174 ASSERT_TRUE(ToD1 && ToD2); 5175 5176 P1 = ToD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam( 5177 0); 5178 P2 = ToD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam( 5179 0); 5180 DC = P1->getDeclContext(); 5181 5182 EXPECT_EQ(P1, P2); 5183 EXPECT_TRUE(DC == ToD1 || DC == ToD2); 5184 5185 ASTImporterLookupTable *Tbl = SharedStatePtr->getLookupTable(); 5186 if (Tbl->contains(ToD1, P1)) { 5187 EXPECT_FALSE(Tbl->contains(ToD2, P1)); 5188 } else { 5189 EXPECT_TRUE(Tbl->contains(ToD2, P1)); 5190 } 5191 } 5192 5193 TEST_P(ASTImporterOptionSpecificTestBase, RecordVarTemplateDecl) { 5194 Decl *ToTU = getToTuDecl( 5195 R"( 5196 template <class T> 5197 class A { 5198 public: 5199 template <class U> 5200 static constexpr bool X = true; 5201 }; 5202 )", 5203 Lang_CXX14); 5204 5205 auto *ToTUX = FirstDeclMatcher<VarTemplateDecl>().match( 5206 ToTU, varTemplateDecl(hasName("X"))); 5207 Decl *FromTU = getTuDecl( 5208 R"( 5209 template <class T> 5210 class A { 5211 public: 5212 template <class U> 5213 static constexpr bool X = true; 5214 }; 5215 )", 5216 Lang_CXX14, "input1.cc"); 5217 auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match( 5218 FromTU, varTemplateDecl(hasName("X"))); 5219 auto *ToX = Import(FromX, Lang_CXX11); 5220 EXPECT_TRUE(ToX); 5221 EXPECT_EQ(ToTUX, ToX); 5222 } 5223 5224 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateDeclConflict) { 5225 getToTuDecl( 5226 R"( 5227 template <class U> 5228 constexpr int X = 1; 5229 )", 5230 Lang_CXX14); 5231 5232 Decl *FromTU = getTuDecl( 5233 R"( 5234 template <class U> 5235 constexpr int X = 2; 5236 )", 5237 Lang_CXX14, "input1.cc"); 5238 auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match( 5239 FromTU, varTemplateDecl(hasName("X"))); 5240 auto *ToX = Import(FromX, Lang_CXX11); 5241 // FIXME: This import should fail. 5242 EXPECT_TRUE(ToX); 5243 } 5244 5245 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateStaticDefinition) { 5246 Decl *ToTU = getToTuDecl( 5247 R"( 5248 struct A { 5249 template <class U> 5250 static int X; 5251 }; 5252 )", 5253 Lang_CXX14); 5254 auto *ToX = FirstDeclMatcher<VarTemplateDecl>().match( 5255 ToTU, varTemplateDecl(hasName("X"))); 5256 ASSERT_FALSE(ToX->isThisDeclarationADefinition()); 5257 5258 Decl *FromTU = getTuDecl( 5259 R"( 5260 struct A { 5261 template <class U> 5262 static int X; 5263 }; 5264 template <class U> 5265 int A::X = 2; 5266 )", 5267 Lang_CXX14, "input1.cc"); 5268 auto *FromXDef = LastDeclMatcher<VarTemplateDecl>().match( 5269 FromTU, varTemplateDecl(hasName("X"))); 5270 ASSERT_TRUE(FromXDef->isThisDeclarationADefinition()); 5271 auto *ToXDef = Import(FromXDef, Lang_CXX14); 5272 EXPECT_TRUE(ToXDef); 5273 EXPECT_TRUE(ToXDef->isThisDeclarationADefinition()); 5274 EXPECT_EQ(ToXDef->getPreviousDecl(), ToX); 5275 } 5276 5277 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateSpecializationDeclValue) { 5278 Decl *ToTU = getToTuDecl( 5279 R"( 5280 template <class U> 5281 constexpr int X = U::Value; 5282 struct A { static constexpr int Value = 1; }; 5283 constexpr int Y = X<A>; 5284 )", 5285 Lang_CXX14); 5286 5287 auto *ToTUX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match( 5288 ToTU, varTemplateSpecializationDecl(hasName("X"))); 5289 Decl *FromTU = getTuDecl( 5290 R"( 5291 template <class U> 5292 constexpr int X = U::Value; 5293 struct A { static constexpr int Value = 1; }; 5294 constexpr int Y = X<A>; 5295 )", 5296 Lang_CXX14, "input1.cc"); 5297 auto *FromX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match( 5298 FromTU, varTemplateSpecializationDecl(hasName("X"))); 5299 auto *ToX = Import(FromX, Lang_CXX14); 5300 EXPECT_TRUE(ToX); 5301 EXPECT_EQ(ToTUX, ToX); 5302 } 5303 5304 TEST_P(ASTImporterOptionSpecificTestBase, 5305 VarTemplateSpecializationDeclValueConflict) { 5306 getToTuDecl( 5307 R"( 5308 template <class U> 5309 constexpr int X = U::Value; 5310 struct A { static constexpr int Value = 1; }; 5311 constexpr int Y = X<A>; 5312 )", 5313 Lang_CXX14); 5314 5315 Decl *FromTU = getTuDecl( 5316 R"( 5317 template <class U> 5318 constexpr int X = U::Value; 5319 struct A { static constexpr int Value = 2; }; 5320 constexpr int Y = X<A>; 5321 )", 5322 Lang_CXX14, "input1.cc"); 5323 auto *FromX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match( 5324 FromTU, varTemplateSpecializationDecl(hasName("X"))); 5325 auto *ToX = Import(FromX, Lang_CXX14); 5326 EXPECT_FALSE(ToX); 5327 } 5328 5329 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateDeclInlineWithCXX17) { 5330 Decl *FromTU = getTuDecl( 5331 R"( 5332 struct S { 5333 template <unsigned> static constexpr bool X = true; 5334 }; 5335 )", 5336 Lang_CXX17, "input1.cc"); 5337 Decl *FromTU2 = getTuDecl( 5338 R"( 5339 struct S { 5340 template <unsigned> static constexpr bool X = true; 5341 template <typename T> void get() { X<sizeof(T)>; } 5342 }; 5343 template <typename U> U qvariant_cast(const S &v) { return v.get; } 5344 )", 5345 Lang_CXX17, "input2.cc"); 5346 auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match( 5347 FromTU, varTemplateDecl(hasName("X"))); 5348 auto *ToX = Import(FromX, Lang_CXX17); 5349 ASSERT_TRUE(ToX); 5350 auto *FromX2 = FirstDeclMatcher<VarTemplateDecl>().match( 5351 FromTU2, varTemplateDecl(hasName("X"))); 5352 auto *ToX2 = Import(FromX2, Lang_CXX17); 5353 EXPECT_TRUE(ToX2); 5354 EXPECT_EQ(ToX, ToX2); 5355 } 5356 5357 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) { 5358 constexpr auto Code = 5359 R"( 5360 template<class T1, class T2> 5361 int X1; 5362 template<class T2> 5363 int X1<int, T2>; 5364 5365 namespace Ns { 5366 template<class T1, class T2> 5367 int X2; 5368 template<class T2> 5369 int X2<int, T2>; 5370 } 5371 )"; 5372 5373 Decl *FromTU = getTuDecl(Code, Lang_CXX14); 5374 5375 auto *FromD1 = FirstDeclMatcher<VarTemplateDecl>().match( 5376 FromTU, varTemplateDecl(hasName("X1"))); 5377 auto *FromD1Part = 5378 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match( 5379 FromTU, varTemplatePartialSpecializationDecl(hasName("X1"))); 5380 auto *FromD2 = FirstDeclMatcher<VarTemplateDecl>().match( 5381 FromTU, varTemplateDecl(hasName("X2"))); 5382 auto *FromD2Part = 5383 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match( 5384 FromTU, varTemplatePartialSpecializationDecl(hasName("X2"))); 5385 5386 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(), 5387 FromD1->getDeclContext()); 5388 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(), 5389 FromD2->getDeclContext()); 5390 5391 ASSERT_EQ(FromD1Part->getTemplateParameters()->getParam(0)->getDeclContext(), 5392 FromD1Part->getDeclContext()); 5393 // FIXME: VarTemplatePartialSpecializationDecl does not update ("adopt") 5394 // template parameter decl context 5395 // ASSERT_EQ(FromD2Part->getTemplateParameters()->getParam(0)->getDeclContext(), 5396 // FromD2Part->getDeclContext()); 5397 5398 auto *ToD1 = Import(FromD1, Lang_CXX14); 5399 auto *ToD2 = Import(FromD2, Lang_CXX14); 5400 5401 auto *ToD1Part = Import(FromD1Part, Lang_CXX14); 5402 auto *ToD2Part = Import(FromD2Part, Lang_CXX14); 5403 5404 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(), 5405 ToD1->getDeclContext()); 5406 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 5407 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0))); 5408 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(), 5409 ToD2->getDeclContext()); 5410 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 5411 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0))); 5412 5413 EXPECT_EQ(ToD1Part->getTemplateParameters()->getParam(0)->getDeclContext(), 5414 ToD1Part->getDeclContext()); 5415 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 5416 ToD1Part->getDeclContext(), 5417 ToD1Part->getTemplateParameters()->getParam(0))); 5418 // EXPECT_EQ(ToD2Part->getTemplateParameters()->getParam(0)->getDeclContext(), 5419 // ToD2Part->getDeclContext()); 5420 // EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 5421 // ToD2Part->getDeclContext(), 5422 // ToD2Part->getTemplateParameters()->getParam(0))); 5423 (void)ToD2Part; 5424 } 5425 5426 TEST_P(ASTImporterOptionSpecificTestBase, 5427 TypeAliasTemplateParameterDeclContext) { 5428 constexpr auto Code = 5429 R"( 5430 template<class T1, class T2> 5431 struct S {}; 5432 template<class T> using S1 = S<T, int>; 5433 namespace Ns { 5434 template<class T> using S2 = S<T, int>; 5435 } 5436 )"; 5437 5438 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 5439 5440 auto *FromD1 = FirstDeclMatcher<TypeAliasTemplateDecl>().match( 5441 FromTU, typeAliasTemplateDecl(hasName("S1"))); 5442 auto *FromD2 = FirstDeclMatcher<TypeAliasTemplateDecl>().match( 5443 FromTU, typeAliasTemplateDecl(hasName("S2"))); 5444 5445 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(), 5446 FromD1->getDeclContext()); 5447 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(), 5448 FromD2->getDeclContext()); 5449 5450 auto *ToD1 = Import(FromD1, Lang_CXX11); 5451 auto *ToD2 = Import(FromD2, Lang_CXX11); 5452 5453 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(), 5454 ToD1->getDeclContext()); 5455 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 5456 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0))); 5457 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(), 5458 ToD2->getDeclContext()); 5459 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 5460 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0))); 5461 } 5462 5463 TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmType) { 5464 constexpr auto Code = R"( 5465 template <class A1, class... A2> struct A { 5466 using B = A1(A2...); 5467 }; 5468 template struct A<void, char, float, int, short>; 5469 )"; 5470 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp"); 5471 auto *FromClass = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 5472 FromTU, classTemplateSpecializationDecl()); 5473 5474 auto testType = [&](ASTContext &Ctx, const char *Name, 5475 std::optional<unsigned> PackIndex) { 5476 const auto *Subst = selectFirst<SubstTemplateTypeParmType>( 5477 "sttp", match(substTemplateTypeParmType( 5478 hasReplacementType(hasCanonicalType(asString(Name)))) 5479 .bind("sttp"), 5480 Ctx)); 5481 const char *ExpectedTemplateParamName = PackIndex ? "A2" : "A1"; 5482 ASSERT_TRUE(Subst); 5483 ASSERT_EQ(Subst->getReplacedParameter()->getIdentifier()->getName(), 5484 ExpectedTemplateParamName); 5485 ASSERT_EQ(Subst->getPackIndex(), PackIndex); 5486 }; 5487 auto tests = [&](ASTContext &Ctx) { 5488 testType(Ctx, "void", std::nullopt); 5489 testType(Ctx, "char", 3); 5490 testType(Ctx, "float", 2); 5491 testType(Ctx, "int", 1); 5492 testType(Ctx, "short", 0); 5493 }; 5494 5495 tests(FromTU->getASTContext()); 5496 5497 ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11); 5498 tests(ToClass->getASTContext()); 5499 } 5500 5501 const AstTypeMatcher<SubstTemplateTypeParmPackType> 5502 substTemplateTypeParmPackType; 5503 5504 TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmPackType) { 5505 constexpr auto Code = R"( 5506 template<typename ...T> struct D { 5507 template<typename... U> using B = int(int (*...p)(T, U)); 5508 template<typename U1, typename U2> D(B<U1, U2>*); 5509 }; 5510 int f(int(int, int), int(int, int)); 5511 5512 using asd = D<float, double, float>::B<int, long, int>; 5513 )"; 5514 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp"); 5515 auto *FromClass = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 5516 FromTU, classTemplateSpecializationDecl()); 5517 5518 { 5519 ASTContext &FromCtx = FromTU->getASTContext(); 5520 const auto *FromSubstPack = selectFirst<SubstTemplateTypeParmPackType>( 5521 "pack", match(substTemplateTypeParmPackType().bind("pack"), FromCtx)); 5522 5523 ASSERT_TRUE(FromSubstPack); 5524 ASSERT_EQ(FromSubstPack->getIdentifier()->getName(), "T"); 5525 ArrayRef<TemplateArgument> FromArgPack = 5526 FromSubstPack->getArgumentPack().pack_elements(); 5527 ASSERT_EQ(FromArgPack.size(), 3u); 5528 ASSERT_EQ(FromArgPack[0].getAsType(), FromCtx.FloatTy); 5529 ASSERT_EQ(FromArgPack[1].getAsType(), FromCtx.DoubleTy); 5530 ASSERT_EQ(FromArgPack[2].getAsType(), FromCtx.FloatTy); 5531 } 5532 { 5533 // Let's do the import. 5534 ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11); 5535 ASTContext &ToCtx = ToClass->getASTContext(); 5536 5537 const auto *ToSubstPack = selectFirst<SubstTemplateTypeParmPackType>( 5538 "pack", match(substTemplateTypeParmPackType().bind("pack"), ToCtx)); 5539 5540 // Check if it meets the requirements. 5541 ASSERT_TRUE(ToSubstPack); 5542 ASSERT_EQ(ToSubstPack->getIdentifier()->getName(), "T"); 5543 ArrayRef<TemplateArgument> ToArgPack = 5544 ToSubstPack->getArgumentPack().pack_elements(); 5545 ASSERT_EQ(ToArgPack.size(), 3u); 5546 ASSERT_EQ(ToArgPack[0].getAsType(), ToCtx.FloatTy); 5547 ASSERT_EQ(ToArgPack[1].getAsType(), ToCtx.DoubleTy); 5548 ASSERT_EQ(ToArgPack[2].getAsType(), ToCtx.FloatTy); 5549 } 5550 } 5551 5552 struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {}; 5553 5554 TEST_P(ASTImporterLookupTableTest, OneDecl) { 5555 auto *ToTU = getToTuDecl("int a;", Lang_CXX03); 5556 auto *D = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("a"))); 5557 ASTImporterLookupTable LT(*ToTU); 5558 auto Res = LT.lookup(ToTU, D->getDeclName()); 5559 ASSERT_EQ(Res.size(), 1u); 5560 EXPECT_EQ(*Res.begin(), D); 5561 } 5562 5563 static Decl *findInDeclListOfDC(DeclContext *DC, DeclarationName Name) { 5564 for (Decl *D : DC->decls()) { 5565 if (auto *ND = dyn_cast<NamedDecl>(D)) 5566 if (ND->getDeclName() == Name) 5567 return ND; 5568 } 5569 return nullptr; 5570 } 5571 5572 TEST_P(ASTImporterLookupTableTest, 5573 FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup) { 5574 auto *Code = R"( 5575 template <class T> 5576 struct X { 5577 friend void foo(){} 5578 }; 5579 )"; 5580 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 5581 auto *X = FirstDeclMatcher<ClassTemplateDecl>().match( 5582 ToTU, classTemplateDecl(hasName("X"))); 5583 auto *Foo = FirstDeclMatcher<FunctionDecl>().match( 5584 ToTU, functionDecl(hasName("foo"))); 5585 DeclContext *FooDC = Foo->getDeclContext(); 5586 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext(); 5587 ASSERT_EQ(cast<Decl>(FooLexicalDC), X->getTemplatedDecl()); 5588 ASSERT_EQ(cast<Decl>(FooDC), ToTU); 5589 DeclarationName FooName = Foo->getDeclName(); 5590 5591 // Cannot find in the LookupTable of its DC (TUDecl) 5592 SmallVector<NamedDecl *, 2> FoundDecls; 5593 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 5594 EXPECT_EQ(FoundDecls.size(), 0u); 5595 5596 // Cannot find in the LookupTable of its LexicalDC (X) 5597 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 5598 EXPECT_EQ(FoundDecls.size(), 0u); 5599 5600 // Can't find in the list of Decls of the DC. 5601 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr); 5602 5603 // Can't find in the list of Decls of the LexicalDC 5604 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), nullptr); 5605 5606 // ASTImporter specific lookup finds it. 5607 ASTImporterLookupTable LT(*ToTU); 5608 auto Res = LT.lookup(FooDC, Foo->getDeclName()); 5609 ASSERT_EQ(Res.size(), 1u); 5610 EXPECT_EQ(*Res.begin(), Foo); 5611 } 5612 5613 TEST_P(ASTImporterLookupTableTest, 5614 FwdDeclStructShouldBeFoundByImporterSpecificLookup) { 5615 TranslationUnitDecl *ToTU = 5616 getToTuDecl("struct A { struct Foo *p; };", Lang_C99); 5617 auto *Foo = 5618 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("Foo"))); 5619 auto *A = 5620 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A"))); 5621 DeclContext *FooDC = Foo->getDeclContext(); 5622 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext(); 5623 ASSERT_EQ(cast<Decl>(FooLexicalDC), A); 5624 ASSERT_EQ(cast<Decl>(FooDC), ToTU); 5625 DeclarationName FooName = Foo->getDeclName(); 5626 5627 // Cannot find in the LookupTable of its DC (TUDecl). 5628 SmallVector<NamedDecl *, 2> FoundDecls; 5629 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 5630 EXPECT_EQ(FoundDecls.size(), 0u); 5631 5632 // Finds via linear search of its LexicalDC (A). 5633 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls); 5634 EXPECT_EQ(FoundDecls.size(), 1u); 5635 5636 // Can't find in the list of Decls of the DC. 5637 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr); 5638 5639 // Can find in the list of Decls of the LexicalDC. 5640 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), Foo); 5641 5642 // ASTImporter specific lookup finds it. 5643 ASTImporterLookupTable LT(*ToTU); 5644 auto Res = LT.lookup(FooDC, Foo->getDeclName()); 5645 ASSERT_EQ(Res.size(), 1u); 5646 EXPECT_EQ(*Res.begin(), Foo); 5647 } 5648 5649 TEST_P(ASTImporterLookupTableTest, LookupFindsNamesInDifferentDC) { 5650 TranslationUnitDecl *ToTU = 5651 getToTuDecl("int V; struct A { int V; }; struct B { int V; };", Lang_C99); 5652 DeclarationName VName = FirstDeclMatcher<VarDecl>() 5653 .match(ToTU, varDecl(hasName("V"))) 5654 ->getDeclName(); 5655 auto *A = 5656 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A"))); 5657 auto *B = 5658 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("B"))); 5659 5660 ASTImporterLookupTable LT(*ToTU); 5661 5662 auto Res = LT.lookup(cast<DeclContext>(A), VName); 5663 ASSERT_EQ(Res.size(), 1u); 5664 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match( 5665 ToTU, fieldDecl(hasName("V"), 5666 hasParent(recordDecl(hasName("A")))))); 5667 Res = LT.lookup(cast<DeclContext>(B), VName); 5668 ASSERT_EQ(Res.size(), 1u); 5669 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match( 5670 ToTU, fieldDecl(hasName("V"), 5671 hasParent(recordDecl(hasName("B")))))); 5672 Res = LT.lookup(ToTU, VName); 5673 ASSERT_EQ(Res.size(), 1u); 5674 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<VarDecl>().match( 5675 ToTU, varDecl(hasName("V"), 5676 hasParent(translationUnitDecl())))); 5677 } 5678 5679 TEST_P(ASTImporterLookupTableTest, LookupFindsOverloadedNames) { 5680 TranslationUnitDecl *ToTU = getToTuDecl( 5681 R"( 5682 void foo(); 5683 void foo(int); 5684 void foo(int, int); 5685 )", 5686 Lang_CXX03); 5687 5688 ASTImporterLookupTable LT(*ToTU); 5689 auto *F0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl()); 5690 auto *F2 = LastDeclMatcher<FunctionDecl>().match(ToTU, functionDecl()); 5691 DeclarationName Name = F0->getDeclName(); 5692 auto Res = LT.lookup(ToTU, Name); 5693 EXPECT_EQ(Res.size(), 3u); 5694 EXPECT_EQ(Res.count(F0), 1u); 5695 EXPECT_EQ(Res.count(F2), 1u); 5696 } 5697 5698 TEST_P(ASTImporterLookupTableTest, 5699 DifferentOperatorsShouldHaveDifferentResultSet) { 5700 TranslationUnitDecl *ToTU = getToTuDecl( 5701 R"( 5702 struct X{}; 5703 void operator+(X, X); 5704 void operator-(X, X); 5705 )", 5706 Lang_CXX03); 5707 5708 ASTImporterLookupTable LT(*ToTU); 5709 auto *FPlus = FirstDeclMatcher<FunctionDecl>().match( 5710 ToTU, functionDecl(hasOverloadedOperatorName("+"))); 5711 auto *FMinus = FirstDeclMatcher<FunctionDecl>().match( 5712 ToTU, functionDecl(hasOverloadedOperatorName("-"))); 5713 DeclarationName NamePlus = FPlus->getDeclName(); 5714 auto ResPlus = LT.lookup(ToTU, NamePlus); 5715 EXPECT_EQ(ResPlus.size(), 1u); 5716 EXPECT_EQ(ResPlus.count(FPlus), 1u); 5717 EXPECT_EQ(ResPlus.count(FMinus), 0u); 5718 DeclarationName NameMinus = FMinus->getDeclName(); 5719 auto ResMinus = LT.lookup(ToTU, NameMinus); 5720 EXPECT_EQ(ResMinus.size(), 1u); 5721 EXPECT_EQ(ResMinus.count(FMinus), 1u); 5722 EXPECT_EQ(ResMinus.count(FPlus), 0u); 5723 EXPECT_NE(*ResMinus.begin(), *ResPlus.begin()); 5724 } 5725 5726 TEST_P(ASTImporterLookupTableTest, LookupDeclNamesFromDifferentTUs) { 5727 TranslationUnitDecl *ToTU = getToTuDecl( 5728 R"( 5729 struct X {}; 5730 void operator+(X, X); 5731 )", 5732 Lang_CXX03); 5733 auto *ToPlus = FirstDeclMatcher<FunctionDecl>().match( 5734 ToTU, functionDecl(hasOverloadedOperatorName("+"))); 5735 5736 Decl *FromTU = getTuDecl( 5737 R"( 5738 struct X {}; 5739 void operator+(X, X); 5740 )", 5741 Lang_CXX03); 5742 auto *FromPlus = FirstDeclMatcher<FunctionDecl>().match( 5743 FromTU, functionDecl(hasOverloadedOperatorName("+"))); 5744 5745 // FromPlus have a different TU, thus its DeclarationName is different too. 5746 ASSERT_NE(ToPlus->getDeclName(), FromPlus->getDeclName()); 5747 5748 ASTImporterLookupTable LT(*ToTU); 5749 auto Res = LT.lookup(ToTU, ToPlus->getDeclName()); 5750 ASSERT_EQ(Res.size(), 1u); 5751 EXPECT_EQ(*Res.begin(), ToPlus); 5752 5753 // FromPlus have a different TU, thus its DeclarationName is different too. 5754 Res = LT.lookup(ToTU, FromPlus->getDeclName()); 5755 ASSERT_EQ(Res.size(), 0u); 5756 } 5757 5758 TEST_P(ASTImporterLookupTableTest, 5759 LookupFindsFwdFriendClassDeclWithElaboratedType) { 5760 TranslationUnitDecl *ToTU = getToTuDecl( 5761 R"( 5762 class Y { friend class F; }; 5763 )", 5764 Lang_CXX03); 5765 5766 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent. 5767 // So we must dig up the underlying CXXRecordDecl. 5768 ASTImporterLookupTable LT(*ToTU); 5769 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 5770 const RecordDecl *RD = getRecordDeclOfFriend(FriendD); 5771 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match( 5772 ToTU, cxxRecordDecl(hasName("Y"))); 5773 5774 DeclarationName Name = RD->getDeclName(); 5775 auto Res = LT.lookup(ToTU, Name); 5776 EXPECT_EQ(Res.size(), 1u); 5777 EXPECT_EQ(*Res.begin(), RD); 5778 5779 Res = LT.lookup(Y, Name); 5780 EXPECT_EQ(Res.size(), 0u); 5781 } 5782 5783 TEST_P(ASTImporterLookupTableTest, 5784 LookupFindsFwdFriendClassDeclWithUnelaboratedType) { 5785 TranslationUnitDecl *ToTU = getToTuDecl( 5786 R"( 5787 class F; 5788 class Y { friend F; }; 5789 )", 5790 Lang_CXX11); 5791 5792 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent. 5793 // So we must dig up the underlying CXXRecordDecl. 5794 ASTImporterLookupTable LT(*ToTU); 5795 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 5796 const RecordDecl *RD = getRecordDeclOfFriend(FriendD); 5797 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, cxxRecordDecl(hasName("Y"))); 5798 5799 DeclarationName Name = RD->getDeclName(); 5800 auto Res = LT.lookup(ToTU, Name); 5801 EXPECT_EQ(Res.size(), 1u); 5802 EXPECT_EQ(*Res.begin(), RD); 5803 5804 Res = LT.lookup(Y, Name); 5805 EXPECT_EQ(Res.size(), 0u); 5806 } 5807 5808 TEST_P(ASTImporterLookupTableTest, 5809 LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert) { 5810 TranslationUnitDecl *ToTU = getToTuDecl( 5811 R"( 5812 class F; 5813 using alias_of_f = F; 5814 class Y { friend alias_of_f; }; 5815 )", 5816 Lang_CXX11); 5817 5818 // ASTImporterLookupTable constructor handles using declarations correctly, 5819 // no assert is expected. 5820 ASTImporterLookupTable LT(*ToTU); 5821 5822 auto *Alias = FirstDeclMatcher<TypeAliasDecl>().match( 5823 ToTU, typeAliasDecl(hasName("alias_of_f"))); 5824 DeclarationName Name = Alias->getDeclName(); 5825 auto Res = LT.lookup(ToTU, Name); 5826 EXPECT_EQ(Res.count(Alias), 1u); 5827 } 5828 5829 TEST_P(ASTImporterLookupTableTest, 5830 LookupFindsFriendClassDeclWithUsingTypeDoesNotAssert) { 5831 TranslationUnitDecl *ToTU = getToTuDecl( 5832 R"( 5833 namespace a { 5834 namespace b { class InnerClass; } 5835 using b::InnerClass; 5836 } 5837 class B { 5838 friend a::InnerClass; 5839 }; 5840 )", 5841 Lang_CXX11); 5842 5843 // ASTImporterLookupTable constructor handles friend with using-type without 5844 // asserts. 5845 ASTImporterLookupTable LT(*ToTU); 5846 5847 auto *Using = FirstDeclMatcher<UsingDecl>().match( 5848 ToTU, usingDecl(hasName("InnerClass"))); 5849 DeclarationName Name = Using->getDeclName(); 5850 auto Res = LT.lookup(ToTU, Name); 5851 EXPECT_EQ(Res.size(), 0u); 5852 auto *NsA = FirstDeclMatcher<NamespaceDecl>().match( 5853 ToTU, namespaceDecl(hasName("a"))); 5854 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match( 5855 ToTU, cxxRecordDecl(hasName("B"))); 5856 auto Res1 = LT.lookup(NsA, Name); 5857 EXPECT_EQ(Res1.count(Using), 1u); 5858 auto Res2 = LT.lookup(RecordB, Name); 5859 EXPECT_EQ(Res2.size(), 0u); 5860 } 5861 5862 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassTemplateDecl) { 5863 TranslationUnitDecl *ToTU = getToTuDecl( 5864 R"( 5865 class Y { template <class T> friend class F; }; 5866 )", 5867 Lang_CXX03); 5868 5869 ASTImporterLookupTable LT(*ToTU); 5870 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match( 5871 ToTU, classTemplateDecl(hasName("F"))); 5872 DeclarationName Name = F->getDeclName(); 5873 auto Res = LT.lookup(ToTU, Name); 5874 EXPECT_EQ(Res.size(), 2u); 5875 EXPECT_EQ(Res.count(F), 1u); 5876 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 5877 } 5878 5879 TEST_P(ASTImporterLookupTableTest, DependentFriendClass) { 5880 TranslationUnitDecl *ToTU = getToTuDecl( 5881 R"( 5882 template <typename T> 5883 class F; 5884 5885 template <typename T> 5886 class Y { 5887 friend class F<T>; 5888 }; 5889 )", 5890 Lang_CXX03); 5891 5892 ASTImporterLookupTable LT(*ToTU); 5893 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match( 5894 ToTU, classTemplateDecl(hasName("F"))); 5895 DeclarationName Name = F->getDeclName(); 5896 auto Res = LT.lookup(ToTU, Name); 5897 EXPECT_EQ(Res.size(), 2u); 5898 EXPECT_EQ(Res.count(F), 1u); 5899 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 5900 } 5901 5902 TEST_P(ASTImporterLookupTableTest, FriendClassTemplateSpecialization) { 5903 TranslationUnitDecl *ToTU = getToTuDecl( 5904 R"( 5905 template <typename T> 5906 class F; 5907 5908 class Y { 5909 friend class F<int>; 5910 }; 5911 )", 5912 Lang_CXX03); 5913 5914 ASTImporterLookupTable LT(*ToTU); 5915 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match( 5916 ToTU, classTemplateDecl(hasName("F"))); 5917 DeclarationName Name = F->getDeclName(); 5918 auto Res = LT.lookup(ToTU, Name); 5919 ASSERT_EQ(Res.size(), 3u); 5920 EXPECT_EQ(Res.count(F), 1u); 5921 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 5922 EXPECT_EQ(Res.count(*F->spec_begin()), 1u); 5923 } 5924 5925 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionDecl) { 5926 TranslationUnitDecl *ToTU = getToTuDecl( 5927 R"( 5928 class Y { friend void F(); }; 5929 )", 5930 Lang_CXX03); 5931 5932 ASTImporterLookupTable LT(*ToTU); 5933 auto *F = 5934 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("F"))); 5935 DeclarationName Name = F->getDeclName(); 5936 auto Res = LT.lookup(ToTU, Name); 5937 EXPECT_EQ(Res.size(), 1u); 5938 EXPECT_EQ(*Res.begin(), F); 5939 } 5940 5941 TEST_P(ASTImporterLookupTableTest, 5942 LookupFindsDeclsInClassTemplateSpecialization) { 5943 TranslationUnitDecl *ToTU = getToTuDecl( 5944 R"( 5945 template <typename T> 5946 struct X { 5947 int F; 5948 }; 5949 void foo() { 5950 X<char> xc; 5951 } 5952 )", 5953 Lang_CXX03); 5954 5955 ASTImporterLookupTable LT(*ToTU); 5956 5957 auto *Template = FirstDeclMatcher<ClassTemplateDecl>().match( 5958 ToTU, classTemplateDecl(hasName("X"))); 5959 auto *FieldInTemplate = FirstDeclMatcher<FieldDecl>().match( 5960 ToTU, 5961 fieldDecl(hasParent(cxxRecordDecl(hasParent(classTemplateDecl()))))); 5962 5963 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 5964 ToTU, classTemplateSpecializationDecl(hasName("X"))); 5965 FieldDecl *FieldInSpec = *Spec->field_begin(); 5966 ASSERT_TRUE(FieldInSpec); 5967 5968 DeclarationName Name = FieldInSpec->getDeclName(); 5969 auto TemplateDC = cast<DeclContext>(Template->getTemplatedDecl()); 5970 5971 SmallVector<NamedDecl *, 2> FoundDecls; 5972 TemplateDC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); 5973 EXPECT_EQ(FoundDecls.size(), 1u); 5974 EXPECT_EQ(FoundDecls[0], FieldInTemplate); 5975 5976 auto Res = LT.lookup(TemplateDC, Name); 5977 ASSERT_EQ(Res.size(), 1u); 5978 EXPECT_EQ(*Res.begin(), FieldInTemplate); 5979 5980 cast<DeclContext>(Spec)->getRedeclContext()->localUncachedLookup(Name, 5981 FoundDecls); 5982 EXPECT_EQ(FoundDecls.size(), 1u); 5983 EXPECT_EQ(FoundDecls[0], FieldInSpec); 5984 5985 Res = LT.lookup(cast<DeclContext>(Spec), Name); 5986 ASSERT_EQ(Res.size(), 1u); 5987 EXPECT_EQ(*Res.begin(), FieldInSpec); 5988 } 5989 5990 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionTemplateDecl) { 5991 TranslationUnitDecl *ToTU = getToTuDecl( 5992 R"( 5993 class Y { template <class T> friend void F(); }; 5994 )", 5995 Lang_CXX03); 5996 5997 ASTImporterLookupTable LT(*ToTU); 5998 auto *F = FirstDeclMatcher<FunctionTemplateDecl>().match( 5999 ToTU, functionTemplateDecl(hasName("F"))); 6000 DeclarationName Name = F->getDeclName(); 6001 auto Res = LT.lookup(ToTU, Name); 6002 EXPECT_EQ(Res.size(), 2u); 6003 EXPECT_EQ(Res.count(F), 1u); 6004 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u); 6005 } 6006 6007 TEST_P(ASTImporterLookupTableTest, MultipleBefriendingClasses) { 6008 TranslationUnitDecl *ToTU = getToTuDecl( 6009 R"( 6010 struct X; 6011 struct A { 6012 friend struct X; 6013 }; 6014 struct B { 6015 friend struct X; 6016 }; 6017 )", 6018 Lang_CXX03); 6019 6020 ASTImporterLookupTable LT(*ToTU); 6021 auto *X = FirstDeclMatcher<CXXRecordDecl>().match( 6022 ToTU, cxxRecordDecl(hasName("X"))); 6023 auto *FriendD0 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 6024 auto *FriendD1 = LastDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 6025 const RecordDecl *RD0 = getRecordDeclOfFriend(FriendD0); 6026 const RecordDecl *RD1 = getRecordDeclOfFriend(FriendD1); 6027 ASSERT_EQ(RD0, RD1); 6028 ASSERT_EQ(RD1, X); 6029 6030 DeclarationName Name = X->getDeclName(); 6031 auto Res = LT.lookup(ToTU, Name); 6032 EXPECT_EQ(Res.size(), 1u); 6033 EXPECT_EQ(*Res.begin(), X); 6034 } 6035 6036 TEST_P(ASTImporterLookupTableTest, EnumConstantDecl) { 6037 TranslationUnitDecl *ToTU = getToTuDecl( 6038 R"( 6039 enum E { 6040 A, 6041 B 6042 }; 6043 )", 6044 Lang_C99); 6045 6046 ASTImporterLookupTable LT(*ToTU); 6047 auto *E = FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(hasName("E"))); 6048 auto *A = FirstDeclMatcher<EnumConstantDecl>().match( 6049 ToTU, enumConstantDecl(hasName("A"))); 6050 6051 DeclarationName Name = A->getDeclName(); 6052 // Redecl context is the TU. 6053 ASSERT_EQ(E->getRedeclContext(), ToTU); 6054 6055 SmallVector<NamedDecl *, 2> FoundDecls; 6056 // Normal lookup finds in the DC. 6057 E->localUncachedLookup(Name, FoundDecls); 6058 EXPECT_EQ(FoundDecls.size(), 1u); 6059 6060 // Normal lookup finds in the Redecl context. 6061 ToTU->localUncachedLookup(Name, FoundDecls); 6062 EXPECT_EQ(FoundDecls.size(), 1u); 6063 6064 // Import specific lookup finds in the DC. 6065 auto Res = LT.lookup(E, Name); 6066 ASSERT_EQ(Res.size(), 1u); 6067 EXPECT_EQ(*Res.begin(), A); 6068 6069 // Import specific lookup finds in the Redecl context. 6070 Res = LT.lookup(ToTU, Name); 6071 ASSERT_EQ(Res.size(), 1u); 6072 EXPECT_EQ(*Res.begin(), A); 6073 } 6074 6075 TEST_P(ASTImporterLookupTableTest, LookupSearchesInActualNamespaceOnly) { 6076 TranslationUnitDecl *ToTU = getToTuDecl( 6077 R"( 6078 namespace N { 6079 int A; 6080 } 6081 namespace N { 6082 } 6083 )", 6084 Lang_CXX03); 6085 auto *N1 = FirstDeclMatcher<NamespaceDecl>().match( 6086 ToTU, namespaceDecl(hasName("N"))); 6087 auto *N2 = 6088 LastDeclMatcher<NamespaceDecl>().match(ToTU, namespaceDecl(hasName("N"))); 6089 auto *A = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("A"))); 6090 DeclarationName Name = A->getDeclName(); 6091 6092 ASTImporterLookupTable LT(*ToTU); 6093 auto Res = LT.lookup(N1, Name); 6094 ASSERT_EQ(Res.size(), 1u); 6095 EXPECT_EQ(*Res.begin(), A); 6096 EXPECT_TRUE(LT.lookup(N2, Name).empty()); 6097 } 6098 6099 TEST_P(ASTImporterOptionSpecificTestBase, 6100 RedeclChainShouldBeCorrectAmongstNamespaces) { 6101 Decl *FromTU = getTuDecl( 6102 R"( 6103 namespace NS { 6104 struct X; 6105 struct Y { 6106 static const int I = 3; 6107 }; 6108 } 6109 namespace NS { 6110 struct X { // <--- To be imported 6111 void method(int i = Y::I) {} 6112 int f; 6113 }; 6114 } 6115 )", 6116 Lang_CXX03); 6117 auto *FromFwd = FirstDeclMatcher<CXXRecordDecl>().match( 6118 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit()))); 6119 auto *FromDef = LastDeclMatcher<CXXRecordDecl>().match( 6120 FromTU, 6121 cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit()))); 6122 ASSERT_NE(FromFwd, FromDef); 6123 ASSERT_FALSE(FromFwd->isThisDeclarationADefinition()); 6124 ASSERT_TRUE(FromDef->isThisDeclarationADefinition()); 6125 ASSERT_EQ(FromFwd->getCanonicalDecl(), FromDef->getCanonicalDecl()); 6126 6127 auto *ToDef = cast_or_null<CXXRecordDecl>(Import(FromDef, Lang_CXX03)); 6128 auto *ToFwd = cast_or_null<CXXRecordDecl>(Import(FromFwd, Lang_CXX03)); 6129 EXPECT_NE(ToFwd, ToDef); 6130 EXPECT_FALSE(ToFwd->isThisDeclarationADefinition()); 6131 EXPECT_TRUE(ToDef->isThisDeclarationADefinition()); 6132 EXPECT_EQ(ToFwd->getCanonicalDecl(), ToDef->getCanonicalDecl()); 6133 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 6134 // We expect no (ODR) warning during the import. 6135 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings()); 6136 } 6137 6138 struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {}; 6139 6140 TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) { 6141 Decl *ToTU = getToTuDecl( 6142 R"( 6143 class X { 6144 template <typename T> friend void foo(); 6145 }; 6146 )", 6147 Lang_CXX03); 6148 auto *Friend = FirstDeclMatcher<FunctionTemplateDecl>().match( 6149 ToTU, functionTemplateDecl(hasName("foo"))); 6150 6151 Decl *FromTU = getTuDecl( 6152 R"( 6153 template <typename T> void foo(); 6154 )", 6155 Lang_CXX03); 6156 auto *FromFoo = FirstDeclMatcher<FunctionTemplateDecl>().match( 6157 FromTU, functionTemplateDecl(hasName("foo"))); 6158 auto *Imported = Import(FromFoo, Lang_CXX03); 6159 6160 EXPECT_EQ(Imported->getPreviousDecl(), Friend); 6161 } 6162 6163 TEST_P(ImportFriendFunctionTemplates, ImportFriendFunctionInsideClassTemplate) { 6164 Decl *From, *To; 6165 std::tie(From, To) = getImportedDecl( 6166 R"( 6167 template <typename T> struct X { 6168 template <typename U> friend void f(); 6169 }; 6170 )", 6171 Lang_CXX03, "", Lang_CXX03, "X"); 6172 6173 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(From, friendDecl()); 6174 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(To, friendDecl()); 6175 6176 EXPECT_TRUE(FromFriend == 6177 LastDeclMatcher<FriendDecl>().match(From, friendDecl())); 6178 EXPECT_TRUE(ToFriend == 6179 LastDeclMatcher<FriendDecl>().match(To, friendDecl())); 6180 6181 auto *FromDecl = FromFriend->getFriendDecl(); 6182 auto *FromDC = FromFriend->getDeclContext(); 6183 auto *FromLexicalDC = FromFriend->getLexicalDeclContext(); 6184 6185 EXPECT_TRUE(FromDC->containsDecl(FromFriend)); 6186 EXPECT_FALSE(FromDC->containsDecl(FromDecl)); 6187 EXPECT_TRUE(FromLexicalDC->containsDecl(FromFriend)); 6188 EXPECT_FALSE(FromLexicalDC->containsDecl(FromDecl)); 6189 6190 auto *ToDecl = ToFriend->getFriendDecl(); 6191 auto *ToDC = ToFriend->getDeclContext(); 6192 auto *ToLexicalDC = ToFriend->getLexicalDeclContext(); 6193 6194 EXPECT_TRUE(ToDC->containsDecl(ToFriend)); 6195 EXPECT_FALSE(ToDC->containsDecl(ToDecl)); 6196 EXPECT_TRUE(ToLexicalDC->containsDecl(ToFriend)); 6197 EXPECT_FALSE(ToLexicalDC->containsDecl(ToDecl)); 6198 } 6199 6200 struct ASTImporterWithFakeErrors : ASTImporter { 6201 using ASTImporter::ASTImporter; 6202 bool returnWithErrorInTest() override { return true; } 6203 }; 6204 6205 struct ErrorHandlingTest : ASTImporterOptionSpecificTestBase { 6206 ErrorHandlingTest() { 6207 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 6208 ASTContext &FromContext, FileManager &FromFileManager, 6209 bool MinimalImport, 6210 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 6211 return new ASTImporterWithFakeErrors(ToContext, ToFileManager, 6212 FromContext, FromFileManager, 6213 MinimalImport, SharedState); 6214 }; 6215 } 6216 // In this test we purposely report an error (UnsupportedConstruct) when 6217 // importing the below stmt. 6218 static constexpr auto* ErroneousStmt = R"( asm(""); )"; 6219 }; 6220 6221 // Check a case when no new AST node is created in the AST before encountering 6222 // the error. 6223 TEST_P(ErrorHandlingTest, ErrorHappensBeforeCreatingANewNode) { 6224 TranslationUnitDecl *ToTU = getToTuDecl( 6225 R"( 6226 template <typename T> 6227 class X {}; 6228 template <> 6229 class X<int> { int a; }; 6230 )", 6231 Lang_CXX03); 6232 TranslationUnitDecl *FromTU = getTuDecl( 6233 R"( 6234 template <typename T> 6235 class X {}; 6236 template <> 6237 class X<int> { double b; }; 6238 )", 6239 Lang_CXX03); 6240 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 6241 FromTU, classTemplateSpecializationDecl(hasName("X"))); 6242 ClassTemplateSpecializationDecl *ImportedSpec = Import(FromSpec, Lang_CXX03); 6243 EXPECT_FALSE(ImportedSpec); 6244 6245 // The original Decl is kept, no new decl is created. 6246 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match( 6247 ToTU, classTemplateSpecializationDecl(hasName("X"))), 6248 1u); 6249 6250 // But an error is set to the counterpart in the "from" context. 6251 ASTImporter *Importer = findFromTU(FromSpec)->Importer.get(); 6252 std::optional<ASTImportError> OptErr = 6253 Importer->getImportDeclErrorIfAny(FromSpec); 6254 ASSERT_TRUE(OptErr); 6255 EXPECT_EQ(OptErr->Error, ASTImportError::NameConflict); 6256 } 6257 6258 // Check a case when a new AST node is created but not linked to the AST before 6259 // encountering the error. 6260 TEST_P(ErrorHandlingTest, 6261 ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST) { 6262 TranslationUnitDecl *FromTU = getTuDecl( 6263 std::string("void foo() { ") + ErroneousStmt + " }", Lang_CXX03); 6264 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match( 6265 FromTU, functionDecl(hasName("foo"))); 6266 6267 FunctionDecl *ImportedFoo = Import(FromFoo, Lang_CXX03); 6268 EXPECT_FALSE(ImportedFoo); 6269 6270 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 6271 // Created, but not linked. 6272 EXPECT_EQ( 6273 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("foo"))), 6274 0u); 6275 6276 ASTImporter *Importer = findFromTU(FromFoo)->Importer.get(); 6277 std::optional<ASTImportError> OptErr = 6278 Importer->getImportDeclErrorIfAny(FromFoo); 6279 ASSERT_TRUE(OptErr); 6280 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6281 } 6282 6283 // Check a case when a new AST node is created and linked to the AST before 6284 // encountering the error. The error is set for the counterpart of the nodes in 6285 // the "from" context. 6286 TEST_P(ErrorHandlingTest, ErrorHappensAfterNodeIsCreatedAndLinked) { 6287 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 6288 void f(); 6289 void f() { )") + ErroneousStmt + R"( } 6290 )", 6291 Lang_CXX03); 6292 auto *FromProto = FirstDeclMatcher<FunctionDecl>().match( 6293 FromTU, functionDecl(hasName("f"))); 6294 auto *FromDef = 6295 LastDeclMatcher<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))); 6296 FunctionDecl *ImportedProto = Import(FromProto, Lang_CXX03); 6297 EXPECT_FALSE(ImportedProto); // Could not import. 6298 // However, we created two nodes in the AST. 1) the fwd decl 2) the 6299 // definition. The definition is not added to its DC, but the fwd decl is 6300 // there. 6301 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 6302 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))), 6303 1u); 6304 // Match the fwd decl. 6305 auto *ToProto = 6306 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))); 6307 EXPECT_TRUE(ToProto); 6308 // An error is set to the counterpart in the "from" context both for the fwd 6309 // decl and the definition. 6310 ASTImporter *Importer = findFromTU(FromProto)->Importer.get(); 6311 std::optional<ASTImportError> OptErr = 6312 Importer->getImportDeclErrorIfAny(FromProto); 6313 ASSERT_TRUE(OptErr); 6314 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6315 OptErr = Importer->getImportDeclErrorIfAny(FromDef); 6316 ASSERT_TRUE(OptErr); 6317 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6318 } 6319 6320 // An error should be set for a class if we cannot import one member. 6321 TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) { 6322 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 6323 class X { 6324 void f() { )") + ErroneousStmt + R"( } // This member has the error 6325 // during import. 6326 void ok(); // The error should not prevent importing this. 6327 }; // An error will be set for X too. 6328 )", 6329 Lang_CXX03); 6330 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 6331 FromTU, cxxRecordDecl(hasName("X"))); 6332 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 6333 6334 // An error is set for X. 6335 EXPECT_FALSE(ImportedX); 6336 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 6337 std::optional<ASTImportError> OptErr = 6338 Importer->getImportDeclErrorIfAny(FromX); 6339 ASSERT_TRUE(OptErr); 6340 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6341 6342 // An error is set for f(). 6343 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match( 6344 FromTU, cxxMethodDecl(hasName("f"))); 6345 OptErr = Importer->getImportDeclErrorIfAny(FromF); 6346 ASSERT_TRUE(OptErr); 6347 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6348 // And any subsequent import should fail. 6349 CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX03); 6350 EXPECT_FALSE(ImportedF); 6351 6352 // There is an error set for the other member too. 6353 auto *FromOK = FirstDeclMatcher<CXXMethodDecl>().match( 6354 FromTU, cxxMethodDecl(hasName("ok"))); 6355 OptErr = Importer->getImportDeclErrorIfAny(FromOK); 6356 EXPECT_TRUE(OptErr); 6357 // Cannot import the other member. 6358 CXXMethodDecl *ImportedOK = Import(FromOK, Lang_CXX03); 6359 EXPECT_FALSE(ImportedOK); 6360 } 6361 6362 // Check that an error propagates to the dependent AST nodes. 6363 // In the below code it means that an error in X should propagate to A. 6364 // And even to F since the containing A is erroneous. 6365 // And to all AST nodes which we visit during the import process which finally 6366 // ends up in a failure (in the error() function). 6367 TEST_P(ErrorHandlingTest, ErrorPropagatesThroughImportCycles) { 6368 Decl *FromTU = getTuDecl(std::string(R"( 6369 namespace NS { 6370 class A { 6371 template <int I> class F {}; 6372 class X { 6373 template <int I> friend class F; 6374 void error() { )") + 6375 ErroneousStmt + R"( } 6376 }; 6377 }; 6378 6379 class B {}; 6380 } // NS 6381 )", 6382 Lang_CXX03, "input0.cc"); 6383 6384 auto *FromFRD = FirstDeclMatcher<CXXRecordDecl>().match( 6385 FromTU, cxxRecordDecl(hasName("F"), isDefinition())); 6386 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 6387 FromTU, cxxRecordDecl(hasName("A"), isDefinition())); 6388 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match( 6389 FromTU, cxxRecordDecl(hasName("B"), isDefinition())); 6390 auto *FromNS = FirstDeclMatcher<NamespaceDecl>().match( 6391 FromTU, namespaceDecl(hasName("NS"))); 6392 6393 // Start by importing the templated CXXRecordDecl of F. 6394 // Import fails for that. 6395 EXPECT_FALSE(Import(FromFRD, Lang_CXX03)); 6396 // Import fails for A. 6397 EXPECT_FALSE(Import(FromA, Lang_CXX03)); 6398 // But we should be able to import the independent B. 6399 EXPECT_TRUE(Import(FromB, Lang_CXX03)); 6400 // And the namespace. 6401 EXPECT_TRUE(Import(FromNS, Lang_CXX03)); 6402 6403 // An error is set to the templated CXXRecordDecl of F. 6404 ASTImporter *Importer = findFromTU(FromFRD)->Importer.get(); 6405 std::optional<ASTImportError> OptErr = 6406 Importer->getImportDeclErrorIfAny(FromFRD); 6407 EXPECT_TRUE(OptErr); 6408 6409 // An error is set to A. 6410 OptErr = Importer->getImportDeclErrorIfAny(FromA); 6411 EXPECT_TRUE(OptErr); 6412 6413 // There is no error set to B. 6414 OptErr = Importer->getImportDeclErrorIfAny(FromB); 6415 EXPECT_FALSE(OptErr); 6416 6417 // There is no error set to NS. 6418 OptErr = Importer->getImportDeclErrorIfAny(FromNS); 6419 EXPECT_FALSE(OptErr); 6420 6421 // Check some of those decls whose ancestor is X, they all should have an 6422 // error set if we visited them during an import process which finally failed. 6423 // These decls are part of a cycle in an ImportPath. 6424 // There would not be any error set for these decls if we hadn't follow the 6425 // ImportPaths and the cycles. 6426 OptErr = Importer->getImportDeclErrorIfAny( 6427 FirstDeclMatcher<ClassTemplateDecl>().match( 6428 FromTU, classTemplateDecl(hasName("F")))); 6429 // An error is set to the 'F' ClassTemplateDecl. 6430 EXPECT_TRUE(OptErr); 6431 // An error is set to the FriendDecl. 6432 OptErr = Importer->getImportDeclErrorIfAny( 6433 FirstDeclMatcher<FriendDecl>().match( 6434 FromTU, friendDecl())); 6435 EXPECT_TRUE(OptErr); 6436 // An error is set to the implicit class of A. 6437 OptErr = 6438 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match( 6439 FromTU, cxxRecordDecl(hasName("A"), isImplicit()))); 6440 EXPECT_TRUE(OptErr); 6441 // An error is set to the implicit class of X. 6442 OptErr = 6443 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match( 6444 FromTU, cxxRecordDecl(hasName("X"), isImplicit()))); 6445 EXPECT_TRUE(OptErr); 6446 } 6447 6448 TEST_P(ErrorHandlingTest, ErrorIsNotPropagatedFromMemberToNamespace) { 6449 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 6450 namespace X { 6451 void f() { )") + ErroneousStmt + R"( } // This member has the error 6452 // during import. 6453 void ok(); // The error should not prevent importing this. 6454 }; // An error will be set for X too. 6455 )", 6456 Lang_CXX03); 6457 auto *FromX = FirstDeclMatcher<NamespaceDecl>().match( 6458 FromTU, namespaceDecl(hasName("X"))); 6459 NamespaceDecl *ImportedX = Import(FromX, Lang_CXX03); 6460 6461 // There is no error set for X. 6462 EXPECT_TRUE(ImportedX); 6463 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 6464 std::optional<ASTImportError> OptErr = 6465 Importer->getImportDeclErrorIfAny(FromX); 6466 ASSERT_FALSE(OptErr); 6467 6468 // An error is set for f(). 6469 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 6470 FromTU, functionDecl(hasName("f"))); 6471 OptErr = Importer->getImportDeclErrorIfAny(FromF); 6472 ASSERT_TRUE(OptErr); 6473 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6474 // And any subsequent import should fail. 6475 FunctionDecl *ImportedF = Import(FromF, Lang_CXX03); 6476 EXPECT_FALSE(ImportedF); 6477 6478 // There is no error set for ok(). 6479 auto *FromOK = FirstDeclMatcher<FunctionDecl>().match( 6480 FromTU, functionDecl(hasName("ok"))); 6481 OptErr = Importer->getImportDeclErrorIfAny(FromOK); 6482 EXPECT_FALSE(OptErr); 6483 // And we should be able to import. 6484 FunctionDecl *ImportedOK = Import(FromOK, Lang_CXX03); 6485 EXPECT_TRUE(ImportedOK); 6486 } 6487 6488 TEST_P(ErrorHandlingTest, ODRViolationWithinTypedefDecls) { 6489 // Importing `z` should fail - instead of crashing - due to an ODR violation. 6490 // The `bar::e` typedef sets it's DeclContext after the import is done. 6491 // However, if the importation fails, it will be left as a nullptr. 6492 // During the cleanup of the failed import, we should check whether the 6493 // DeclContext is null or not - instead of dereferencing that unconditionally. 6494 constexpr auto ToTUCode = R"( 6495 namespace X { 6496 struct bar { 6497 int odr_violation; 6498 }; 6499 })"; 6500 constexpr auto FromTUCode = R"( 6501 namespace X { 6502 enum b {}; 6503 struct bar { 6504 typedef b e; 6505 static e d; 6506 }; 6507 } 6508 int z = X::bar::d; 6509 )"; 6510 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11); 6511 static_cast<void>(ToTU); 6512 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 6513 auto *FromZ = 6514 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("z"))); 6515 ASSERT_TRUE(FromZ); 6516 ASSERT_TRUE(FromZ->hasInit()); 6517 6518 auto *ImportedZ = Import(FromZ, Lang_CXX11); 6519 EXPECT_FALSE(ImportedZ); 6520 } 6521 6522 // An error should be set for a class if it had a previous import with an error 6523 // from another TU. 6524 TEST_P(ErrorHandlingTest, 6525 ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt) { 6526 // We already have a fwd decl. 6527 TranslationUnitDecl *ToTU = getToTuDecl("class X;", Lang_CXX03); 6528 // Then we import a definition. 6529 { 6530 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 6531 class X { 6532 void f() { )") + ErroneousStmt + R"( } 6533 void ok(); 6534 }; 6535 )", 6536 Lang_CXX03); 6537 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 6538 FromTU, cxxRecordDecl(hasName("X"))); 6539 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 6540 6541 // An error is set for X ... 6542 EXPECT_FALSE(ImportedX); 6543 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 6544 std::optional<ASTImportError> OptErr = 6545 Importer->getImportDeclErrorIfAny(FromX); 6546 ASSERT_TRUE(OptErr); 6547 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6548 } 6549 // ... but the node had been created. 6550 auto *ToXDef = FirstDeclMatcher<CXXRecordDecl>().match( 6551 ToTU, cxxRecordDecl(hasName("X"), isDefinition())); 6552 // An error is set for "ToXDef" in the shared state. 6553 std::optional<ASTImportError> OptErr = 6554 SharedStatePtr->getImportDeclErrorIfAny(ToXDef); 6555 ASSERT_TRUE(OptErr); 6556 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6557 6558 auto *ToXFwd = FirstDeclMatcher<CXXRecordDecl>().match( 6559 ToTU, cxxRecordDecl(hasName("X"), unless(isDefinition()))); 6560 // An error is NOT set for the fwd Decl of X in the shared state. 6561 OptErr = SharedStatePtr->getImportDeclErrorIfAny(ToXFwd); 6562 ASSERT_FALSE(OptErr); 6563 6564 // Try to import X again but from another TU. 6565 { 6566 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 6567 class X { 6568 void f() { )") + ErroneousStmt + R"( } 6569 void ok(); 6570 }; 6571 )", 6572 Lang_CXX03, "input1.cc"); 6573 6574 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 6575 FromTU, cxxRecordDecl(hasName("X"))); 6576 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03); 6577 6578 // If we did not save the errors for the "to" context then the below checks 6579 // would fail, because the lookup finds the fwd Decl of the existing 6580 // definition in the "to" context. We can reach the existing definition via 6581 // the found fwd Decl. That existing definition is structurally equivalent 6582 // (we check only the fields) with this one we want to import, so we return 6583 // with the existing definition, which is erroneous (one method is missing). 6584 6585 // The import should fail. 6586 EXPECT_FALSE(ImportedX); 6587 ASTImporter *Importer = findFromTU(FromX)->Importer.get(); 6588 std::optional<ASTImportError> OptErr = 6589 Importer->getImportDeclErrorIfAny(FromX); 6590 // And an error is set for this new X in the "from" ctx. 6591 ASSERT_TRUE(OptErr); 6592 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6593 } 6594 } 6595 6596 TEST_P(ErrorHandlingTest, ImportOfOverriddenMethods) { 6597 auto MatchFooA = 6598 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A")))); 6599 auto MatchFooB = 6600 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B")))); 6601 auto MatchFooC = 6602 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("C")))); 6603 6604 // Provoke import of a method that has overridden methods with import error. 6605 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"( 6606 struct C; 6607 struct A { 6608 virtual void foo(); 6609 void f1(C *); 6610 }; 6611 void A::foo() { 6612 )") + ErroneousStmt + R"( 6613 } 6614 struct B : public A { 6615 void foo() override; 6616 }; 6617 struct C : public B { 6618 void foo() override; 6619 }; 6620 )", 6621 Lang_CXX11); 6622 auto *FromFooA = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooA); 6623 auto *FromFooB = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooB); 6624 auto *FromFooC = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooC); 6625 6626 EXPECT_FALSE(Import(FromFooA, Lang_CXX11)); 6627 ASTImporter *Importer = findFromTU(FromFooA)->Importer.get(); 6628 auto CheckError = [&Importer](Decl *FromD) { 6629 std::optional<ASTImportError> OptErr = 6630 Importer->getImportDeclErrorIfAny(FromD); 6631 ASSERT_TRUE(OptErr); 6632 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct); 6633 }; 6634 CheckError(FromFooA); 6635 EXPECT_FALSE(Import(FromFooB, Lang_CXX11)); 6636 CheckError(FromFooB); 6637 EXPECT_FALSE(Import(FromFooC, Lang_CXX11)); 6638 CheckError(FromFooC); 6639 } 6640 6641 TEST_P(ErrorHandlingTest, ODRViolationWithinParmVarDecls) { 6642 // Importing of 'f' and parameter 'P' should cause an ODR error. 6643 // The error happens after the ParmVarDecl for 'P' was already created. 6644 // This is a special case because the ParmVarDecl has a temporary DeclContext. 6645 // Expected is no crash at error handling of ASTImporter. 6646 constexpr auto ToTUCode = R"( 6647 struct X { 6648 char A; 6649 }; 6650 )"; 6651 constexpr auto FromTUCode = R"( 6652 struct X { 6653 enum Y { Z }; 6654 }; 6655 void f(int P = X::Z); 6656 )"; 6657 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11); 6658 static_cast<void>(ToTU); 6659 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 6660 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 6661 FromTU, functionDecl(hasName("f"))); 6662 ASSERT_TRUE(FromF); 6663 6664 auto *ImportedF = Import(FromF, Lang_CXX11); 6665 EXPECT_FALSE(ImportedF); 6666 } 6667 6668 TEST_P(ErrorHandlingTest, DoNotInheritErrorFromNonDependentChild) { 6669 // Declarations should not inherit an import error from a child object 6670 // if the declaration has no direct dependence to such a child. 6671 // For example a namespace should not get import error if one of the 6672 // declarations inside it fails to import. 6673 // There was a special case in error handling (when "import path circles" are 6674 // encountered) when this property was not held. This case is provoked by the 6675 // following code. 6676 constexpr auto ToTUCode = R"( 6677 namespace ns { 6678 struct Err { 6679 char A; 6680 }; 6681 } 6682 )"; 6683 constexpr auto FromTUCode = R"( 6684 namespace ns { 6685 struct A { 6686 using U = struct Err; 6687 }; 6688 } 6689 namespace ns { 6690 struct Err {}; // ODR violation 6691 void f(A) {} 6692 } 6693 )"; 6694 6695 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11); 6696 static_cast<void>(ToTU); 6697 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 6698 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 6699 FromTU, cxxRecordDecl(hasName("A"), hasDefinition())); 6700 ASSERT_TRUE(FromA); 6701 auto *ImportedA = Import(FromA, Lang_CXX11); 6702 // 'A' can not be imported: ODR error at 'Err' 6703 EXPECT_FALSE(ImportedA); 6704 // When import of 'A' failed there was a "saved import path circle" that 6705 // contained namespace 'ns' (A - U - Err - ns - f - A). This should not mean 6706 // that every object in this path fails to import. 6707 6708 Decl *FromNS = FirstDeclMatcher<NamespaceDecl>().match( 6709 FromTU, namespaceDecl(hasName("ns"))); 6710 EXPECT_TRUE(FromNS); 6711 auto *ImportedNS = Import(FromNS, Lang_CXX11); 6712 EXPECT_TRUE(ImportedNS); 6713 } 6714 6715 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) { 6716 Decl *FromTU = getTuDecl( 6717 R"( 6718 void f() { 6719 auto L = [](){}; 6720 } 6721 )", 6722 Lang_CXX11, "input0.cc"); 6723 auto Pattern = lambdaExpr(); 6724 CXXRecordDecl *FromL = 6725 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 6726 6727 auto ToL = Import(FromL, Lang_CXX11); 6728 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); 6729 unsigned FromLSize = 6730 std::distance(FromL->decls().begin(), FromL->decls().end()); 6731 EXPECT_NE(ToLSize, 0u); 6732 EXPECT_EQ(ToLSize, FromLSize); 6733 EXPECT_FALSE(FromL->isDependentLambda()); 6734 } 6735 6736 TEST_P(ASTImporterOptionSpecificTestBase, 6737 ReturnTypeDeclaredInsideOfCXX11LambdaWithoutTrailingReturn) { 6738 Decl *From, *To; 6739 std::tie(From, To) = getImportedDecl( 6740 R"( 6741 void foo() { 6742 (void) []() { 6743 struct X {}; 6744 return X(); 6745 }; 6746 } 6747 )", 6748 Lang_CXX11, "", Lang_CXX11, "foo"); // c++11 only 6749 auto *ToLambda = FirstDeclMatcher<LambdaExpr>().match(To, lambdaExpr()); 6750 EXPECT_TRUE(ToLambda); 6751 } 6752 6753 TEST_P(ASTImporterOptionSpecificTestBase, 6754 ReturnTypeDeclaredInsideOfCXX11LambdaWithTrailingReturn) { 6755 Decl *From, *To; 6756 std::tie(From, To) = getImportedDecl( 6757 R"( 6758 void foo() { 6759 (void) [] { 6760 struct X {}; 6761 return X(); 6762 }; 6763 } 6764 )", 6765 Lang_CXX11, "", Lang_CXX11, "foo"); // c++11 only 6766 auto *ToLambda = FirstDeclMatcher<LambdaExpr>().match(To, lambdaExpr()); 6767 EXPECT_TRUE(ToLambda); 6768 } 6769 6770 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) { 6771 Decl *FromTU = getTuDecl( 6772 R"( 6773 template <typename F> 6774 void f(F L = [](){}) {} 6775 )", 6776 Lang_CXX11, "input0.cc"); 6777 auto Pattern = lambdaExpr(); 6778 CXXRecordDecl *FromL = 6779 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 6780 6781 auto ToL = Import(FromL, Lang_CXX11); 6782 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); 6783 unsigned FromLSize = 6784 std::distance(FromL->decls().begin(), FromL->decls().end()); 6785 EXPECT_NE(ToLSize, 0u); 6786 EXPECT_EQ(ToLSize, FromLSize); 6787 EXPECT_TRUE(FromL->isDependentLambda()); 6788 } 6789 6790 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInGlobalScope) { 6791 Decl *FromTU = getTuDecl( 6792 R"( 6793 auto l1 = [](unsigned lp) { return 1; }; 6794 auto l2 = [](int lp) { return 2; }; 6795 int f(int p) { 6796 return l1(p) + l2(p); 6797 } 6798 )", 6799 Lang_CXX11, "input0.cc"); 6800 FunctionDecl *FromF = FirstDeclMatcher<FunctionDecl>().match( 6801 FromTU, functionDecl(hasName("f"))); 6802 FunctionDecl *ToF = Import(FromF, Lang_CXX11); 6803 EXPECT_TRUE(ToF); 6804 } 6805 6806 TEST_P(ASTImporterOptionSpecificTestBase, 6807 ImportExistingFriendClassTemplateDef) { 6808 auto Code = 6809 R"( 6810 template <class T1, class T2> 6811 struct Base { 6812 template <class U1, class U2> 6813 friend struct Class; 6814 }; 6815 template <class T1, class T2> 6816 struct Class { }; 6817 )"; 6818 6819 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03); 6820 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc"); 6821 6822 auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match( 6823 ToTU, classTemplateDecl(hasName("Class"))); 6824 auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match( 6825 ToTU, classTemplateDecl(hasName("Class"))); 6826 ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition()); 6827 ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition()); 6828 // Previous friend decl is not linked to it! 6829 ASSERT_FALSE(ToClassDef->getPreviousDecl()); 6830 ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef); 6831 ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto); 6832 6833 auto *FromClassProto = FirstDeclMatcher<ClassTemplateDecl>().match( 6834 FromTU, classTemplateDecl(hasName("Class"))); 6835 auto *FromClassDef = LastDeclMatcher<ClassTemplateDecl>().match( 6836 FromTU, classTemplateDecl(hasName("Class"))); 6837 ASSERT_FALSE(FromClassProto->isThisDeclarationADefinition()); 6838 ASSERT_TRUE(FromClassDef->isThisDeclarationADefinition()); 6839 ASSERT_FALSE(FromClassDef->getPreviousDecl()); 6840 ASSERT_EQ(FromClassDef->getMostRecentDecl(), FromClassDef); 6841 ASSERT_EQ(FromClassProto->getMostRecentDecl(), FromClassProto); 6842 6843 auto *ImportedDef = Import(FromClassDef, Lang_CXX03); 6844 // At import we should find the definition for 'Class' even if the 6845 // prototype (inside 'friend') for it comes first in the AST and is not 6846 // linked to the definition. 6847 EXPECT_EQ(ImportedDef, ToClassDef); 6848 } 6849 6850 struct LLDBLookupTest : ASTImporterOptionSpecificTestBase { 6851 LLDBLookupTest() { 6852 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 6853 ASTContext &FromContext, FileManager &FromFileManager, 6854 bool MinimalImport, 6855 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 6856 return new ASTImporter(ToContext, ToFileManager, FromContext, 6857 FromFileManager, MinimalImport, 6858 // We use the regular lookup. 6859 /*SharedState=*/nullptr); 6860 }; 6861 } 6862 }; 6863 6864 TEST_P(LLDBLookupTest, ImporterShouldFindInTransparentContext) { 6865 TranslationUnitDecl *ToTU = getToTuDecl( 6866 R"( 6867 extern "C" { 6868 class X{}; 6869 }; 6870 )", 6871 Lang_CXX03); 6872 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match( 6873 ToTU, cxxRecordDecl(hasName("X"))); 6874 6875 // Set up a stub external storage. 6876 ToTU->setHasExternalLexicalStorage(true); 6877 // Set up DeclContextBits.HasLazyExternalLexicalLookups to true. 6878 ToTU->setMustBuildLookupTable(); 6879 struct TestExternalASTSource : ExternalASTSource {}; 6880 ToTU->getASTContext().setExternalSource(new TestExternalASTSource()); 6881 6882 Decl *FromTU = getTuDecl( 6883 R"( 6884 class X; 6885 )", 6886 Lang_CXX03); 6887 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 6888 FromTU, cxxRecordDecl(hasName("X"))); 6889 auto *ImportedX = Import(FromX, Lang_CXX03); 6890 // The lookup must find the existing class definition in the LinkageSpecDecl. 6891 // Then the importer renders the existing and the new decl into one chain. 6892 EXPECT_EQ(ImportedX->getCanonicalDecl(), ToX->getCanonicalDecl()); 6893 } 6894 6895 struct SVEBuiltins : ASTImporterOptionSpecificTestBase {}; 6896 6897 TEST_P(SVEBuiltins, ImportTypes) { 6898 static const char *const TypeNames[] = { 6899 "__SVInt8_t", "__SVInt16_t", "__SVInt32_t", "__SVInt64_t", 6900 "__SVUint8_t", "__SVUint16_t", "__SVUint32_t", "__SVUint64_t", 6901 "__SVFloat16_t", "__SVBfloat16_t", "__SVFloat32_t", "__SVFloat64_t", 6902 "__SVBool_t"}; 6903 6904 TranslationUnitDecl *ToTU = getToTuDecl("", Lang_CXX03); 6905 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cc"); 6906 for (auto *TypeName : TypeNames) { 6907 auto *ToTypedef = FirstDeclMatcher<TypedefDecl>().match( 6908 ToTU, typedefDecl(hasName(TypeName))); 6909 QualType ToType = ToTypedef->getUnderlyingType(); 6910 6911 auto *FromTypedef = FirstDeclMatcher<TypedefDecl>().match( 6912 FromTU, typedefDecl(hasName(TypeName))); 6913 QualType FromType = FromTypedef->getUnderlyingType(); 6914 6915 QualType ImportedType = ImportType(FromType, FromTypedef, Lang_CXX03); 6916 EXPECT_EQ(ImportedType, ToType); 6917 } 6918 } 6919 6920 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfDefaultImplicitFunctions) { 6921 // Test that import of implicit functions works and the functions 6922 // are merged into one chain. 6923 auto GetDeclToImport = [this](StringRef File) { 6924 Decl *FromTU = getTuDecl( 6925 R"( 6926 struct X { }; 6927 // Force generating some implicit operator definitions for X. 6928 void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; } 6929 )", 6930 Lang_CXX11, File); 6931 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 6932 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit()))); 6933 // Destructor is picked as one example of implicit function. 6934 return FromD->getDestructor(); 6935 }; 6936 6937 auto *ToD1 = Import(GetDeclToImport("input1.cc"), Lang_CXX11); 6938 ASSERT_TRUE(ToD1); 6939 6940 auto *ToD2 = Import(GetDeclToImport("input2.cc"), Lang_CXX11); 6941 ASSERT_TRUE(ToD2); 6942 6943 EXPECT_EQ(ToD1->getCanonicalDecl(), ToD2->getCanonicalDecl()); 6944 } 6945 6946 TEST_P(ASTImporterOptionSpecificTestBase, 6947 ImportOfExplicitlyDefaultedOrDeleted) { 6948 Decl *FromTU = getTuDecl( 6949 R"( 6950 struct X { X() = default; X(const X&) = delete; }; 6951 )", 6952 Lang_CXX11); 6953 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 6954 FromTU, cxxRecordDecl(hasName("X"))); 6955 auto *ImportedX = Import(FromX, Lang_CXX11); 6956 auto *Constr1 = FirstDeclMatcher<CXXConstructorDecl>().match( 6957 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit()))); 6958 auto *Constr2 = LastDeclMatcher<CXXConstructorDecl>().match( 6959 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit()))); 6960 6961 ASSERT_TRUE(ImportedX); 6962 EXPECT_TRUE(Constr1->isDefaulted()); 6963 EXPECT_TRUE(Constr1->isExplicitlyDefaulted()); 6964 EXPECT_TRUE(Constr2->isDeletedAsWritten()); 6965 EXPECT_EQ(ImportedX->isAggregate(), FromX->isAggregate()); 6966 } 6967 6968 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, SVEBuiltins, 6969 ::testing::Values(std::vector<std::string>{ 6970 "-target", "aarch64-linux-gnu"})); 6971 6972 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, DeclContextTest, 6973 ::testing::Values(std::vector<std::string>())); 6974 6975 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CanonicalRedeclChain, 6976 ::testing::Values(std::vector<std::string>())); 6977 6978 TEST_P(ASTImporterOptionSpecificTestBase, LambdasAreDifferentiated) { 6979 Decl *FromTU = getTuDecl( 6980 R"( 6981 void f() { 6982 auto L0 = [](){}; 6983 auto L1 = [](){}; 6984 } 6985 )", 6986 Lang_CXX11, "input0.cc"); 6987 auto Pattern = lambdaExpr(); 6988 CXXRecordDecl *FromL0 = 6989 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 6990 CXXRecordDecl *FromL1 = 6991 LastDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); 6992 ASSERT_NE(FromL0, FromL1); 6993 6994 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 6995 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 6996 EXPECT_NE(ToL0, ToL1); 6997 } 6998 6999 TEST_P(ASTImporterOptionSpecificTestBase, 7000 LambdasInFunctionParamsAreDifferentiated) { 7001 Decl *FromTU = getTuDecl( 7002 R"( 7003 template <typename F0, typename F1> 7004 void f(F0 L0 = [](){}, F1 L1 = [](){}) {} 7005 )", 7006 Lang_CXX11, "input0.cc"); 7007 auto Pattern = cxxRecordDecl(isLambda()); 7008 CXXRecordDecl *FromL0 = 7009 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 7010 CXXRecordDecl *FromL1 = 7011 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 7012 ASSERT_NE(FromL0, FromL1); 7013 7014 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 7015 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 7016 ASSERT_NE(ToL0, ToL1); 7017 } 7018 7019 TEST_P(ASTImporterOptionSpecificTestBase, 7020 LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed) { 7021 Decl *FromTU = getTuDecl( 7022 R"( 7023 #define LAMBDA [](){} 7024 template <typename F0, typename F1> 7025 void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {} 7026 )", 7027 Lang_CXX11, "input0.cc"); 7028 auto Pattern = cxxRecordDecl(isLambda()); 7029 CXXRecordDecl *FromL0 = 7030 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 7031 CXXRecordDecl *FromL1 = 7032 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); 7033 ASSERT_NE(FromL0, FromL1); 7034 7035 Import(FromL0, Lang_CXX11); 7036 Import(FromL1, Lang_CXX11); 7037 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); 7038 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); 7039 ASSERT_NE(ToL0, ToL1); 7040 } 7041 7042 TEST_P(ASTImporterOptionSpecificTestBase, ImportAssignedLambda) { 7043 Decl *FromTU = getTuDecl( 7044 R"( 7045 void f() { 7046 auto x = []{} = {}; auto x2 = x; 7047 } 7048 )", 7049 Lang_CXX20, "input0.cc"); 7050 auto FromF = FirstDeclMatcher<FunctionDecl>().match( 7051 FromTU, functionDecl(hasName("f"))); 7052 // We have only one lambda class. 7053 ASSERT_EQ( 7054 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())), 7055 1u); 7056 7057 FunctionDecl *ToF = Import(FromF, Lang_CXX20); 7058 EXPECT_TRUE(ToF); 7059 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 7060 // We have only one lambda class after the import. 7061 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())), 7062 1u); 7063 } 7064 7065 TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) { 7066 Decl *FromTU = getTuDecl( 7067 R"( 7068 void f() { 7069 auto x = []{} = {}; 7070 auto xb = []{} = {}; 7071 } 7072 )", 7073 Lang_CXX20, "input0.cc"); 7074 auto FromF = FirstDeclMatcher<FunctionDecl>().match( 7075 FromTU, functionDecl(hasName("f"))); 7076 // We have two lambda classes. 7077 ASSERT_EQ( 7078 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())), 7079 2u); 7080 7081 FunctionDecl *ToF = Import(FromF, Lang_CXX20); 7082 EXPECT_TRUE(ToF); 7083 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); 7084 // We have two lambda classes after the import. 7085 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())), 7086 2u); 7087 } 7088 7089 TEST_P(ASTImporterOptionSpecificTestBase, 7090 ImportFunctionDeclWithTypeSourceInfoWithSourceDecl) { 7091 // This code results in a lambda with implicit constructor. 7092 // The constructor's TypeSourceInfo points out the function prototype. 7093 // This prototype has an EST_Unevaluated in its exception information and a 7094 // SourceDecl that is the function declaration itself. 7095 // The test verifies that AST import of such AST does not crash. 7096 // (Here the function's TypeSourceInfo references the function itself.) 7097 Decl *FromTU = getTuDecl( 7098 R"( 7099 template<typename T> void f(T) { auto X = [](){}; } 7100 void g() { f(10); } 7101 )", 7102 Lang_CXX11, "input0.cc"); 7103 7104 // Use LastDeclMatcher to find the LambdaExpr in the template specialization. 7105 CXXRecordDecl *FromL = LastDeclMatcher<LambdaExpr>() 7106 .match(FromTU, lambdaExpr()) 7107 ->getLambdaClass(); 7108 7109 CXXConstructorDecl *FromCtor = *FromL->ctor_begin(); 7110 ASSERT_TRUE(FromCtor->isCopyConstructor()); 7111 ASSERT_TRUE(FromCtor->getTypeSourceInfo()); 7112 const auto *FromFPT = FromCtor->getType()->getAs<FunctionProtoType>(); 7113 ASSERT_TRUE(FromFPT); 7114 EXPECT_EQ(FromCtor->getTypeSourceInfo()->getType().getTypePtr(), FromFPT); 7115 FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo(); 7116 // If type is EST_Unevaluated, SourceDecl should be set to the parent Decl. 7117 EXPECT_EQ(FromEPI.ExceptionSpec.Type, EST_Unevaluated); 7118 EXPECT_EQ(FromEPI.ExceptionSpec.SourceDecl, FromCtor); 7119 7120 auto ToL = Import(FromL, Lang_CXX11); 7121 7122 // Check if the import was correct. 7123 CXXConstructorDecl *ToCtor = *ToL->ctor_begin(); 7124 EXPECT_TRUE(ToCtor->getTypeSourceInfo()); 7125 const auto *ToFPT = ToCtor->getType()->getAs<FunctionProtoType>(); 7126 ASSERT_TRUE(ToFPT); 7127 EXPECT_EQ(ToCtor->getTypeSourceInfo()->getType().getTypePtr(), ToFPT); 7128 FunctionProtoType::ExtProtoInfo ToEPI = ToFPT->getExtProtoInfo(); 7129 EXPECT_EQ(ToEPI.ExceptionSpec.Type, EST_Unevaluated); 7130 EXPECT_EQ(ToEPI.ExceptionSpec.SourceDecl, ToCtor); 7131 } 7132 7133 struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase { 7134 void testImport(llvm::StringRef Code, clang::TestLanguage Lang = Lang_CXX14, 7135 bool FindLast = false) { 7136 Decl *FromTU = getTuDecl(Code, Lang, "input0.cc"); 7137 FunctionDecl *From = FindLast ? LastDeclMatcher<FunctionDecl>().match( 7138 FromTU, functionDecl(hasName("foo"))) 7139 : FirstDeclMatcher<FunctionDecl>().match( 7140 FromTU, functionDecl(hasName("foo"))); 7141 7142 FunctionDecl *To = Import(From, Lang); 7143 EXPECT_TRUE(To); 7144 // We check here only that the type is auto type. 7145 // These tests are to verify that no crash happens. 7146 // The crash possibility is the presence of a reference to a declaration 7147 // in the function's body from the return type, if the function has auto 7148 // return type. 7149 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 7150 } 7151 }; 7152 7153 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate1) { 7154 testImport( 7155 R"( 7156 template<class C> 7157 C f1() { return C(); } 7158 auto foo() { 7159 struct B {}; 7160 return f1<B>(); 7161 } 7162 )"); 7163 } 7164 7165 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate2) { 7166 testImport( 7167 R"( 7168 template<class T> 7169 int f1(T t) { return 1; } 7170 auto foo() { 7171 struct B {}; 7172 return f1(B()); 7173 } 7174 )"); 7175 } 7176 7177 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate3) { 7178 testImport( 7179 R"( 7180 template<class A> struct S1 {}; 7181 template<class A> struct S2 {}; 7182 template<class C> 7183 S1<C> f1() { return S1<C>(); } 7184 auto foo() { 7185 struct B {}; 7186 return f1<S2<B *>>(); 7187 } 7188 )"); 7189 } 7190 7191 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate4) { 7192 testImport( 7193 R"( 7194 template<class... A> struct S1 {}; 7195 template<class... A> struct S2 {}; 7196 template<class... C> 7197 S1<C...> f1() { return S1<C...>(); } 7198 auto foo() { 7199 struct B {}; 7200 return f1<S2<int, B *>, bool>(); 7201 } 7202 )"); 7203 } 7204 7205 TEST_P(ImportAutoFunctions, ReturnWithVarTemplate1) { 7206 testImport( 7207 R"( 7208 template<class T> T X; 7209 auto foo() { 7210 struct A {}; 7211 return X<A>; 7212 } 7213 )"); 7214 } 7215 7216 TEST_P(ImportAutoFunctions, ReturnWithVarTemplate2) { 7217 testImport( 7218 R"( 7219 template<class A> struct S1 {}; 7220 template<class T> S1<T> X; 7221 auto foo() { 7222 struct A {}; 7223 return X<S1<A>>; 7224 } 7225 )"); 7226 } 7227 7228 TEST_P(ImportAutoFunctions, ReturnWithVarTemplate3) { 7229 testImport( 7230 R"( 7231 template<class... A> struct S1 {}; 7232 template<class... T> S1<T...> X; 7233 auto foo() { 7234 struct A {}; 7235 return X<bool, S1<A, int>>; 7236 } 7237 )"); 7238 } 7239 7240 TEST_P(ImportAutoFunctions, ReturnWithAutoUnresolvedArg) { 7241 testImport( 7242 R"( 7243 template<int A> 7244 auto foo() { 7245 return 22; 7246 } 7247 )"); 7248 } 7249 7250 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTemplateTemplateArg) { 7251 // FIXME: Is it possible to have the template arg inside the function? 7252 testImport( 7253 R"( 7254 template<int> struct Tmpl {}; 7255 template<template<int> class> struct TmplTmpl {}; 7256 auto foo() { 7257 return TmplTmpl<Tmpl>(); 7258 } 7259 )"); 7260 } 7261 7262 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithDeclarationTemplateArg) { 7263 // FIXME: Is it possible to have the template arg inside the function? 7264 testImport( 7265 R"( 7266 template<const int *> struct Tmpl {}; 7267 int A[10]; 7268 auto foo() { 7269 return Tmpl<A>(); 7270 } 7271 )"); 7272 } 7273 7274 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithNullPtrTemplateArg) { 7275 testImport( 7276 R"( 7277 template<int *> struct Tmpl {}; 7278 auto foo() { 7279 constexpr int* A = nullptr; 7280 return Tmpl<A>(); 7281 } 7282 )"); 7283 } 7284 7285 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithIntegralTemplateArg) { 7286 testImport( 7287 R"( 7288 template<int> struct Tmpl {}; 7289 auto foo() { 7290 using Int = int; 7291 constexpr Int A = 7; 7292 return Tmpl<A>(); 7293 } 7294 )"); 7295 } 7296 7297 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithDecltypeTypeDeclaredInside) { 7298 testImport( 7299 R"( 7300 template<class> struct Tmpl {}; 7301 auto foo() { 7302 struct X {}; 7303 X x; 7304 return Tmpl<decltype(x)>(); 7305 } 7306 )"); 7307 } 7308 7309 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithUsingTypeDeclaredInside) { 7310 testImport( 7311 R"( 7312 template<class> struct Tmpl {}; 7313 namespace A { struct X {}; } 7314 auto foo() { 7315 using A::X; 7316 return Tmpl<X>(); 7317 } 7318 )"); 7319 } 7320 7321 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithArrayTypeDeclaredInside) { 7322 testImport( 7323 R"( 7324 template<class> struct Tmpl {}; 7325 auto foo() { 7326 struct X {}; 7327 return Tmpl<X[10]>(); 7328 } 7329 )"); 7330 } 7331 7332 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithArraySizeExprDeclaredInside) { 7333 testImport( 7334 R"( 7335 template<class> struct Tmpl {}; 7336 auto foo() { 7337 constexpr int S = 10; 7338 return Tmpl<int[S]>(); 7339 } 7340 )"); 7341 } 7342 7343 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithPackArgDeclaredInside) { 7344 testImport( 7345 R"( 7346 template<class ...> struct Tmpl {}; 7347 auto foo() { 7348 using X = bool; 7349 return Tmpl<int, X>(); 7350 } 7351 )"); 7352 } 7353 7354 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithIntegerArgDeclaredInside) { 7355 testImport( 7356 R"( 7357 template<int> struct Tmpl {}; 7358 auto foo() { 7359 constexpr int X = 1; 7360 return Tmpl<X>(); 7361 } 7362 )"); 7363 } 7364 7365 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithPtrToStructDeclaredInside) { 7366 testImport( 7367 R"( 7368 template<class> struct Tmpl {}; 7369 auto foo() { 7370 struct X {}; 7371 return Tmpl<X *>(); 7372 } 7373 )"); 7374 } 7375 7376 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithRefToStructDeclaredInside) { 7377 testImport( 7378 R"( 7379 template<class> struct Tmpl {}; 7380 struct X {}; 7381 auto foo() { 7382 using Y = X; 7383 return Tmpl<Y &>(); 7384 } 7385 )"); 7386 } 7387 7388 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside1) { 7389 testImport( 7390 R"( 7391 template<class> struct Tmpl {}; 7392 auto foo() { 7393 struct X {}; 7394 return Tmpl<X>(); 7395 } 7396 )"); 7397 } 7398 7399 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside2) { 7400 testImport( 7401 R"( 7402 template<class> struct Tmpl {}; 7403 auto foo() { 7404 struct X {}; 7405 return Tmpl<Tmpl<X>>(); 7406 } 7407 )"); 7408 } 7409 7410 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTypedefDeclaredInside) { 7411 testImport( 7412 R"( 7413 template<class> struct Tmpl {}; 7414 auto foo() { 7415 struct X {}; 7416 using x_type = X; 7417 return Tmpl<x_type>(); 7418 } 7419 )"); 7420 } 7421 7422 TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) { 7423 Decl *FromTU = getTuDecl( 7424 R"( 7425 auto X = [](long l) { 7426 using int_type = long; 7427 auto dur = 13; 7428 return static_cast<int_type>(dur); 7429 }; 7430 )", 7431 Lang_CXX14, "input0.cc"); 7432 CXXMethodDecl *From = 7433 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, cxxMethodDecl()); 7434 7435 // Explicitly set the return type of the lambda's operator() to the TypeAlias. 7436 // Normally the return type would be the built-in 'long' type. However, there 7437 // are cases when Clang does not use the canonical type and the TypeAlias is 7438 // used. I could not create such an AST from regular source code, it requires 7439 // some special state in the preprocessor. I've found such an AST when Clang 7440 // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce 7441 // that with creduce, because after preprocessing, the AST no longer 7442 // contained the TypeAlias as a return type of the lambda. 7443 ASTContext &Ctx = From->getASTContext(); 7444 TypeAliasDecl *FromTA = 7445 FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl()); 7446 QualType TT = Ctx.getTypedefType(FromTA); 7447 const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType()); 7448 QualType NewFunType = 7449 Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo()); 7450 From->setType(NewFunType); 7451 7452 CXXMethodDecl *To = Import(From, Lang_CXX14); 7453 EXPECT_TRUE(To); 7454 EXPECT_TRUE(isa<TypedefType>(To->getReturnType())); 7455 } 7456 7457 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside) { 7458 testImport( 7459 R"( 7460 auto foo() { 7461 struct X {}; 7462 return X(); 7463 } 7464 )"); 7465 } 7466 7467 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside2) { 7468 Decl *FromTU = getTuDecl( 7469 R"( 7470 auto foo() { 7471 struct X {}; 7472 return X(); 7473 } 7474 )", 7475 Lang_CXX14, "input0.cc"); 7476 FunctionDecl *From = 7477 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); 7478 7479 // This time import the type directly. 7480 QualType ToT = ImportType(From->getType(), From, Lang_CXX14); 7481 const FunctionProtoType *FPT = cast<FunctionProtoType>(ToT); 7482 EXPECT_TRUE(isa<AutoType>(FPT->getReturnType())); 7483 } 7484 7485 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside3) { 7486 Decl *FromTU = getTuDecl( 7487 R"( 7488 struct S { 7489 constexpr auto foo(); 7490 }; 7491 constexpr auto S::foo() { 7492 struct X {}; 7493 return X(); 7494 } 7495 )", 7496 Lang_CXX14, "input0.cc"); 7497 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( 7498 FromTU, functionDecl(hasName("foo"), unless(hasBody(stmt())))); 7499 ASSERT_FALSE(From->isThisDeclarationADefinition()); 7500 7501 FunctionDecl *To = Import(From, Lang_CXX17); 7502 EXPECT_TRUE(To); 7503 EXPECT_TRUE(isa<AutoType>(To->getReturnType())); 7504 EXPECT_FALSE(To->isThisDeclarationADefinition()); 7505 } 7506 7507 TEST_P(ImportAutoFunctions, ReturnWithTypedefToStructDeclaredInside) { 7508 testImport( 7509 R"( 7510 auto foo() { 7511 struct X {}; 7512 using Y = X; 7513 return Y(); 7514 } 7515 )"); 7516 } 7517 7518 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredNestedInside) { 7519 testImport( 7520 R"( 7521 auto foo() { 7522 struct X { struct Y{}; }; 7523 return X::Y(); 7524 } 7525 )"); 7526 } 7527 7528 TEST_P(ImportAutoFunctions, ReturnWithInternalLambdaType) { 7529 testImport( 7530 R"( 7531 auto foo() { 7532 auto l = []() { 7533 struct X {}; 7534 return X(); 7535 }; 7536 return l(); 7537 } 7538 )", 7539 Lang_CXX17); 7540 } 7541 7542 TEST_P(ImportAutoFunctions, ReturnWithTypeInIf) { 7543 testImport( 7544 R"( 7545 auto foo() { 7546 if (struct X {} x; true) 7547 return X(); 7548 else 7549 return X(); 7550 } 7551 )", 7552 Lang_CXX17); 7553 } 7554 7555 TEST_P(ImportAutoFunctions, ReturnWithTypeInFor) { 7556 testImport( 7557 R"( 7558 auto foo() { 7559 for (struct X {} x;;) 7560 return X(); 7561 } 7562 )", 7563 Lang_CXX17); 7564 } 7565 7566 TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) { 7567 testImport( 7568 R"( 7569 auto foo() { 7570 switch (struct X {} x; 10) { 7571 case 10: 7572 return X(); 7573 } 7574 } 7575 )", 7576 Lang_CXX17); 7577 } 7578 7579 TEST_P(ImportAutoFunctions, ReturnWithAutoTemplateType) { 7580 testImport( 7581 R"( 7582 template<class T> 7583 struct S {}; 7584 template<class T> 7585 auto foo() { 7586 return S<T>{}; 7587 } 7588 auto a = foo<int>(); 7589 )", 7590 Lang_CXX14, /*FindLast=*/true); 7591 } 7592 7593 TEST_P(ImportAutoFunctions, ReturnWithSubstNonTypeTemplateParmExpr) { 7594 const char *Code = 7595 R"( 7596 template<int> 7597 struct array {}; 7598 7599 template <int N> 7600 auto foo() { return array<N>(); } 7601 7602 void bar() { foo<0>(); } 7603 )"; 7604 Decl *FromTU = getTuDecl(Code, Lang_CXX17); 7605 7606 auto *FromBar = FirstDeclMatcher<FunctionDecl>().match( 7607 FromTU, functionDecl(hasName("bar"))); 7608 7609 auto *ToBar = Import(FromBar, Lang_CXX17); 7610 EXPECT_TRUE(ToBar); 7611 } 7612 7613 TEST_P(ImportAutoFunctions, ReturnWithUnaryTransformType) { 7614 const char *Code = 7615 R"( 7616 enum E { E1 }; 7617 7618 template<typename T> 7619 auto foo(T v) { return static_cast<__underlying_type(T)>(v); } 7620 7621 bool bar() { return foo(E1); } 7622 )"; 7623 Decl *FromTU = getTuDecl(Code, Lang_CXX17); 7624 7625 auto *FromBar = FirstDeclMatcher<FunctionDecl>().match( 7626 FromTU, functionDecl(hasName("bar"))); 7627 7628 auto *ToBar = Import(FromBar, Lang_CXX17); 7629 EXPECT_TRUE(ToBar); 7630 } 7631 7632 struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {}; 7633 7634 TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) { 7635 // Tests that the FileID tree structure (with the links being the include 7636 // chains) is preserved while importing other files (which need to be 7637 // added to this structure with fake include locations. 7638 7639 SourceLocation Location1; 7640 { 7641 auto Pattern = varDecl(hasName("X")); 7642 Decl *FromTU = getTuDecl("int X;", Lang_C99, "input0.c"); 7643 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 7644 7645 Location1 = Import(FromD, Lang_C99)->getLocation(); 7646 } 7647 SourceLocation Location2; 7648 { 7649 auto Pattern = varDecl(hasName("Y")); 7650 Decl *FromTU = getTuDecl("int Y;", Lang_C99, "input1.c"); 7651 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 7652 7653 Location2 = Import(FromD, Lang_C99)->getLocation(); 7654 } 7655 7656 SourceManager &ToSM = ToAST->getSourceManager(); 7657 FileID FileID1 = ToSM.getFileID(Location1); 7658 FileID FileID2 = ToSM.getFileID(Location2); 7659 7660 // Check that the imported files look like as if they were included from the 7661 // start of the main file. 7662 SourceLocation FileStart = ToSM.getLocForStartOfFile(ToSM.getMainFileID()); 7663 EXPECT_NE(FileID1, ToSM.getMainFileID()); 7664 EXPECT_NE(FileID2, ToSM.getMainFileID()); 7665 EXPECT_EQ(ToSM.getIncludeLoc(FileID1), FileStart); 7666 EXPECT_EQ(ToSM.getIncludeLoc(FileID2), FileStart); 7667 7668 // Let the SourceManager check the order of the locations. The order should 7669 // be the order in which the declarations are imported. 7670 EXPECT_TRUE(ToSM.isBeforeInTranslationUnit(Location1, Location2)); 7671 EXPECT_FALSE(ToSM.isBeforeInTranslationUnit(Location2, Location1)); 7672 } 7673 7674 TEST_P(ImportSourceLocations, NormalFileBuffer) { 7675 // Test importing normal file buffers. 7676 7677 std::string Path = "input0.c"; 7678 std::string Source = "int X;"; 7679 TranslationUnitDecl *FromTU = getTuDecl(Source, Lang_C99, Path); 7680 7681 SourceLocation ImportedLoc; 7682 { 7683 // Import the VarDecl to trigger the importing of the FileID. 7684 auto Pattern = varDecl(hasName("X")); 7685 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 7686 ImportedLoc = Import(FromD, Lang_C99)->getLocation(); 7687 } 7688 7689 // Make sure the imported buffer has the original contents. 7690 SourceManager &ToSM = ToAST->getSourceManager(); 7691 FileID ImportedID = ToSM.getFileID(ImportedLoc); 7692 EXPECT_EQ(Source, 7693 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer()); 7694 } 7695 7696 TEST_P(ImportSourceLocations, OverwrittenFileBuffer) { 7697 // Test importing overwritten file buffers. 7698 7699 std::string Path = "input0.c"; 7700 TranslationUnitDecl *FromTU = getTuDecl("int X;", Lang_C99, Path); 7701 7702 // Overwrite the file buffer for our input file with new content. 7703 const std::string Contents = "overwritten contents"; 7704 SourceLocation ImportedLoc; 7705 { 7706 SourceManager &FromSM = FromTU->getASTContext().getSourceManager(); 7707 clang::FileManager &FM = FromSM.getFileManager(); 7708 clang::FileEntryRef FE = 7709 FM.getVirtualFileRef(Path, static_cast<off_t>(Contents.size()), 0); 7710 7711 llvm::SmallVector<char, 64> Buffer; 7712 Buffer.append(Contents.begin(), Contents.end()); 7713 auto FileContents = std::make_unique<llvm::SmallVectorMemoryBuffer>( 7714 std::move(Buffer), Path, /*RequiresNullTerminator=*/false); 7715 FromSM.overrideFileContents(FE, std::move(FileContents)); 7716 7717 // Import the VarDecl to trigger the importing of the FileID. 7718 auto Pattern = varDecl(hasName("X")); 7719 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); 7720 ImportedLoc = Import(FromD, Lang_C99)->getLocation(); 7721 } 7722 7723 // Make sure the imported buffer has the overwritten contents. 7724 SourceManager &ToSM = ToAST->getSourceManager(); 7725 FileID ImportedID = ToSM.getFileID(ImportedLoc); 7726 EXPECT_EQ(Contents, 7727 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer()); 7728 } 7729 7730 struct ImportAttributes : public ASTImporterOptionSpecificTestBase { 7731 void checkAttrImportCommon(const Attr *From, const Attr *To, 7732 const Decl *ToD) { 7733 7734 // Verify that dump does not crash because invalid data. 7735 ToD->dump(llvm::nulls()); 7736 7737 EXPECT_EQ(From->getParsedKind(), To->getParsedKind()); 7738 EXPECT_EQ(From->getSyntax(), To->getSyntax()); 7739 if (From->getAttrName()) { 7740 EXPECT_TRUE(To->getAttrName()); 7741 EXPECT_STREQ(From->getAttrName()->getNameStart(), 7742 To->getAttrName()->getNameStart()); 7743 } else { 7744 EXPECT_FALSE(To->getAttrName()); 7745 } 7746 if (From->getScopeName()) { 7747 EXPECT_TRUE(To->getScopeName()); 7748 EXPECT_STREQ(From->getScopeName()->getNameStart(), 7749 To->getScopeName()->getNameStart()); 7750 } else { 7751 EXPECT_FALSE(To->getScopeName()); 7752 } 7753 EXPECT_EQ(From->getSpellingListIndex(), To->getSpellingListIndex()); 7754 EXPECT_STREQ(From->getSpelling(), To->getSpelling()); 7755 EXPECT_EQ(From->isInherited(), To->isInherited()); 7756 EXPECT_EQ(From->isImplicit(), To->isImplicit()); 7757 EXPECT_EQ(From->isPackExpansion(), To->isPackExpansion()); 7758 EXPECT_EQ(From->isLateParsed(), To->isLateParsed()); 7759 } 7760 7761 template <class DT, class AT> 7762 void importAttr(const char *Code, AT *&FromAttr, AT *&ToAttr, 7763 TestLanguage Lang = Lang_CXX11) { 7764 static_assert(std::is_base_of<Attr, AT>::value, "AT should be an Attr"); 7765 static_assert(std::is_base_of<Decl, DT>::value, "DT should be a Decl"); 7766 7767 Decl *FromTU = getTuDecl(Code, Lang, "input.cc"); 7768 DT *FromD = 7769 FirstDeclMatcher<DT>().match(FromTU, namedDecl(hasName("test"))); 7770 ASSERT_TRUE(FromD); 7771 7772 DT *ToD = Import(FromD, Lang_CXX11); 7773 ASSERT_TRUE(ToD); 7774 7775 FromAttr = FromD->template getAttr<AT>(); 7776 ToAttr = ToD->template getAttr<AT>(); 7777 ASSERT_TRUE(FromAttr); 7778 EXPECT_TRUE(ToAttr); 7779 7780 checkAttrImportCommon(FromAttr, ToAttr, ToD); 7781 } 7782 7783 template <class T> void checkImported(const T *From, const T *To) { 7784 EXPECT_TRUE(To); 7785 EXPECT_NE(From, To); 7786 } 7787 7788 template <class T> 7789 void checkImportVariadicArg(const llvm::iterator_range<T **> &From, 7790 const llvm::iterator_range<T **> &To) { 7791 for (auto FromI = From.begin(), ToI = To.begin(); FromI != From.end(); 7792 ++FromI, ++ToI) { 7793 ASSERT_NE(ToI, To.end()); 7794 checkImported(*FromI, *ToI); 7795 } 7796 } 7797 }; 7798 7799 template <> 7800 void ImportAttributes::checkImported<Decl>(const Decl *From, const Decl *To) { 7801 EXPECT_TRUE(To); 7802 EXPECT_NE(From, To); 7803 EXPECT_EQ(To->getTranslationUnitDecl(), 7804 ToAST->getASTContext().getTranslationUnitDecl()); 7805 } 7806 7807 TEST_P(ImportAttributes, ImportAligned) { 7808 AlignedAttr *FromAttr, *ToAttr; 7809 importAttr<RecordDecl>( 7810 R"( 7811 struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; }; 7812 struct alignas(alignof(A)) test {}; 7813 )", 7814 FromAttr, ToAttr); 7815 checkImported(FromAttr->getAlignmentExpr(), ToAttr->getAlignmentExpr()); 7816 7817 auto *ToA = FirstDeclMatcher<CXXRecordDecl>().match( 7818 ToAST->getASTContext().getTranslationUnitDecl(), 7819 cxxRecordDecl(hasName("A"), unless(isImplicit()))); 7820 // Ensure that 'struct A' was imported (through reference from attribute of 7821 // struct 'test'). 7822 EXPECT_TRUE(ToA); 7823 } 7824 7825 TEST_P(ImportAttributes, ImportAlignValue) { 7826 AlignValueAttr *FromAttr, *ToAttr; 7827 importAttr<VarDecl>( 7828 R"( 7829 void *test __attribute__((align_value(64))); 7830 )", 7831 FromAttr, ToAttr); 7832 checkImported(FromAttr->getAlignment(), ToAttr->getAlignment()); 7833 } 7834 7835 TEST_P(ImportAttributes, ImportFormat) { 7836 FormatAttr *FromAttr, *ToAttr; 7837 importAttr<FunctionDecl>( 7838 R"( 7839 int test(const char * fmt, ...) 7840 __attribute__ ((__format__ (__scanf__, 1, 2))); 7841 )", 7842 FromAttr, ToAttr); 7843 7844 EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName()); 7845 EXPECT_EQ(FromAttr->getFirstArg(), ToAttr->getFirstArg()); 7846 EXPECT_EQ(FromAttr->getFormatIdx(), ToAttr->getFormatIdx()); 7847 } 7848 7849 TEST_P(ImportAttributes, ImportEnableIf) { 7850 EnableIfAttr *FromAttr, *ToAttr; 7851 importAttr<FunctionDecl>( 7852 "void test(int A) __attribute__((enable_if(A == 1, \"message\")));", 7853 FromAttr, ToAttr); 7854 checkImported(FromAttr->getCond(), ToAttr->getCond()); 7855 EXPECT_EQ(FromAttr->getMessage(), ToAttr->getMessage()); 7856 } 7857 7858 TEST_P(ImportAttributes, ImportGuardedVar) { 7859 GuardedVarAttr *FromAttr, *ToAttr; 7860 importAttr<VarDecl>("int test __attribute__((guarded_var));", FromAttr, 7861 ToAttr); 7862 } 7863 7864 TEST_P(ImportAttributes, ImportPtGuardedVar) { 7865 PtGuardedVarAttr *FromAttr, *ToAttr; 7866 importAttr<VarDecl>("int *test __attribute__((pt_guarded_var));", FromAttr, 7867 ToAttr); 7868 } 7869 7870 TEST_P(ImportAttributes, ImportScopedLockable) { 7871 ScopedLockableAttr *FromAttr, *ToAttr; 7872 importAttr<CXXRecordDecl>("struct __attribute__((scoped_lockable)) test {};", 7873 FromAttr, ToAttr); 7874 } 7875 7876 TEST_P(ImportAttributes, ImportCapability) { 7877 CapabilityAttr *FromAttr, *ToAttr; 7878 importAttr<CXXRecordDecl>( 7879 "struct __attribute__((capability(\"cap\"))) test {};", FromAttr, ToAttr); 7880 EXPECT_EQ(FromAttr->getName(), ToAttr->getName()); 7881 } 7882 7883 TEST_P(ImportAttributes, ImportAssertCapability) { 7884 AssertCapabilityAttr *FromAttr, *ToAttr; 7885 importAttr<FunctionDecl>( 7886 "void test(int A1, int A2) __attribute__((assert_capability(A1, A2)));", 7887 FromAttr, ToAttr); 7888 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 7889 } 7890 7891 TEST_P(ImportAttributes, ImportAcquireCapability) { 7892 AcquireCapabilityAttr *FromAttr, *ToAttr; 7893 importAttr<FunctionDecl>( 7894 "void test(int A1, int A2) __attribute__((acquire_capability(A1, A2)));", 7895 FromAttr, ToAttr); 7896 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 7897 } 7898 7899 TEST_P(ImportAttributes, ImportTryAcquireCapability) { 7900 TryAcquireCapabilityAttr *FromAttr, *ToAttr; 7901 importAttr<FunctionDecl>( 7902 "void test(int A1, int A2) __attribute__((try_acquire_capability(1, A1, " 7903 "A2)));", 7904 FromAttr, ToAttr); 7905 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); 7906 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 7907 } 7908 7909 TEST_P(ImportAttributes, ImportReleaseCapability) { 7910 ReleaseCapabilityAttr *FromAttr, *ToAttr; 7911 importAttr<FunctionDecl>( 7912 "void test(int A1, int A2) __attribute__((release_capability(A1, A2)));", 7913 FromAttr, ToAttr); 7914 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 7915 } 7916 7917 TEST_P(ImportAttributes, ImportRequiresCapability) { 7918 RequiresCapabilityAttr *FromAttr, *ToAttr; 7919 importAttr<FunctionDecl>( 7920 "void test(int A1, int A2) __attribute__((requires_capability(A1, A2)));", 7921 FromAttr, ToAttr); 7922 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 7923 } 7924 7925 TEST_P(ImportAttributes, ImportNoThreadSafetyAnalysis) { 7926 NoThreadSafetyAnalysisAttr *FromAttr, *ToAttr; 7927 importAttr<FunctionDecl>( 7928 "void test() __attribute__((no_thread_safety_analysis));", FromAttr, 7929 ToAttr); 7930 } 7931 7932 TEST_P(ImportAttributes, ImportGuardedBy) { 7933 GuardedByAttr *FromAttr, *ToAttr; 7934 importAttr<VarDecl>( 7935 R"( 7936 int G; 7937 int test __attribute__((guarded_by(G))); 7938 )", 7939 FromAttr, ToAttr); 7940 checkImported(FromAttr->getArg(), ToAttr->getArg()); 7941 } 7942 7943 TEST_P(ImportAttributes, ImportPtGuardedBy) { 7944 PtGuardedByAttr *FromAttr, *ToAttr; 7945 importAttr<VarDecl>( 7946 R"( 7947 int G; 7948 int *test __attribute__((pt_guarded_by(G))); 7949 )", 7950 FromAttr, ToAttr); 7951 checkImported(FromAttr->getArg(), ToAttr->getArg()); 7952 } 7953 7954 TEST_P(ImportAttributes, ImportAcquiredAfter) { 7955 AcquiredAfterAttr *FromAttr, *ToAttr; 7956 importAttr<VarDecl>( 7957 R"( 7958 struct __attribute__((lockable)) L {}; 7959 L A1; 7960 L A2; 7961 L test __attribute__((acquired_after(A1, A2))); 7962 )", 7963 FromAttr, ToAttr); 7964 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 7965 } 7966 7967 TEST_P(ImportAttributes, ImportAcquiredBefore) { 7968 AcquiredBeforeAttr *FromAttr, *ToAttr; 7969 importAttr<VarDecl>( 7970 R"( 7971 struct __attribute__((lockable)) L {}; 7972 L A1; 7973 L A2; 7974 L test __attribute__((acquired_before(A1, A2))); 7975 )", 7976 FromAttr, ToAttr); 7977 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 7978 } 7979 7980 TEST_P(ImportAttributes, ImportAssertExclusiveLock) { 7981 AssertExclusiveLockAttr *FromAttr, *ToAttr; 7982 importAttr<FunctionDecl>("void test(int A1, int A2) " 7983 "__attribute__((assert_exclusive_lock(A1, A2)));", 7984 FromAttr, ToAttr); 7985 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 7986 } 7987 7988 TEST_P(ImportAttributes, ImportAssertSharedLock) { 7989 AssertSharedLockAttr *FromAttr, *ToAttr; 7990 importAttr<FunctionDecl>( 7991 "void test(int A1, int A2) __attribute__((assert_shared_lock(A1, A2)));", 7992 FromAttr, ToAttr); 7993 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 7994 } 7995 7996 TEST_P(ImportAttributes, ImportExclusiveTrylockFunction) { 7997 ExclusiveTrylockFunctionAttr *FromAttr, *ToAttr; 7998 importAttr<FunctionDecl>( 7999 "void test(int A1, int A2) __attribute__((exclusive_trylock_function(1, " 8000 "A1, A2)));", 8001 FromAttr, ToAttr); 8002 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); 8003 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 8004 } 8005 8006 TEST_P(ImportAttributes, ImportSharedTrylockFunction) { 8007 SharedTrylockFunctionAttr *FromAttr, *ToAttr; 8008 importAttr<FunctionDecl>( 8009 "void test(int A1, int A2) __attribute__((shared_trylock_function(1, A1, " 8010 "A2)));", 8011 FromAttr, ToAttr); 8012 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); 8013 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 8014 } 8015 8016 TEST_P(ImportAttributes, ImportLockReturned) { 8017 LockReturnedAttr *FromAttr, *ToAttr; 8018 importAttr<FunctionDecl>( 8019 "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr, 8020 ToAttr); 8021 checkImported(FromAttr->getArg(), ToAttr->getArg()); 8022 } 8023 8024 TEST_P(ImportAttributes, ImportLocksExcluded) { 8025 LocksExcludedAttr *FromAttr, *ToAttr; 8026 importAttr<FunctionDecl>( 8027 "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));", 8028 FromAttr, ToAttr); 8029 checkImportVariadicArg(FromAttr->args(), ToAttr->args()); 8030 } 8031 8032 TEST_P(ImportAttributes, ImportC99NoThrowAttr) { 8033 NoThrowAttr *FromAttr, *ToAttr; 8034 importAttr<FunctionDecl>("void test () __attribute__ ((__nothrow__));", 8035 FromAttr, ToAttr, Lang_C99); 8036 checkImported(FromAttr->getAttrName(), ToAttr->getAttrName()); 8037 } 8038 8039 template <typename T> 8040 auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) { 8041 auto Copy = Values; 8042 for (std::vector<std::string> &ArgV : Copy) { 8043 for (const std::string &Arg : Args) { 8044 ArgV.push_back(Arg); 8045 } 8046 } 8047 return ::testing::ValuesIn(Copy); 8048 } 8049 8050 struct ImportWithExternalSource : ASTImporterOptionSpecificTestBase { 8051 ImportWithExternalSource() { 8052 Creator = [](ASTContext &ToContext, FileManager &ToFileManager, 8053 ASTContext &FromContext, FileManager &FromFileManager, 8054 bool MinimalImport, 8055 const std::shared_ptr<ASTImporterSharedState> &SharedState) { 8056 return new ASTImporter(ToContext, ToFileManager, FromContext, 8057 // Use minimal import for these tests. 8058 FromFileManager, /*MinimalImport=*/true, 8059 // We use the regular lookup. 8060 /*SharedState=*/nullptr); 8061 }; 8062 } 8063 }; 8064 8065 /// An ExternalASTSource that keeps track of the tags is completed. 8066 struct SourceWithCompletedTagList : clang::ExternalASTSource { 8067 std::vector<clang::TagDecl *> &CompletedTags; 8068 SourceWithCompletedTagList(std::vector<clang::TagDecl *> &CompletedTags) 8069 : CompletedTags(CompletedTags) {} 8070 void CompleteType(TagDecl *Tag) override { 8071 auto *Record = cast<CXXRecordDecl>(Tag); 8072 Record->startDefinition(); 8073 Record->completeDefinition(); 8074 CompletedTags.push_back(Tag); 8075 } 8076 using clang::ExternalASTSource::CompleteType; 8077 }; 8078 8079 TEST_P(ImportWithExternalSource, CompleteRecordBeforeImporting) { 8080 // Create an empty TU. 8081 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cpp"); 8082 8083 // Create and add the test ExternalASTSource. 8084 std::vector<clang::TagDecl *> CompletedTags; 8085 IntrusiveRefCntPtr<ExternalASTSource> source = 8086 new SourceWithCompletedTagList(CompletedTags); 8087 clang::ASTContext &Context = FromTU->getASTContext(); 8088 Context.setExternalSource(std::move(source)); 8089 8090 // Create a dummy class by hand with external lexical storage. 8091 IdentifierInfo &Ident = Context.Idents.get("test_class"); 8092 auto *Record = 8093 CXXRecordDecl::Create(Context, TagTypeKind::Class, FromTU, 8094 SourceLocation(), SourceLocation(), &Ident); 8095 Record->setHasExternalLexicalStorage(); 8096 FromTU->addDecl(Record); 8097 8098 // Do a minimal import of the created class. 8099 EXPECT_EQ(0U, CompletedTags.size()); 8100 Import(Record, Lang_CXX03); 8101 EXPECT_EQ(0U, CompletedTags.size()); 8102 8103 // Import the definition of the created class. 8104 llvm::Error Err = findFromTU(Record)->Importer->ImportDefinition(Record); 8105 EXPECT_FALSE((bool)Err); 8106 consumeError(std::move(Err)); 8107 8108 // Make sure the class was completed once. 8109 EXPECT_EQ(1U, CompletedTags.size()); 8110 EXPECT_EQ(Record, CompletedTags.front()); 8111 } 8112 8113 TEST_P(ImportFunctions, CTADImplicit) { 8114 Decl *FromTU = getTuDecl( 8115 R"( 8116 template <typename T> struct A { 8117 A(T); 8118 }; 8119 A a{(int)0}; 8120 )", 8121 Lang_CXX17, "input.cc"); 8122 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 8123 FromTU, 8124 cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>"))))); 8125 auto *ToD = Import(FromD, Lang_CXX17); 8126 ASSERT_TRUE(ToD); 8127 EXPECT_EQ(ToD->getDeductionCandidateKind(), DeductionCandidate::Copy); 8128 EXPECT_EQ(ToD->getSourceDeductionGuide(), nullptr); 8129 EXPECT_EQ(ToD->getSourceDeductionGuideKind(), 8130 CXXDeductionGuideDecl::SourceDeductionGuideKind::None); 8131 // Check that the deduced class template is also imported. 8132 EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull( 8133 FromD->getDeducedTemplate())); 8134 } 8135 8136 TEST_P(ImportFunctions, CTADUserDefinedExplicit) { 8137 Decl *FromTU = getTuDecl( 8138 R"( 8139 template <typename T> struct A { 8140 A(T); 8141 }; 8142 template <typename T> explicit A(T) -> A<float>; 8143 A a{(int)0}; // calls A<float>::A(float) 8144 )", 8145 Lang_CXX17, "input.cc"); 8146 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 8147 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 8148 // Not-implicit: i.e. not compiler-generated, user defined. 8149 ASSERT_FALSE(FromD->isImplicit()); 8150 ASSERT_TRUE(FromD->isExplicit()); // Has the explicit keyword. 8151 auto *ToD = Import(FromD, Lang_CXX17); 8152 ASSERT_TRUE(ToD); 8153 EXPECT_FALSE(FromD->isImplicit()); 8154 EXPECT_TRUE(ToD->isExplicit()); 8155 EXPECT_EQ(ToD->getSourceDeductionGuide(), nullptr); 8156 EXPECT_EQ(ToD->getSourceDeductionGuideKind(), 8157 CXXDeductionGuideDecl::SourceDeductionGuideKind::None); 8158 } 8159 8160 TEST_P(ImportFunctions, CTADWithLocalTypedef) { 8161 Decl *TU = getTuDecl( 8162 R"( 8163 template <typename T> struct A { 8164 typedef T U; 8165 A(U); 8166 }; 8167 A a{(int)0}; 8168 )", 8169 Lang_CXX17, "input.cc"); 8170 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 8171 TU, cxxDeductionGuideDecl()); 8172 auto *ToD = Import(FromD, Lang_CXX17); 8173 ASSERT_TRUE(ToD); 8174 } 8175 8176 TEST_P(ImportFunctions, CTADAliasTemplate) { 8177 Decl *TU = getTuDecl( 8178 R"( 8179 template <typename T> struct A { 8180 A(T); 8181 }; 8182 template<typename T> 8183 using B = A<T>; 8184 B b{(int)0}; 8185 )", 8186 Lang_CXX20, "input.cc"); 8187 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 8188 TU, cxxDeductionGuideDecl(hasParameter(0, hasType(asString("int"))))); 8189 auto *ToD = Import(FromD, Lang_CXX20); 8190 ASSERT_TRUE(ToD); 8191 EXPECT_TRUE(ToD->getSourceDeductionGuideKind() == 8192 CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias); 8193 EXPECT_TRUE(ToD->getSourceDeductionGuide()); 8194 } 8195 8196 TEST_P(ImportFunctions, ParmVarDeclDeclContext) { 8197 constexpr auto FromTUCode = R"( 8198 void f(int P); 8199 )"; 8200 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11); 8201 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 8202 FromTU, functionDecl(hasName("f"))); 8203 ASSERT_TRUE(FromF); 8204 8205 auto *ImportedF = Import(FromF, Lang_CXX11); 8206 EXPECT_TRUE(ImportedF); 8207 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 8208 ImportedF, ImportedF->getParamDecl(0))); 8209 } 8210 8211 // FIXME Move these tests out of ASTImporterTest. For that we need to factor 8212 // out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase 8213 // into a new test Fixture. Then we should lift up this Fixture to its own 8214 // implementation file and only then could we reuse the Fixture in other AST 8215 // unitttests. 8216 struct CTAD : ASTImporterOptionSpecificTestBase {}; 8217 8218 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) { 8219 Decl *TU = getTuDecl( 8220 R"( 8221 typedef int U; 8222 template <typename T> struct A { 8223 A(U, T); 8224 }; 8225 A a{(int)0, (int)0}; 8226 )", 8227 Lang_CXX17, "input.cc"); 8228 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 8229 TU, cxxDeductionGuideDecl()); 8230 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 8231 TU, typedefNameDecl(hasName("U"))); 8232 ParmVarDecl *Param = Guide->getParamDecl(0); 8233 // The type of the first param (which is a typedef) should match the typedef 8234 // in the global scope. 8235 EXPECT_EQ(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef); 8236 } 8237 8238 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) { 8239 Decl *TU = getTuDecl( 8240 R"( 8241 typedef int U; 8242 template <typename T> struct A { 8243 A(U*, T); 8244 }; 8245 A a{(int*)0, (int)0}; 8246 )", 8247 Lang_CXX17, "input.cc"); 8248 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 8249 TU, cxxDeductionGuideDecl()); 8250 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 8251 TU, typedefNameDecl(hasName("U"))); 8252 ParmVarDecl *Param = Guide->getParamDecl(0); 8253 EXPECT_EQ(Param->getType() 8254 ->getAs<PointerType>() 8255 ->getPointeeType() 8256 ->getAs<TypedefType>() 8257 ->getDecl(), 8258 Typedef); 8259 } 8260 8261 TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) { 8262 Decl *TU = getTuDecl( 8263 R"( 8264 template <typename T> struct A { 8265 typedef T U; 8266 A(U, T); 8267 }; 8268 A a{(int)0, (int)0}; 8269 )", 8270 Lang_CXX17, "input.cc"); 8271 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 8272 TU, cxxDeductionGuideDecl()); 8273 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match( 8274 TU, typedefNameDecl(hasName("U"))); 8275 ParmVarDecl *Param = Guide->getParamDecl(0); 8276 EXPECT_NE(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef); 8277 } 8278 8279 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CTAD, 8280 DefaultTestValuesForRunOptions); 8281 8282 TEST_P(ASTImporterOptionSpecificTestBase, TypedefWithAttribute) { 8283 Decl *TU = getTuDecl( 8284 R"( 8285 namespace N { 8286 typedef int X __attribute__((annotate("A"))); 8287 } 8288 )", 8289 Lang_CXX17, "input.cc"); 8290 auto *FromD = 8291 FirstDeclMatcher<TypedefDecl>().match(TU, typedefDecl(hasName("X"))); 8292 auto *ToD = Import(FromD, Lang_CXX17); 8293 ASSERT_TRUE(ToD); 8294 ASSERT_EQ(ToD->getAttrs().size(), 1U); 8295 auto *ToAttr = dyn_cast<AnnotateAttr>(ToD->getAttrs()[0]); 8296 ASSERT_TRUE(ToAttr); 8297 EXPECT_EQ(ToAttr->getAnnotation(), "A"); 8298 } 8299 8300 TEST_P(ASTImporterOptionSpecificTestBase, 8301 ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) { 8302 Decl *FromTU = getTuDecl( 8303 R"( 8304 8305 namespace std { 8306 template<typename T> 8307 class basic_stringbuf; 8308 } 8309 namespace std { 8310 class char_traits; 8311 template<typename T = char_traits> 8312 class basic_stringbuf; 8313 } 8314 namespace std { 8315 template<typename T> 8316 class basic_stringbuf {}; 8317 } 8318 8319 )", 8320 Lang_CXX11); 8321 8322 auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match( 8323 FromTU, 8324 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); 8325 auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11)); 8326 EXPECT_TRUE(To1); 8327 8328 auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match( 8329 FromTU, 8330 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); 8331 auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11)); 8332 EXPECT_TRUE(To2); 8333 } 8334 8335 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfCapturedVLAType) { 8336 Decl *FromTU = getTuDecl( 8337 R"( 8338 void declToImport(int N) { 8339 int VLA[N]; 8340 [&VLA] {}; // FieldDecl inside the lambda. 8341 } 8342 )", 8343 Lang_CXX14); 8344 auto *FromFD = FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl()); 8345 ASSERT_TRUE(FromFD); 8346 ASSERT_TRUE(FromFD->hasCapturedVLAType()); 8347 8348 auto *ToFD = Import(FromFD, Lang_CXX14); 8349 EXPECT_TRUE(ToFD); 8350 EXPECT_TRUE(ToFD->hasCapturedVLAType()); 8351 EXPECT_NE(FromFD->getCapturedVLAType(), ToFD->getCapturedVLAType()); 8352 } 8353 8354 TEST_P(ASTImporterOptionSpecificTestBase, ImportEnumMemberSpecialization) { 8355 Decl *FromTU = getTuDecl( 8356 R"( 8357 template <class T> struct A { 8358 enum tagname { enumerator }; 8359 }; 8360 template struct A<int>; 8361 )", 8362 Lang_CXX03); 8363 auto *FromD = FirstDeclMatcher<EnumDecl>().match( 8364 FromTU, enumDecl(hasName("tagname"), 8365 hasParent(classTemplateSpecializationDecl()))); 8366 ASSERT_TRUE(FromD); 8367 ASSERT_TRUE(FromD->getMemberSpecializationInfo()); 8368 8369 auto *ToD = Import(FromD, Lang_CXX03); 8370 EXPECT_TRUE(ToD); 8371 EXPECT_TRUE(ToD->getMemberSpecializationInfo()); 8372 EXPECT_EQ(FromD->getTemplateSpecializationKind(), 8373 ToD->getTemplateSpecializationKind()); 8374 } 8375 8376 TEST_P(ASTImporterOptionSpecificTestBase, ImportIsInheritingConstructorBit) { 8377 Decl *FromTU = getTuDecl( 8378 R"( 8379 struct A { 8380 A(int); 8381 }; 8382 struct B : A { 8383 using A::A; // Inherited ctor. 8384 }; 8385 void f() { 8386 (B(0)); 8387 } 8388 )", 8389 Lang_CXX11); 8390 auto *FromD = FirstDeclMatcher<CXXConstructorDecl>().match( 8391 FromTU, cxxConstructorDecl(isInheritingConstructor())); 8392 ASSERT_TRUE(FromD); 8393 ASSERT_TRUE(FromD->isInheritingConstructor()); 8394 8395 auto *ToD = Import(FromD, Lang_CXX11); 8396 ASSERT_TRUE(ToD); 8397 EXPECT_TRUE(ToD->isInheritingConstructor()); 8398 } 8399 8400 TEST_P(ASTImporterOptionSpecificTestBase, ImportConstructorUsingShadow) { 8401 TranslationUnitDecl *FromTU = getTuDecl( 8402 R"( 8403 struct A { 8404 A(int, int); 8405 }; 8406 struct B : A { 8407 using A::A; 8408 }; 8409 struct C : B { 8410 using B::B; 8411 }; 8412 )", 8413 Lang_CXX11); 8414 8415 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordC) { 8416 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match( 8417 TU, cxxRecordDecl(hasName("A"))); 8418 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match( 8419 TU, cxxRecordDecl(hasName("B"))); 8420 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match( 8421 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)), 8422 parameterCountIs(2))); 8423 auto *ShadowBA = cast<ConstructorUsingShadowDecl>( 8424 FirstDeclMatcher<UsingShadowDecl>().match( 8425 TU, usingShadowDecl(hasParent(equalsNode(RecordB)), 8426 hasTargetDecl(equalsNode(ConstrA))))); 8427 auto *ShadowCA = cast<ConstructorUsingShadowDecl>( 8428 FirstDeclMatcher<UsingShadowDecl>().match( 8429 TU, usingShadowDecl(hasParent(equalsNode(RecordC)), 8430 hasTargetDecl(equalsNode(ConstrA))))); 8431 EXPECT_EQ(ShadowBA->getTargetDecl(), ConstrA); 8432 EXPECT_EQ(ShadowBA->getNominatedBaseClass(), RecordA); 8433 EXPECT_EQ(ShadowBA->getConstructedBaseClass(), RecordA); 8434 EXPECT_EQ(ShadowBA->getNominatedBaseClassShadowDecl(), nullptr); 8435 EXPECT_EQ(ShadowBA->getConstructedBaseClassShadowDecl(), nullptr); 8436 EXPECT_FALSE(ShadowBA->constructsVirtualBase()); 8437 EXPECT_EQ(ShadowCA->getTargetDecl(), ConstrA); 8438 EXPECT_EQ(ShadowCA->getNominatedBaseClass(), RecordB); 8439 EXPECT_EQ(ShadowCA->getConstructedBaseClass(), RecordB); 8440 EXPECT_EQ(ShadowCA->getNominatedBaseClassShadowDecl(), ShadowBA); 8441 EXPECT_EQ(ShadowCA->getConstructedBaseClassShadowDecl(), ShadowBA); 8442 EXPECT_FALSE(ShadowCA->constructsVirtualBase()); 8443 }; 8444 8445 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match( 8446 FromTU, cxxRecordDecl(hasName("C"))); 8447 8448 auto *ToC = Import(FromC, Lang_CXX11); 8449 TranslationUnitDecl *ToTU = ToC->getTranslationUnitDecl(); 8450 8451 CheckAST(FromTU, FromC); 8452 CheckAST(ToTU, ToC); 8453 } 8454 8455 TEST_P(ASTImporterOptionSpecificTestBase, 8456 ImportFunctionDeclBitShouldNotOverwriteCtorDeclBits) { 8457 Decl *From, *To; 8458 std::tie(From, To) = getImportedDecl( 8459 R"s( 8460 struct A { 8461 A() : m() {} 8462 int m; 8463 }; 8464 8465 A foo() { A a; return a; } 8466 A bar() { return {}; } 8467 )s", 8468 Lang_CXX17, 8469 R"s( 8470 struct A { 8471 A() : m() {} 8472 int m; 8473 }; 8474 A baz() { return {}; } 8475 )s", 8476 Lang_CXX17, "A"); 8477 8478 auto HasCtorInit = 8479 hasAnyConstructorInitializer(cxxCtorInitializer(isMemberInitializer())); 8480 auto ImpMoveCtor = 8481 cxxConstructorDecl(isMoveConstructor(), isImplicit(), HasCtorInit); 8482 8483 auto *FromImpMoveCtor = FirstDeclMatcher<CXXConstructorDecl>().match( 8484 From, ImpMoveCtor); 8485 auto *ToImpMoveCtor = FirstDeclMatcher<CXXConstructorDecl>().match( 8486 To, ImpMoveCtor); 8487 8488 EXPECT_TRUE(FromImpMoveCtor->getNumCtorInitializers() == 1); 8489 EXPECT_FALSE(FromImpMoveCtor->FriendConstraintRefersToEnclosingTemplate()); 8490 8491 EXPECT_TRUE(ToImpMoveCtor->getNumCtorInitializers() == 1); 8492 EXPECT_FALSE(ToImpMoveCtor->FriendConstraintRefersToEnclosingTemplate()); 8493 EXPECT_TRUE(*ToImpMoveCtor->init_begin()); 8494 } 8495 8496 AST_MATCHER_P(UsingShadowDecl, hasIntroducerDecl, internal::Matcher<NamedDecl>, 8497 InnerMatcher) { 8498 return InnerMatcher.matches(*Node.getIntroducer(), Finder, Builder); 8499 } 8500 8501 TEST_P(ASTImporterOptionSpecificTestBase, 8502 ImportConstructorUsingShadowVirtualBase) { 8503 TranslationUnitDecl *FromTU = getTuDecl( 8504 R"( 8505 struct A { A(int, int); }; 8506 struct B : A { using A::A; }; 8507 8508 struct V1 : virtual B { using B::B; }; 8509 struct V2 : virtual B { using B::B; }; 8510 8511 struct D2 : V1, V2 { 8512 using V1::V1; 8513 using V2::V2; 8514 }; 8515 )", 8516 Lang_CXX11); 8517 8518 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordD2) { 8519 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match( 8520 TU, cxxRecordDecl(hasName("A"))); 8521 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match( 8522 TU, cxxRecordDecl(hasName("B"))); 8523 auto *RecordV1 = FirstDeclMatcher<CXXRecordDecl>().match( 8524 TU, cxxRecordDecl(hasName("V1"))); 8525 auto *RecordV2 = FirstDeclMatcher<CXXRecordDecl>().match( 8526 TU, cxxRecordDecl(hasName("V2"))); 8527 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match( 8528 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)), 8529 parameterCountIs(2))); 8530 auto *ConstrB = FirstDeclMatcher<CXXConstructorDecl>().match( 8531 TU, cxxConstructorDecl(hasParent(equalsNode(RecordB)), 8532 isCopyConstructor())); 8533 auto *UsingD2V1 = FirstDeclMatcher<UsingDecl>().match( 8534 TU, usingDecl(hasParent(equalsNode(RecordD2)))); 8535 auto *UsingD2V2 = LastDeclMatcher<UsingDecl>().match( 8536 TU, usingDecl(hasParent(equalsNode(RecordD2)))); 8537 auto *ShadowBA = cast<ConstructorUsingShadowDecl>( 8538 FirstDeclMatcher<UsingShadowDecl>().match( 8539 TU, usingShadowDecl(hasParent(equalsNode(RecordB)), 8540 hasTargetDecl(equalsNode(ConstrA))))); 8541 auto *ShadowV1A = cast<ConstructorUsingShadowDecl>( 8542 FirstDeclMatcher<UsingShadowDecl>().match( 8543 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)), 8544 hasTargetDecl(equalsNode(ConstrA))))); 8545 auto *ShadowV1B = cast<ConstructorUsingShadowDecl>( 8546 FirstDeclMatcher<UsingShadowDecl>().match( 8547 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)), 8548 hasTargetDecl(equalsNode(ConstrB))))); 8549 auto *ShadowV2A = cast<ConstructorUsingShadowDecl>( 8550 FirstDeclMatcher<UsingShadowDecl>().match( 8551 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)), 8552 hasTargetDecl(equalsNode(ConstrA))))); 8553 auto *ShadowV2B = cast<ConstructorUsingShadowDecl>( 8554 FirstDeclMatcher<UsingShadowDecl>().match( 8555 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)), 8556 hasTargetDecl(equalsNode(ConstrB))))); 8557 auto *ShadowD2V1A = cast<ConstructorUsingShadowDecl>( 8558 FirstDeclMatcher<UsingShadowDecl>().match( 8559 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 8560 hasIntroducerDecl(equalsNode(UsingD2V1)), 8561 hasTargetDecl(equalsNode(ConstrA))))); 8562 auto *ShadowD2V1B = cast<ConstructorUsingShadowDecl>( 8563 FirstDeclMatcher<UsingShadowDecl>().match( 8564 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 8565 hasIntroducerDecl(equalsNode(UsingD2V1)), 8566 hasTargetDecl(equalsNode(ConstrB))))); 8567 auto *ShadowD2V2A = cast<ConstructorUsingShadowDecl>( 8568 FirstDeclMatcher<UsingShadowDecl>().match( 8569 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 8570 hasIntroducerDecl(equalsNode(UsingD2V2)), 8571 hasTargetDecl(equalsNode(ConstrA))))); 8572 auto *ShadowD2V2B = cast<ConstructorUsingShadowDecl>( 8573 FirstDeclMatcher<UsingShadowDecl>().match( 8574 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)), 8575 hasIntroducerDecl(equalsNode(UsingD2V2)), 8576 hasTargetDecl(equalsNode(ConstrB))))); 8577 8578 EXPECT_EQ(ShadowD2V1A->getTargetDecl(), ConstrA); 8579 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClassShadowDecl(), ShadowV1A); 8580 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClass(), RecordV1); 8581 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClassShadowDecl(), ShadowBA); 8582 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClass(), RecordB); 8583 EXPECT_TRUE(ShadowD2V1A->constructsVirtualBase()); 8584 EXPECT_EQ(ShadowD2V1B->getTargetDecl(), ConstrB); 8585 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClassShadowDecl(), ShadowV1B); 8586 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClass(), RecordV1); 8587 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClassShadowDecl(), nullptr); 8588 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClass(), RecordB); 8589 EXPECT_TRUE(ShadowD2V1B->constructsVirtualBase()); 8590 EXPECT_EQ(ShadowD2V2A->getTargetDecl(), ConstrA); 8591 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClassShadowDecl(), ShadowV2A); 8592 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClass(), RecordV2); 8593 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClassShadowDecl(), ShadowBA); 8594 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClass(), RecordB); 8595 EXPECT_TRUE(ShadowD2V2A->constructsVirtualBase()); 8596 EXPECT_EQ(ShadowD2V2B->getTargetDecl(), ConstrB); 8597 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClassShadowDecl(), ShadowV2B); 8598 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClass(), RecordV2); 8599 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClassShadowDecl(), nullptr); 8600 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClass(), RecordB); 8601 EXPECT_TRUE(ShadowD2V2B->constructsVirtualBase()); 8602 8603 EXPECT_TRUE(ShadowV1A->constructsVirtualBase()); 8604 EXPECT_TRUE(ShadowV1B->constructsVirtualBase()); 8605 EXPECT_TRUE(ShadowV2A->constructsVirtualBase()); 8606 EXPECT_TRUE(ShadowV2B->constructsVirtualBase()); 8607 EXPECT_FALSE(ShadowBA->constructsVirtualBase()); 8608 }; 8609 8610 auto *FromD2 = FirstDeclMatcher<CXXRecordDecl>().match( 8611 FromTU, cxxRecordDecl(hasName("D2"))); 8612 8613 auto *ToD2 = Import(FromD2, Lang_CXX11); 8614 TranslationUnitDecl *ToTU = ToD2->getTranslationUnitDecl(); 8615 8616 CheckAST(FromTU, FromD2); 8617 CheckAST(ToTU, ToD2); 8618 } 8619 8620 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingShadowList) { 8621 TranslationUnitDecl *FromTU = getTuDecl( 8622 R"( 8623 struct A { 8624 void f(); 8625 void f(int); 8626 }; 8627 struct B : A { 8628 using A::f; 8629 }; 8630 )", 8631 Lang_CXX11); 8632 8633 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match( 8634 FromTU, cxxRecordDecl(hasName("B"))); 8635 8636 auto *ToB = Import(FromB, Lang_CXX11); 8637 TranslationUnitDecl *ToTU = ToB->getTranslationUnitDecl(); 8638 8639 auto *ToUsing = FirstDeclMatcher<UsingDecl>().match( 8640 ToTU, usingDecl(hasParent(equalsNode(ToB)))); 8641 auto *ToUsingShadowF1 = FirstDeclMatcher<UsingShadowDecl>().match( 8642 ToTU, usingShadowDecl(hasTargetDecl( 8643 functionDecl(hasName("f"), parameterCountIs(0))))); 8644 auto *ToUsingShadowF2 = FirstDeclMatcher<UsingShadowDecl>().match( 8645 ToTU, usingShadowDecl(hasTargetDecl( 8646 functionDecl(hasName("f"), parameterCountIs(1))))); 8647 8648 EXPECT_EQ(ToUsing->shadow_size(), 2u); 8649 auto ShadowI = ToUsing->shadow_begin(); 8650 EXPECT_EQ(*ShadowI, ToUsingShadowF1); 8651 ++ShadowI; 8652 EXPECT_EQ(*ShadowI, ToUsingShadowF2); 8653 } 8654 8655 AST_MATCHER_P(FunctionTemplateDecl, templateParameterCountIs, unsigned, Cnt) { 8656 return Node.getTemplateParameters()->size() == Cnt; 8657 } 8658 8659 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuide) { 8660 TranslationUnitDecl *FromTU = getTuDecl( 8661 R"( 8662 template<class> class A { }; 8663 template<class T> class B { 8664 template<class T1, typename = A<T>> B(T1); 8665 }; 8666 template<class T> 8667 B(T, T) -> B<int>; 8668 )", 8669 Lang_CXX17); 8670 8671 // Get the implicit deduction guide for (non-default) constructor of 'B'. 8672 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 8673 FromTU, functionTemplateDecl(templateParameterCountIs(3))); 8674 // Implicit deduction guide for copy constructor of 'B'. 8675 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 8676 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit())); 8677 // User defined deduction guide. 8678 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 8679 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 8680 8681 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters(); 8682 // Don't know why exactly but this is the DeclContext here. 8683 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(), 8684 FromDGCopyCtor->getTemplatedDecl()); 8685 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(), 8686 FromDGCtor->getTemplatedDecl()); 8687 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(), 8688 FromDGCtor->getTemplatedDecl()); 8689 EXPECT_EQ( 8690 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 8691 FromDGCopyCtor->getTemplatedDecl()); 8692 EXPECT_EQ(FromDGOther->getDescribedTemplate() 8693 ->getTemplateParameters() 8694 ->getParam(0) 8695 ->getDeclContext(), 8696 FromDGOther); 8697 8698 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17); 8699 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17); 8700 auto *ToDGOther = Import(FromDGOther, Lang_CXX17); 8701 ASSERT_TRUE(ToDGCtor); 8702 ASSERT_TRUE(ToDGCopyCtor); 8703 ASSERT_TRUE(ToDGOther); 8704 8705 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters(); 8706 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(), 8707 ToDGCopyCtor->getTemplatedDecl()); 8708 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(), 8709 ToDGCtor->getTemplatedDecl()); 8710 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(), 8711 ToDGCtor->getTemplatedDecl()); 8712 EXPECT_EQ( 8713 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 8714 ToDGCopyCtor->getTemplatedDecl()); 8715 EXPECT_EQ(ToDGOther->getDescribedTemplate() 8716 ->getTemplateParameters() 8717 ->getParam(0) 8718 ->getDeclContext(), 8719 ToDGOther); 8720 } 8721 8722 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuideDifferentOrder) { 8723 // This test demonstrates that the DeclContext of the imported object is 8724 // dependent on the order of import. The test is an exact copy of the previous 8725 // one except at the indicated locations. 8726 TranslationUnitDecl *FromTU = getTuDecl( 8727 R"( 8728 template<class> class A { }; 8729 template<class T> class B { 8730 template<class T1, typename = A<T>> B(T1); 8731 }; 8732 template<class T> 8733 B(T, T) -> B<int>; 8734 )", 8735 Lang_CXX17); 8736 8737 // Get the implicit deduction guide for (non-default) constructor of 'B'. 8738 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 8739 FromTU, functionTemplateDecl(templateParameterCountIs(3))); 8740 // Implicit deduction guide for copy constructor of 'B'. 8741 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match( 8742 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit())); 8743 // User defined deduction guide. 8744 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match( 8745 FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); 8746 8747 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters(); 8748 // Don't know why exactly but this is the DeclContext here. 8749 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(), 8750 FromDGCopyCtor->getTemplatedDecl()); 8751 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(), 8752 FromDGCtor->getTemplatedDecl()); 8753 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(), 8754 FromDGCtor->getTemplatedDecl()); 8755 EXPECT_EQ( 8756 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 8757 FromDGCopyCtor->getTemplatedDecl()); 8758 EXPECT_EQ(FromDGOther->getDescribedTemplate() 8759 ->getTemplateParameters() 8760 ->getParam(0) 8761 ->getDeclContext(), 8762 FromDGOther); 8763 8764 // Here the import of 'ToDGCopyCtor' and 'ToDGCtor' is reversed relative to 8765 // the previous test. 8766 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17); 8767 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17); 8768 auto *ToDGOther = Import(FromDGOther, Lang_CXX17); 8769 ASSERT_TRUE(ToDGCtor); 8770 ASSERT_TRUE(ToDGCopyCtor); 8771 ASSERT_TRUE(ToDGOther); 8772 8773 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters(); 8774 // Next line: DeclContext is different relative to the previous test. 8775 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(), 8776 ToDGCtor->getTemplatedDecl()); 8777 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(), 8778 ToDGCtor->getTemplatedDecl()); 8779 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(), 8780 ToDGCtor->getTemplatedDecl()); 8781 // Next line: DeclContext is different relative to the previous test. 8782 EXPECT_EQ( 8783 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(), 8784 ToDGCtor->getTemplatedDecl()); 8785 EXPECT_EQ(ToDGOther->getDescribedTemplate() 8786 ->getTemplateParameters() 8787 ->getParam(0) 8788 ->getDeclContext(), 8789 ToDGOther); 8790 } 8791 8792 TEST_P(ASTImporterOptionSpecificTestBase, 8793 ImportFieldsFirstForCorrectRecordLayout) { 8794 // UnaryOperator(&) triggers RecordLayout computation, which relies on 8795 // correctly imported fields. 8796 auto Code = 8797 R"( 8798 class A { 8799 int m() { 8800 return &((A *)0)->f1 - &((A *)0)->f2; 8801 } 8802 int f1; 8803 int f2; 8804 }; 8805 )"; 8806 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 8807 8808 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match( 8809 FromTU, cxxMethodDecl(hasName("A::m"))); 8810 Import(FromF, Lang_CXX11); 8811 } 8812 8813 TEST_P(ASTImporterOptionSpecificTestBase, 8814 ImportCirularRefFieldsWithoutCorruptedRecordLayoutCache) { 8815 // Import sequence: A => A.b => B => B.f() => ... => UnaryOperator(&) => ... 8816 // 8817 // UnaryOperator(&) should not introduce invalid RecordLayout since 'A' is 8818 // still not completely imported. 8819 auto Code = 8820 R"( 8821 class B; 8822 class A { 8823 B* b; 8824 int c; 8825 }; 8826 class B { 8827 A *f() { return &((B *)0)->a; } 8828 A a; 8829 }; 8830 )"; 8831 8832 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 8833 getTuDecl(Code, Lang_CXX11), cxxRecordDecl(hasName("A"))); 8834 FromR = FromR->getDefinition(); 8835 auto &FromAST = FromR->getASTContext(); 8836 auto *ToR = Import(FromR, Lang_CXX11); 8837 auto &ToAST = ToR->getASTContext(); 8838 8839 uint64_t SecondFieldOffset = FromAST.getTypeSize(FromAST.VoidPtrTy); 8840 8841 EXPECT_TRUE(FromR->isCompleteDefinition()); 8842 const auto &FromLayout = FromAST.getASTRecordLayout(FromR); 8843 EXPECT_TRUE(FromLayout.getFieldOffset(0) == 0); 8844 EXPECT_TRUE(FromLayout.getFieldOffset(1) == SecondFieldOffset); 8845 8846 EXPECT_TRUE(ToR->isCompleteDefinition()); 8847 const auto &ToLayout = ToAST.getASTRecordLayout(ToR); 8848 EXPECT_TRUE(ToLayout.getFieldOffset(0) == 0); 8849 EXPECT_TRUE(ToLayout.getFieldOffset(1) == SecondFieldOffset); 8850 } 8851 8852 TEST_P(ASTImporterOptionSpecificTestBase, 8853 ImportRecordWithLayoutRequestingExpr) { 8854 TranslationUnitDecl *FromTU = getTuDecl( 8855 R"( 8856 struct A { 8857 int idx; 8858 static void foo(A x) { 8859 (void)&"text"[x.idx]; 8860 } 8861 }; 8862 )", 8863 Lang_CXX11); 8864 8865 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 8866 FromTU, cxxRecordDecl(hasName("A"))); 8867 8868 // Test that during import of 'foo' the record layout can be obtained without 8869 // crash. 8870 auto *ToA = Import(FromA, Lang_CXX11); 8871 EXPECT_TRUE(ToA); 8872 EXPECT_TRUE(ToA->isCompleteDefinition()); 8873 } 8874 8875 TEST_P(ASTImporterOptionSpecificTestBase, 8876 ImportRecordWithLayoutRequestingExprDifferentRecord) { 8877 TranslationUnitDecl *FromTU = getTuDecl( 8878 R"( 8879 struct B; 8880 struct A { 8881 int idx; 8882 B *b; 8883 }; 8884 struct B { 8885 static void foo(A x) { 8886 (void)&"text"[x.idx]; 8887 } 8888 }; 8889 )", 8890 Lang_CXX11); 8891 8892 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 8893 FromTU, cxxRecordDecl(hasName("A"))); 8894 8895 // Test that during import of 'foo' the record layout (of 'A') can be obtained 8896 // without crash. It is not possible to have all of the fields of 'A' imported 8897 // at that time (without big code changes). 8898 auto *ToA = Import(FromA, Lang_CXX11); 8899 EXPECT_TRUE(ToA); 8900 EXPECT_TRUE(ToA->isCompleteDefinition()); 8901 } 8902 8903 TEST_P(ASTImporterOptionSpecificTestBase, ImportInClassInitializerFromField) { 8904 // Encounter import of a field when the field already exists but has the 8905 // in-class initializer expression not yet set. Such case can occur in the AST 8906 // of generated template specializations. 8907 // The first code forces to create a template specialization of 8908 // `A<int>` but without implicit constructors. 8909 // The second ("From") code contains a variable of type `A<int>`, this 8910 // results in a template specialization that has constructors and 8911 // CXXDefaultInitExpr nodes. 8912 Decl *ToTU = getToTuDecl( 8913 R"( 8914 void f(); 8915 template<typename> struct A { int X = 1; }; 8916 struct B { A<int> Y; }; 8917 )", 8918 Lang_CXX11); 8919 auto *ToX = FirstDeclMatcher<FieldDecl>().match( 8920 ToTU, 8921 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl()))); 8922 ASSERT_TRUE(ToX->hasInClassInitializer()); 8923 ASSERT_FALSE(ToX->getInClassInitializer()); 8924 8925 Decl *FromTU = getTuDecl( 8926 R"( 8927 void f(); 8928 template<typename> struct A { int X = 1; }; 8929 struct B { A<int> Y; }; 8930 // 8931 A<int> Z; 8932 )", 8933 Lang_CXX11, "input1.cc"); 8934 auto *FromX = FirstDeclMatcher<FieldDecl>().match( 8935 FromTU, 8936 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl()))); 8937 8938 auto *ToXImported = Import(FromX, Lang_CXX11); 8939 EXPECT_EQ(ToXImported, ToX); 8940 EXPECT_TRUE(ToX->getInClassInitializer()); 8941 } 8942 8943 TEST_P(ASTImporterOptionSpecificTestBase, 8944 ImportInClassInitializerFromCXXDefaultInitExpr) { 8945 // Encounter AST import of a CXXDefaultInitExpr where the "to-field" 8946 // of it exists but has the in-class initializer not set yet. 8947 Decl *ToTU = getToTuDecl( 8948 R"( 8949 namespace N { 8950 template<typename> int b; 8951 struct X; 8952 } 8953 template<typename> struct A { N::X *X = nullptr; }; 8954 struct B { A<int> Y; }; 8955 )", 8956 Lang_CXX14); 8957 auto *ToX = FirstDeclMatcher<FieldDecl>().match( 8958 ToTU, 8959 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl()))); 8960 ASSERT_TRUE(ToX->hasInClassInitializer()); 8961 ASSERT_FALSE(ToX->getInClassInitializer()); 8962 8963 Decl *FromTU = getTuDecl( 8964 R"( 8965 namespace N { 8966 template<typename> int b; 8967 struct X; 8968 } 8969 template<typename> struct A { N::X *X = nullptr; }; 8970 struct B { A<int> Y; }; 8971 // 8972 void f() { 8973 (void)A<int>{}; 8974 } 8975 struct C { 8976 C(): attr(new A<int>{}){} 8977 A<int> *attr; 8978 const int value = N::b<C>; 8979 }; 8980 )", 8981 Lang_CXX14, "input1.cc"); 8982 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 8983 FromTU, functionDecl(hasName("f"), isDefinition())); 8984 auto *ToF = Import(FromF, Lang_CXX11); 8985 EXPECT_TRUE(ToF); 8986 EXPECT_TRUE(ToX->getInClassInitializer()); 8987 } 8988 8989 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer) { 8990 const char *Code = 8991 R"( 8992 struct AP_TECS; 8993 8994 struct AP_Landing { 8995 AP_TECS *TECS_controller; 8996 }; 8997 8998 struct AP_TECS { 8999 AP_Landing landing; 9000 }; 9001 9002 class Plane { 9003 AP_TECS TECS_controller{landing}; 9004 AP_Landing landing{&TECS_controller}; 9005 }; 9006 )"; 9007 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 9008 9009 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match( 9010 FromTU, cxxRecordDecl(hasName("Plane"))); 9011 for (FieldDecl *F : FromR->fields()) 9012 EXPECT_TRUE(F->getInClassInitializer()); 9013 auto *ToR = Import(FromR, Lang_CXX11); 9014 for (FieldDecl *F : ToR->fields()) 9015 EXPECT_TRUE(F->getInClassInitializer()); 9016 } 9017 9018 TEST_P(ASTImporterOptionSpecificTestBase, ImportFieldInitializerWithItself) { 9019 const char *Code = 9020 R"( 9021 class A { 9022 int a{a}; 9023 }; 9024 )"; 9025 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 9026 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 9027 FromTU, cxxRecordDecl(hasName("A"))); 9028 EXPECT_TRUE(FromA->field_begin()->getInClassInitializer()); 9029 auto *ToA = Import(FromA, Lang_CXX11); 9030 EXPECT_TRUE(ToA->field_begin()->getInClassInitializer()); 9031 } 9032 9033 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer1) { 9034 // FIXME: This is a example of recursive field initialization that is not 9035 // supported. 9036 // The following import chain occurs (not complete): 9037 // import of A => A.a => in-class initializer of A.a => ref_B() => B => B.b 9038 // => in-class initializer of B.b => ref_A() => CXXConstructExpr for A => 9039 // CXXDefaultInitExpr for A.a => in-class initializer of A.a 9040 // in-class initializer of A.a is created in two different instances in this 9041 // case (import of FieldDecl and CXXDefaultInitExpr). Probably not a big 9042 // problem because it is an Expr (the second construction can be ignored 9043 // instead of assert). But such recursive init code should not occur in 9044 // practice. 9045 const char *Code = 9046 R"( 9047 static int ref_A(); 9048 static int ref_B(); 9049 struct A { 9050 int a = ref_B(); 9051 }; 9052 struct B { 9053 int b = ref_A(); 9054 }; 9055 int ref_B() { B b; return b.b; } 9056 int ref_A() { A a; return a.a; } 9057 )"; 9058 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 9059 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 9060 FromTU, cxxRecordDecl(hasName("A"))); 9061 EXPECT_TRUE(FromA->field_begin()->getInClassInitializer()); 9062 // auto *ToA = Import(FromA, Lang_CXX11); 9063 // EXPECT_TRUE(ToA->field_begin()->getInClassInitializer()); 9064 } 9065 9066 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) { 9067 Decl *FromTU = getTuDecl( 9068 R"( 9069 int bar() { 9070 return 0; 9071 } 9072 void other() { 9073 bar(); 9074 } 9075 )", 9076 Lang_CXX11); 9077 Decl *ToTU = getToTuDecl( 9078 R"( 9079 int bar() { 9080 return 0; 9081 } 9082 )", 9083 Lang_CXX11); 9084 auto *FromOther = FirstDeclMatcher<FunctionDecl>().match( 9085 FromTU, functionDecl(hasName("other"))); 9086 ASSERT_TRUE(FromOther); 9087 9088 auto *ToOther = Import(FromOther, Lang_CXX11); 9089 ASSERT_TRUE(ToOther); 9090 9091 auto *ToBar = FirstDeclMatcher<FunctionDecl>().match( 9092 ToTU, functionDecl(hasName("bar"))); 9093 9094 EXPECT_TRUE(SharedStatePtr->isNewDecl(ToOther)); 9095 EXPECT_FALSE(SharedStatePtr->isNewDecl(ToBar)); 9096 } 9097 9098 struct ImportInjectedClassNameType : public ASTImporterOptionSpecificTestBase { 9099 protected: 9100 const CXXRecordDecl *findInjected(const CXXRecordDecl *Parent) { 9101 for (Decl *Found : Parent->decls()) { 9102 const auto *Record = dyn_cast<CXXRecordDecl>(Found); 9103 if (Record && Record->isInjectedClassName()) 9104 return Record; 9105 } 9106 return nullptr; 9107 } 9108 9109 void checkInjType(const CXXRecordDecl *D) { 9110 // The whole redecl chain should have the same InjectedClassNameType 9111 // instance. The injected record declaration is a separate chain, this 9112 // should contain the same type too. 9113 const Type *Ty = nullptr; 9114 for (const Decl *ReD : D->redecls()) { 9115 const auto *ReRD = cast<CXXRecordDecl>(ReD); 9116 EXPECT_TRUE(ReRD->getTypeForDecl()); 9117 EXPECT_TRUE(!Ty || Ty == ReRD->getTypeForDecl()); 9118 Ty = ReRD->getTypeForDecl(); 9119 } 9120 ASSERT_TRUE(Ty); 9121 const auto *InjTy = Ty->castAs<InjectedClassNameType>(); 9122 EXPECT_TRUE(InjTy); 9123 if (CXXRecordDecl *Def = D->getDefinition()) { 9124 const CXXRecordDecl *InjRD = findInjected(Def); 9125 EXPECT_TRUE(InjRD); 9126 EXPECT_EQ(InjRD->getTypeForDecl(), InjTy); 9127 } 9128 } 9129 9130 void testImport(Decl *ToTU, Decl *FromTU, Decl *FromD) { 9131 checkInjType(cast<CXXRecordDecl>(FromD)); 9132 Decl *ToD = Import(FromD, Lang_CXX11); 9133 if (auto *ToRD = dyn_cast<CXXRecordDecl>(ToD)) 9134 checkInjType(ToRD); 9135 } 9136 9137 const char *ToCodeA = 9138 R"( 9139 template <class T> 9140 struct A; 9141 )"; 9142 const char *ToCodeADef = 9143 R"( 9144 template <class T> 9145 struct A { 9146 typedef A T1; 9147 }; 9148 )"; 9149 const char *ToCodeC = 9150 R"( 9151 template <class T> 9152 struct C; 9153 )"; 9154 const char *ToCodeCDef = 9155 R"( 9156 template <class T> 9157 struct A { 9158 typedef A T1; 9159 }; 9160 9161 template <class T1, class T2> 9162 struct B {}; 9163 9164 template<class T> 9165 struct C { 9166 typedef typename A<T>::T1 T1; 9167 typedef B<T1, T> T2; 9168 typedef B<T1, C> T3; 9169 }; 9170 )"; 9171 const char *FromCode = 9172 R"( 9173 template <class T> 9174 struct A; 9175 template <class T> 9176 struct A { 9177 typedef A T1; 9178 }; 9179 template <class T> 9180 struct A; 9181 9182 template <class T1, class T2> 9183 struct B {}; 9184 9185 template <class T> 9186 struct C; 9187 template <class T> 9188 struct C { 9189 typedef typename A<T>::T1 T1; 9190 typedef B<T1, T> T2; 9191 typedef B<T1, C> T3; 9192 }; 9193 template <class T> 9194 struct C; 9195 9196 template <class T> 9197 struct D { 9198 void f(typename C<T>::T3 *); 9199 }; 9200 )"; 9201 }; 9202 9203 TEST_P(ImportInjectedClassNameType, ImportADef) { 9204 Decl *ToTU = getToTuDecl(ToCodeA, Lang_CXX11); 9205 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9206 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 9207 FromTU, cxxRecordDecl(hasName("A"), isDefinition())); 9208 testImport(ToTU, FromTU, FromA); 9209 } 9210 9211 TEST_P(ImportInjectedClassNameType, ImportAFirst) { 9212 Decl *ToTU = getToTuDecl(ToCodeA, Lang_CXX11); 9213 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9214 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 9215 FromTU, cxxRecordDecl(hasName("A"))); 9216 testImport(ToTU, FromTU, FromA); 9217 } 9218 9219 TEST_P(ImportInjectedClassNameType, ImportALast) { 9220 Decl *ToTU = getToTuDecl(ToCodeA, Lang_CXX11); 9221 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9222 auto *FromA = LastDeclMatcher<CXXRecordDecl>().match( 9223 FromTU, cxxRecordDecl(hasName("A"))); 9224 testImport(ToTU, FromTU, FromA); 9225 } 9226 9227 TEST_P(ImportInjectedClassNameType, ImportADefToDef) { 9228 Decl *ToTU = getToTuDecl(ToCodeADef, Lang_CXX11); 9229 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9230 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 9231 FromTU, cxxRecordDecl(hasName("A"), isDefinition())); 9232 testImport(ToTU, FromTU, FromA); 9233 } 9234 9235 TEST_P(ImportInjectedClassNameType, ImportAFirstToDef) { 9236 Decl *ToTU = getToTuDecl(ToCodeADef, Lang_CXX11); 9237 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9238 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match( 9239 FromTU, cxxRecordDecl(hasName("A"))); 9240 testImport(ToTU, FromTU, FromA); 9241 } 9242 9243 TEST_P(ImportInjectedClassNameType, ImportALastToDef) { 9244 Decl *ToTU = getToTuDecl(ToCodeADef, Lang_CXX11); 9245 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9246 auto *FromA = LastDeclMatcher<CXXRecordDecl>().match( 9247 FromTU, cxxRecordDecl(hasName("A"))); 9248 testImport(ToTU, FromTU, FromA); 9249 } 9250 9251 TEST_P(ImportInjectedClassNameType, ImportCDef) { 9252 Decl *ToTU = getToTuDecl(ToCodeC, Lang_CXX11); 9253 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9254 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match( 9255 FromTU, cxxRecordDecl(hasName("C"), isDefinition())); 9256 testImport(ToTU, FromTU, FromC); 9257 } 9258 9259 TEST_P(ImportInjectedClassNameType, ImportCLast) { 9260 Decl *ToTU = getToTuDecl(ToCodeC, Lang_CXX11); 9261 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9262 auto *FromC = LastDeclMatcher<CXXRecordDecl>().match( 9263 FromTU, cxxRecordDecl(hasName("C"))); 9264 testImport(ToTU, FromTU, FromC); 9265 } 9266 9267 TEST_P(ImportInjectedClassNameType, ImportCDefToDef) { 9268 Decl *ToTU = getToTuDecl(ToCodeCDef, Lang_CXX11); 9269 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9270 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match( 9271 FromTU, cxxRecordDecl(hasName("C"), isDefinition())); 9272 testImport(ToTU, FromTU, FromC); 9273 } 9274 9275 TEST_P(ImportInjectedClassNameType, ImportCLastToDef) { 9276 Decl *ToTU = getToTuDecl(ToCodeCDef, Lang_CXX11); 9277 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9278 auto *FromC = LastDeclMatcher<CXXRecordDecl>().match( 9279 FromTU, cxxRecordDecl(hasName("C"))); 9280 testImport(ToTU, FromTU, FromC); 9281 } 9282 9283 TEST_P(ImportInjectedClassNameType, ImportD) { 9284 Decl *ToTU = getToTuDecl("", Lang_CXX11); 9285 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9286 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 9287 FromTU, cxxRecordDecl(hasName("D"), isDefinition())); 9288 testImport(ToTU, FromTU, FromD); 9289 } 9290 9291 TEST_P(ImportInjectedClassNameType, ImportDToDef) { 9292 Decl *ToTU = getToTuDecl(ToCodeCDef, Lang_CXX11); 9293 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11); 9294 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match( 9295 FromTU, cxxRecordDecl(hasName("D"), isDefinition())); 9296 testImport(ToTU, FromTU, FromD); 9297 } 9298 9299 TEST_P(ImportInjectedClassNameType, ImportTypedefType) { 9300 Decl *ToTU = getToTuDecl( 9301 R"( 9302 template <class T> 9303 struct A { 9304 typedef A A1; 9305 void f(A1 *); 9306 }; 9307 )", 9308 Lang_CXX11); 9309 Decl *FromTU = getTuDecl( 9310 R"( 9311 template <class T> 9312 struct A { 9313 typedef A A1; 9314 void f(A1 *); 9315 }; 9316 template<class T> 9317 void A<T>::f(A::A1 *) {} 9318 )", 9319 Lang_CXX11); 9320 9321 auto *FromF = FirstDeclMatcher<FunctionDecl>().match( 9322 FromTU, functionDecl(hasName("f"), isDefinition())); 9323 auto *ToF = Import(FromF, Lang_CXX11); 9324 EXPECT_TRUE(ToF); 9325 ASTContext &ToCtx = ToF->getDeclContext()->getParentASTContext(); 9326 9327 auto *ToA1 = 9328 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("A1"))); 9329 QualType ToInjTypedef = ToA1->getUnderlyingType().getCanonicalType(); 9330 QualType ToInjParmVar = 9331 ToF->parameters()[0]->getType().getDesugaredType(ToCtx); 9332 ToInjParmVar = 9333 ToInjParmVar->getAs<PointerType>()->getPointeeType().getCanonicalType(); 9334 EXPECT_TRUE(isa<InjectedClassNameType>(ToInjTypedef)); 9335 EXPECT_TRUE(isa<InjectedClassNameType>(ToInjParmVar)); 9336 EXPECT_TRUE(ToCtx.hasSameType(ToInjTypedef, ToInjParmVar)); 9337 } 9338 9339 TEST_P(ASTImporterOptionSpecificTestBase, ImportMacroQualifiedType) { 9340 Decl *From, *To; 9341 std::tie(From, To) = getImportedDecl( 9342 R"( 9343 #define CDECL __attribute__((cdecl)) 9344 typedef void (CDECL *X)(); 9345 )", 9346 Lang_CXX03, "", Lang_CXX03, "X"); 9347 9348 auto *FromTy = 9349 FirstDeclMatcher<MacroQualifiedType>().match(From, macroQualifiedType()); 9350 auto *ToTy = 9351 FirstDeclMatcher<MacroQualifiedType>().match(To, macroQualifiedType()); 9352 9353 EXPECT_TRUE(isa<AttributedType>(FromTy->getUnderlyingType())); 9354 EXPECT_TRUE(isa<AttributedType>(ToTy->getUnderlyingType())); 9355 } 9356 9357 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplateName) { 9358 constexpr auto TestCode = R"( 9359 template <class T> 9360 struct A; 9361 template <class T> 9362 struct A {}; 9363 template <template<class> class T = A> 9364 struct B {}; 9365 using C = B<>; 9366 )"; 9367 Decl *ToTU = getToTuDecl(TestCode, Lang_CXX11); 9368 Decl *FromTU = getTuDecl(TestCode, Lang_CXX11); 9369 9370 auto *ToUsingFirst = FirstDeclMatcher<TypeAliasDecl>().match( 9371 ToTU, typeAliasDecl(hasName("C"))); 9372 9373 auto *FromUsing = FirstDeclMatcher<TypeAliasDecl>().match( 9374 FromTU, typeAliasDecl(hasName("C"))); 9375 auto *ToUsing = Import(FromUsing, Lang_CXX11); 9376 EXPECT_TRUE(ToUsing); 9377 9378 auto *ToB = FirstDeclMatcher<ClassTemplateDecl>().match( 9379 ToTU, classTemplateDecl(hasName("B"))); 9380 auto *ToB1 = LastDeclMatcher<ClassTemplateDecl>().match( 9381 ToTU, classTemplateDecl(hasName("B"))); 9382 // One template definition of 'B' should exist. 9383 EXPECT_EQ(ToB, ToB1); 9384 9385 // These declarations are imported separately. 9386 EXPECT_NE(ToUsingFirst, ToUsing); 9387 9388 auto SpB = ToB->spec_begin(); 9389 auto SpE = ToB->spec_end(); 9390 EXPECT_TRUE(SpB != SpE); 9391 ClassTemplateSpecializationDecl *Spec1 = *SpB; 9392 ++SpB; 9393 // The template 'B' should have one specialization (with default argument). 9394 EXPECT_TRUE(SpB == SpE); 9395 9396 // Even if 'B' has one specialization with the default arguments, the AST 9397 // contains after the import two specializations that are linked in the 9398 // declaration chain. The 'spec_begin' iteration does not find these because 9399 // the template arguments are the same. But the imported type alias has the 9400 // link to the second specialization. The template name object in these 9401 // specializations must point to the same (and one) instance of definition of 9402 // 'B'. 9403 auto *Spec2 = cast<ClassTemplateSpecializationDecl>( 9404 ToUsing->getUnderlyingType() 9405 ->getAs<TemplateSpecializationType>() 9406 ->getAsRecordDecl()); 9407 EXPECT_NE(Spec1, Spec2); 9408 EXPECT_TRUE(Spec1->getPreviousDecl() == Spec2 || 9409 Spec2->getPreviousDecl() == Spec1); 9410 TemplateDecl *Templ1 = 9411 Spec1->getTemplateArgs()[0].getAsTemplate().getAsTemplateDecl(); 9412 TemplateDecl *Templ2 = 9413 Spec2->getTemplateArgs()[0].getAsTemplate().getAsTemplateDecl(); 9414 EXPECT_EQ(Templ1, Templ2); 9415 } 9416 9417 TEST_P(ASTImporterOptionSpecificTestBase, VaListC) { 9418 Decl *FromTU = getTuDecl(R"(typedef __builtin_va_list va_list;)", Lang_C99); 9419 9420 auto *FromVaList = FirstDeclMatcher<TypedefDecl>().match( 9421 FromTU, typedefDecl(hasName("va_list"))); 9422 ASSERT_TRUE(FromVaList); 9423 9424 auto *ToVaList = Import(FromVaList, Lang_C99); 9425 ASSERT_TRUE(ToVaList); 9426 9427 auto *ToBuiltinVaList = FirstDeclMatcher<TypedefDecl>().match( 9428 ToAST->getASTContext().getTranslationUnitDecl(), 9429 typedefDecl(hasName("__builtin_va_list"))); 9430 9431 ASSERT_TRUE(ToAST->getASTContext().hasSameType( 9432 ToVaList->getUnderlyingType(), ToBuiltinVaList->getUnderlyingType())); 9433 } 9434 9435 TEST_P(ASTImporterOptionSpecificTestBase, VaListCpp) { 9436 Decl *FromTU = getTuDecl(R"(typedef __builtin_va_list va_list;)", Lang_CXX03); 9437 9438 auto *FromVaList = FirstDeclMatcher<TypedefDecl>().match( 9439 FromTU, typedefDecl(hasName("va_list"))); 9440 ASSERT_TRUE(FromVaList); 9441 9442 auto *ToVaList = Import(FromVaList, Lang_CXX03); 9443 ASSERT_TRUE(ToVaList); 9444 9445 auto *ToBuiltinVaList = FirstDeclMatcher<TypedefDecl>().match( 9446 ToAST->getASTContext().getTranslationUnitDecl(), 9447 typedefDecl(hasName("__builtin_va_list"))); 9448 9449 ASSERT_TRUE(ToAST->getASTContext().hasSameType( 9450 ToVaList->getUnderlyingType(), ToBuiltinVaList->getUnderlyingType())); 9451 } 9452 9453 TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingTypedefToRecord) { 9454 const char *Code = 9455 R"( 9456 struct S { int i; }; 9457 typedef struct S T; 9458 extern T x; 9459 )"; 9460 Decl *ToTU = getToTuDecl(Code, Lang_C99); 9461 Decl *FromTU = getTuDecl(Code, Lang_C99); 9462 9463 auto *FromX = 9464 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x"))); 9465 auto *ToX = Import(FromX, Lang_C99); 9466 EXPECT_TRUE(ToX); 9467 9468 auto *Typedef1 = 9469 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); 9470 auto *Typedef2 = 9471 LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); 9472 EXPECT_EQ(Typedef1, Typedef2); 9473 } 9474 9475 TEST_P(ASTImporterOptionSpecificTestBase, 9476 ImportExistingTypedefToUnnamedRecord) { 9477 const char *Code = 9478 R"( 9479 typedef const struct { int f; } T; 9480 extern T x; 9481 )"; 9482 Decl *ToTU = getToTuDecl(Code, Lang_C99); 9483 Decl *FromTU = getTuDecl(Code, Lang_C99); 9484 9485 auto *FromX = 9486 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x"))); 9487 auto *ToX = Import(FromX, Lang_C99); 9488 EXPECT_TRUE(ToX); 9489 9490 auto *Typedef1 = 9491 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); 9492 auto *Typedef2 = 9493 LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); 9494 EXPECT_NE(Typedef1, Typedef2); 9495 EXPECT_NE(Typedef1->getUnderlyingType().getTypePtr(), 9496 Typedef2->getUnderlyingType().getTypePtr()); 9497 EXPECT_EQ(ToX->getType()->getAs<TypedefType>()->getDecl(), Typedef2); 9498 } 9499 9500 TEST_P(ASTImporterOptionSpecificTestBase, ImportTwoTypedefsToUnnamedRecord) { 9501 const char *Code = 9502 R"( 9503 typedef struct { int f; } T1; 9504 typedef struct { int f; } T2; 9505 extern T1 x1; 9506 extern T2 x2; 9507 )"; 9508 Decl *ToTU = getToTuDecl("", Lang_C99); 9509 Decl *FromTU = getTuDecl(Code, Lang_C99); 9510 9511 auto *FromX1 = 9512 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x1"))); 9513 auto *FromX2 = 9514 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x2"))); 9515 auto *ToX1 = Import(FromX1, Lang_C99); 9516 EXPECT_TRUE(ToX1); 9517 auto *ToX2 = Import(FromX2, Lang_C99); 9518 EXPECT_TRUE(ToX2); 9519 9520 auto *Typedef1 = 9521 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T1"))); 9522 auto *Typedef2 = 9523 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T2"))); 9524 EXPECT_NE(Typedef1->getUnderlyingType().getTypePtr(), 9525 Typedef2->getUnderlyingType().getTypePtr()); 9526 } 9527 9528 TEST_P(ASTImporterOptionSpecificTestBase, 9529 ImportExistingTypedefToUnnamedRecordPtr) { 9530 const char *Code = 9531 R"( 9532 typedef const struct { int fff; } * const T; 9533 extern T x; 9534 )"; 9535 Decl *ToTU = getToTuDecl(Code, Lang_C99); 9536 Decl *FromTU = getTuDecl(Code, Lang_C99); 9537 9538 auto *FromX = 9539 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x"))); 9540 auto *ToX = Import(FromX, Lang_C99); 9541 EXPECT_TRUE(ToX); 9542 9543 auto *Typedef1 = 9544 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); 9545 auto *Typedef2 = 9546 LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); 9547 // FIXME: These should be imported separately, like in the test above. 9548 // Or: In the test above these should be merged too. 9549 EXPECT_EQ(Typedef1, Typedef2); 9550 9551 auto *FromR = FirstDeclMatcher<RecordDecl>().match( 9552 FromTU, recordDecl(hasDescendant(fieldDecl(hasName("fff"))))); 9553 auto *ToRExisting = FirstDeclMatcher<RecordDecl>().match( 9554 ToTU, recordDecl(hasDescendant(fieldDecl(hasName("fff"))))); 9555 ASSERT_TRUE(FromR); 9556 auto *ToRImported = Import(FromR, Lang_C99); 9557 // FIXME: If typedefs are not imported separately, do not import ToRImported 9558 // separately. 9559 EXPECT_NE(ToRExisting, ToRImported); 9560 } 9561 9562 TEST_P(ASTImporterOptionSpecificTestBase, 9563 ImportTypedefWithDifferentUnderlyingType) { 9564 const char *Code = 9565 R"( 9566 using X1 = int; 9567 using Y1 = int; 9568 9569 using RPB1 = X1*; 9570 typedef RPB1 RPX1; 9571 using RPB1 = Y1*; // redeclared 9572 typedef RPB1 RPY1; 9573 9574 auto X = 0 ? (RPX1){} : (RPY1){}; 9575 )"; 9576 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 9577 9578 auto *FromX = 9579 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("X"))); 9580 9581 auto *FromXType = FromX->getType()->getAs<TypedefType>(); 9582 EXPECT_FALSE(FromXType->typeMatchesDecl()); 9583 9584 auto *ToX = Import(FromX, Lang_CXX11); 9585 auto *ToXType = ToX->getType()->getAs<TypedefType>(); 9586 // FIXME: This should be false. 9587 EXPECT_TRUE(ToXType->typeMatchesDecl()); 9588 } 9589 9590 TEST_P(ASTImporterOptionSpecificTestBase, 9591 ImportTemplateArgumentWithPointerToDifferentInstantiation) { 9592 const char *CodeTo = 9593 R"( 9594 template<class A> 9595 A f1() { 9596 return A(); 9597 } 9598 template<class A, A (B)()> 9599 class X {}; 9600 9601 X<int, f1<int>> x; 9602 )"; 9603 const char *CodeFrom = 9604 R"( 9605 template<class A> 9606 A f1(); 9607 template<class A, A (B)()> 9608 class X {}; 9609 9610 X<int, f1<int>> x; 9611 )"; 9612 Decl *ToTU = getToTuDecl(CodeTo, Lang_CXX11); 9613 Decl *FromTU = getTuDecl(CodeFrom, Lang_CXX11); 9614 9615 auto *ToF1 = FirstDeclMatcher<FunctionDecl>().match( 9616 ToTU, functionDecl(hasName("f1"), isInstantiated())); 9617 auto *FromF1 = FirstDeclMatcher<FunctionDecl>().match( 9618 FromTU, functionDecl(hasName("f1"), isInstantiated())); 9619 EXPECT_TRUE(ToF1->isThisDeclarationADefinition()); 9620 EXPECT_FALSE(FromF1->isThisDeclarationADefinition()); 9621 9622 auto *ToX = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 9623 ToTU, classTemplateSpecializationDecl(hasName("X"))); 9624 auto *FromX = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 9625 FromTU, classTemplateSpecializationDecl(hasName("X"))); 9626 9627 Decl *ToTArgF = ToX->getTemplateArgs().get(1).getAsDecl(); 9628 Decl *FromTArgF = FromX->getTemplateArgs().get(1).getAsDecl(); 9629 EXPECT_EQ(ToTArgF, ToF1); 9630 EXPECT_EQ(FromTArgF, FromF1); 9631 9632 auto *ToXImported = Import(FromX, Lang_CXX11); 9633 // The template argument 1 of 'X' in the "From" code points to a function 9634 // that has no definition. The import must ensure that this template argument 9635 // is imported in a way that it will point to the existing 'f1' function, not 9636 // to the 'f1' that is imported. In this way when specialization of 'X' is 9637 // imported it will have the same template arguments as the existing one. 9638 EXPECT_EQ(ToXImported, ToX); 9639 // FIXME: This matcher causes a crash "Tried to match orphan node". 9640 // The code is removed until the problem is fixed. 9641 // auto *ToF1Imported = 9642 // LastDeclMatcher<FunctionDecl>().match(ToTU, 9643 // functionDecl(hasName("f1"),isInstantiated())); 9644 // EXPECT_NE(ToF1Imported, ToF1); 9645 // EXPECT_EQ(ToF1Imported->getPreviousDecl(), ToF1); 9646 } 9647 9648 TEST_P(ASTImporterOptionSpecificTestBase, 9649 ImportTypeAliasTemplateAfterSimilarCalledTemplateTypeParm) { 9650 const char *Code = 9651 R"( 9652 struct S; 9653 template <typename> 9654 using Callable = S; 9655 template <typename Callable> 9656 int bindingFunctionVTable; 9657 )"; 9658 Decl *FromTU = getTuDecl(Code, Lang_CXX17); 9659 9660 auto *FromCallable = FirstDeclMatcher<TypeAliasTemplateDecl>().match( 9661 FromTU, typeAliasTemplateDecl(hasName("Callable"))); 9662 9663 auto *FromCallableParm = FirstDeclMatcher<TemplateTypeParmDecl>().match( 9664 FromTU, templateTypeParmDecl(hasName("Callable"))); 9665 9666 auto *ToFromCallableParm = Import(FromCallableParm, Lang_CXX17); 9667 auto *ToCallable = Import(FromCallable, Lang_CXX17); 9668 EXPECT_TRUE(ToFromCallableParm); 9669 EXPECT_TRUE(ToCallable); 9670 } 9671 9672 TEST_P(ASTImporterOptionSpecificTestBase, ImportConflictTypeAliasTemplate) { 9673 const char *ToCode = 9674 R"( 9675 struct S; 9676 template <typename, typename> 9677 using Callable = S; 9678 )"; 9679 const char *Code = 9680 R"( 9681 struct S; 9682 template <typename> 9683 using Callable = S; 9684 )"; 9685 (void)getToTuDecl(ToCode, Lang_CXX17); 9686 Decl *FromTU = getTuDecl(Code, Lang_CXX17); 9687 9688 auto *FromCallable = FirstDeclMatcher<TypeAliasTemplateDecl>().match( 9689 FromTU, typeAliasTemplateDecl(hasName("Callable"))); 9690 9691 auto *ImportedCallable = Import(FromCallable, Lang_CXX17); 9692 EXPECT_FALSE(ImportedCallable); 9693 } 9694 9695 AST_MATCHER(ClassTemplateSpecializationDecl, hasInstantiatedFromMember) { 9696 if (auto Instantiate = Node.getInstantiatedFrom()) { 9697 if (auto *FromPartialSpecialization = 9698 cast<ClassTemplatePartialSpecializationDecl *>(Instantiate)) { 9699 return nullptr != FromPartialSpecialization->getInstantiatedFromMember(); 9700 } 9701 } 9702 return false; 9703 } 9704 9705 TEST_P(ASTImporterOptionSpecificTestBase, ImportInstantiatedFromMember) { 9706 const char *Code = 9707 R"( 9708 template <typename> struct B { 9709 template <typename, bool = false> union D; 9710 template <typename T> union D<T> {}; 9711 D<int> d; 9712 }; 9713 B<int> b; 9714 )"; 9715 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 9716 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match( 9717 FromTU, classTemplateSpecializationDecl(hasName("D"), 9718 hasInstantiatedFromMember())); 9719 auto *FromPartialSpecialization = 9720 cast<ClassTemplatePartialSpecializationDecl *>( 9721 FromD->getInstantiatedFrom()); 9722 ASSERT_TRUE(FromPartialSpecialization->getInstantiatedFromMember()); 9723 auto *ImportedPartialSpecialization = 9724 Import(FromPartialSpecialization, Lang_CXX11); 9725 EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember()); 9726 } 9727 9728 AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, ConstName) { 9729 for (EnumConstantDecl *D : Node.enumerators()) 9730 if (D->getName() == ConstName) 9731 return true; 9732 return false; 9733 } 9734 9735 TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnums) { 9736 const char *Code = 9737 R"( 9738 struct A { 9739 enum { E1, E2 } x; 9740 enum { E3, E4 } y; 9741 }; 9742 )"; 9743 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 9744 auto *FromEnumE1 = FirstDeclMatcher<EnumDecl>().match( 9745 FromTU, enumDecl(hasEnumConstName("E1"))); 9746 auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11); 9747 EXPECT_TRUE(ImportedEnumE1); 9748 auto *FromEnumE3 = FirstDeclMatcher<EnumDecl>().match( 9749 FromTU, enumDecl(hasEnumConstName("E3"))); 9750 auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11); 9751 EXPECT_TRUE(ImportedEnumE3); 9752 EXPECT_NE(ImportedEnumE1, ImportedEnumE3); 9753 } 9754 9755 TEST_P(ASTImporterOptionSpecificTestBase, ImportFreeStandingAnonymousEnums) { 9756 const char *Code = 9757 R"( 9758 struct A { 9759 enum { E1, E2 }; 9760 enum { E3, E4 }; 9761 }; 9762 )"; 9763 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 9764 auto *FromEnumE1 = FirstDeclMatcher<EnumDecl>().match( 9765 FromTU, enumDecl(hasEnumConstName("E1"))); 9766 auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11); 9767 EXPECT_TRUE(ImportedEnumE1); 9768 auto *FromEnumE3 = FirstDeclMatcher<EnumDecl>().match( 9769 FromTU, enumDecl(hasEnumConstName("E3"))); 9770 auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11); 9771 EXPECT_TRUE(ImportedEnumE3); 9772 EXPECT_NE(ImportedEnumE1, ImportedEnumE3); 9773 } 9774 9775 TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingAnonymousEnums) { 9776 const char *ToCode = 9777 R"( 9778 struct A { 9779 enum { E1, E2 } x; 9780 enum { E3, E4 } y; 9781 }; 9782 )"; 9783 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11); 9784 auto *ToEnumE1 = FirstDeclMatcher<EnumDecl>().match( 9785 ToTU, enumDecl(hasEnumConstName("E1"))); 9786 auto *ToEnumE3 = FirstDeclMatcher<EnumDecl>().match( 9787 ToTU, enumDecl(hasEnumConstName("E3"))); 9788 const char *Code = 9789 R"( 9790 struct A { 9791 enum { E1, E2 } x; 9792 enum { E3, E4 } y; 9793 }; 9794 )"; 9795 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 9796 auto *FromEnumE1 = FirstDeclMatcher<EnumDecl>().match( 9797 FromTU, enumDecl(hasEnumConstName("E1"))); 9798 auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11); 9799 ASSERT_TRUE(ImportedEnumE1); 9800 EXPECT_EQ(ImportedEnumE1, ToEnumE1); 9801 auto *FromEnumE3 = FirstDeclMatcher<EnumDecl>().match( 9802 FromTU, enumDecl(hasEnumConstName("E3"))); 9803 auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11); 9804 ASSERT_TRUE(ImportedEnumE3); 9805 EXPECT_EQ(ImportedEnumE3, ToEnumE3); 9806 } 9807 9808 TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingEmptyAnonymousEnums) { 9809 const char *ToCode = 9810 R"( 9811 struct A { 9812 enum {}; 9813 }; 9814 )"; 9815 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11); 9816 auto *ToE1 = FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl()); 9817 const char *Code = 9818 R"( 9819 struct A { 9820 enum {}; 9821 enum {}; 9822 }; 9823 )"; 9824 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 9825 auto *FromE1 = FirstDeclMatcher<EnumDecl>().match(FromTU, enumDecl()); 9826 auto *ImportedE1 = Import(FromE1, Lang_CXX11); 9827 ASSERT_TRUE(ImportedE1); 9828 EXPECT_EQ(ImportedE1, ToE1); 9829 auto *FromE2 = LastDeclMatcher<EnumDecl>().match(FromTU, enumDecl()); 9830 ASSERT_NE(FromE1, FromE2); 9831 auto *ImportedE2 = Import(FromE2, Lang_CXX11); 9832 ASSERT_TRUE(ImportedE2); 9833 // FIXME: These should not be equal, or the import should fail. 9834 EXPECT_EQ(ImportedE2, ToE1); 9835 } 9836 9837 TEST_P(ASTImporterOptionSpecificTestBase, ImportMultipleAnonymousEnumDecls) { 9838 Decl *ToTU = getToTuDecl("", Lang_CXX03); 9839 Decl *FromTU = getTuDecl( 9840 R"( 9841 struct foo { 9842 enum { A }; 9843 enum { B }; 9844 }; 9845 )", 9846 Lang_CXX03); 9847 9848 auto EnumConstA = enumConstantDecl(hasName("A")); 9849 auto EnumConstB = enumConstantDecl(hasName("B")); 9850 9851 auto *FromA = FirstDeclMatcher<EnumConstantDecl>().match(FromTU, EnumConstA); 9852 auto *FromB = FirstDeclMatcher<EnumConstantDecl>().match(FromTU, EnumConstB); 9853 9854 auto *ToA = Import(FromA, Lang_CXX03); 9855 auto *ToB = Import(FromB, Lang_CXX03); 9856 9857 ASSERT_TRUE(ToA); 9858 ASSERT_TRUE(ToB); 9859 9860 auto *ToFooA = FirstDeclMatcher<CXXRecordDecl>().match( 9861 ToTU, tagDecl(has(enumDecl(has(EnumConstA))))); 9862 auto *ToFooB = FirstDeclMatcher<CXXRecordDecl>().match( 9863 ToTU, tagDecl(has(enumDecl(has(EnumConstB))))); 9864 ASSERT_EQ(ToFooA, ToFooB); 9865 9866 // different EnumDecl 9867 auto *ToEnumDeclA = 9868 FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(has(EnumConstA))); 9869 auto *ToEnumDeclB = 9870 FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(has(EnumConstB))); 9871 ASSERT_NE(ToEnumDeclA, ToEnumDeclB); 9872 } 9873 9874 struct ImportTemplateParmDeclDefaultValue 9875 : public ASTImporterOptionSpecificTestBase { 9876 protected: 9877 void checkTemplateParams(RedeclarableTemplateDecl *D, 9878 RedeclarableTemplateDecl *InheritedFromD) { 9879 auto *NonTypeP = 9880 cast<NonTypeTemplateParmDecl>(D->getTemplateParameters()->getParam(0)); 9881 auto *TypeP = 9882 cast<TemplateTypeParmDecl>(D->getTemplateParameters()->getParam(1)); 9883 auto *TemplateP = 9884 cast<TemplateTemplateParmDecl>(D->getTemplateParameters()->getParam(2)); 9885 if (InheritedFromD) { 9886 EXPECT_TRUE(NonTypeP->getDefaultArgStorage().isInherited()); 9887 EXPECT_TRUE(TypeP->getDefaultArgStorage().isInherited()); 9888 EXPECT_TRUE(TemplateP->getDefaultArgStorage().isInherited()); 9889 EXPECT_EQ(NonTypeP->getDefaultArgStorage().getInheritedFrom(), 9890 InheritedFromD->getTemplateParameters()->getParam(0)); 9891 EXPECT_EQ(TypeP->getDefaultArgStorage().getInheritedFrom(), 9892 InheritedFromD->getTemplateParameters()->getParam(1)); 9893 EXPECT_EQ(TemplateP->getDefaultArgStorage().getInheritedFrom(), 9894 InheritedFromD->getTemplateParameters()->getParam(2)); 9895 } else { 9896 EXPECT_FALSE(NonTypeP->getDefaultArgStorage().isInherited()); 9897 EXPECT_FALSE(TypeP->getDefaultArgStorage().isInherited()); 9898 EXPECT_FALSE(TemplateP->getDefaultArgStorage().isInherited()); 9899 } 9900 } 9901 9902 void testImport(RedeclarableTemplateDecl *FromD1, 9903 RedeclarableTemplateDecl *FromD2, 9904 RedeclarableTemplateDecl *FromD3, 9905 RedeclarableTemplateDecl *ToExistingD1) { 9906 auto *ToD1 = Import(FromD1, Lang_CXX14); 9907 auto *ToD2 = Import(FromD2, Lang_CXX14); 9908 auto *ToD3 = Import(FromD3, Lang_CXX14); 9909 checkTemplateParams(ToD1, nullptr); 9910 checkTemplateParams(ToD2, ToD1); 9911 checkTemplateParams(ToD3, ToExistingD1 ? ToExistingD1 : ToD1); 9912 } 9913 9914 // In these tests a circular dependency is created between the template 9915 // parameter default value and the template declaration (with the same 9916 // template parameter). 9917 template <class TemplateParmDeclT> 9918 void 9919 testTemplateParmDeclCircularDependency(ClassTemplateDecl *FromD, 9920 ClassTemplateDecl *FromDInherited) { 9921 auto GetTemplateParm = 9922 [](ClassTemplateDecl *D) -> const TemplateParmDeclT * { 9923 return dyn_cast<TemplateParmDeclT>( 9924 D->getTemplateParameters()->getParam(0)); 9925 }; 9926 9927 ASSERT_FALSE(GetTemplateParm(FromD)->getDefaultArgStorage().isInherited()); 9928 ASSERT_TRUE( 9929 GetTemplateParm(FromDInherited)->getDefaultArgStorage().isInherited()); 9930 9931 auto *ToD = Import(FromD, Lang_CXX14); 9932 EXPECT_TRUE(ToD); 9933 9934 auto *ToDInherited = Import(FromDInherited, Lang_CXX14); 9935 EXPECT_TRUE(ToDInherited); 9936 9937 EXPECT_FALSE(GetTemplateParm(ToD)->getDefaultArgStorage().isInherited()); 9938 EXPECT_TRUE( 9939 GetTemplateParm(ToDInherited)->getDefaultArgStorage().isInherited()); 9940 EXPECT_EQ(GetTemplateParm(ToDInherited) 9941 ->getDefaultArgStorage() 9942 .getInheritedFrom(), 9943 GetTemplateParm(ToD)); 9944 9945 EXPECT_EQ(ToD->getPreviousDecl(), ToDInherited); 9946 } 9947 9948 const char *CodeFunction = 9949 R"( 9950 template <class> struct X; 9951 9952 template <int A = 2, typename B = int, template<class> class C = X> 9953 void test(); 9954 template <int A, typename B, template<class> class C> 9955 void test(); 9956 template <int A, typename B, template<class> class C> 9957 void test() {} 9958 )"; 9959 9960 const char *CodeClass = 9961 R"( 9962 namespace N { 9963 template <class> struct X; 9964 9965 template <int A = 2, typename B = int, template<class> class C = X> 9966 struct test; 9967 template <int A, typename B, template<class> class C> 9968 struct test; 9969 template <int A, typename B, template<class> class C> 9970 struct test {}; 9971 } 9972 )"; 9973 9974 const char *CodeVar = 9975 R"( 9976 namespace N { 9977 template <class> struct X; 9978 9979 template <int A = 2, typename B = int, template<class> class C = X> 9980 extern int test; 9981 template <int A, typename B, template<class> class C> 9982 extern int test; 9983 template <int A, typename B, template<class> class C> 9984 int test = A; 9985 } 9986 )"; 9987 }; 9988 9989 TEST_P(ImportTemplateParmDeclDefaultValue, InvisibleInheritedFrom) { 9990 const char *ToCode = 9991 R"( 9992 template <int P = 1> 9993 void f() {} 9994 )"; 9995 TranslationUnitDecl *ToTU = getToTuDecl(ToCode, Lang_CXX14); 9996 auto *ToFDef = FirstDeclMatcher<FunctionTemplateDecl>().match( 9997 ToTU, functionTemplateDecl(hasName("f"))); 9998 9999 const char *FromCode = 10000 R"( 10001 template <int P = 1> 10002 void f() {} 10003 template <int P> 10004 void f(); 10005 )"; 10006 TranslationUnitDecl *FromTU = getTuDecl(FromCode, Lang_CXX14); 10007 auto *FromFDef = FirstDeclMatcher<FunctionTemplateDecl>().match( 10008 FromTU, functionTemplateDecl(hasName("f"))); 10009 auto *FromF = LastDeclMatcher<FunctionTemplateDecl>().match( 10010 FromTU, functionTemplateDecl(hasName("f"))); 10011 10012 auto *ToFDefImported = Import(FromFDef, Lang_CXX14); 10013 EXPECT_EQ(ToFDefImported, ToFDef); 10014 auto *ToF = Import(FromF, Lang_CXX14); 10015 EXPECT_NE(ToF, ToFDef); 10016 const auto *Parm = dyn_cast<NonTypeTemplateParmDecl>( 10017 ToF->getTemplateParameters()->getParam(0)); 10018 EXPECT_TRUE(Parm->defaultArgumentWasInherited()); 10019 // FIXME: This behavior may be confusing: 10020 // Default value is not inherited from the existing declaration, instead a new 10021 // is created at import that is similar to the existing but not reachable from 10022 // the AST. 10023 EXPECT_NE(Parm->getDefaultArgStorage().getInheritedFrom(), 10024 ToFDef->getTemplateParameters()->getParam(0)); 10025 } 10026 10027 TEST_P(ImportTemplateParmDeclDefaultValue, DefValImportError) { 10028 const char *ToCode = 10029 R"( 10030 class X { 10031 int A; 10032 }; 10033 )"; 10034 getToTuDecl(ToCode, Lang_CXX14); 10035 10036 const char *FromCode = 10037 R"( 10038 class X; 10039 10040 template <typename P = X> 10041 void f() {} 10042 10043 class X { 10044 char A; 10045 }; 10046 )"; 10047 TranslationUnitDecl *FromTU = getTuDecl(FromCode, Lang_CXX14); 10048 auto *FromF = FirstDeclMatcher<FunctionTemplateDecl>().match( 10049 FromTU, functionTemplateDecl(hasName("f"))); 10050 10051 auto *ToFImported = Import(FromF, Lang_CXX14); 10052 EXPECT_FALSE(ToFImported); 10053 } 10054 10055 TEST_P(ImportTemplateParmDeclDefaultValue, ImportFunctionTemplate) { 10056 TranslationUnitDecl *FromTU = getTuDecl(CodeFunction, Lang_CXX14); 10057 auto *D3 = LastDeclMatcher<FunctionTemplateDecl>().match( 10058 FromTU, functionTemplateDecl(hasName("test") /*, hasBody(stmt())*/)); 10059 auto *D2 = dyn_cast<FunctionTemplateDecl>(D3->getPreviousDecl()); 10060 auto *D1 = dyn_cast<FunctionTemplateDecl>(D2->getPreviousDecl()); 10061 testImport(D1, D2, D3, nullptr); 10062 } 10063 10064 TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingFunctionTemplate) { 10065 TranslationUnitDecl *ToTU = getToTuDecl(CodeFunction, Lang_CXX14); 10066 auto *ToD1 = FirstDeclMatcher<FunctionTemplateDecl>().match( 10067 ToTU, functionTemplateDecl(hasName("test"))); 10068 TranslationUnitDecl *FromTU = getTuDecl(CodeFunction, Lang_CXX14); 10069 auto *D3 = LastDeclMatcher<FunctionTemplateDecl>().match( 10070 FromTU, functionTemplateDecl(hasName("test"))); 10071 auto *D2 = dyn_cast<FunctionTemplateDecl>(D3->getPreviousDecl()); 10072 auto *D1 = dyn_cast<FunctionTemplateDecl>(D2->getPreviousDecl()); 10073 testImport(D1, D2, D3, ToD1); 10074 } 10075 10076 TEST_P(ImportTemplateParmDeclDefaultValue, ImportClassTemplate) { 10077 TranslationUnitDecl *FromTU = getTuDecl(CodeClass, Lang_CXX14); 10078 auto *D3 = LastDeclMatcher<ClassTemplateDecl>().match( 10079 FromTU, classTemplateDecl(hasName("test"))); 10080 auto *D2 = dyn_cast<ClassTemplateDecl>(D3->getPreviousDecl()); 10081 auto *D1 = dyn_cast<ClassTemplateDecl>(D2->getPreviousDecl()); 10082 testImport(D1, D2, D3, nullptr); 10083 } 10084 10085 TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingClassTemplate) { 10086 TranslationUnitDecl *ToTU = getToTuDecl(CodeClass, Lang_CXX14); 10087 auto *ToD1 = FirstDeclMatcher<ClassTemplateDecl>().match( 10088 ToTU, classTemplateDecl(hasName("test"))); 10089 TranslationUnitDecl *FromTU = getTuDecl(CodeClass, Lang_CXX14); 10090 auto *D3 = LastDeclMatcher<ClassTemplateDecl>().match( 10091 FromTU, classTemplateDecl(hasName("test"))); 10092 auto *D2 = dyn_cast<ClassTemplateDecl>(D3->getPreviousDecl()); 10093 auto *D1 = dyn_cast<ClassTemplateDecl>(D2->getPreviousDecl()); 10094 testImport(D1, D2, D3, ToD1); 10095 } 10096 10097 TEST_P(ImportTemplateParmDeclDefaultValue, ImportVarTemplate) { 10098 TranslationUnitDecl *FromTU = getTuDecl(CodeVar, Lang_CXX14); 10099 auto *D3 = LastDeclMatcher<VarTemplateDecl>().match( 10100 FromTU, varTemplateDecl(hasName("test"))); 10101 auto *D2 = dyn_cast<VarTemplateDecl>(D3->getPreviousDecl()); 10102 auto *D1 = dyn_cast<VarTemplateDecl>(D2->getPreviousDecl()); 10103 testImport(D1, D2, D3, nullptr); 10104 } 10105 10106 TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingVarTemplate) { 10107 TranslationUnitDecl *ToTU = getToTuDecl(CodeVar, Lang_CXX14); 10108 auto *ToD1 = FirstDeclMatcher<VarTemplateDecl>().match( 10109 ToTU, varTemplateDecl(hasName("test"))); 10110 TranslationUnitDecl *FromTU = getTuDecl(CodeVar, Lang_CXX14); 10111 auto *D3 = LastDeclMatcher<VarTemplateDecl>().match( 10112 FromTU, varTemplateDecl(hasName("test"))); 10113 auto *D2 = dyn_cast<VarTemplateDecl>(D3->getPreviousDecl()); 10114 auto *D1 = dyn_cast<VarTemplateDecl>(D2->getPreviousDecl()); 10115 testImport(D1, D2, D3, ToD1); 10116 } 10117 10118 TEST_P(ImportTemplateParmDeclDefaultValue, 10119 NonTypeTemplateParmDeclCircularDependency) { 10120 const char *Code = 10121 R"( 10122 struct Z; 10123 10124 struct Y { 10125 Z *z; 10126 static const int x = 1; 10127 }; 10128 10129 template <int P1 = Y::x> 10130 struct X; 10131 10132 template <int P2> 10133 struct X { 10134 static const int A = 1; 10135 }; 10136 10137 struct Z { 10138 template<int P> 10139 void f(int A = X<P>::A); 10140 }; 10141 )"; 10142 10143 Decl *FromTU = getTuDecl(Code, Lang_CXX14); 10144 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 10145 FromTU, classTemplateDecl(hasName("X"))); 10146 auto *FromDInherited = LastDeclMatcher<ClassTemplateDecl>().match( 10147 FromTU, classTemplateDecl(hasName("X"))); 10148 10149 testTemplateParmDeclCircularDependency<NonTypeTemplateParmDecl>( 10150 FromD, FromDInherited); 10151 } 10152 10153 TEST_P(ImportTemplateParmDeclDefaultValue, 10154 TemplateTypeParmDeclCircularDependency) { 10155 const char *Code = 10156 R"( 10157 struct Z; 10158 10159 struct Y { 10160 Z *z; 10161 }; 10162 10163 template <typename T1 = Y> 10164 struct X; 10165 10166 template <typename T2> 10167 struct X { 10168 static const int A = 1; 10169 }; 10170 10171 struct Z { 10172 template<typename T> 10173 void f(int A = X<T>::A); 10174 }; 10175 )"; 10176 10177 Decl *FromTU = getTuDecl(Code, Lang_CXX14); 10178 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 10179 FromTU, classTemplateDecl(hasName("X"))); 10180 auto *FromDInherited = LastDeclMatcher<ClassTemplateDecl>().match( 10181 FromTU, classTemplateDecl(hasName("X"))); 10182 10183 testTemplateParmDeclCircularDependency<TemplateTypeParmDecl>(FromD, 10184 FromDInherited); 10185 } 10186 10187 TEST_P(ImportTemplateParmDeclDefaultValue, 10188 TemplateTemplateParmDeclCircularDependency) { 10189 const char *Code = 10190 R"( 10191 struct Z; 10192 10193 template <int> 10194 struct Y { 10195 Z *z; 10196 }; 10197 10198 template <template <int> class T1 = Y> 10199 struct X; 10200 10201 template <template <int> class T2> 10202 struct X { 10203 static const int A = 1; 10204 }; 10205 10206 struct Z { 10207 template <template <int> class T> 10208 void f(int A = X<T>::A); 10209 }; 10210 )"; 10211 10212 Decl *FromTU = getTuDecl(Code, Lang_CXX14); 10213 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( 10214 FromTU, classTemplateDecl(hasName("X"))); 10215 auto *FromDInherited = LastDeclMatcher<ClassTemplateDecl>().match( 10216 FromTU, classTemplateDecl(hasName("X"))); 10217 10218 testTemplateParmDeclCircularDependency<TemplateTemplateParmDecl>( 10219 FromD, FromDInherited); 10220 } 10221 10222 TEST_P(ASTImporterOptionSpecificTestBase, ImportIntoReopenedNamespaceNoMatch1) { 10223 const char *ToCode = 10224 R"( 10225 namespace a { 10226 } 10227 namespace a { 10228 struct X { int A; }; 10229 } 10230 )"; 10231 getToTuDecl(ToCode, Lang_CXX11); 10232 const char *Code = 10233 R"( 10234 namespace a { 10235 struct X { char A; }; 10236 } 10237 )"; 10238 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 10239 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 10240 FromTU, cxxRecordDecl(hasName("X"))); 10241 auto *ImportedX = Import(FromX, Lang_CXX11); 10242 EXPECT_FALSE(ImportedX); 10243 } 10244 10245 TEST_P(ASTImporterOptionSpecificTestBase, ImportIntoReopenedNamespaceNoMatch2) { 10246 const char *ToCode = 10247 R"( 10248 namespace a { 10249 struct X { int A; }; 10250 } 10251 namespace a { 10252 } 10253 )"; 10254 getToTuDecl(ToCode, Lang_CXX11); 10255 const char *Code = 10256 R"( 10257 namespace a { 10258 struct X { char A; }; 10259 } 10260 )"; 10261 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 10262 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 10263 FromTU, cxxRecordDecl(hasName("X"))); 10264 auto *ImportedX = Import(FromX, Lang_CXX11); 10265 EXPECT_FALSE(ImportedX); 10266 } 10267 10268 TEST_P(ASTImporterOptionSpecificTestBase, ImportIntoReopenedNamespaceMatch1) { 10269 const char *ToCode = 10270 R"( 10271 namespace a { 10272 } 10273 namespace a { 10274 struct X { int A; }; 10275 } 10276 )"; 10277 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11); 10278 const char *Code = 10279 R"( 10280 namespace a { 10281 struct X { int A; }; 10282 } 10283 )"; 10284 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 10285 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 10286 FromTU, cxxRecordDecl(hasName("X"))); 10287 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match( 10288 ToTU, cxxRecordDecl(hasName("X"))); 10289 auto *ImportedX = Import(FromX, Lang_CXX11); 10290 EXPECT_EQ(ImportedX, ToX); 10291 } 10292 10293 TEST_P(ASTImporterOptionSpecificTestBase, ImportIntoReopenedNamespaceMatch2) { 10294 const char *ToCode = 10295 R"( 10296 namespace a { 10297 struct X { int A; }; 10298 } 10299 namespace a { 10300 } 10301 )"; 10302 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11); 10303 const char *Code = 10304 R"( 10305 namespace a { 10306 struct X { int A; }; 10307 } 10308 )"; 10309 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 10310 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( 10311 FromTU, cxxRecordDecl(hasName("X"))); 10312 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match( 10313 ToTU, cxxRecordDecl(hasName("X"))); 10314 auto *ImportedX = Import(FromX, Lang_CXX11); 10315 EXPECT_EQ(ImportedX, ToX); 10316 } 10317 10318 TEST_P(ASTImporterLookupTableTest, PrimaryDCChangeAtImport) { 10319 const char *ToCode = 10320 R"( 10321 template <class T> 10322 struct X; 10323 )"; 10324 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11); 10325 auto *ToX = FirstDeclMatcher<ClassTemplateDecl>().match( 10326 ToTU, classTemplateDecl(hasName("X"))); 10327 NamedDecl *ToParm = ToX->getTemplateParameters()->getParam(0); 10328 DeclContext *OldPrimaryDC = ToX->getTemplatedDecl()->getPrimaryContext(); 10329 ASSERT_EQ(ToParm->getDeclContext(), ToX->getTemplatedDecl()); 10330 ASSERT_EQ(SharedStatePtr->getLookupTable() 10331 ->lookup(ToX->getTemplatedDecl(), ToParm->getDeclName()) 10332 .size(), 10333 1u); 10334 ASSERT_TRUE(SharedStatePtr->getLookupTable()->contains( 10335 ToX->getTemplatedDecl(), ToParm)); 10336 10337 const char *Code = 10338 R"( 10339 template <class T> 10340 struct X; 10341 template <class T> 10342 struct X {}; 10343 )"; 10344 Decl *FromTU = getTuDecl(Code, Lang_CXX11); 10345 auto *FromX = LastDeclMatcher<ClassTemplateDecl>().match( 10346 FromTU, classTemplateDecl(hasName("X"))); 10347 10348 auto *ImportedX = Import(FromX, Lang_CXX11); 10349 10350 EXPECT_TRUE(ImportedX); 10351 EXPECT_EQ(ImportedX->getTemplateParameters()->getParam(0)->getDeclContext(), 10352 ImportedX->getTemplatedDecl()); 10353 10354 // ToX did not change at the import. 10355 // Verify that primary context has changed after import of class definition. 10356 DeclContext *NewPrimaryDC = ToX->getTemplatedDecl()->getPrimaryContext(); 10357 EXPECT_NE(OldPrimaryDC, NewPrimaryDC); 10358 // The lookup table should not be different than it was before. 10359 EXPECT_EQ(SharedStatePtr->getLookupTable() 10360 ->lookup(ToX->getTemplatedDecl(), ToParm->getDeclName()) 10361 .size(), 10362 1u); 10363 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains( 10364 ToX->getTemplatedDecl(), ToParm)); 10365 } 10366 10367 TEST_P(ASTImporterOptionSpecificTestBase, 10368 ExistingUndeclaredImportDeclaredFriend) { 10369 Decl *ToTU = getToTuDecl( 10370 R"( 10371 template <class A, A> 10372 struct foo; 10373 10374 template <class A> 10375 struct X { 10376 template <class A1, A1> 10377 friend struct foo; 10378 }; 10379 )", 10380 Lang_CXX11); 10381 Decl *FromTU = getTuDecl( 10382 R"( 10383 template <class A, A> 10384 struct foo; 10385 10386 template <class A> 10387 struct X { 10388 template <class A1, A1> 10389 friend struct foo; 10390 }; 10391 10392 X<int> x; 10393 )", 10394 Lang_CXX11); 10395 10396 auto *ToFr1 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 10397 auto *ToFrD1 = ToFr1->getFriendDecl(); 10398 10399 auto *FromFr1 = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl()); 10400 auto *FromFr2 = LastDeclMatcher<FriendDecl>().match(FromTU, friendDecl()); 10401 10402 auto *FromFrD1 = FromFr1->getFriendDecl(); 10403 auto *FromFrD2 = FromFr2->getFriendDecl(); 10404 10405 auto *Ctx1 = cast<Decl>(FromFrD1->getDeclContext()); 10406 auto *Ctx2 = cast<Decl>(FromFrD2->getDeclContext()); 10407 10408 ASSERT_EQ(Ctx1, Ctx2); 10409 ASSERT_EQ(ToFrD1->getTemplateDepth(), 1u); 10410 ASSERT_EQ(FromFrD2->getTemplateDepth(), 0u); 10411 ASSERT_EQ(ToFrD1->getFriendObjectKind(), Decl::FOK_Undeclared); 10412 ASSERT_EQ(FromFrD2->getFriendObjectKind(), Decl::FOK_Declared); 10413 10414 auto *ToFr2Imp = Import(FromFr2, Lang_CXX11); 10415 10416 EXPECT_TRUE(ToFr2Imp); 10417 } 10418 10419 TEST_P(ASTImporterOptionSpecificTestBase, 10420 ExistingDeclaredImportUndeclaredFriend) { 10421 Decl *ToTU = getToTuDecl( 10422 R"( 10423 template <class A, A> 10424 struct foo; 10425 10426 template <class A> 10427 struct X { 10428 template <class A1, A1> 10429 friend struct foo; 10430 }; 10431 10432 X<int> x; 10433 )", 10434 Lang_CXX11); 10435 Decl *FromTU = getTuDecl( 10436 R"( 10437 template <class A, A> 10438 struct foo; 10439 10440 template <class A> 10441 struct X { 10442 template <class A1, A1> 10443 friend struct foo; 10444 }; 10445 )", 10446 Lang_CXX11); 10447 10448 auto *ToFr1 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 10449 auto *ToFr2 = LastDeclMatcher<FriendDecl>().match(ToTU, friendDecl()); 10450 10451 auto *ToFrD1 = ToFr1->getFriendDecl(); 10452 auto *ToFrD2 = ToFr2->getFriendDecl(); 10453 10454 auto *FromFr1 = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl()); 10455 auto *FromFrD1 = FromFr1->getFriendDecl(); 10456 10457 auto *Ctx1 = cast<Decl>(ToFrD1->getDeclContext()); 10458 auto *Ctx2 = cast<Decl>(ToFrD2->getDeclContext()); 10459 10460 ASSERT_EQ(Ctx1, Ctx2); 10461 ASSERT_EQ(FromFrD1->getTemplateDepth(), 1u); 10462 ASSERT_EQ(ToFrD2->getTemplateDepth(), 0u); 10463 ASSERT_EQ(FromFrD1->getFriendObjectKind(), Decl::FOK_Undeclared); 10464 ASSERT_EQ(ToFrD2->getFriendObjectKind(), Decl::FOK_Declared); 10465 10466 auto *ToFr1Imp = Import(FromFr1, Lang_CXX11); 10467 10468 EXPECT_TRUE(ToFr1Imp); 10469 EXPECT_EQ(ToFr1Imp, ToFr1); 10470 } 10471 10472 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest, 10473 DefaultTestValuesForRunOptions); 10474 10475 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportPath, 10476 ::testing::Values(std::vector<std::string>())); 10477 10478 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportExpr, 10479 DefaultTestValuesForRunOptions); 10480 10481 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFixedPointExpr, 10482 ExtendWithOptions(DefaultTestArrayForRunOptions, 10483 std::vector<std::string>{ 10484 "-ffixed-point"})); 10485 10486 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportBlock, 10487 ExtendWithOptions(DefaultTestArrayForRunOptions, 10488 std::vector<std::string>{ 10489 "-fblocks"})); 10490 10491 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportType, 10492 DefaultTestValuesForRunOptions); 10493 10494 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportDecl, 10495 DefaultTestValuesForRunOptions); 10496 10497 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterOptionSpecificTestBase, 10498 DefaultTestValuesForRunOptions); 10499 10500 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ErrorHandlingTest, 10501 DefaultTestValuesForRunOptions); 10502 10503 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, RedirectingImporterTest, 10504 DefaultTestValuesForRunOptions); 10505 10506 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctions, 10507 DefaultTestValuesForRunOptions); 10508 10509 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAutoFunctions, 10510 DefaultTestValuesForRunOptions); 10511 10512 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctionTemplates, 10513 DefaultTestValuesForRunOptions); 10514 10515 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctionTemplates, 10516 DefaultTestValuesForRunOptions); 10517 10518 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportClasses, 10519 DefaultTestValuesForRunOptions); 10520 10521 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctions, 10522 DefaultTestValuesForRunOptions); 10523 10524 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendClasses, 10525 DefaultTestValuesForRunOptions); 10526 10527 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, 10528 ImportFunctionTemplateSpecializations, 10529 DefaultTestValuesForRunOptions); 10530 10531 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportImplicitMethods, 10532 DefaultTestValuesForRunOptions); 10533 10534 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportVariables, 10535 DefaultTestValuesForRunOptions); 10536 10537 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, LLDBLookupTest, 10538 DefaultTestValuesForRunOptions); 10539 10540 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportSourceLocations, 10541 DefaultTestValuesForRunOptions); 10542 10543 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportWithExternalSource, 10544 DefaultTestValuesForRunOptions); 10545 10546 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAttributes, 10547 DefaultTestValuesForRunOptions); 10548 10549 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportInjectedClassNameType, 10550 DefaultTestValuesForRunOptions); 10551 10552 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportMatrixType, 10553 DefaultTestValuesForRunOptions); 10554 10555 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportTemplateParmDeclDefaultValue, 10556 DefaultTestValuesForRunOptions); 10557 10558 // FIXME: Make ImportOpenCLPipe test work. 10559 // INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportOpenCLPipe, 10560 // DefaultTestValuesForRunOptions); 10561 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImportOpenCLPipe); 10562 10563 } // end namespace ast_matchers 10564 } // end namespace clang 10565