[Clang][ASTImporter] Added visibility check for ClassTemplateDecl.

Summary:
ASTImporter makes now difference between class templates with same
name in different translation units if these are not visible outside.

Reviewers: martong, a.sidorin, shafik

Reviewed By: martong

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, teemperor, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67543
This commit is contained in:
Balázs Kéri 2019-11-15 15:05:20 +01:00
parent 02419ab5c7
commit c2f6efc732
2 changed files with 33 additions and 1 deletions

View File

@ -5075,6 +5075,8 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
Decl *Found = FoundDecl;
auto *FoundTemplate = dyn_cast<ClassTemplateDecl>(Found);
if (FoundTemplate) {
if (!hasSameVisibilityContext(FoundTemplate, D))
continue;
if (IsStructuralMatch(D, FoundTemplate)) {
ClassTemplateDecl *TemplateWithDef =

View File

@ -49,6 +49,10 @@ struct GetFunTemplPattern {
return functionTemplateDecl(hasName("f"));
}
};
struct GetClassTemplPattern {
using DeclTy = ClassTemplateDecl;
BindableMatcher<Decl> operator()() { return classTemplateDecl(hasName("X")); }
};
// Values for the value-parameterized test fixtures.
// FunctionDecl:
@ -74,6 +78,9 @@ const auto *AnonUsing = "namespace { using T = int; }";
const auto *ExternFT = "template <class> void f();";
const auto *StaticFT = "template <class> static void f();";
const auto *AnonFT = "namespace { template <class> void f(); }";
// ClassTemplateDecl:
const auto *ExternCT = "template <class> class X;";
const auto *AnonCT = "namespace { template <class> class X; }";
// First value in tuple: Compile options.
// Second value in tuple: Source code to be used in the test.
@ -120,6 +127,8 @@ using ImportVariablesVisibilityChain = ImportVisibilityChain<GetVarPattern>;
using ImportClassesVisibilityChain = ImportVisibilityChain<GetClassPattern>;
using ImportFunctionTemplatesVisibilityChain =
ImportVisibilityChain<GetFunTemplPattern>;
using ImportClassTemplatesVisibilityChain =
ImportVisibilityChain<GetClassTemplPattern>;
// Value-parameterized test for functions.
TEST_P(ImportFunctionsVisibilityChain, ImportChain) {
@ -137,6 +146,10 @@ TEST_P(ImportClassesVisibilityChain, ImportChain) {
TEST_P(ImportFunctionTemplatesVisibilityChain, ImportChain) {
TypedTest_ImportChain();
}
// Value-parameterized test for class templates.
TEST_P(ImportClassTemplatesVisibilityChain, ImportChain) {
TypedTest_ImportChain();
}
// Automatic instantiation of the value-parameterized tests.
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionsVisibilityChain,
@ -165,6 +178,10 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests,
::testing::Combine(DefaultTestValuesForRunOptions,
::testing::Values(ExternFT, StaticFT,
AnonFT)), );
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClassTemplatesVisibilityChain,
::testing::Combine(DefaultTestValuesForRunOptions,
::testing::Values(ExternCT,
AnonCT)), );
// First value in tuple: Compile options.
// Second value in tuple: Tuple with informations for the test.
@ -276,6 +293,7 @@ using ImportClassesVisibility = ImportVisibility<GetClassPattern>;
using ImportEnumsVisibility = ImportVisibility<GetEnumPattern>;
using ImportTypedefNameVisibility = ImportVisibility<GetTypedefNamePattern>;
using ImportFunctionTemplatesVisibility = ImportVisibility<GetFunTemplPattern>;
using ImportClassTemplatesVisibility = ImportVisibility<GetClassTemplPattern>;
// FunctionDecl.
TEST_P(ImportFunctionsVisibility, ImportAfter) {
@ -319,6 +337,11 @@ TEST_P(ImportFunctionTemplatesVisibility, ImportAfter) {
TEST_P(ImportFunctionTemplatesVisibility, ImportAfterImport) {
TypedTest_ImportAfterImport();
}
// ClassTemplateDecl.
TEST_P(ImportClassTemplatesVisibility, ImportAfter) { TypedTest_ImportAfter(); }
TEST_P(ImportClassTemplatesVisibility, ImportAfterImport) {
TypedTest_ImportAfterImport();
}
const bool ExpectLinkedDeclChain = true;
const bool ExpectUnlinkedDeclChain = false;
@ -411,6 +434,13 @@ INSTANTIATE_TEST_CASE_P(
std::make_tuple(AnonFT, ExternFT, ExpectUnlinkedDeclChain),
std::make_tuple(AnonFT, StaticFT, ExpectUnlinkedDeclChain),
std::make_tuple(AnonFT, AnonFT, ExpectUnlinkedDeclChain))), );
INSTANTIATE_TEST_CASE_P(
ParameterizedTests, ImportClassTemplatesVisibility,
::testing::Combine(
DefaultTestValuesForRunOptions,
::testing::Values(std::make_tuple(ExternCT, ExternCT, ExpectLinkedDeclChain),
std::make_tuple(ExternCT, AnonCT, ExpectUnlinkedDeclChain),
std::make_tuple(AnonCT, ExternCT, ExpectUnlinkedDeclChain),
std::make_tuple(AnonCT, AnonCT, ExpectUnlinkedDeclChain))), );
} // end namespace ast_matchers
} // end namespace clang