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