]> granicus.if.org Git - clang/commitdiff
This patch will build the Records lazily per Steve's comments.
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 17 Dec 2008 21:40:49 +0000 (21:40 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 17 Dec 2008 21:40:49 +0000 (21:40 +0000)
Note that one test duplicate-ivar-check.m will fail because I
need to re-implement duplicate ivar checking.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61154 91177308-0d34-0410-b5e6-96231b3b80d8

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

index cd503130aca0bc51ad46c386570c956499deffad..2bd274cbde212af43f1f59a62b7cde3c0ff9db46 100644 (file)
@@ -72,6 +72,9 @@ class ASTContext {
   llvm::DenseMap<const ObjCInterfaceDecl*, 
                  const ASTRecordLayout*> ASTObjCInterfaces;
   
+  llvm::DenseMap<const ObjCInterfaceDecl*,
+                 const RecordDecl*> ASTRecordForInterface;
+  
   /// BuiltinVaListType - built-in va list type.
   /// This is initially null and set by Sema::LazilyCreateBuiltin when
   /// a builtin that takes a valist is encountered.
@@ -387,6 +390,7 @@ public:
   const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D);
   
   const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D);
+  const RecordDecl *addRecordToClass(const ObjCInterfaceDecl *D);
   //===--------------------------------------------------------------------===//
   //                            Type Operators
   //===--------------------------------------------------------------------===//
index 1ccc8a5570af5099dce9cd61fcc1bc20372e7dde..007c63d688ce7a66b35e4423ab3fc13be13d9f5b 100644 (file)
@@ -277,10 +277,6 @@ class ObjCInterfaceDecl : public NamedDecl, public DeclContext {
   Type *TypeForDecl;
   friend class ASTContext;
   
-  // FIXME: We should be able to get away with this slot by saving the
-  // record decl. build lazily in a map.
-  RecordDecl *RecordForDecl;
-  
   /// Class's super class.
   ObjCInterfaceDecl *SuperClass;
   
@@ -317,7 +313,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), RecordForDecl(0), SuperClass(0),
+      TypeForDecl(0), SuperClass(0),
       Ivars(0), NumIvars(0),
       InstanceMethods(0), NumInstanceMethods(0), 
       ClassMethods(0), NumClassMethods(0),
@@ -352,11 +348,6 @@ 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; }
-  RecordDecl *getRecordForDecl() { return RecordForDecl; }
-  
   typedef ObjCIvarDecl * const *ivar_iterator;
   ivar_iterator ivar_begin() const { return Ivars; }
   ivar_iterator ivar_end() const { return Ivars + ivar_size();}
@@ -388,7 +379,6 @@ public:
                                    SourceLocation RBracLoc);
   FieldDecl *lookupFieldDeclForIvar(ASTContext &Context, 
                                     const ObjCIvarDecl *ivar);
-  void addRecordToClass(ASTContext &Context);
 
   void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
                   ObjCMethodDecl **clsMethods, unsigned numClsMembers,
index 9f8db595b750361be4080ccb8e728697cb6616bd..4983d217c3e549fb64e10b71bb0385c77524608a 100644 (file)
@@ -472,6 +472,46 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
   Alignment = std::max(Alignment, FieldAlign);
 }
 
+static void CollectObjCIvars(const ObjCInterfaceDecl *OI,
+                             std::vector<FieldDecl*> &Fields) {
+  const ObjCInterfaceDecl *SuperClass = OI->getSuperClass();
+  if (SuperClass)
+    CollectObjCIvars(SuperClass, Fields);
+  for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
+       E = OI->ivar_end(); I != E; ++I) {
+    ObjCIvarDecl *IVDecl = (*I);
+    if (!IVDecl->isInvalidDecl())
+      Fields.push_back(cast<FieldDecl>(IVDecl));
+  }
+}
+
+/// addRecordToClass - produces record info. for the class for its
+/// ivars and all those inherited.
+///
+const RecordDecl *ASTContext::addRecordToClass(const ObjCInterfaceDecl *D)
+{
+  const RecordDecl *&RD = ASTRecordForInterface[D];
+  if (RD)
+    return RD;
+  std::vector<FieldDecl*> RecFields;
+  CollectObjCIvars(D, RecFields);
+  RecordDecl *NewRD = RecordDecl::Create(*this, TagDecl::TK_struct, 0,
+                                         D->getLocation(),
+                                         D->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(*this, NewRD, 
+                                          RecFields[i]->getLocation(), 
+                                          RecFields[i]->getIdentifier(),
+                                          RecFields[i]->getType(), 
+                                          RecFields[i]->getBitWidth(), false, 0);
+    NewRD->addDecl(*this, Field);
+  }
+  NewRD->completeDefinition(*this);
+  RD = NewRD;
+  return RD;
+}
 
 /// getASTObjcInterfaceLayout - Get or compute information about the layout of
 /// the specified Objective C, which indicates its size and ivar
index a7e878fc24f916547833235afc272b46fc19d530..ec8a1ff044b8eb388cad24eba5c7236f4f3abee6 100644 (file)
@@ -338,18 +338,6 @@ 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);
-    if (!IVDecl->isInvalidDecl())
-      Fields.push_back(cast<FieldDecl>(IVDecl));
-  }
-}
-  
 /// ObjCAddInstanceVariablesToClass - Inserts instance variables
 /// into ObjCInterfaceDecl's fields.
 ///
@@ -369,44 +357,17 @@ void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
 ///
 FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context, 
                                                      const ObjCIvarDecl *ivar) {
-  /* When a super class's ivar is referenced in the subclass method with no ivar 
-     of its own, record for the sub-class is not built yet. Build it lazily
-     here. */
-  if (!RecordForDecl)
-    addRecordToClass(Context);
+  const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
   assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
   DeclarationName Member = ivar->getDeclName();
-  DeclContext::lookup_result Lookup = RecordForDecl->lookup(Context, Member);
+  DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
+                                        ->lookup(Context, Member);
   assert((Lookup.first != Lookup.second) && "field decl not found");
   FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
   assert(MemberDecl && "field decl not found");
   return MemberDecl;
 }
 
-/// addRecordToClass - produces record info. for the class for its
-/// ivars and all those inherited.
-///
-void ObjCInterfaceDecl::addRecordToClass(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, 
-                                          RecFields[i]->getLocation(), 
-                                          RecFields[i]->getIdentifier(),
-                                          RecFields[i]->getType(), 
-                                          RecFields[i]->getBitWidth(), false, 0);
-    RD->addDecl(Context, Field);
-  }
-  RD->completeDefinition(Context);
-  RecordForDecl = RD;
-}
-
 /// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance 
 /// Variables (Ivars) relative to what declared in @implementation;s class. 
 /// Ivars into ObjCImplementationDecl's fields.
index 10b1e15ae399cfa7ef1b068d3b655c262690ea2a..e8a38a286b64afc615cebf4cc9bf27485092168f 100644 (file)
@@ -273,13 +273,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
     // We are issuing warnings elsewhere!
     ObjCInterfaceType OIT = cast<ObjCInterfaceType>(Ty);
     ObjCInterfaceDecl *ID = OIT.getDecl();
-    RecordDecl *RD = ID->getRecordForDecl();
-    if(!RD) {
-      // Sometimes, class type is being directly generated in code gen for
-      // built-in class types.
-      ID->addRecordToClass(Context);
-      RD = ID->getRecordForDecl();
-    }
+    const RecordDecl *RD = Context.addRecordToClass(ID);
     return ConvertTagDeclType(cast<TagDecl>(RD));
   }
       
index 6ef9ecd81728f4b71761e9ce8da13ffd14df1fc7..5ae266ef00367beccb67b284933db5a3c476c163 100644 (file)
@@ -3029,7 +3029,7 @@ void Sema::ActOnFields(Scope* S,
     ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(&RecFields[0]);
     if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl)) {
       ID->addInstanceVariablesToClass(ClsFields, RecFields.size(), RBrac);
-      ID->addRecordToClass(Context);
+#if 0
       // Must enforce the rule that ivars in the base classes may not be
       // duplicates.
       FieldIDs.clear();
@@ -3049,6 +3049,7 @@ void Sema::ActOnFields(Scope* S,
               }
           }
       }
+#endif
     }
     else if (ObjCImplementationDecl *IMPDecl = 
                dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
index 5887f29d4f0fba57795350fde1b94cc81997c9e4..d4cef9b0de1e2abf583ed4eef33cb70e7e513ac9 100644 (file)
@@ -599,7 +599,6 @@ 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->addRecordToClass(Context);
     return;
   }
   // If implementation has empty ivar list, just return.