Add storage layout to ObjC classes.

llvm-svn: 60993
This commit is contained in:
Fariborz Jahanian 2008-12-13 20:28:25 +00:00
parent 77c76ae3de
commit 0222553d1c
4 changed files with 47 additions and 2 deletions

View File

@ -23,6 +23,7 @@ class Expr;
class Stmt; class Stmt;
class FunctionDecl; class FunctionDecl;
class AttributeList; class AttributeList;
class RecordDecl;
class ObjCIvarDecl; class ObjCIvarDecl;
class ObjCMethodDecl; class ObjCMethodDecl;
class ObjCProtocolDecl; class ObjCProtocolDecl;
@ -276,6 +277,8 @@ class ObjCInterfaceDecl : public NamedDecl, public DeclContext {
Type *TypeForDecl; Type *TypeForDecl;
friend class ASTContext; friend class ASTContext;
RecordDecl *RecordForDecl;
/// Class's super class. /// Class's super class.
ObjCInterfaceDecl *SuperClass; ObjCInterfaceDecl *SuperClass;
@ -312,7 +315,7 @@ class ObjCInterfaceDecl : public NamedDecl, public DeclContext {
ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id, ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id,
SourceLocation CLoc, bool FD, bool isInternal) SourceLocation CLoc, bool FD, bool isInternal)
: NamedDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface), : NamedDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface),
TypeForDecl(0), SuperClass(0), TypeForDecl(0), RecordForDecl(0), SuperClass(0),
Ivars(0), NumIvars(0), Ivars(0), NumIvars(0),
InstanceMethods(0), NumInstanceMethods(0), InstanceMethods(0), NumInstanceMethods(0),
ClassMethods(0), NumClassMethods(0), ClassMethods(0), NumClassMethods(0),
@ -347,6 +350,10 @@ public:
protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
void CollectObjCIvars(std::vector<FieldDecl*> &Fields);
void setRecordForDecl(RecordDecl *Decl) { RecordForDecl = Decl; }
RecordDecl *getRecordForDecl() const { return RecordForDecl; }
typedef ObjCIvarDecl * const *ivar_iterator; typedef ObjCIvarDecl * const *ivar_iterator;
ivar_iterator ivar_begin() const { return Ivars; } ivar_iterator ivar_begin() const { return Ivars; }
ivar_iterator ivar_end() const { return Ivars + ivar_size();} ivar_iterator ivar_end() const { return Ivars + ivar_size();}
@ -376,6 +383,8 @@ public:
void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars, void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars,
SourceLocation RBracLoc); SourceLocation RBracLoc);
void addLayoutToClass(ASTContext &Context);
void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers, void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
ObjCMethodDecl **clsMethods, unsigned numClsMembers, ObjCMethodDecl **clsMethods, unsigned numClsMembers,

View File

@ -338,6 +338,17 @@ ObjCIvarDecl *
return 0; return 0;
} }
void ObjCInterfaceDecl::CollectObjCIvars(std::vector<FieldDecl*> &Fields) {
ObjCInterfaceDecl *SuperClass = getSuperClass();
if (SuperClass)
SuperClass->CollectObjCIvars(Fields);
for (ObjCInterfaceDecl::ivar_iterator I = ivar_begin(),
E = ivar_end(); I != E; ++I) {
ObjCIvarDecl *IVDecl = (*I);
Fields.push_back(cast<FieldDecl>(IVDecl));
}
}
/// ObjCAddInstanceVariablesToClass - Inserts instance variables /// ObjCAddInstanceVariablesToClass - Inserts instance variables
/// into ObjCInterfaceDecl's fields. /// into ObjCInterfaceDecl's fields.
/// ///
@ -352,6 +363,28 @@ void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
setLocEnd(RBrac); setLocEnd(RBrac);
} }
/// addInstanceVariablesToClass - produces layout info. for the class for its
/// ivars and all those inherited.
///
void ObjCInterfaceDecl::addLayoutToClass(ASTContext &Context)
{
std::vector<FieldDecl*> RecFields;
CollectObjCIvars(RecFields);
RecordDecl *RD = RecordDecl::Create(Context, TagDecl::TK_struct, 0,
getLocation(),
getIdentifier());
/// FIXME! Can do collection of ivars and adding to the record while
/// doing it.
for (unsigned int i = 0; i != RecFields.size(); i++) {
FieldDecl *Field = FieldDecl::Create(Context, RD, SourceLocation(),
RecFields[i]->getIdentifier(),
RecFields[i]->getType(), 0, false, 0);
RD->addDecl(Context, Field);
}
RD->completeDefinition(Context);
setRecordForDecl(RD);
}
/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance /// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
/// Variables (Ivars) relative to what declared in @implementation;s class. /// Variables (Ivars) relative to what declared in @implementation;s class.
/// Ivars into ObjCImplementationDecl's fields. /// Ivars into ObjCImplementationDecl's fields.

View File

@ -3075,8 +3075,10 @@ void Sema::ActOnFields(Scope* S,
Consumer.HandleTagDeclDefinition(Record); Consumer.HandleTagDeclDefinition(Record);
} else { } else {
ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(&RecFields[0]); ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(&RecFields[0]);
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl)) if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl)) {
ID->addInstanceVariablesToClass(ClsFields, RecFields.size(), RBrac); ID->addInstanceVariablesToClass(ClsFields, RecFields.size(), RBrac);
ID->addLayoutToClass(Context);
}
else if (ObjCImplementationDecl *IMPDecl = else if (ObjCImplementationDecl *IMPDecl =
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) { dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl"); assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl");

View File

@ -588,6 +588,7 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
/// Add implementations's ivar to the synthesize class's ivar list. /// Add implementations's ivar to the synthesize class's ivar list.
if (IDecl->ImplicitInterfaceDecl()) { if (IDecl->ImplicitInterfaceDecl()) {
IDecl->addInstanceVariablesToClass(ivars, numIvars, RBrace); IDecl->addInstanceVariablesToClass(ivars, numIvars, RBrace);
IDecl->addLayoutToClass(Context);
return; return;
} }
// If implementation has empty ivar list, just return. // If implementation has empty ivar list, just return.