r335491 - Revert "[ASTImporter] Import the whole redecl chain of functions"
Gábor Márton via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 25 14:14:25 PDT 2018
Hi Nico,
Yes, I reverted because it broke one of the lldb build bots.
Next time I'll include the reason in the revert commit.
Gábor
On Mon, 25 Jun 2018, 22:50 Nico Weber, <thakis at chromium.org> wrote:
> 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/a06f0d05/attachment-0001.html>
More information about the cfe-commits
mailing list