aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-03 00:34:39 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-03 00:34:39 +0000
commit1931b44da8da86979a8d7ceb48685686503f197b (patch)
treedba897c62d24d63d0f881f34ac6a8e045e3451da /lib/Sema/SemaDecl.cpp
parent45012a7ef5abf1042c893f3f2fa5c23cb5485ea9 (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.cpp33
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;