aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
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/AST
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/AST')
-rw-r--r--lib/AST/ASTImporter.cpp37
-rw-r--r--lib/AST/Decl.cpp8
-rw-r--r--lib/AST/DeclBase.cpp5
-rw-r--r--lib/AST/ExprClassification.cpp1
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)));