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@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@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits