[cfe-commits] r111679 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/DeclObjC.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/DeclObjC.cpp lib/CodeGen/CGObjCMac.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclObjC.cpp lib/Serialization/ASTReaderDecl.cpp

Fariborz Jahanian fjahanian at apple.com
Fri Aug 20 14:21:08 PDT 2010


Author: fjahanian
Date: Fri Aug 20 16:21:08 2010
New Revision: 111679

URL: http://llvm.org/viewvc/llvm-project?rev=111679&view=rev
Log:
objective-c ivar refactoring patch. Iterations
over ivars for a varienty of puposes is now
consolidated into two small routines; DeepCollectObjCIvars
and ShallowCollectObjCIvars. 

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Aug 20 16:21:08 2010
@@ -1009,13 +1009,12 @@
   /// of class definition.
   const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
 
-  void CollectObjCIvars(const ObjCInterfaceDecl *OI,
-                        llvm::SmallVectorImpl<FieldDecl*> &Fields);
-
   void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
                                llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
-  void CollectNonClassIvars(const ObjCInterfaceDecl *OI,
-                               llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+  
+  void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
+                            llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+  
   unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI);
   void CollectInheritedProtocols(const Decl *CDecl,
                           llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Fri Aug 20 16:21:08 2010
@@ -464,6 +464,10 @@
   /// List of categories defined for this class.
   /// FIXME: Why is this a linked list??
   ObjCCategoryDecl *CategoryList;
+  
+  /// IvarList - List of all ivars defined by this class; including class
+  /// extensions and implementation. This list is built lazily.
+  ObjCIvarDecl *IvarList;
 
   bool ForwardDecl:1; // declared with @class.
   bool InternalInterface:1; // true - no @interface for @implementation
@@ -518,7 +522,10 @@
     return std::distance(ivar_begin(), ivar_end());
   }
   bool ivar_empty() const { return ivar_begin() == ivar_end(); }
-
+  
+  ObjCIvarDecl  *all_declared_ivar_begin();
+  void setIvarList(ObjCIvarDecl *ivar) { IvarList = ivar; }
+  
   /// setProtocolList - Set the list of protocols that this interface
   /// implements.
   void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
@@ -640,7 +647,7 @@
                QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
                bool synthesized)
     : FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
-      DeclAccess(ac),  Synthesized(synthesized) {}
+      NextIvar(0), DeclAccess(ac),  Synthesized(synthesized) {}
 
 public:
   static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
@@ -654,6 +661,9 @@
   /// interface the ivar is conceptually a part of in the case of synthesized
   /// ivars.
   const ObjCInterfaceDecl *getContainingInterface() const;
+  
+  ObjCIvarDecl *getNextIvar() { return NextIvar; }
+  void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
 
   void setAccessControl(AccessControl ac) { DeclAccess = ac; }
 
@@ -671,6 +681,10 @@
   static bool classof(const ObjCIvarDecl *D) { return true; }
   static bool classofKind(Kind K) { return K == ObjCIvar; }
 private:
+  /// NextIvar - Next Ivar in the list of ivars declared in class; class's 
+  /// extensions and class's implementation
+  ObjCIvarDecl *NextIvar;
+  
   // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
   unsigned DeclAccess : 3;
   unsigned Synthesized : 1;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Aug 20 16:21:08 2010
@@ -1754,7 +1754,7 @@
 
   /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
   /// initialization.
-  void CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
+  void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
                                   llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
   //===--------------------------------------------------------------------===//
   // Statement Parsing Callbacks: SemaStmt.cpp.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Aug 20 16:21:08 2010
@@ -829,60 +829,37 @@
   return ABIAlign;
 }
 
-static void CollectLocalObjCIvars(ASTContext *Ctx,
-                                  const ObjCInterfaceDecl *OI,
-                                  llvm::SmallVectorImpl<FieldDecl*> &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));
-  }
-}
-
-void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI,
-                             llvm::SmallVectorImpl<FieldDecl*> &Fields) {
-  if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
-    CollectObjCIvars(SuperClass, Fields);
-  CollectLocalObjCIvars(this, OI, Fields);
-}
-
 /// ShallowCollectObjCIvars -
 /// Collect all ivars, including those synthesized, in the current class.
 ///
 void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
                                  llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
-  for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
-         E = OI->ivar_end(); I != E; ++I) {
-     Ivars.push_back(*I);
-  }
-
-  CollectNonClassIvars(OI, Ivars);
+  // FIXME. This need be removed but there are two many places which
+  // assume const-ness of ObjCInterfaceDecl
+  ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
+  for (ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv; 
+        Iv= Iv->getNextIvar())
+    Ivars.push_back(Iv);
 }
 
-/// CollectNonClassIvars -
-/// This routine collects all other ivars which are not declared in the class.
-/// This includes synthesized ivars (via @synthesize) and those in
-//  class's @implementation.
+/// DeepCollectObjCIvars -
+/// This routine first collects all declared, but not synthesized, ivars in
+/// super class and then collects all ivars, including those synthesized for
+/// current class. This routine is used for implementation of current class
+/// when all ivars, declared and synthesized are known.
 ///
-void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI,
+void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
+                                      bool leafClass,
                                 llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
-  // Find ivars declared in class extension.
-  for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
-       CDecl = CDecl->getNextClassExtension()) {
-    for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
-         E = CDecl->ivar_end(); I != E; ++I) {
-      Ivars.push_back(*I);
-    }
-  }
-
-  // Also add any ivar defined in this class's implementation.  This
-  // includes synthesized ivars.
-  if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) {
-    for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
-         E = ImplDecl->ivar_end(); I != E; ++I)
+  if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
+    DeepCollectObjCIvars(SuperClass, false, Ivars);
+  if (!leafClass) {
+    for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
+         E = OI->ivar_end(); I != E; ++I)
       Ivars.push_back(*I);
   }
+  else
+    ShallowCollectObjCIvars(OI, Ivars);
 }
 
 /// CollectInheritedProtocols - Collect all protocols in current class and
@@ -3853,15 +3830,14 @@
     const IdentifierInfo *II = OI->getIdentifier();
     S += II->getName();
     S += '=';
-    llvm::SmallVector<FieldDecl*, 32> RecFields;
-    CollectObjCIvars(OI, RecFields);
-    for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
-      if (RecFields[i]->isBitField())
-        getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,
-                                   RecFields[i]);
+    llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
+    DeepCollectObjCIvars(OI, true, Ivars);
+    for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
+      FieldDecl *Field = cast<FieldDecl>(Ivars[i]);
+      if (Field->isBitField())
+        getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field);
       else
-        getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,
-                                   FD);
+        getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD);
     }
     S += '}';
     return;

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Fri Aug 20 16:21:08 2010
@@ -442,7 +442,8 @@
                   SourceLocation CLoc, bool FD, bool isInternal)
   : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
     TypeForDecl(0), SuperClass(0),
-    CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
+    CategoryList(0), IvarList(0), 
+    ForwardDecl(FD), InternalInterface(isInternal),
     ClassLoc(CLoc) {
 }
 
@@ -455,6 +456,49 @@
   getASTContext().setObjCImplementation(this, ImplD);
 }
 
+/// all_declared_ivar_begin - return first ivar declared in this class,
+/// its extensions and its implementation. Lazily build the list on first
+/// access.
+ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
+  if (IvarList)
+    return IvarList;
+  
+  ObjCIvarDecl *curIvar = 0;
+  if (!ivar_empty()) {
+    ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
+    IvarList = (*I); ++I;
+    for (curIvar = IvarList; I != E; curIvar = *I, ++I)
+      curIvar->setNextIvar(*I);
+  }
+  
+  for (const ObjCCategoryDecl *CDecl = getFirstClassExtension(); CDecl;
+       CDecl = CDecl->getNextClassExtension()) {
+    if (!CDecl->ivar_empty()) {
+      ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
+                                          E = CDecl->ivar_end();
+      if (!IvarList) {
+        IvarList = (*I); ++I;
+        curIvar = IvarList;
+      }
+      for ( ;I != E; curIvar = *I, ++I)
+        curIvar->setNextIvar(*I);
+    }
+  }
+  
+  if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
+    if (!ImplDecl->ivar_empty()) {
+      ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
+                                            E = ImplDecl->ivar_end();
+      if (!IvarList) {
+        IvarList = (*I); ++I;
+        curIvar = IvarList;
+      }
+      for ( ;I != E; curIvar = *I, ++I)
+        curIvar->setNextIvar(*I);
+    }
+  }
+  return IvarList;
+}
 
 /// FindCategoryDeclaration - Finds category declaration in the list of
 /// categories for this class and returns it. Name of the category is passed
@@ -556,6 +600,16 @@
     assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
             isa<ObjCCategoryDecl>(DC)) &&
            "Invalid ivar decl context!");
+    // Once a new ivar is created in any of class/class-extension/implementation
+    // decl contexts, the previously built IvarList must be rebuilt.
+    ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
+    if (!ID) {
+      if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
+        ID = IM->getClassInterface();
+      else
+        ID = (cast<ObjCCategoryDecl>(DC))->getClassInterface();
+    }
+    ID->setIvarList(0);
   }
 
   return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW, synthesized);

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Aug 20 16:21:08 2010
@@ -3871,13 +3871,11 @@
   if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
     return llvm::Constant::getNullValue(PtrTy);
 
-  llvm::SmallVector<FieldDecl*, 32> RecFields;
+  llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
   const ObjCInterfaceDecl *OI = OMD->getClassInterface();
-  CGM.getContext().CollectObjCIvars(OI, RecFields);
+  CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
 
-  // Add this implementations synthesized ivars.
-  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
-  CGM.getContext().CollectNonClassIvars(OI, Ivars);
+  llvm::SmallVector<FieldDecl*, 32> RecFields;
   for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
     RecFields.push_back(cast<FieldDecl>(Ivars[k]));
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Aug 20 16:21:08 2010
@@ -6921,7 +6921,7 @@
 void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
   if (!getLangOptions().CPlusPlus)
     return;
-  if (const ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
+  if (ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
     llvm::SmallVector<ObjCIvarDecl*, 8> ivars;
     CollectIvarsToConstructOrDestruct(OID, ivars);
     if (ivars.empty())

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri Aug 20 16:21:08 2010
@@ -1395,6 +1395,7 @@
         DefaultSynthesizeProperties(S, IC, IDecl);
       ImplMethodsVsClassMethods(S, IC, IDecl);
       AtomicPropertySetterGetterRules(IC, IDecl);
+  
       if (LangOpts.ObjCNonFragileABI2)
         while (IDecl->getSuperClass()) {
           DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
@@ -1651,11 +1652,11 @@
   }
 
   // Collect the instance variables
-  llvm::SmallVector<FieldDecl*, 32> RecFields;
-  Context.CollectObjCIvars(Class, RecFields);
+  llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
+  Context.DeepCollectObjCIvars(Class, true, Ivars);
   // For each ivar, create a fresh ObjCAtDefsFieldDecl.
-  for (unsigned i = 0; i < RecFields.size(); i++) {
-    FieldDecl* ID = RecFields[i];
+  for (unsigned i = 0; i < Ivars.size(); i++) {
+    FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
     RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>());
     Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record, ID->getLocation(),
                                            ID->getIdentifier(), ID->getType(),
@@ -1770,38 +1771,13 @@
 
 /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
 /// initialization.
-void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
+void Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
                                 llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
-  for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
-       E = OI->ivar_end(); I != E; ++I) {
-    ObjCIvarDecl *Iv = (*I);
+  for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv; 
+       Iv= Iv->getNextIvar()) {
     QualType QT = Context.getBaseElementType(Iv->getType());
     if (QT->isRecordType())
-      Ivars.push_back(*I);
-  }
-  
-  // Find ivars to construct/destruct in class extension.
-  for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
-      CDecl = CDecl->getNextClassExtension()) {
-    for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
-         E = CDecl->ivar_end(); I != E; ++I) {
-      ObjCIvarDecl *Iv = (*I);
-      QualType QT = Context.getBaseElementType(Iv->getType());
-      if (QT->isRecordType())
-        Ivars.push_back(*I);
-    }
-  }
-  
-  // Also add any ivar defined in this class's implementation.  This
-  // includes synthesized ivars.
-  if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) {
-    for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
-         E = ImplDecl->ivar_end(); I != E; ++I) {
-      ObjCIvarDecl *Iv = (*I);
-      QualType QT = Context.getBaseElementType(Iv->getType());
-      if (QT->isRecordType())
-        Ivars.push_back(*I);
-    }
+      Ivars.push_back(Iv);
   }
 }
 

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Aug 20 16:21:08 2010
@@ -392,6 +392,8 @@
     IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
   ID->setCategoryList(
                cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
+  // We will rebuild this list lazily.
+  ID->setIvarList(0);
   ID->setForwardDecl(Record[Idx++]);
   ID->setImplicitInterfaceDecl(Record[Idx++]);
   ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -402,6 +404,8 @@
 void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
   VisitFieldDecl(IVD);
   IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
+  // This field will be built lazily.
+  IVD->setNextIvar(0);
   bool synth = Record[Idx++];
   IVD->setSynthesize(synth);
 }





More information about the cfe-commits mailing list