diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -16598,6 +16598,19 @@ // Make the previous decl visible. makeMergedDefinitionVisible(SkipBody.Previous); + // For the ignored `EnumDecl` definition remove its `EnumConstantDecl` from + // global name lookup to avoid future ambiguous lookups. Doing this for ObjC/C + // to mimic early return in `Sema::ActOnTag` that avoids calling + // `PushOnScopeChains` for duplicate `TagDecl` definitions. Doing it only for + // `EnumDecl` among all `TagDecl` because enum constants have global name + // lookup while record field lookup is limited to a record. + if (!getLangOpts().CPlusPlus) { + if (const auto *ED = dyn_cast(SkipBody.New)) + for (EnumDecl::enumerator_iterator EC = ED->enumerator_begin(), + End = ED->enumerator_end(); + EC != End; ++EC) + IdResolver.RemoveDecl(*EC); + } return true; } diff --git a/clang/test/Modules/redefinition-c-tagtypes.m b/clang/test/Modules/redefinition-c-tagtypes.m --- a/clang/test/Modules/redefinition-c-tagtypes.m +++ b/clang/test/Modules/redefinition-c-tagtypes.m @@ -32,6 +32,10 @@ TRD = 55 }; +int testReferencingNSEConstant() { + return FST; +} + #define NS_ENUM(_type, _name) \ enum _name : _type _name; \ enum _name : _type @@ -42,7 +46,11 @@ MinXOther = MinX, #else MinXOther = TRD, // expected-note {{enumerator 'MinXOther' with value 55 here}} - // expected-error@redefinition-c-tagtypes.m:39 {{type 'enum NSMyEnum' has incompatible definitions}} + // expected-error@redefinition-c-tagtypes.m:43 {{type 'enum NSMyEnum' has incompatible definitions}} // expected-note@Inputs/F.framework/PrivateHeaders/NS.h:18 {{enumerator 'MinXOther' with value 11 here}} #endif }; + +int testReferencingNSMyEnumConstant() { + return MinX; +}