diff options
-rw-r--r-- | include/clang/AST/DeclObjC.h | 11 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 33 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 1 |
4 files changed, 47 insertions, 2 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 00e51783af..f83ac4a7af 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -23,6 +23,7 @@ class Expr; class Stmt; class FunctionDecl; class AttributeList; +class RecordDecl; class ObjCIvarDecl; class ObjCMethodDecl; class ObjCProtocolDecl; @@ -276,6 +277,8 @@ class ObjCInterfaceDecl : public NamedDecl, public DeclContext { Type *TypeForDecl; friend class ASTContext; + RecordDecl *RecordForDecl; + /// Class's super class. ObjCInterfaceDecl *SuperClass; @@ -312,7 +315,7 @@ class ObjCInterfaceDecl : public NamedDecl, public DeclContext { ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id, SourceLocation CLoc, bool FD, bool isInternal) : NamedDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface), - TypeForDecl(0), SuperClass(0), + TypeForDecl(0), RecordForDecl(0), SuperClass(0), Ivars(0), NumIvars(0), InstanceMethods(0), NumInstanceMethods(0), ClassMethods(0), NumClassMethods(0), @@ -347,6 +350,10 @@ public: protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 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; ivar_iterator ivar_begin() const { return Ivars; } ivar_iterator ivar_end() const { return Ivars + ivar_size();} @@ -376,6 +383,8 @@ public: void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars, SourceLocation RBracLoc); + + void addLayoutToClass(ASTContext &Context); void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers, ObjCMethodDecl **clsMethods, unsigned numClsMembers, diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index b9226318e3..e3e4548f64 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -338,6 +338,17 @@ ObjCIvarDecl * 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 /// into ObjCInterfaceDecl's fields. /// @@ -352,6 +363,28 @@ void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars, 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 /// Variables (Ivars) relative to what declared in @implementation;s class. /// Ivars into ObjCImplementationDecl's fields. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 2890464657..253850a0df 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3075,8 +3075,10 @@ void Sema::ActOnFields(Scope* S, Consumer.HandleTagDeclDefinition(Record); } else { 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->addLayoutToClass(Context); + } else if (ObjCImplementationDecl *IMPDecl = dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) { assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl"); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index d135724770..3545eb0c0a 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -588,6 +588,7 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, /// Add implementations's ivar to the synthesize class's ivar list. if (IDecl->ImplicitInterfaceDecl()) { IDecl->addInstanceVariablesToClass(ivars, numIvars, RBrace); + IDecl->addLayoutToClass(Context); return; } // If implementation has empty ivar list, just return. |