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