brintos

brintos / llvm-project-archived public Read only

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