From: Douglas Gregor Date: Thu, 16 Sep 2010 23:58:57 +0000 (+0000) Subject: When dealing with an anonymous enumeration declared in function X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=069ea646616e4ece684e1dec652640f644f0d40a;p=clang When dealing with an anonymous enumeration declared in function prototype scope, temporarily set the context of the enumeration declaration to the translation unit. We do the same thing for parameters, until we have an actual function declaration on which to hang them. Fixes . There is more work to do in this area, since we have existing bugs with tags being declared/defined in function parameter lists. This fix is correct, and we'll end up extending it when we deal with those existing bugs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114135 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e314c1acfe..51b5ae91d6 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5326,11 +5326,11 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous, /// TagSpec indicates what kind of tag this is. TUK indicates whether this is a /// reference/declaration/definition of a tag. Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, - SourceLocation KWLoc, CXXScopeSpec &SS, - IdentifierInfo *Name, SourceLocation NameLoc, - AttributeList *Attr, AccessSpecifier AS, - MultiTemplateParamsArg TemplateParameterLists, - bool &OwnedDecl, bool &IsDependent) { + SourceLocation KWLoc, CXXScopeSpec &SS, + IdentifierInfo *Name, SourceLocation NameLoc, + AttributeList *Attr, AccessSpecifier AS, + MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent) { // If this is not a definition, it must have a name. assert((Name != 0 || TUK == TUK_Definition) && "Nameless record must be a definition!"); @@ -5459,6 +5459,10 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, while (isa(SearchDC) || isa(SearchDC)) SearchDC = SearchDC->getParent(); } + } else if (S->isFunctionPrototypeScope()) { + // If this is an enum declaration in function prototype scope, set its + // initial context to the translation unit. + SearchDC = Context.getTranslationUnitDecl(); } if (Previous.isSingleResult() && diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp new file mode 100644 index 0000000000..34a8c854a6 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { }; +A::A (enum { e1 }) {} // expected-error{{can not be defined in a parameter}} \ +// expected-error{{out-of-line definition}} +void A::f(enum { e2 }) {} // expected-error{{can not be defined in a parameter}} \ +// expected-error{{out-of-line definition}} + +enum { e3 } A::g() { } // expected-error{{can not be defined in the result type}} \ +// expected-error{{out-of-line definition}}