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( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits