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 | 87c2e121cf0522fc266efe2922b58091cd2e0182 (patch) | |
tree | 0def875d14aa76bd01d54b4ebb9a41db1007c6a7 /lib/AST | |
parent | a4c2475961184a4bad6f6f087eeb1038bb784cad (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/AST')
-rw-r--r-- | lib/AST/ASTImporter.cpp | 37 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 8 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 5 | ||||
-rw-r--r-- | lib/AST/ExprClassification.cpp | 1 |
4 files changed, 48 insertions, 3 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 7b16809a1f..980e93c04d 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -98,6 +98,7 @@ namespace { Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); Decl *VisitCXXConversionDecl(CXXConversionDecl *D); Decl *VisitFieldDecl(FieldDecl *D); + Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D); Decl *VisitObjCIvarDecl(ObjCIvarDecl *D); Decl *VisitVarDecl(VarDecl *D); Decl *VisitImplicitParamDecl(ImplicitParamDecl *D); @@ -2020,6 +2021,42 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { return ToField; } +Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { + // Import the major distinguishing characteristics of a variable. + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) + return 0; + + // Import the type. + QualType T = Importer.Import(D->getType()); + if (T.isNull()) + return 0; + + NamedDecl **NamedChain = + new (Importer.getToContext())NamedDecl*[D->getChainingSize()]; + + unsigned i = 0; + for (IndirectFieldDecl::chain_iterator PI = D->chain_begin(), + PE = D->chain_end(); PI != PE; ++PI) { + Decl* D = Importer.Import(*PI); + if (!D) + return 0; + NamedChain[i++] = cast<NamedDecl>(D); + } + + IndirectFieldDecl *ToIndirectField = IndirectFieldDecl::Create( + Importer.getToContext(), DC, + Loc, Name.getAsIdentifierInfo(), T, + NamedChain, D->getChainingSize()); + ToIndirectField->setAccess(D->getAccess()); + ToIndirectField->setLexicalDeclContext(LexicalDC); + Importer.Imported(D, ToIndirectField); + LexicalDC->addDecl(ToIndirectField); + return ToIndirectField; +} + Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) { // Import the major distinguishing characteristics of an ivar. DeclContext *DC, *LexicalDC; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index c448116ed2..ef8f16861e 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -768,7 +768,7 @@ bool NamedDecl::isCXXInstanceMember() const { if (isa<UsingShadowDecl>(D)) D = cast<UsingShadowDecl>(D)->getTargetDecl(); - if (isa<FieldDecl>(D)) + if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) return true; if (isa<CXXMethodDecl>(D)) return cast<CXXMethodDecl>(D)->isInstance(); @@ -2030,6 +2030,12 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, return new (C) EnumConstantDecl(CD, L, Id, T, E, V); } +IndirectFieldDecl *IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, + QualType T, NamedDecl **CH, int CHS) { + return new (C) IndirectFieldDecl(DC, L, Id, T, CH, CHS); +} + SourceRange EnumConstantDecl::getSourceRange() const { SourceLocation End = getLocation(); if (Init) diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 5ba6623b20..7d8a92530e 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -249,6 +249,9 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCProperty: return IDNS_Ordinary; + case IndirectField: + return IDNS_Ordinary | IDNS_Member; + case ObjCCompatibleAlias: case ObjCInterface: return IDNS_Ordinary | IDNS_Type; @@ -524,8 +527,6 @@ bool DeclContext::isTransparentContext() const { return !cast<EnumDecl>(this)->isScoped(); else if (DeclKind == Decl::LinkageSpec) return true; - else if (DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord) - return cast<RecordDecl>(this)->isAnonymousStructOrUnion(); return false; } diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index ba5970038d..bf26bd1f93 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -333,6 +333,7 @@ static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D) { islvalue = NTTParm->getType()->isReferenceType(); else islvalue = isa<VarDecl>(D) || isa<FieldDecl>(D) || + isa<IndirectFieldDecl>(D) || (Ctx.getLangOptions().CPlusPlus && (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D))); |