[clang] d4741c4 - [ASTImporter] Added visibility check for scoped enums.
Balázs Kéri via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 17 05:35:15 PST 2020
Author: Balázs Kéri
Date: 2020-02-17T14:34:13+01:00
New Revision: d4741c44ab45a6ab9f32d773612f1bb79854f52f
URL: https://github.com/llvm/llvm-project/commit/d4741c44ab45a6ab9f32d773612f1bb79854f52f
DIFF: https://github.com/llvm/llvm-project/commit/d4741c44ab45a6ab9f32d773612f1bb79854f52f.diff
LOG: [ASTImporter] Added visibility check for scoped enums.
Summary:
ASTImporter makes now difference between C++11 scoped enums with same
name in different translation units if these are not visible outside.
Enum declarations are linked into decl chain correctly.
Reviewers: martong, a.sidorin, shafik, a_sidorin, teemperor
Reviewed By: shafik, a_sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, teemperor, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D74554
Added:
Modified:
clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterGenericRedeclTest.cpp
clang/unittests/AST/ASTImporterODRStrategiesTest.cpp
clang/unittests/AST/ASTImporterVisibilityTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 49058ceaab25..8710ef06aa51 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -2578,6 +2578,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
IDNS |= Decl::IDNS_Ordinary;
// We may already have an enum of the same name; try to find and match it.
+ EnumDecl *PrevDecl = nullptr;
if (!DC->isFunctionOrMethod() && SearchName) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
auto FoundDecls =
@@ -2594,8 +2595,13 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
if (auto *FoundEnum = dyn_cast<EnumDecl>(FoundDecl)) {
if (!hasSameVisibilityContext(FoundEnum, D))
continue;
- if (IsStructuralMatch(D, FoundEnum))
- return Importer.MapImported(D, FoundEnum);
+ if (IsStructuralMatch(D, FoundEnum)) {
+ EnumDecl *FoundDef = FoundEnum->getDefinition();
+ if (D->isThisDeclarationADefinition() && FoundDef)
+ return Importer.MapImported(D, FoundDef);
+ PrevDecl = FoundEnum->getMostRecentDecl();
+ break;
+ }
ConflictingDecls.push_back(FoundDecl);
}
}
@@ -2623,7 +2629,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
EnumDecl *D2;
if (GetImportedOrCreateDecl(
D2, D, Importer.getToContext(), DC, ToBeginLoc,
- Loc, Name.getAsIdentifierInfo(), nullptr, D->isScoped(),
+ Loc, Name.getAsIdentifierInfo(), PrevDecl, D->isScoped(),
D->isScopedUsingClassTag(), D->isFixed()))
return D2;
diff --git a/clang/unittests/AST/ASTImporterGenericRedeclTest.cpp b/clang/unittests/AST/ASTImporterGenericRedeclTest.cpp
index 0f994c107340..e0c5e9407788 100644
--- a/clang/unittests/AST/ASTImporterGenericRedeclTest.cpp
+++ b/clang/unittests/AST/ASTImporterGenericRedeclTest.cpp
@@ -35,6 +35,15 @@ struct Class {
}
};
+struct EnumClass {
+ using DeclTy = EnumDecl;
+ static constexpr auto *Prototype = "enum class X;";
+ static constexpr auto *Definition = "enum class X {};";
+ BindableMatcher<Decl> getPattern() {
+ return enumDecl(hasName("X"), unless(isImplicit()));
+ }
+};
+
struct Variable {
using DeclTy = VarDecl;
static constexpr auto *Prototype = "extern int X;";
@@ -406,6 +415,9 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
RedeclChain, Class, ,
PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, EnumClass, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
RedeclChain, Variable, ,
PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
@@ -426,6 +438,8 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
DefinitionShouldBeImportedAsADefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
DefinitionShouldBeImportedAsADefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, EnumClass, ,
+ DefinitionShouldBeImportedAsADefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
DefinitionShouldBeImportedAsADefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
@@ -441,6 +455,8 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportPrototypeAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
ImportPrototypeAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, EnumClass, ,
+ ImportPrototypeAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypeAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
@@ -456,6 +472,8 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportDefinitionAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
ImportDefinitionAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, EnumClass, ,
+ ImportDefinitionAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportDefinitionAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
@@ -471,6 +489,8 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportPrototypeAfterImportedDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
ImportPrototypeAfterImportedDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, EnumClass, ,
+ ImportPrototypeAfterImportedDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypeAfterImportedDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
@@ -485,6 +505,8 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportPrototypes)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, , ImportPrototypes)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, EnumClass, ,
+ ImportPrototypes)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypes)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
@@ -499,6 +521,8 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportDefinitions)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, , ImportDefinitions)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, EnumClass, ,
+ ImportDefinitions)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportDefinitions)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
@@ -514,6 +538,8 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportDefinitionThenPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
ImportDefinitionThenPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, EnumClass, ,
+ ImportDefinitionThenPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportDefinitionThenPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
@@ -529,6 +555,8 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportPrototypeThenDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
ImportPrototypeThenDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, EnumClass, ,
+ ImportPrototypeThenDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypeThenDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
@@ -562,6 +590,8 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainFunction,
DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainClass,
DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainEnumClass,
+ DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainVariable,
DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainFunctionTemplate,
diff --git a/clang/unittests/AST/ASTImporterODRStrategiesTest.cpp b/clang/unittests/AST/ASTImporterODRStrategiesTest.cpp
index 6a2aa2bfc328..2bd62e23ea38 100644
--- a/clang/unittests/AST/ASTImporterODRStrategiesTest.cpp
+++ b/clang/unittests/AST/ASTImporterODRStrategiesTest.cpp
@@ -64,6 +64,14 @@ struct Enum {
Language getLang() { return Lang_CXX; }
};
+struct EnumClass {
+ using DeclTy = EnumDecl;
+ static constexpr auto *Definition = "enum class X { a, b };";
+ static constexpr auto *ConflictingDefinition = "enum class X { a, b, c };";
+ BindableMatcher<Decl> getPattern() { return enumDecl(hasName("X")); }
+ Language getLang() { return Lang_CXX11; }
+};
+
struct EnumConstant {
using DeclTy = EnumConstantDecl;
static constexpr auto *Definition = "enum E { X = 0 };";
@@ -396,6 +404,9 @@ ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
Enum, Liberal, ,
ImportConflictingDefAfterDef)
+ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
+ EnumClass, Liberal, ,
+ ImportConflictingDefAfterDef)
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
EnumConstant, Liberal, ,
ImportConflictingDefAfterDef)
@@ -434,6 +445,9 @@ ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
Enum, Conservative, ,
DontImportConflictingDefAfterDef)
+ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
+ EnumClass, Conservative, ,
+ DontImportConflictingDefAfterDef)
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
EnumConstant, Conservative, ,
DontImportConflictingDefAfterDef)
@@ -595,6 +609,9 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, EnumConservative,
DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(
+ ODRViolationTests, EnumClassConservative,
+ DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, EnumConstantConservative,
DefaultTestValuesForRunOptions, );
@@ -640,6 +657,9 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, EnumLiberal,
DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(
+ ODRViolationTests, EnumClassLiberal,
+ DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, EnumConstantLiberal,
DefaultTestValuesForRunOptions, );
diff --git a/clang/unittests/AST/ASTImporterVisibilityTest.cpp b/clang/unittests/AST/ASTImporterVisibilityTest.cpp
index d00829f5cfee..14a6706cc761 100644
--- a/clang/unittests/AST/ASTImporterVisibilityTest.cpp
+++ b/clang/unittests/AST/ASTImporterVisibilityTest.cpp
@@ -69,6 +69,8 @@ const auto *AnonC = "namespace { class X; }";
// EnumDecl:
const auto *ExternE = "enum E {};";
const auto *AnonE = "namespace { enum E {}; }";
+const auto *ExternEC = "enum class E;";
+const auto *AnonEC = "namespace { enum class E; }";
// TypedefNameDecl:
const auto *ExternTypedef = "typedef int T;";
const auto *AnonTypedef = "namespace { typedef int T; }";
@@ -125,6 +127,7 @@ class ImportVisibilityChain
using ImportFunctionsVisibilityChain = ImportVisibilityChain<GetFunPattern>;
using ImportVariablesVisibilityChain = ImportVisibilityChain<GetVarPattern>;
using ImportClassesVisibilityChain = ImportVisibilityChain<GetClassPattern>;
+using ImportScopedEnumsVisibilityChain = ImportVisibilityChain<GetEnumPattern>;
using ImportFunctionTemplatesVisibilityChain =
ImportVisibilityChain<GetFunTemplPattern>;
using ImportClassTemplatesVisibilityChain =
@@ -142,6 +145,10 @@ TEST_P(ImportVariablesVisibilityChain, ImportChain) {
TEST_P(ImportClassesVisibilityChain, ImportChain) {
TypedTest_ImportChain();
}
+// Value-parameterized test for scoped enums.
+TEST_P(ImportScopedEnumsVisibilityChain, ImportChain) {
+ TypedTest_ImportChain();
+}
// Value-parameterized test for function templates.
TEST_P(ImportFunctionTemplatesVisibilityChain, ImportChain) {
TypedTest_ImportChain();
@@ -173,6 +180,11 @@ INSTANTIATE_TEST_CASE_P(
::testing::Combine(
DefaultTestValuesForRunOptions,
::testing::Values(ExternC, AnonC)), );
+INSTANTIATE_TEST_CASE_P(
+ ParameterizedTests, ImportScopedEnumsVisibilityChain,
+ ::testing::Combine(
+ DefaultTestValuesForRunOptions,
+ ::testing::Values(ExternEC, AnonEC)), );
INSTANTIATE_TEST_CASE_P(ParameterizedTests,
ImportFunctionTemplatesVisibilityChain,
::testing::Combine(DefaultTestValuesForRunOptions,
@@ -291,6 +303,7 @@ using ImportFunctionsVisibility = ImportVisibility<GetFunPattern>;
using ImportVariablesVisibility = ImportVisibility<GetVarPattern>;
using ImportClassesVisibility = ImportVisibility<GetClassPattern>;
using ImportEnumsVisibility = ImportVisibility<GetEnumPattern>;
+using ImportScopedEnumsVisibility = ImportVisibility<GetEnumPattern>;
using ImportTypedefNameVisibility = ImportVisibility<GetTypedefNamePattern>;
using ImportFunctionTemplatesVisibility = ImportVisibility<GetFunTemplPattern>;
using ImportClassTemplatesVisibility = ImportVisibility<GetClassTemplPattern>;
@@ -323,6 +336,12 @@ TEST_P(ImportEnumsVisibility, ImportAfter) {
TEST_P(ImportEnumsVisibility, ImportAfterImport) {
TypedTest_ImportAfterImportWithMerge();
}
+TEST_P(ImportScopedEnumsVisibility, ImportAfter) {
+ TypedTest_ImportAfter();
+}
+TEST_P(ImportScopedEnumsVisibility, ImportAfterImport) {
+ TypedTest_ImportAfterImport();
+}
// TypedefNameDecl.
TEST_P(ImportTypedefNameVisibility, ImportAfter) {
TypedTest_ImportAfterWithMerge();
@@ -392,6 +411,15 @@ INSTANTIATE_TEST_CASE_P(
std::make_tuple(ExternE, AnonE, ExpectUnlinkedDeclChain),
std::make_tuple(AnonE, ExternE, ExpectUnlinkedDeclChain),
std::make_tuple(AnonE, AnonE, ExpectUnlinkedDeclChain))), );
+INSTANTIATE_TEST_CASE_P(
+ ParameterizedTests, ImportScopedEnumsVisibility,
+ ::testing::Combine(
+ DefaultTestValuesForRunOptions,
+ ::testing::Values(
+ std::make_tuple(ExternEC, ExternEC, ExpectLinkedDeclChain),
+ std::make_tuple(ExternEC, AnonEC, ExpectUnlinkedDeclChain),
+ std::make_tuple(AnonEC, ExternEC, ExpectUnlinkedDeclChain),
+ std::make_tuple(AnonEC, AnonEC, ExpectUnlinkedDeclChain))), );
INSTANTIATE_TEST_CASE_P(
ParameterizedTests, ImportTypedefNameVisibility,
::testing::Combine(
More information about the cfe-commits
mailing list