Skip to content
This repository has been archived by the owner on Mar 30, 2021. It is now read-only.

Fix ClassTemplateSpecialization in wrong DC #270

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4308,9 +4308,13 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(

D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());

// Add the specialization to this context.
// Set the context of this specialization/instantiation.
D2->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(D2);

// Add to the DC only if it was an explicit specialization/instantiation.
if (D2->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
LexicalDC->addDeclInternal(D2);
}
}
Importer.Imported(D, D2);
if (D->isCompleteDefinition() && ImportDefinition(D, D2))
Expand Down
61 changes: 61 additions & 0 deletions unittests/AST/ASTImporterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,67 @@ TEST_F(Fixture, TUshouldNotContainTemplatedDeclOfTypeAlias) {
Check(To);
}

TEST_F(
Fixture,
TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) {

Decl *From, *To;
std::tie(From, To) = getImportedDecl(
R"(
template<class T>
class Base {};
class declToImport : public Base<declToImport> {};
)",
Lang_CXX, "", Lang_CXX);

// Check that the ClassTemplateSpecializationDecl is NOT the child of the TU
auto Pattern =
translationUnitDecl(unless(has(classTemplateSpecializationDecl())));
ASSERT_TRUE(
MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
EXPECT_TRUE(
MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));

// Check that the ClassTemplateSpecializationDecl is the child of the
// ClassTemplateDecl
Pattern = translationUnitDecl(has(classTemplateDecl(
hasName("Base"), has(classTemplateSpecializationDecl()))));
ASSERT_TRUE(
MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
EXPECT_TRUE(
MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
}

TEST_F(
Fixture,
TUshouldContainClassTemplateSpecializationOfExplicitInstantiation) {

Decl *From, *To;
std::tie(From, To) = getImportedDecl(
R"(
namespace NS {
template<class T>
class X {};
template class X<int>;
}
)",
Lang_CXX, "", Lang_CXX, "NS");

// Check that the ClassTemplateSpecializationDecl is NOT the child of the
// ClassTemplateDecl
auto Pattern = namespaceDecl(has(classTemplateDecl(
hasName("X"), unless(has(classTemplateSpecializationDecl())))));
ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));

// Check that the ClassTemplateSpecializationDecl is the child of the
// NamespaceDecl
Pattern = namespaceDecl(has(classTemplateSpecializationDecl(hasName("X"))));
ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
}


TEST_F(Fixture, CXXRecordDeclFieldsShouldBeInCorrectOrder) {


Expand Down