aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorFrancois Pichet <pichet2000@gmail.com>2010-11-21 06:08:52 +0000
committerFrancois Pichet <pichet2000@gmail.com>2010-11-21 06:08:52 +0000
commit87c2e121cf0522fc266efe2922b58091cd2e0182 (patch)
tree0def875d14aa76bd01d54b4ebb9a41db1007c6a7 /lib/Sema/SemaDecl.cpp
parenta4c2475961184a4bad6f6f087eeb1038bb784cad (diff)
Major anonymous union/struct redesign.
A new AST node is introduced: def IndirectField : DDecl<Value>; IndirectFields are injected into the anonymous's parent scope and chain back to the original field. Name lookup for anonymous entities now result in an IndirectFieldDecl instead of a FieldDecl. There is no functionality change, the code generated should be the same. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119919 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp33
1 files changed, 27 insertions, 6 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 7c2a8fb105..2b970a34c4 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1748,7 +1748,8 @@ static bool CheckAnonMemberRedeclaration(Sema &SemaRef,
static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
DeclContext *Owner,
RecordDecl *AnonRecord,
- AccessSpecifier AS) {
+ AccessSpecifier AS,
+ llvm::SmallVector<NamedDecl*, 2> &Chaining) {
unsigned diagKind
= AnonRecord->isUnion() ? diag::err_anonymous_union_member_redecl
: diag::err_anonymous_struct_member_redecl;
@@ -1771,20 +1772,37 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
// definition, the members of the anonymous union are
// considered to have been defined in the scope in which the
// anonymous union is declared.
- Owner->makeDeclVisibleInContext(*F);
- S->AddDecl(*F);
- SemaRef.IdResolver.AddDecl(*F);
+ Chaining.push_back(*F);
+ assert(Chaining.size() >= 2);
+ NamedDecl **NamedChain =
+ new (SemaRef.Context)NamedDecl*[Chaining.size()];
+ for (unsigned i = 0; i < Chaining.size(); i++)
+ NamedChain[i] = Chaining[i];
+
+ IndirectFieldDecl* IndirectField =
+ IndirectFieldDecl::Create(SemaRef.Context, Owner, F->getLocation(),
+ F->getIdentifier(), F->getType(),
+ NamedChain, Chaining.size());
+
+ IndirectField->setAccess(AS);
+ IndirectField->setImplicit();
+ SemaRef.PushOnScopeChains(IndirectField, S);
// That includes picking up the appropriate access specifier.
if (AS != AS_none) (*F)->setAccess(AS);
+
+ Chaining.pop_back();
}
} else if (const RecordType *InnerRecordType
= (*F)->getType()->getAs<RecordType>()) {
RecordDecl *InnerRecord = InnerRecordType->getDecl();
+
+ Chaining.push_back(*F);
if (InnerRecord->isAnonymousStructOrUnion())
Invalid = Invalid ||
InjectAnonymousStructOrUnionMembers(SemaRef, S, Owner,
- InnerRecord, AS);
+ InnerRecord, AS, Chaining);
+ Chaining.pop_back();
}
}
@@ -1999,7 +2017,10 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// Inject the members of the anonymous struct/union into the owning
// context and into the identifier resolver chain for name lookup
// purposes.
- if (InjectAnonymousStructOrUnionMembers(*this, S, Owner, Record, AS))
+ llvm::SmallVector<NamedDecl*, 2> Chain;
+ Chain.push_back(Anon);
+
+ if (InjectAnonymousStructOrUnionMembers(*this, S, Owner, Record, AS, Chain))
Invalid = true;
// Mark this as an anonymous struct/union type. Note that we do not