]> granicus.if.org Git - clang/commitdiff
Add storage layout to ObjC classes.
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 13 Dec 2008 20:28:25 +0000 (20:28 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 13 Dec 2008 20:28:25 +0000 (20:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60993 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp

index 00e51783af44555360104f7c964e9a1678ab0ca2..f83ac4a7af5453b199605bfa3bf7ce033e6151b7 100644 (file)
@@ -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,
index b9226318e397ca0138171de1932af5e80741693c..e3e4548f644dd9023f28fdca7d2da97e74dee70a 100644 (file)
@@ -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.
index 2890464657332004c3cb4d1dff3c086b0947cc2d..253850a0df0028d7468533fe686214d89ba8a5dd 100644 (file)
@@ -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");
index d1357247709e0f9d55467723a0625d79e8f8182d..3545eb0c0a07150fffbd6b68567fae938c6979d7 100644 (file)
@@ -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.