diff options
| author | Francois Pichet <pichet2000@gmail.com> | 2010-11-21 06:08:52 +0000 | 
|---|---|---|
| committer | Francois Pichet <pichet2000@gmail.com> | 2010-11-21 06:08:52 +0000 | 
| commit | 783dd6ece4d1cacbbe9c5790c5a0b6cf9a4b7c9c (patch) | |
| tree | 835aace2ba6a248986b02e383139a1f63bfb80fa /clang/lib/Sema/SemaDecl.cpp | |
| parent | e040a46eb354d1eb3d2102b416620e869a10883b (diff) | |
| download | bcm5719-llvm-783dd6ece4d1cacbbe9c5790c5a0b6cf9a4b7c9c.tar.gz bcm5719-llvm-783dd6ece4d1cacbbe9c5790c5a0b6cf9a4b7c9c.zip | |
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.
llvm-svn: 119919
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 33 | 
1 files changed, 27 insertions, 6 deletions
| diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 7c2a8fb105e..2b970a34c45 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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 | 

