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, <tha...@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@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