aboutsummaryrefslogtreecommitdiff
path: root/unittests/AST/ASTImporterTest.cpp
diff options
context:
space:
mode:
authorGabor Marton <martongabesz@gmail.com>2019-03-19 14:04:50 +0000
committerGabor Marton <martongabesz@gmail.com>2019-03-19 14:04:50 +0000
commitf6f53c0d9bc5c14a4cc1ebd9dfb9ae01fc570703 (patch)
treef817f7a7a3def4c9925d95abb925bfbf29c876b8 /unittests/AST/ASTImporterTest.cpp
parente99393cc7ff622c1e730bfb176a579dd3cd3f5af (diff)
[ASTImporter] Fix redecl failures of FunctionTemplateSpec
Summary: Redecl chains of function template specializations are not handled well currently. We want to handle them similarly to functions, i.e. try to keep the structure of the original AST as much as possible. The aim is to not squash a prototype with a definition, rather we create both and put them in a redecl chain. Reviewers: a_sidorin, shafik, a.sidorin Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58668 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356455 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/AST/ASTImporterTest.cpp')
-rw-r--r--unittests/AST/ASTImporterTest.cpp137
1 files changed, 60 insertions, 77 deletions
diff --git a/unittests/AST/ASTImporterTest.cpp b/unittests/AST/ASTImporterTest.cpp
index 497d22007e..d6bd134985 100644
--- a/unittests/AST/ASTImporterTest.cpp
+++ b/unittests/AST/ASTImporterTest.cpp
@@ -3978,6 +3978,45 @@ struct RedeclChain : ASTImporterOptionSpecificTestBase {
std::string getDefinition() { return TypeParam::Definition; }
BindableMatcher<Decl> getPattern() const { return TypeParam().getPattern(); }
+ void CheckPreviousDecl(Decl *Prev, Decl *Current) {
+ ASSERT_NE(Prev, Current);
+ ASSERT_EQ(&Prev->getASTContext(), &Current->getASTContext());
+ EXPECT_EQ(Prev->getCanonicalDecl(), Current->getCanonicalDecl());
+
+ // Templates.
+ if (auto *PrevT = dyn_cast<TemplateDecl>(Prev)) {
+ EXPECT_EQ(Current->getPreviousDecl(), Prev);
+ auto *CurrentT = cast<TemplateDecl>(Current);
+ ASSERT_TRUE(PrevT->getTemplatedDecl());
+ ASSERT_TRUE(CurrentT->getTemplatedDecl());
+ EXPECT_EQ(CurrentT->getTemplatedDecl()->getPreviousDecl(),
+ PrevT->getTemplatedDecl());
+ return;
+ }
+
+ // Specializations.
+ if (auto *PrevF = dyn_cast<FunctionDecl>(Prev)) {
+ if (PrevF->getTemplatedKind() ==
+ FunctionDecl::TK_FunctionTemplateSpecialization) {
+ // There may be a hidden fwd spec decl before a spec decl.
+ // In that case the previous visible decl can be reached through that
+ // invisible one.
+ EXPECT_THAT(Prev, testing::AnyOf(
+ Current->getPreviousDecl(),
+ Current->getPreviousDecl()->getPreviousDecl()));
+ auto *ToTU = Prev->getTranslationUnitDecl();
+ auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
+ ToTU, functionTemplateDecl());
+ auto *FirstSpecD = *(TemplateD->spec_begin());
+ EXPECT_EQ(FirstSpecD->getCanonicalDecl(), PrevF->getCanonicalDecl());
+ return;
+ }
+ }
+
+ // The rest: Classes, Functions, etc.
+ EXPECT_EQ(Current->getPreviousDecl(), Prev);
+ }
+
void
TypedTest_PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition() {
Decl *FromTU = getTuDecl(getPrototype(), Lang_CXX);
@@ -4030,14 +4069,8 @@ struct RedeclChain : ASTImporterOptionSpecificTestBase {
EXPECT_TRUE(Imported1 == To1);
EXPECT_FALSE(To0->isThisDeclarationADefinition());
EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
- if (auto *ToT0 = dyn_cast<TemplateDecl>(To0)) {
- auto *ToT1 = cast<TemplateDecl>(To1);
- ASSERT_TRUE(ToT0->getTemplatedDecl());
- ASSERT_TRUE(ToT1->getTemplatedDecl());
- EXPECT_EQ(ToT1->getTemplatedDecl()->getPreviousDecl(),
- ToT0->getTemplatedDecl());
- }
+
+ CheckPreviousDecl(To0, To1);
}
void TypedTest_ImportDefinitionAfterImportedPrototype() {
@@ -4059,14 +4092,8 @@ struct RedeclChain : ASTImporterOptionSpecificTestBase {
EXPECT_TRUE(ImportedDef == ToDef);
EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
- if (auto *ToProtoT = dyn_cast<TemplateDecl>(ToProto)) {
- auto *ToDefT = cast<TemplateDecl>(ToDef);
- ASSERT_TRUE(ToProtoT->getTemplatedDecl());
- ASSERT_TRUE(ToDefT->getTemplatedDecl());
- EXPECT_EQ(ToDefT->getTemplatedDecl()->getPreviousDecl(),
- ToProtoT->getTemplatedDecl());
- }
+
+ CheckPreviousDecl(ToProto, ToDef);
}
void TypedTest_ImportPrototypeAfterImportedDefinition() {
@@ -4088,14 +4115,8 @@ struct RedeclChain : ASTImporterOptionSpecificTestBase {
EXPECT_TRUE(ImportedProto == ToProto);
EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
- if (auto *ToDefT = dyn_cast<TemplateDecl>(ToDef)) {
- auto *ToProtoT = cast<TemplateDecl>(ToProto);
- ASSERT_TRUE(ToDefT->getTemplatedDecl());
- ASSERT_TRUE(ToProtoT->getTemplatedDecl());
- EXPECT_EQ(ToProtoT->getTemplatedDecl()->getPreviousDecl(),
- ToDefT->getTemplatedDecl());
- }
+
+ CheckPreviousDecl(ToDef, ToProto);
}
void TypedTest_ImportPrototypes() {
@@ -4117,27 +4138,8 @@ struct RedeclChain : ASTImporterOptionSpecificTestBase {
EXPECT_TRUE(Imported1 == To1);
EXPECT_FALSE(To0->isThisDeclarationADefinition());
EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
- if (auto *ToT0 = dyn_cast<TemplateDecl>(To0)) {
- auto *ToT1 = cast<TemplateDecl>(To1);
- ASSERT_TRUE(ToT0->getTemplatedDecl());
- ASSERT_TRUE(ToT1->getTemplatedDecl());
- EXPECT_EQ(ToT1->getTemplatedDecl()->getPreviousDecl(),
- ToT0->getTemplatedDecl());
- }
- // Extra check for specializations.
- // FIXME Add this check to other tests too (possibly factor out into a
- // function), when they start to pass.
- if (auto *From0F = dyn_cast<FunctionDecl>(From0)) {
- auto *To0F = cast<FunctionDecl>(To0);
- if (From0F->getTemplatedKind() ==
- FunctionDecl::TK_FunctionTemplateSpecialization) {
- auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
- ToTU, functionTemplateDecl());
- auto *FirstSpecD = *(TemplateD->spec_begin());
- EXPECT_EQ(FirstSpecD->getCanonicalDecl(), To0F->getCanonicalDecl());
- }
- }
+
+ CheckPreviousDecl(To0, To1);
}
void TypedTest_ImportDefinitions() {
@@ -4182,14 +4184,8 @@ struct RedeclChain : ASTImporterOptionSpecificTestBase {
EXPECT_TRUE(ImportedProto == ToProto);
EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
- if (auto *ToDefT = dyn_cast<TemplateDecl>(ToDef)) {
- auto *ToProtoT = cast<TemplateDecl>(ToProto);
- ASSERT_TRUE(ToDefT->getTemplatedDecl());
- ASSERT_TRUE(ToProtoT->getTemplatedDecl());
- EXPECT_EQ(ToProtoT->getTemplatedDecl()->getPreviousDecl(),
- ToDefT->getTemplatedDecl());
- }
+
+ CheckPreviousDecl(ToDef, ToProto);
}
void TypedTest_ImportPrototypeThenDefinition() {
@@ -4213,14 +4209,8 @@ struct RedeclChain : ASTImporterOptionSpecificTestBase {
EXPECT_TRUE(ImportedProto == ToProto);
EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
- if (auto *ToDefT = dyn_cast<TemplateDecl>(ToDef)) {
- auto *ToProtoT = cast<TemplateDecl>(ToProto);
- ASSERT_TRUE(ToDefT->getTemplatedDecl());
- ASSERT_TRUE(ToProtoT->getTemplatedDecl());
- EXPECT_EQ(ToDefT->getTemplatedDecl()->getPreviousDecl(),
- ToProtoT->getTemplatedDecl());
- }
+
+ CheckPreviousDecl(ToProto, ToDef);
}
void TypedTest_WholeRedeclChainIsImportedAtOnce() {
@@ -4262,7 +4252,8 @@ struct RedeclChain : ASTImporterOptionSpecificTestBase {
EXPECT_TRUE(DefinitionD->getPreviousDecl());
EXPECT_FALSE(
DefinitionD->getPreviousDecl()->isThisDeclarationADefinition());
- EXPECT_EQ(DefinitionD->getPreviousDecl()->getPreviousDecl(), ProtoD);
+
+ CheckPreviousDecl(ProtoD, DefinitionD->getPreviousDecl());
}
};
@@ -4366,11 +4357,10 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportPrototypes)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportPrototypes)
-// FIXME This does not pass, possible error with Spec import.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
- DISABLED_, ImportPrototypes)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
ImportPrototypes)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportPrototypes)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportDefinitions)
@@ -4382,11 +4372,10 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportDefinitions)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportDefinitions)
-// FIXME This does not pass, possible error with Spec import.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
- DISABLED_, ImportDefinitions)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
ImportDefinitions)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportDefinitions)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportDefinitionThenPrototype)
@@ -4398,9 +4387,7 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportDefinitionThenPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportDefinitionThenPrototype)
-// FIXME This does not pass, possible error with Spec import.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
ImportDefinitionThenPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
ImportDefinitionThenPrototype)
@@ -4415,9 +4402,7 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportPrototypeThenDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportPrototypeThenDefinition)
-// FIXME This does not pass, possible error with Spec import.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
ImportPrototypeThenDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
ImportPrototypeThenDefinition)
@@ -4437,9 +4422,7 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypeThenProtoAndDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportPrototypeThenProtoAndDefinition)
-// FIXME This does not pass, possible error with Spec import.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
ImportPrototypeThenProtoAndDefinition)
INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainFunction,