diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-02-03 00:34:39 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-02-03 00:34:39 +0000 |
commit | 1931b44da8da86979a8d7ceb48685686503f197b (patch) | |
tree | dba897c62d24d63d0f881f34ac6a8e045e3451da /lib/Sema/SemaDecl.cpp | |
parent | 45012a7ef5abf1042c893f3f2fa5c23cb5485ea9 (diff) |
Simplify the way in which we inject the names of tag definitions and
elaborated-type-specifier declarations into outer scopes while
retaining their proper lexical scope. This way is simpler and more
consistent with the way DeclContexts work, and also fixes
http://llvm.org/bugs/show_bug.cgi?id=3430
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63581 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d2140b2267..d7c5fa6860 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -839,6 +839,11 @@ Sema::DeclTy *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, } } else if ((*Mem)->isImplicit()) { // Any implicit members are fine. + } else if (isa<TagDecl>(*Mem) && (*Mem)->getDeclContext() != Record) { + // This is a type that showed up in an + // elaborated-type-specifier inside the anonymous struct or + // union, but which actually declares a type outside of the + // anonymous struct or union. It's okay. } else if (RecordDecl *MemRecord = dyn_cast<RecordDecl>(*Mem)) { if (!MemRecord->isAnonymousStructOrUnion() && MemRecord->getDeclName()) { @@ -2791,7 +2796,6 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, DeclContext *SearchDC = CurContext; DeclContext *DC = CurContext; - DeclContext *LexicalContext = CurContext; Decl *PrevDecl = 0; bool Invalid = false; @@ -2806,6 +2810,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, } DC = static_cast<DeclContext*>(SS.getScopeRep()); + SearchDC = DC; // Look-up name inside 'foo::'. PrevDecl = dyn_cast_or_null<TagDecl>( LookupQualifiedName(DC, Name, LookupTagName).getAsDecl()); @@ -2944,9 +2949,8 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, // Find the context where we'll be declaring the tag. // FIXME: We would like to maintain the current DeclContext as the // lexical context, - while (DC->isRecord()) - DC = DC->getParent(); - LexicalContext = DC; + while (SearchDC->isRecord()) + SearchDC = SearchDC->getParent(); // Find the scope where we'll be declaring the tag. while (S->isClassScope() || @@ -2972,7 +2976,7 @@ CreateNewDecl: if (Kind == TagDecl::TK_enum) { // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // enum X { A, B, C } D; D should chain to X. - New = EnumDecl::Create(Context, DC, Loc, Name, + New = EnumDecl::Create(Context, SearchDC, Loc, Name, cast_or_null<EnumDecl>(PrevDecl)); // If this is an undefined enum, warn. if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum); @@ -2983,10 +2987,10 @@ CreateNewDecl: // struct X { int A; } D; D should chain to X. if (getLangOptions().CPlusPlus) // FIXME: Look for a way to use RecordDecl for simple structs. - New = CXXRecordDecl::Create(Context, Kind, DC, Loc, Name, + New = CXXRecordDecl::Create(Context, Kind, SearchDC, Loc, Name, cast_or_null<CXXRecordDecl>(PrevDecl)); else - New = RecordDecl::Create(Context, Kind, DC, Loc, Name, + New = RecordDecl::Create(Context, Kind, SearchDC, Loc, Name, cast_or_null<RecordDecl>(PrevDecl)); } @@ -3041,7 +3045,7 @@ CreateNewDecl: // Set the lexical context. If the tag has a C++ scope specifier, the // lexical context will be different from the semantic context. - New->setLexicalDeclContext(LexicalContext); + New->setLexicalDeclContext(CurContext); if (TK == TK_Definition) New->startDefinition(); @@ -3049,18 +3053,9 @@ CreateNewDecl: // If this has an identifier, add it to the scope stack. if (Name) { S = getNonFieldDeclScope(S); - - // Add it to the decl chain. - if (LexicalContext != CurContext) { - // FIXME: PushOnScopeChains should not rely on CurContext! - DeclContext *OldContext = CurContext; - CurContext = LexicalContext; - PushOnScopeChains(New, S); - CurContext = OldContext; - } else - PushOnScopeChains(New, S); + PushOnScopeChains(New, S); } else { - LexicalContext->addDecl(New); + CurContext->addDecl(New); } return New; |