balazske created this revision.
Herald added subscribers: cfe-commits, teemperor, gamesh411, Szelethus, dkrupp.
Herald added a reviewer: martong.
Herald added a reviewer: a.sidorin.
Herald added a reviewer: shafik.
Herald added a project: clang.
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.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D74554
Files:
clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterTest.cpp
clang/unittests/AST/ASTImporterVisibilityTest.cpp
Index: clang/unittests/AST/ASTImporterVisibilityTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterVisibilityTest.cpp
+++ clang/unittests/AST/ASTImporterVisibilityTest.cpp
@@ -69,6 +69,8 @@
// 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 @@
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(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 @@
::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 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, 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 @@
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(
Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4864,6 +4864,33 @@
EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
}
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportOfEnumDefinitionAfterFwdDeclaration) {
+ Decl *ToTU = getToTuDecl(
+ R"(
+ enum class E;
+ )",
+ Lang_CXX11);
+ Decl *FromTU = getTuDecl(
+ R"(
+ enum class E {};
+ )",
+ Lang_CXX11);
+ auto *ToFwdE = FirstDeclMatcher<EnumDecl>().match(
+ ToTU, enumDecl(hasName("E"), unless(isImplicit())));
+ auto *FromDefE = FirstDeclMatcher<EnumDecl>().match(
+ FromTU,
+ enumDecl(hasName("E"), isDefinition(), unless(isImplicit())));
+ ASSERT_FALSE(ToFwdE->isThisDeclarationADefinition());
+ ASSERT_TRUE(FromDefE->isThisDeclarationADefinition());
+
+ auto *ToDefE = Import(FromDefE, Lang_CXX11);
+
+ EXPECT_TRUE(ToDefE);
+ EXPECT_TRUE(ToDefE->isThisDeclarationADefinition());
+ EXPECT_EQ(ToFwdE->getCanonicalDecl(), ToDefE->getCanonicalDecl());
+}
+
struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {};
TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) {
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -2578,6 +2578,7 @@
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 @@
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 @@
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;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits