Skip to content

Commit

Permalink
[ASTImporter] Added visibility check for variable templates.
Browse files Browse the repository at this point in the history
Summary:
ASTImporter makes now difference between variable templates
with same name in different translation units if not visible
outside.

Reviewers: a.sidorin, shafik, a_sidorin

Reviewed By: a_sidorin

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

Tags: #clang

Differential Revision: https://reviews.llvm.org/D75732
  • Loading branch information
balazske committed Mar 9, 2020
1 parent f35d112 commit 8d67bcf
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
4 changes: 4 additions & 0 deletions clang/lib/AST/ASTImporter.cpp
Expand Up @@ -5489,6 +5489,10 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
continue;

if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(FoundDecl)) {
// Use the templated decl, some linkage flags are set only there.
if (!hasSameVisibilityContextAndLinkage(FoundTemplate->getTemplatedDecl(),
D->getTemplatedDecl()))
continue;
if (IsStructuralMatch(D, FoundTemplate)) {
// The Decl in the "From" context has a definition, but in the
// "To" context we already have a definition.
Expand Down
43 changes: 43 additions & 0 deletions clang/unittests/AST/ASTImporterVisibilityTest.cpp
Expand Up @@ -49,6 +49,12 @@ struct GetFunTemplPattern {
return functionTemplateDecl(hasName("f"));
}
};
struct GetVarTemplPattern {
using DeclTy = VarTemplateDecl;
BindableMatcher<Decl> operator()() {
return namedDecl(hasName("v"), has(templateTypeParmDecl()));
}
};
struct GetClassTemplPattern {
using DeclTy = ClassTemplateDecl;
BindableMatcher<Decl> operator()() { return classTemplateDecl(hasName("X")); }
Expand Down Expand Up @@ -80,6 +86,10 @@ 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(); }";
// VarTemplateDecl:
const auto *ExternVT = "template <class> extern int v;";
const auto *StaticVT = "template <class> static int v;";
const auto *AnonVT = "namespace { template <class> extern int v; }";
// ClassTemplateDecl:
const auto *ExternCT = "template <class> class X;";
const auto *AnonCT = "namespace { template <class> class X; }";
Expand Down Expand Up @@ -130,6 +140,8 @@ using ImportClassesVisibilityChain = ImportVisibilityChain<GetClassPattern>;
using ImportScopedEnumsVisibilityChain = ImportVisibilityChain<GetEnumPattern>;
using ImportFunctionTemplatesVisibilityChain =
ImportVisibilityChain<GetFunTemplPattern>;
using ImportVariableTemplatesVisibilityChain =
ImportVisibilityChain<GetVarTemplPattern>;
using ImportClassTemplatesVisibilityChain =
ImportVisibilityChain<GetClassTemplPattern>;

Expand All @@ -153,6 +165,10 @@ TEST_P(ImportScopedEnumsVisibilityChain, ImportChain) {
TEST_P(ImportFunctionTemplatesVisibilityChain, ImportChain) {
TypedTest_ImportChain();
}
// Value-parameterized test for variable templates.
TEST_P(ImportVariableTemplatesVisibilityChain, ImportChain) {
TypedTest_ImportChain();
}
// Value-parameterized test for class templates.
TEST_P(ImportClassTemplatesVisibilityChain, ImportChain) {
TypedTest_ImportChain();
Expand Down Expand Up @@ -190,6 +206,11 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests,
::testing::Combine(DefaultTestValuesForRunOptions,
::testing::Values(ExternFT, StaticFT,
AnonFT)), );
INSTANTIATE_TEST_CASE_P(ParameterizedTests,
ImportVariableTemplatesVisibilityChain,
::testing::Combine(DefaultTestValuesForRunOptions,
::testing::Values(ExternVT,
AnonVT)), );
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClassTemplatesVisibilityChain,
::testing::Combine(DefaultTestValuesForRunOptions,
::testing::Values(ExternCT,
Expand Down Expand Up @@ -306,6 +327,7 @@ using ImportEnumsVisibility = ImportVisibility<GetEnumPattern>;
using ImportScopedEnumsVisibility = ImportVisibility<GetEnumPattern>;
using ImportTypedefNameVisibility = ImportVisibility<GetTypedefNamePattern>;
using ImportFunctionTemplatesVisibility = ImportVisibility<GetFunTemplPattern>;
using ImportVariableTemplatesVisibility = ImportVisibility<GetVarTemplPattern>;
using ImportClassTemplatesVisibility = ImportVisibility<GetClassTemplPattern>;

// FunctionDecl.
Expand Down Expand Up @@ -356,6 +378,13 @@ TEST_P(ImportFunctionTemplatesVisibility, ImportAfter) {
TEST_P(ImportFunctionTemplatesVisibility, ImportAfterImport) {
TypedTest_ImportAfterImport();
}
// VarTemplateDecl.
TEST_P(ImportVariableTemplatesVisibility, ImportAfter) {
TypedTest_ImportAfter();
}
TEST_P(ImportVariableTemplatesVisibility, ImportAfterImport) {
TypedTest_ImportAfterImport();
}
// ClassTemplateDecl.
TEST_P(ImportClassTemplatesVisibility, ImportAfter) { TypedTest_ImportAfter(); }
TEST_P(ImportClassTemplatesVisibility, ImportAfterImport) {
Expand Down Expand Up @@ -462,6 +491,20 @@ 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, ImportVariableTemplatesVisibility,
::testing::Combine(
DefaultTestValuesForRunOptions,
::testing::Values(
std::make_tuple(ExternVT, ExternVT, ExpectLinkedDeclChain),
std::make_tuple(ExternVT, StaticVT, ExpectUnlinkedDeclChain),
std::make_tuple(ExternVT, AnonVT, ExpectUnlinkedDeclChain),
std::make_tuple(StaticVT, ExternVT, ExpectUnlinkedDeclChain),
std::make_tuple(StaticVT, StaticVT, ExpectUnlinkedDeclChain),
std::make_tuple(StaticVT, AnonVT, ExpectUnlinkedDeclChain),
std::make_tuple(AnonVT, ExternVT, ExpectUnlinkedDeclChain),
std::make_tuple(AnonVT, StaticVT, ExpectUnlinkedDeclChain),
std::make_tuple(AnonVT, AnonVT, ExpectUnlinkedDeclChain))), );
INSTANTIATE_TEST_CASE_P(
ParameterizedTests, ImportClassTemplatesVisibility,
::testing::Combine(
Expand Down

0 comments on commit 8d67bcf

Please sign in to comment.