r335491 - Revert "[ASTImporter] Import the whole redecl chain of functions"
Gabor Marton via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 25 09:25:30 PDT 2018
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
More information about the cfe-commits
mailing list