r335491 - Revert "[ASTImporter] Import the whole redecl chain of functions"

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 25 13:50:21 PDT 2018


When reverting things, please say why in the commit message. (In this case,
apparently because it broke the lldb buildbots?)

On Mon, Jun 25, 2018 at 12:30 PM Gabor Marton via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: martong
> Date: Mon Jun 25 09:25:30 2018
> New Revision: 335491
>
> URL: http://llvm.org/viewvc/llvm-project?rev=335491&view=rev
> Log:
> Revert "[ASTImporter] Import the whole redecl chain of functions"
>
> This reverts commit r335480.
>
> Modified:
>     cfe/trunk/include/clang/AST/ASTImporter.h
>     cfe/trunk/lib/AST/ASTImporter.cpp
>     cfe/trunk/lib/AST/DeclBase.cpp
>     cfe/trunk/test/ASTMerge/class/test.cpp
>     cfe/trunk/unittests/AST/ASTImporterTest.cpp
>
> Modified: cfe/trunk/include/clang/AST/ASTImporter.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=335491&r1=335490&r2=335491&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTImporter.h (original)
> +++ cfe/trunk/include/clang/AST/ASTImporter.h Mon Jun 25 09:25:30 2018
> @@ -43,15 +43,6 @@ class TagDecl;
>  class TypeSourceInfo;
>  class Attr;
>
> -  // \brief Returns with a list of declarations started from the
> canonical decl
> -  // then followed by subsequent decls in the translation unit.
> -  // This gives a canonical list for each entry in the redecl chain.
> -  // `Decl::redecls()` gives a list of decls which always start from the
> -  // previous decl and the next item is actually the previous item in the
> order
> -  // of source locations.  Thus, `Decl::redecls()` gives different lists
> for
> -  // the different entries in a given redecl chain.
> -  llvm::SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D);
> -
>    /// Imports selected nodes from one AST context into another context,
>    /// merging AST nodes where appropriate.
>    class ASTImporter {
>
> Modified: cfe/trunk/lib/AST/ASTImporter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=335491&r1=335490&r2=335491&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTImporter.cpp (original)
> +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jun 25 09:25:30 2018
> @@ -71,25 +71,6 @@
>
>  namespace clang {
>
> -  template <class T>
> -  SmallVector<Decl*, 2>
> -  getCanonicalForwardRedeclChain(Redeclarable<T>* D) {
> -    SmallVector<Decl*, 2> Redecls;
> -    for (auto *R : D->getFirstDecl()->redecls()) {
> -      if (R != D->getFirstDecl())
> -        Redecls.push_back(R);
> -    }
> -    Redecls.push_back(D->getFirstDecl());
> -    std::reverse(Redecls.begin(), Redecls.end());
> -    return Redecls;
> -  }
> -
> -  SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D) {
> -    // Currently only FunctionDecl is supported
> -    auto FD = cast<FunctionDecl>(D);
> -    return getCanonicalForwardRedeclChain<FunctionDecl>(FD);
> -  }
> -
>    class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
>                            public DeclVisitor<ASTNodeImporter, Decl *>,
>                            public StmtVisitor<ASTNodeImporter, Stmt *> {
> @@ -214,12 +195,6 @@ namespace clang {
>                                          const InContainerTy &Container,
>                                          TemplateArgumentListInfo &Result);
>
> -    using TemplateArgsTy = SmallVector<TemplateArgument, 8>;
> -    using OptionalTemplateArgsTy = Optional<TemplateArgsTy>;
> -    std::tuple<FunctionTemplateDecl *, OptionalTemplateArgsTy>
> -    ImportFunctionTemplateWithTemplateArgsFromSpecialization(
> -        FunctionDecl *FromFD);
> -
>      bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl
> *ToFD);
>
>      bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
> @@ -433,8 +408,6 @@ namespace clang {
>
>      // Importing overrides.
>      void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl
> *FromMethod);
> -
> -    FunctionDecl *FindFunctionTemplateSpecialization(FunctionDecl
> *FromFD);
>    };
>
>  template <typename InContainerTy>
> @@ -464,25 +437,6 @@ bool ASTNodeImporter::ImportTemplateArgu
>                                          From.arguments(), Result);
>  }
>
> -std::tuple<FunctionTemplateDecl *,
> ASTNodeImporter::OptionalTemplateArgsTy>
> -ASTNodeImporter::ImportFunctionTemplateWithTemplateArgsFromSpecialization(
> -    FunctionDecl *FromFD) {
> -  assert(FromFD->getTemplatedKind() ==
> -         FunctionDecl::TK_FunctionTemplateSpecialization);
> -  auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
> -  auto *Template = cast_or_null<FunctionTemplateDecl>(
> -      Importer.Import(FTSInfo->getTemplate()));
> -
> -  // Import template arguments.
> -  auto TemplArgs = FTSInfo->TemplateArguments->asArray();
> -  TemplateArgsTy ToTemplArgs;
> -  if (ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
> -                              ToTemplArgs)) // Error during import.
> -    return std::make_tuple(Template, OptionalTemplateArgsTy());
> -
> -  return std::make_tuple(Template, ToTemplArgs);
> -}
> -
>  } // namespace clang
>
>
>  //----------------------------------------------------------------------------
> @@ -2298,17 +2252,23 @@ bool ASTNodeImporter::ImportTemplateInfo
>    }
>
>    case FunctionDecl::TK_FunctionTemplateSpecialization: {
> -    FunctionTemplateDecl* Template;
> -    OptionalTemplateArgsTy ToTemplArgs;
> -    std::tie(Template, ToTemplArgs) =
> -        ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
> -    if (!Template || !ToTemplArgs)
> +    auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
> +    auto *Template = cast_or_null<FunctionTemplateDecl>(
> +        Importer.Import(FTSInfo->getTemplate()));
> +    if (!Template)
> +      return true;
> +    TemplateSpecializationKind TSK =
> FTSInfo->getTemplateSpecializationKind();
> +
> +    // Import template arguments.
> +    auto TemplArgs = FTSInfo->TemplateArguments->asArray();
> +    SmallVector<TemplateArgument, 8> ToTemplArgs;
> +    if (ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
> +                                ToTemplArgs))
>        return true;
>
>      TemplateArgumentList *ToTAList = TemplateArgumentList::CreateCopy(
> -          Importer.getToContext(), *ToTemplArgs);
> +          Importer.getToContext(), ToTemplArgs);
>
> -    auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
>      TemplateArgumentListInfo ToTAInfo;
>      const auto *FromTAArgsAsWritten = FTSInfo->TemplateArgumentsAsWritten;
>      if (FromTAArgsAsWritten)
> @@ -2317,7 +2277,6 @@ bool ASTNodeImporter::ImportTemplateInfo
>
>      SourceLocation POI =
> Importer.Import(FTSInfo->getPointOfInstantiation());
>
> -    TemplateSpecializationKind TSK =
> FTSInfo->getTemplateSpecializationKind();
>      ToFD->setFunctionTemplateSpecialization(
>          Template, ToTAList, /* InsertPos= */ nullptr,
>          TSK, FromTAArgsAsWritten ? &ToTAInfo : nullptr, POI);
> @@ -2353,31 +2312,7 @@ bool ASTNodeImporter::ImportTemplateInfo
>    llvm_unreachable("All cases should be covered!");
>  }
>
> -FunctionDecl *
> -ASTNodeImporter::FindFunctionTemplateSpecialization(FunctionDecl *FromFD)
> {
> -  FunctionTemplateDecl* Template;
> -  OptionalTemplateArgsTy ToTemplArgs;
> -  std::tie(Template, ToTemplArgs) =
> -      ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
> -  if (!Template || !ToTemplArgs)
> -    return nullptr;
> -
> -  void *InsertPos = nullptr;
> -  auto *FoundSpec = Template->findSpecialization(*ToTemplArgs, InsertPos);
> -  return FoundSpec;
> -}
> -
>  Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
> -
> -  SmallVector<Decl*, 2> Redecls = getCanonicalForwardRedeclChain(D);
> -  auto RedeclIt = Redecls.begin();
> -  // Import the first part of the decl chain. I.e. import all previous
> -  // declarations starting from the canonical decl.
> -  for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt)
> -    if (!Importer.Import(*RedeclIt))
> -      return nullptr;
> -  assert(*RedeclIt == D);
> -
>    // Import the major distinguishing characteristics of this function.
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
> @@ -2388,27 +2323,13 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>    if (ToD)
>      return ToD;
>
> -  const FunctionDecl *FoundByLookup = nullptr;
> +  const FunctionDecl *FoundWithoutBody = nullptr;
>
> -  // If this is a function template specialization, then try to find the
> same
> -  // existing specialization in the "to" context. The localUncachedLookup
> -  // below will not find any specialization, but would find the primary
> -  // template; thus, we have to skip normal lookup in case of
> specializations.
> -  // FIXME handle member function templates (TK_MemberSpecialization)
> similarly?
> -  if (D->getTemplatedKind() ==
> -      FunctionDecl::TK_FunctionTemplateSpecialization) {
> -    if (FunctionDecl *FoundFunction =
> FindFunctionTemplateSpecialization(D)) {
> -      if (D->doesThisDeclarationHaveABody() &&
> -          FoundFunction->hasBody())
> -        return Importer.Imported(D, FoundFunction);
> -      FoundByLookup = FoundFunction;
> -    }
> -  }
>    // Try to find a function in our own ("to") context with the same name,
> same
>    // type, and in the same context as the function we're importing.
> -  else if (!LexicalDC->isFunctionOrMethod()) {
> +  if (!LexicalDC->isFunctionOrMethod()) {
>      SmallVector<NamedDecl *, 4> ConflictingDecls;
> -    unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
> +    unsigned IDNS = Decl::IDNS_Ordinary;
>      SmallVector<NamedDecl *, 2> FoundDecls;
>      DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
>      for (auto *FoundDecl : FoundDecls) {
> @@ -2420,11 +2341,15 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>              D->hasExternalFormalLinkage()) {
>            if (Importer.IsStructurallyEquivalent(D->getType(),
>
>  FoundFunction->getType())) {
> -              if (D->doesThisDeclarationHaveABody() &&
> -                  FoundFunction->hasBody())
> -                return Importer.Imported(D, FoundFunction);
> -              FoundByLookup = FoundFunction;
> +            // FIXME: Actually try to merge the body and other attributes.
> +            const FunctionDecl *FromBodyDecl = nullptr;
> +            D->hasBody(FromBodyDecl);
> +            if (D == FromBodyDecl && !FoundFunction->hasBody()) {
> +              // This function is needed to merge completely.
> +              FoundWithoutBody = FoundFunction;
>                break;
> +            }
> +            return Importer.Imported(D, FoundFunction);
>            }
>
>            // FIXME: Check for overloading more carefully, e.g., by
> boosting
> @@ -2574,9 +2499,9 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>    }
>    ToFunction->setParams(Parameters);
>
> -  if (FoundByLookup) {
> +  if (FoundWithoutBody) {
>      auto *Recent = const_cast<FunctionDecl *>(
> -          FoundByLookup->getMostRecentDecl());
> +          FoundWithoutBody->getMostRecentDecl());
>      ToFunction->setPreviousDecl(Recent);
>    }
>
> @@ -2598,11 +2523,10 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>      ToFunction->setType(T);
>    }
>
> -  if (D->doesThisDeclarationHaveABody()) {
> -    if (Stmt *FromBody = D->getBody()) {
> -      if (Stmt *ToBody = Importer.Import(FromBody)) {
> -        ToFunction->setBody(ToBody);
> -      }
> +  // Import the body, if any.
> +  if (Stmt *FromBody = D->getBody()) {
> +    if (Stmt *ToBody = Importer.Import(FromBody)) {
> +      ToFunction->setBody(ToBody);
>      }
>    }
>
> @@ -2612,29 +2536,14 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>    if (ImportTemplateInformation(D, ToFunction))
>      return nullptr;
>
> -  bool IsFriend = D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend);
> -
> -  // TODO Can we generalize this approach to other AST nodes as well?
> -  if (D->getDeclContext()->containsDecl(D))
> -    DC->addDeclInternal(ToFunction);
> -  if (DC != LexicalDC && D->getLexicalDeclContext()->containsDecl(D))
> +  // Add this function to the lexical context.
> +  // NOTE: If the function is templated declaration, it should be not
> added into
> +  // LexicalDC. But described template is imported during import of
> +  // FunctionTemplateDecl (it happens later). So, we use source
> declaration
> +  // to determine if we should add the result function.
> +  if (!D->getDescribedFunctionTemplate())
>      LexicalDC->addDeclInternal(ToFunction);
>
> -  // Friend declaration's lexical context is the befriending class, but
> the
> -  // semantic context is the enclosing scope of the befriending class.
> -  // We want the friend functions to be found in the semantic context by
> lookup.
> -  // FIXME should we handle this generically in VisitFriendDecl?
> -  // In Other cases when LexicalDC != DC we don't want it to be added,
> -  // e.g out-of-class definitions like void B::f() {} .
> -  if (LexicalDC != DC && IsFriend) {
> -    DC->makeDeclVisibleInContext(ToFunction);
> -  }
> -
> -  // Import the rest of the chain. I.e. import all subsequent
> declarations.
> -  for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt)
> -    if (!Importer.Import(*RedeclIt))
> -      return nullptr;
> -
>    if (auto *FromCXXMethod = dyn_cast<CXXMethodDecl>(D))
>      ImportOverrides(cast<CXXMethodDecl>(ToFunction), FromCXXMethod);
>
>
> Modified: cfe/trunk/lib/AST/DeclBase.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=335491&r1=335490&r2=335491&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> +++ cfe/trunk/lib/AST/DeclBase.cpp Mon Jun 25 09:25:30 2018
> @@ -1343,8 +1343,6 @@ bool DeclContext::decls_empty() const {
>  }
>
>  bool DeclContext::containsDecl(Decl *D) const {
> -  if (hasExternalLexicalStorage())
> -    LoadLexicalDeclsFromExternalStorage();
>    return (D->getLexicalDeclContext() == this &&
>            (D->NextInContextAndBits.getPointer() || D == LastDecl));
>  }
>
> Modified: cfe/trunk/test/ASTMerge/class/test.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/class/test.cpp?rev=335491&r1=335490&r2=335491&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/ASTMerge/class/test.cpp (original)
> +++ cfe/trunk/test/ASTMerge/class/test.cpp Mon Jun 25 09:25:30 2018
> @@ -13,12 +13,12 @@
>  // CHECK: class1.cpp:19:3: note: enumerator 'b' with value 1 here
>  // CHECK: class2.cpp:12:3: note: enumerator 'a' with value 0 here
>
> -// CHECK: class1.cpp:43:8: warning: type 'F3' has incompatible
> definitions in different translation units
> -// CHECK: class1.cpp:46:3: note: friend declared here
> -// CHECK: class2.cpp:36:8: note: no corresponding friend here
> -
>  // CHECK: class1.cpp:36:8: warning: type 'F2' has incompatible
> definitions in different translation units
>  // CHECK: class1.cpp:39:3: note: friend declared here
>  // CHECK: class2.cpp:30:8: note: no corresponding friend here
>
> +// CHECK: class1.cpp:43:8: warning: type 'F3' has incompatible
> definitions in different translation units
> +// CHECK: class1.cpp:46:3: note: friend declared here
> +// CHECK: class2.cpp:36:8: note: no corresponding friend here
> +
>  // CHECK: 4 warnings generated.
>
> Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=335491&r1=335490&r2=335491&view=diff
>
> ==============================================================================
> --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
> +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Jun 25 09:25:30 2018
> @@ -20,7 +20,7 @@
>
>  #include "DeclMatcher.h"
>  #include "Language.h"
> -#include "gmock/gmock.h"
> +#include "gtest/gtest.h"
>  #include "llvm/ADT/StringMap.h"
>
>  namespace clang {
> @@ -428,48 +428,6 @@ struct ImportExpr : TestImportBase {};
>  struct ImportType : TestImportBase {};
>  struct ImportDecl : TestImportBase {};
>
> -struct CanonicalRedeclChain : ASTImporterTestBase {};
> -
> -TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers) {
> -  Decl *FromTU = getTuDecl("void f();", Lang_CXX);
> -  auto Pattern = functionDecl(hasName("f"));
> -  auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -
> -  auto Redecls = getCanonicalForwardRedeclChain(D0);
> -  ASSERT_EQ(Redecls.size(), 1u);
> -  EXPECT_EQ(D0, Redecls[0]);
> -}
> -
> -TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers2) {
> -  Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX);
> -  auto Pattern = functionDecl(hasName("f"));
> -  auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -  auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -  FunctionDecl *D1 = D2->getPreviousDecl();
> -
> -  auto Redecls = getCanonicalForwardRedeclChain(D0);
> -  ASSERT_EQ(Redecls.size(), 3u);
> -  EXPECT_EQ(D0, Redecls[0]);
> -  EXPECT_EQ(D1, Redecls[1]);
> -  EXPECT_EQ(D2, Redecls[2]);
> -}
> -
> -TEST_P(CanonicalRedeclChain, ShouldBeSameForAllDeclInTheChain) {
> -  Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX);
> -  auto Pattern = functionDecl(hasName("f"));
> -  auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -  auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -  FunctionDecl *D1 = D2->getPreviousDecl();
> -
> -  auto RedeclsD0 = getCanonicalForwardRedeclChain(D0);
> -  auto RedeclsD1 = getCanonicalForwardRedeclChain(D1);
> -  auto RedeclsD2 = getCanonicalForwardRedeclChain(D2);
> -
> -  EXPECT_THAT(RedeclsD0, ::testing::ContainerEq(RedeclsD1));
> -  EXPECT_THAT(RedeclsD1, ::testing::ContainerEq(RedeclsD2));
> -}
> -
> -
>  TEST_P(ImportExpr, ImportStringLiteral) {
>    MatchVerifier<Decl> Verifier;
>    testImport("void declToImport() { \"foo\"; }",
> @@ -1715,6 +1673,34 @@ TEST_P(
>  struct ImportFunctions : ASTImporterTestBase {};
>
>  TEST_P(ImportFunctions,
> +       PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition) {
> +  Decl *FromTU = getTuDecl("void f();", Lang_CXX);
> +  auto Pattern = functionDecl(hasName("f"));
> +  FunctionDecl *FromD =
> +      FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +
> +  Decl *ImportedD = Import(FromD, Lang_CXX);
> +  Decl *ToTU = ImportedD->getTranslationUnitDecl();
> +
> +  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
> +
> EXPECT_TRUE(!cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
> +}
> +
> +TEST_P(ImportFunctions,
> +       PrototypeShouldBeImportedAsDefintionWhenThereIsADefinition) {
> +  Decl *FromTU = getTuDecl("void f(); void f() {}", Lang_CXX);
> +  auto Pattern = functionDecl(hasName("f"));
> +  FunctionDecl *FromD = // Prototype
> +      FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +
> +  Decl *ImportedD = Import(FromD, Lang_CXX);
> +  Decl *ToTU = ImportedD->getTranslationUnitDecl();
> +
> +  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
> +
> EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
> +}
> +
> +TEST_P(ImportFunctions,
>         DefinitionShouldBeImportedAsDefintionWhenThereIsAPrototype) {
>    Decl *FromTU = getTuDecl("void f(); void f() {}", Lang_CXX);
>    auto Pattern = functionDecl(hasName("f"));
> @@ -1724,7 +1710,7 @@ TEST_P(ImportFunctions,
>    Decl *ImportedD = Import(FromD, Lang_CXX);
>    Decl *ToTU = ImportedD->getTranslationUnitDecl();
>
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> +  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
>
>  EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
>  }
>
> @@ -1741,40 +1727,30 @@ TEST_P(ImportFunctions, DefinitionShould
>
>  EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
>  }
>
> -TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) {
> +TEST_P(ImportFunctions, DISABLED_ImportPrototypeOfRecursiveFunction) {
>    Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX);
>    auto Pattern = functionDecl(hasName("f"));
> -  auto *From =
> -      FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Proto
> +  FunctionDecl *PrototypeFD =
> +      FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
>
> -  Decl *ImportedD = Import(From, Lang_CXX);
> +  Decl *ImportedD = Import(PrototypeFD, Lang_CXX);
>    Decl *ToTU = ImportedD->getTranslationUnitDecl();
>
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To0);
> -  EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
> -  EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(To1->getPreviousDecl(), To0);
> +  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
> +
> EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
>  }
>
>  TEST_P(ImportFunctions, ImportDefinitionOfRecursiveFunction) {
>    Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX);
>    auto Pattern = functionDecl(hasName("f"));
> -  auto *From =
> -      LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Def
> +  FunctionDecl *DefinitionFD =
> +      LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
>
> -  Decl *ImportedD = Import(From, Lang_CXX);
> +  Decl *ImportedD = Import(DefinitionFD, Lang_CXX);
>    Decl *ToTU = ImportedD->getTranslationUnitDecl();
>
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To1);
> -  EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
> -  EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(To1->getPreviousDecl(), To0);
> +  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
> +
> EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
>  }
>
>  TEST_P(ImportFunctions, ImportPrototypes) {
> @@ -1783,48 +1759,23 @@ TEST_P(ImportFunctions, ImportPrototypes
>    Decl *ImportedD;
>    {
>      Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input0.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +    FunctionDecl *FromD =
> +        FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
>
>      ImportedD = Import(FromD, Lang_CXX);
>    }
> +  Decl *ImportedD1;
>    {
>      Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input1.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    Import(FromD, Lang_CXX);
> -  }
> -
> -  Decl *ToTU = ImportedD->getTranslationUnitDecl();
> -
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To0);
> -  EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
> -  EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(To1->getPreviousDecl(), To0);
> -}
> -
> -TEST_P(ImportFunctions, ImportDefinitions) {
> -  auto Pattern = functionDecl(hasName("f"));
> -
> -  Decl *ImportedD;
> -  {
> -    Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input0.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    ImportedD = Import(FromD, Lang_CXX);
> -  }
> -  {
> -    Decl *FromTU = getTuDecl("void f(){};", Lang_CXX, "input1.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    Import(FromD, Lang_CXX);
> +    FunctionDecl *FromD =
> +        FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +    ImportedD1 = Import(FromD, Lang_CXX);
>    }
>
> -  Decl *ToTU = ImportedD->getTranslationUnitDecl();
> -
> +  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
>    EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To0);
> -  EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
> +  EXPECT_EQ(ImportedD, ImportedD1);
> +
> EXPECT_TRUE(!cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
>  }
>
>  TEST_P(ImportFunctions, ImportDefinitionThenPrototype) {
> @@ -1833,24 +1784,23 @@ TEST_P(ImportFunctions, ImportDefinition
>    Decl *ImportedD;
>    {
>      Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input0.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +    FunctionDecl *FromD =
> +        FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +
>      ImportedD = Import(FromD, Lang_CXX);
>    }
> +  Decl *ImportedD1;
>    {
>      Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input1.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    Import(FromD, Lang_CXX);
> +    FunctionDecl *FromD =
> +        FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +    ImportedD1 = Import(FromD, Lang_CXX);
>    }
>
>    Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To0);
> -  EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
> -  EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(To1->getPreviousDecl(), To0);
> +  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
> +  EXPECT_EQ(ImportedD, ImportedD1);
> +
> EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
>  }
>
>  TEST_P(ImportFunctions, ImportPrototypeThenDefinition) {
> @@ -1873,40 +1823,38 @@ TEST_P(ImportFunctions, ImportPrototypeT
>    Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
>    ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
>    FunctionDecl *ProtoD = FirstDeclMatcher<FunctionDecl>().match(ToTU,
> Pattern);
> -  EXPECT_FALSE(ProtoD->doesThisDeclarationHaveABody());
> +  EXPECT_TRUE(!ProtoD->doesThisDeclarationHaveABody());
>    FunctionDecl *DefinitionD =
>        LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
>    EXPECT_TRUE(DefinitionD->doesThisDeclarationHaveABody());
>    EXPECT_EQ(DefinitionD->getPreviousDecl(), ProtoD);
>  }
>
> -TEST_P(ImportFunctions, ImportPrototypeThenProtoAndDefinition) {
> +TEST_P(ImportFunctions, DISABLED_ImportPrototypeThenProtoAndDefinition) {
>    auto Pattern = functionDecl(hasName("f"));
>
>    {
>      Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input0.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +    FunctionDecl *FromD =
> +        FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +
>      Import(FromD, Lang_CXX);
>    }
>    {
>      Decl *FromTU = getTuDecl("void f(); void f(){}", Lang_CXX,
> "input1.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> +    FunctionDecl *FromD =
> +        FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
>      Import(FromD, Lang_CXX);
>    }
>
>    Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -
> -  ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 3u);
> +  ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
>    FunctionDecl *ProtoD = FirstDeclMatcher<FunctionDecl>().match(ToTU,
> Pattern);
> -  EXPECT_FALSE(ProtoD->doesThisDeclarationHaveABody());
> -
> +  EXPECT_TRUE(!ProtoD->doesThisDeclarationHaveABody());
>    FunctionDecl *DefinitionD =
>        LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
>    EXPECT_TRUE(DefinitionD->doesThisDeclarationHaveABody());
> -
> -  EXPECT_TRUE(DefinitionD->getPreviousDecl());
> -
> EXPECT_FALSE(DefinitionD->getPreviousDecl()->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(DefinitionD->getPreviousDecl()->getPreviousDecl(), ProtoD);
> +  EXPECT_EQ(DefinitionD->getPreviousDecl(), ProtoD);
>  }
>
>  TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) {
> @@ -1946,202 +1894,6 @@ TEST_P(ImportFunctions, VirtualFlagShoul
>    EXPECT_TRUE(To->isVirtual());
>  }
>
> -TEST_P(ImportFunctions,
> -       ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl) {
> -  Decl *ToTU = getToTuDecl(
> -      R"(
> -      void f() {}
> -      void f();
> -      )",
> -      Lang_CXX);
> -  ASSERT_EQ(1u,
> -            DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl
> *FD) {
> -              return FD->doesThisDeclarationHaveABody();
> -            }).match(ToTU, functionDecl()));
> -
> -  Decl *FromTU = getTuDecl("void f() {}", Lang_CXX, "input0.cc");
> -  auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU,
> functionDecl());
> -
> -  Import(FromD, Lang_CXX);
> -
> -  EXPECT_EQ(1u,
> -            DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl
> *FD) {
> -              return FD->doesThisDeclarationHaveABody();
> -            }).match(ToTU, functionDecl()));
> -}
> -
> -struct ImportFriendFunctions : ImportFunctions {};
> -
> -TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) {
> -  auto Pattern = functionDecl(hasName("f"));
> -
> -  Decl *FromTU = getTuDecl("struct X { friend void f(); };"
> -                           "void f();",
> -                           Lang_CXX,
> -                           "input0.cc");
> -  auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -
> -  auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX));
> -  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
> -  auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
> -}
> -
> -TEST_P(ImportFriendFunctions,
> -       ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst) {
> -  auto Pattern = functionDecl(hasName("f"));
> -
> -  Decl *FromTU = getTuDecl("void f();"
> -                           "struct X { friend void f(); };",
> -                           Lang_CXX, "input0.cc");
> -  auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -
> -  auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX));
> -  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
> -  auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
> -}
> -
> -TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDef) {
> -  auto Pattern = functionDecl(hasName("f"));
> -
> -  Decl *FromTU = getTuDecl("struct X { friend void f(){} };"
> -                           "void f();",
> -                           Lang_CXX,
> -                           "input0.cc");
> -  auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -
> -  auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX));
> -  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
> -  auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
> -}
> -
> -TEST_P(ImportFriendFunctions,
> -       ImportFriendFunctionRedeclChainDef_OutOfClassDef) {
> -  auto Pattern = functionDecl(hasName("f"));
> -
> -  Decl *FromTU = getTuDecl("struct X { friend void f(); };"
> -                           "void f(){}",
> -                           Lang_CXX, "input0.cc");
> -  auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -
> -  auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX));
> -  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
> -  auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ToFD->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
> -}
> -
> -// This test is disabled, because ATM we create a redundant
> FunctionDecl.  We
> -// start the import with the definition of `f` then we continue with the
> import
> -// of the type of `f` which involves `X`. During the import of `X` we
> start
> -// again the import of the definition of `f` and then finally we create
> the
> -// node. But then in the first frame of `VisitFunctionDecl` we create a
> node
> -// again since we do not check if such a node exists yet or not. This is
> being
> -// fixed in a separate patch: https://reviews.llvm.org/D47632
> -// FIXME enable this test once the above patch is approved.
> -TEST_P(ImportFriendFunctions,
> -    DISABLED_ImportFriendFunctionRedeclChainDefWithClass) {
> -  auto Pattern = functionDecl(hasName("f"));
> -
> -  Decl *FromTU = getTuDecl(
> -      R"(
> -        class X;
> -        void f(X *x){}
> -        class X{
> -        friend void f(X *x);
> -        };
> -      )",
> -      Lang_CXX, "input0.cc");
> -  auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -
> -  auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX));
> -  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
> -  auto *InClassFD = cast<FunctionDecl>(FirstDeclMatcher<FriendDecl>()
> -                                              .match(ToTU, friendDecl())
> -                                              ->getFriendDecl());
> -  EXPECT_FALSE(InClassFD->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(InClassFD->getPreviousDecl(), ImportedD);
> -  // The parameters must refer the same type
> -  EXPECT_EQ((*InClassFD->param_begin())->getOriginalType(),
> -            (*ImportedD->param_begin())->getOriginalType());
> -}
> -
> -// This test is disabled, because ATM we create a redundant
> FunctionDecl.  We
> -// start the import with the definition of `f` then we continue with the
> import
> -// of the type of `f` which involves `X`. During the import of `X` we
> start
> -// again the import of the definition of `f` and then finally we create
> the
> -// node. But then in the first frame of `VisitFunctionDecl` we create a
> node
> -// again since we do not check if such a node exists yet or not. This is
> being
> -// fixed in a separate patch: https://reviews.llvm.org/D47632
> -// FIXME enable this test once the above patch is approved.
> -TEST_P(ImportFriendFunctions,
> -
>  DISABLED_ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) {
> -  auto Pattern = functionDecl(hasName("f"));
> -
> -  Decl *FromTU = getTuDecl(
> -      R"(
> -        class X;
> -        void f(X *x){}
> -        class X{
> -        friend void f(X *x);
> -        };
> -      )",
> -      Lang_CXX, "input0.cc");
> -  auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -
> -  auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX));
> -  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
> -  auto *OutOfClassFD = FirstDeclMatcher<FunctionDecl>().match(
> -      ToTU, functionDecl(unless(hasParent(friendDecl()))));
> -
> -  EXPECT_TRUE(OutOfClassFD->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(ImportedD->getPreviousDecl(), OutOfClassFD);
> -  // The parameters must refer the same type
> -  EXPECT_EQ((*OutOfClassFD->param_begin())->getOriginalType(),
> -            (*ImportedD->param_begin())->getOriginalType());
> -}
> -
> -TEST_P(ImportFriendFunctions, ImportFriendFunctionFromMultipleTU) {
> -  auto Pattern = functionDecl(hasName("f"));
> -
> -  FunctionDecl *ImportedD;
> -  {
> -    Decl *FromTU =
> -        getTuDecl("struct X { friend void f(){} };", Lang_CXX,
> "input0.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX));
> -  }
> -  FunctionDecl *ImportedD1;
> -  {
> -    Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input1.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    ImportedD1 = cast<FunctionDecl>(Import(FromD, Lang_CXX));
> -  }
> -
> -  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
> -  EXPECT_FALSE(ImportedD1->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(ImportedD1->getPreviousDecl(), ImportedD);
> -}
> -
>  AST_MATCHER_P(TagDecl, hasTypedefForAnonDecl, Matcher<TypedefNameDecl>,
>                InnerMatcher) {
>    if (auto *Typedef = Node.getTypedefNameForAnonDecl())
> @@ -2272,328 +2024,9 @@ TEST_P(DeclContextTest, removeDeclOfClas
>    EXPECT_FALSE(NS->containsDecl(Spec));
>  }
>
> -struct ImportFunctionTemplateSpecializations : ASTImporterTestBase {};
> -
> -TEST_P(ImportFunctionTemplateSpecializations,
> -       TUshouldNotContainFunctionTemplateImplicitInstantiation) {
> -
> -  Decl *FromTU = getTuDecl(
> -      R"(
> -      template<class T>
> -      int f() { return 0; }
> -      void foo() { f<int>(); }
> -      )",
> -      Lang_CXX, "input0.cc");
> -
> -  // Check that the function template instantiation is NOT the child of
> the TU.
> -  auto Pattern = translationUnitDecl(
> -      unless(has(functionDecl(hasName("f"), isTemplateInstantiation()))));
> -  ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
> -
> -  auto *Foo = FirstDeclMatcher<FunctionDecl>().match(
> -      FromTU, functionDecl(hasName("foo")));
> -  ASSERT_TRUE(Import(Foo, Lang_CXX));
> -
> -  auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
> -}
> -
> -TEST_P(ImportFunctionTemplateSpecializations,
> -       TUshouldNotContainFunctionTemplateExplicitInstantiation) {
> -
> -  Decl *FromTU = getTuDecl(
> -      R"(
> -      template<class T>
> -      int f() { return 0; }
> -      template int f<int>();
> -      )",
> -      Lang_CXX, "input0.cc");
> -
> -  // Check that the function template instantiation is NOT the child of
> the TU.
> -  auto Instantiation = functionDecl(hasName("f"),
> isTemplateInstantiation());
> -  auto Pattern = translationUnitDecl(unless(has(Instantiation)));
> -  ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
> -
> -  ASSERT_TRUE(
> -      Import(FirstDeclMatcher<Decl>().match(FromTU, Instantiation),
> Lang_CXX));
> -
> -  auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
> -}
> -
> -TEST_P(ImportFunctionTemplateSpecializations,
> -       TUshouldContainFunctionTemplateSpecialization) {
> -
> -  Decl *FromTU = getTuDecl(
> -      R"(
> -      template<class T>
> -      int f() { return 0; }
> -      template <> int f<int>() { return 4; }
> -      )",
> -      Lang_CXX, "input0.cc");
> -
> -  // Check that the function template specialization is the child of the
> TU.
> -  auto Specialization =
> -      functionDecl(hasName("f"), isExplicitTemplateSpecialization());
> -  auto Pattern = translationUnitDecl(has(Specialization));
> -  ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
> -
> -  ASSERT_TRUE(
> -      Import(FirstDeclMatcher<Decl>().match(FromTU, Specialization),
> Lang_CXX));
> -
> -  auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
> -}
> -
> -TEST_P(ImportFunctionTemplateSpecializations,
> -       FunctionTemplateSpecializationRedeclChain) {
> -
> -  Decl *FromTU = getTuDecl(
> -      R"(
> -      template<class T>
> -      int f() { return 0; }
> -      template <> int f<int>() { return 4; }
> -      )",
> -      Lang_CXX, "input0.cc");
> -
> -  auto Spec = functionDecl(hasName("f"),
> isExplicitTemplateSpecialization(),
> -                           hasParent(translationUnitDecl()));
> -  auto *FromSpecD = FirstDeclMatcher<Decl>().match(FromTU, Spec);
> -  {
> -    auto *TU = FromTU;
> -    auto *SpecD = FromSpecD;
> -    auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
> -        TU, functionTemplateDecl());
> -    auto *FirstSpecD = *(TemplateD->spec_begin());
> -    ASSERT_EQ(SpecD, FirstSpecD);
> -    ASSERT_TRUE(SpecD->getPreviousDecl());
> -    ASSERT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
> -                     ->doesThisDeclarationHaveABody());
> -  }
> -
> -  ASSERT_TRUE(Import(FromSpecD, Lang_CXX));
> -
> -  {
> -    auto *TU = ToAST->getASTContext().getTranslationUnitDecl();
> -    auto *SpecD = FirstDeclMatcher<Decl>().match(TU, Spec);
> -    auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
> -        TU, functionTemplateDecl());
> -    auto *FirstSpecD = *(TemplateD->spec_begin());
> -    EXPECT_EQ(SpecD, FirstSpecD);
> -    ASSERT_TRUE(SpecD->getPreviousDecl());
> -    EXPECT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
> -                     ->doesThisDeclarationHaveABody());
> -  }
> -}
> -
> -TEST_P(ImportFunctionTemplateSpecializations,
> -       MatchNumberOfFunctionTemplateSpecializations) {
> -
> -  Decl *FromTU = getTuDecl(
> -      R"(
> -      template <typename T> constexpr int f() { return 0; }
> -      template <> constexpr int f<int>() { return 4; }
> -      void foo() {
> -        static_assert(f<char>() == 0, "");
> -        static_assert(f<int>() == 4, "");
> -      }
> -      )",
> -      Lang_CXX11, "input0.cc");
> -  auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
> -      FromTU, functionDecl(hasName("foo")));
> -
> -  Import(FromD, Lang_CXX11);
> -  auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
> -  EXPECT_EQ(
> -      DeclCounter<FunctionDecl>().match(FromTU,
> functionDecl(hasName("f"))),
> -      DeclCounter<FunctionDecl>().match(ToTU,
> functionDecl(hasName("f"))));
> -}
> -
> -TEST_P(ImportFunctionTemplateSpecializations,
> -       ImportPrototypes) {
> -  auto Pattern = functionDecl(hasName("f"),
> isExplicitTemplateSpecialization());
> -  auto Code =
> -      R"(
> -      // Proto of the primary template.
> -      template <class T>
> -      void f();
> -      // Proto of the specialization.
> -      template <>
> -      void f<int>();
> -      )";
> -
> -  Decl *ImportedD;
> -  {
> -    Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
> -    auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -
> -    ImportedD = Import(FromD, Lang_CXX);
> -  }
> -  {
> -    Decl *FromTU = getTuDecl(Code, Lang_CXX, "input1.cc");
> -    auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    Import(FromD, Lang_CXX);
> -  }
> -
> -  Decl *ToTU = ImportedD->getTranslationUnitDecl();
> -
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To0);
> -  EXPECT_TRUE(ImportedD != To1);
> -  EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
> -  EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
> -  // Check that they are part of the same redecl chain.
> -  EXPECT_EQ(To1->getCanonicalDecl(), To0->getCanonicalDecl());
> -}
> -
> -TEST_P(ImportFunctionTemplateSpecializations, ImportDefinitions) {
> -  auto Pattern = functionDecl(hasName("f"),
> isExplicitTemplateSpecialization());
> -  auto Code =
> -      R"(
> -      // Proto of the primary template.
> -      template <class T>
> -      void f();
> -      // Specialization and definition.
> -      template <>
> -      void f<int>() {}
> -      )";
> -
> -  Decl *ImportedD;
> -  {
> -    Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    ImportedD = Import(FromD, Lang_CXX);
> -  }
> -  {
> -    Decl *FromTU = getTuDecl(Code, Lang_CXX, "input1.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    Import(FromD, Lang_CXX);
> -  }
> -
> -  Decl *ToTU = ImportedD->getTranslationUnitDecl();
> -
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To0);
> -  EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
> -
> -  auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
> -      ToTU, functionTemplateDecl());
> -  auto *FirstSpecD = *(TemplateD->spec_begin());
> -  EXPECT_EQ(FirstSpecD->getCanonicalDecl(), To0->getCanonicalDecl());
> -}
> -
> -TEST_P(ImportFunctionTemplateSpecializations, PrototypeThenPrototype) {
> -  auto Pattern = functionDecl(hasName("f"),
> isExplicitTemplateSpecialization());
> -  auto Code =
> -      R"(
> -      // Proto of the primary template.
> -      template <class T>
> -      void f();
> -      // Specialization proto.
> -      template <>
> -      void f<int>();
> -      // Specialization proto.
> -      template <>
> -      void f<int>();
> -      )";
> -
> -  Decl *ImportedD;
> -  {
> -    Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    ImportedD = Import(FromD, Lang_CXX);
> -  }
> -
> -  Decl *ToTU = ImportedD->getTranslationUnitDecl();
> -
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To0);
> -  EXPECT_TRUE(ImportedD != To1);
> -  EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
> -  EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(To1->getPreviousDecl(), To0);
> -}
> -
> -TEST_P(ImportFunctionTemplateSpecializations, PrototypeThenDefinition) {
> -  auto Pattern = functionDecl(hasName("f"),
> isExplicitTemplateSpecialization());
> -  auto Code =
> -      R"(
> -      // Proto of the primary template.
> -      template <class T>
> -      void f();
> -      // Specialization proto.
> -      template <>
> -      void f<int>();
> -      // Specialization definition.
> -      template <>
> -      void f<int>() {}
> -      )";
> -
> -  Decl *ImportedD;
> -  {
> -    Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    ImportedD = Import(FromD, Lang_CXX);
> -  }
> -
> -  Decl *ToTU = ImportedD->getTranslationUnitDecl();
> -
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To0);
> -  EXPECT_TRUE(ImportedD != To1);
> -  EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
> -  EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(To1->getPreviousDecl(), To0);
> -}
> -
> -TEST_P(ImportFunctionTemplateSpecializations, DefinitionThenPrototype) {
> -  auto Pattern = functionDecl(hasName("f"),
> isExplicitTemplateSpecialization());
> -  auto Code =
> -      R"(
> -      // Proto of the primary template.
> -      template <class T>
> -      void f();
> -      // Specialization definition.
> -      template <>
> -      void f<int>() {}
> -      // Specialization proto.
> -      template <>
> -      void f<int>();
> -      )";
> -
> -  Decl *ImportedD;
> -  {
> -    Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
> -    auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> -    ImportedD = Import(FromD, Lang_CXX);
> -  }
> -
> -  Decl *ToTU = ImportedD->getTranslationUnitDecl();
> -
> -  EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
> -  auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
> -  EXPECT_TRUE(ImportedD == To0);
> -  EXPECT_TRUE(ImportedD != To1);
> -  EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
> -  EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
> -  EXPECT_EQ(To1->getPreviousDecl(), To0);
> -}
> -
>  INSTANTIATE_TEST_CASE_P(ParameterizedTests, DeclContextTest,
>                          ::testing::Values(ArgVector()), );
>
> -INSTANTIATE_TEST_CASE_P(
> -    ParameterizedTests, CanonicalRedeclChain,
> -    ::testing::Values(ArgVector()),);
> -
>  auto DefaultTestValuesForRunOptions = ::testing::Values(
>      ArgVector(),
>      ArgVector{"-fdelayed-template-parsing"},
> @@ -2615,12 +2048,5 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTes
>  INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctions,
>                          DefaultTestValuesForRunOptions, );
>
> -INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
> -                        DefaultTestValuesForRunOptions, );
> -
> -INSTANTIATE_TEST_CASE_P(ParameterizedTests,
> -                        ImportFunctionTemplateSpecializations,
> -                        DefaultTestValuesForRunOptions, );
> -
>  } // end namespace ast_matchers
>  } // end namespace clang
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180625/8e0e0849/attachment-0001.html>


More information about the cfe-commits mailing list