aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclBase.h3
-rw-r--r--include/clang/AST/DeclObjC.h20
-rw-r--r--lib/AST/DeclBase.cpp7
-rw-r--r--lib/AST/DeclObjC.cpp13
-rw-r--r--lib/Sema/SemaDecl.cpp18
5 files changed, 55 insertions, 6 deletions
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 213515010c..d274fd381d 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -45,6 +45,7 @@ public:
Field,
CXXField,
ObjCIvar,
+ ObjCAtDefsField,
ObjCCategory,
ObjCCategoryImpl,
ObjCImplementation,
@@ -84,7 +85,7 @@ public:
// For each non-leaf class, we now define a mapping to the first/last member
// of the class, to allow efficient classof.
NamedFirst = Field , NamedLast = ParmVar,
- FieldFirst = Field , FieldLast = ObjCIvar,
+ FieldFirst = Field , FieldLast = ObjCAtDefsField,
ScopedFirst = Namespace , ScopedLast = ParmVar,
TypeFirst = Typedef , TypeLast = CXXClass,
TagFirst = Enum , TagLast = CXXClass,
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 413426c6a7..f4efbc052b 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -508,6 +508,26 @@ private:
unsigned DeclAccess : 3;
};
+
+/// ObjCAtDefsFieldDecl - Represents a field declaration created by an
+/// @defs(...).
+class ObjCAtDefsFieldDecl : public FieldDecl {
+private:
+ ObjCAtDefsFieldDecl(SourceLocation L, IdentifierInfo *Id,
+ QualType T, Expr *BW)
+ : FieldDecl(ObjCAtDefsField, L, Id, T, BW) {}
+
+public:
+ static ObjCAtDefsFieldDecl *Create(ASTContext &C, SourceLocation L,
+ IdentifierInfo *Id, QualType T,
+ Expr *BW);
+
+ virtual void Destroy(ASTContext& C);
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; }
+ static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
+};
/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
/// declare a pure abstract type (i.e no instance variables are permitted).
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index f48b7346e2..db179fec3e 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -41,6 +41,7 @@ static unsigned nProtocolDecls = 0;
static unsigned nForwardProtocolDecls = 0;
static unsigned nCategoryDecls = 0;
static unsigned nIvarDecls = 0;
+static unsigned nAtDefsFieldDecls = 0;
static unsigned nObjCImplementationDecls = 0;
static unsigned nObjCCategoryImpl = 0;
static unsigned nObjCCompatibleAlias = 0;
@@ -91,7 +92,7 @@ void Decl::PrintStats() {
int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+nCXXFieldDecls+nCXXSUC+
nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
- nNamespaces));
+ nAtDefsFieldDecls+nNamespaces));
fprintf(stderr, " %d namespace decls, %d each (%d bytes)\n",
nNamespaces, (int)sizeof(NamespaceDecl),
int(nNamespaces*sizeof(NamespaceDecl)));
@@ -106,6 +107,9 @@ void Decl::PrintStats() {
fprintf(stderr, " %d field decls, %d each (%d bytes)\n",
nFieldDecls, (int)sizeof(FieldDecl),
int(nFieldDecls*sizeof(FieldDecl)));
+ fprintf(stderr, " %d @defs generated field decls, %d each (%d bytes)\n",
+ nAtDefsFieldDecls, (int)sizeof(ObjCAtDefsFieldDecl),
+ int(nAtDefsFieldDecls*sizeof(ObjCAtDefsFieldDecl)));
fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
nSUC, (int)sizeof(RecordDecl),
int(nSUC*sizeof(RecordDecl)));
@@ -209,6 +213,7 @@ void Decl::addDeclKind(Kind k) {
case ObjCForwardProtocol: nForwardProtocolDecls++; break;
case ObjCCategory: nCategoryDecls++; break;
case ObjCIvar: nIvarDecls++; break;
+ case ObjCAtDefsField: nAtDefsFieldDecls++; break;
case ObjCImplementation: nObjCImplementationDecls++; break;
case ObjCCategoryImpl: nObjCCategoryImpl++; break;
case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index a793ac608d..bd8b874735 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -94,6 +94,19 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
}
+
+ObjCAtDefsFieldDecl
+*ObjCAtDefsFieldDecl::Create(ASTContext &C, SourceLocation L,
+ IdentifierInfo *Id, QualType T, Expr *BW) {
+ void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
+ return new (Mem) ObjCAtDefsFieldDecl(L, Id, T, BW);
+}
+
+void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
+ this->~ObjCAtDefsFieldDecl();
+ C.getAllocator().Deallocate((void *)this);
+}
+
ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
SourceLocation L,
IdentifierInfo *Id) {
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 5a1ad50cd2..b3e278c565 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1794,11 +1794,21 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
/// Collect the instance variables declared in an Objective-C object. Used in
/// the creation of structures from objects using the @defs directive.
-static void CollectIvars(ObjCInterfaceDecl *Class,
+static void CollectIvars(ObjCInterfaceDecl *Class, ASTContext& Ctx,
llvm::SmallVectorImpl<Sema::DeclTy*> &ivars) {
if (Class->getSuperClass())
- CollectIvars(Class->getSuperClass(), ivars);
- ivars.append(Class->ivar_begin(), Class->ivar_end());
+ CollectIvars(Class->getSuperClass(), Ctx, ivars);
+
+ // For each ivar, create a fresh ObjCAtDefsFieldDecl.
+ for (ObjCInterfaceDecl::ivar_iterator I=Class->ivar_begin(), E=Class->ivar_end();
+ I!=E; ++I) {
+
+ ObjCIvarDecl* ID = *I;
+ ivars.push_back(ObjCAtDefsFieldDecl::Create(Ctx, ID->getLocation(),
+ ID->getIdentifier(),
+ ID->getType(),
+ ID->getBitWidth()));
+ }
}
/// Called whenever @defs(ClassName) is encountered in the source. Inserts the
@@ -1813,7 +1823,7 @@ void Sema::ActOnDefs(Scope *S, SourceLocation DeclStart,
return;
}
// Collect the instance variables
- CollectIvars(Class, Decls);
+ CollectIvars(Class, Context, Decls);
}
QualType Sema::TryFixInvalidVariablyModifiedType(QualType T) {