[cfe-commits] r146644 - in /cfe/trunk: include/clang/AST/DeclObjC.h include/clang/Serialization/ASTReader.h lib/AST/ASTImporter.cpp lib/AST/DeclObjC.cpp lib/AST/DeclPrinter.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaExprObjC.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp tools/libclang/IndexingContext.cpp

Douglas Gregor dgregor at apple.com
Wed Dec 14 21:27:12 PST 2011


Author: dgregor
Date: Wed Dec 14 23:27:12 2011
New Revision: 146644

URL: http://llvm.org/viewvc/llvm-project?rev=146644&view=rev
Log:
Move the definition-specific data of ObjCInterfaceDecl into a
separately-allocated DefinitionData structure, which we manage the
same way as CXXRecordDecl::DefinitionData. This prepares the way for
making ObjCInterfaceDecls redeclarable, to more accurately model
forward declarations of Objective-C classes and eliminate the mutation
of ObjCInterfaceDecl that causes us serious trouble in the AST reader.

Note that ObjCInterfaceDecl's accessors are fairly robust against
being applied to forward declarations, because Clang (and Sema in
particular) doesn't perform RequireCompleteType/hasDefinition() checks
everywhere it has to. Each of these overly-robust cases is marked with
a FIXME, which we can tackle over time.



Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/tools/libclang/IndexingContext.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Wed Dec 14 23:27:12 2011
@@ -545,45 +545,63 @@
   /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
   mutable const Type *TypeForDecl;
   friend class ASTContext;
+  
+  struct DefinitionData {
+    /// Class's super class.
+    ObjCInterfaceDecl *SuperClass;
+
+    /// Protocols referenced in the @interface  declaration
+    ObjCProtocolList ReferencedProtocols;
+
+    /// Protocols reference in both the @interface and class extensions.
+    ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
+
+    /// \brief List of categories and class extensions defined for this class.
+    ///
+    /// Categories are stored as a linked list in the AST, since the categories
+    /// and class extensions come long after the initial interface declaration,
+    /// and we avoid dynamically-resized arrays in the AST wherever possible.
+    ObjCCategoryDecl *CategoryList;
+
+    /// IvarList - List of all ivars defined by this class; including class
+    /// extensions and implementation. This list is built lazily.
+    ObjCIvarDecl *IvarList;
+
+    /// \brief Indicates that the contents of this Objective-C class will be
+    /// completed by the external AST source when required.
+    mutable bool ExternallyCompleted : 1;
 
-  /// Class's super class.
-  ObjCInterfaceDecl *SuperClass;
+    SourceLocation SuperClassLoc; // location of the super class identifier.
+  };
 
-  /// Protocols referenced in the @interface  declaration
-  ObjCProtocolList ReferencedProtocols;
+  ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
+                    SourceLocation CLoc, bool FD, bool isInternal);
 
-  /// Protocols reference in both the @interface and class extensions.
-  ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
+  void LoadExternalDefinition() const;
 
-  /// \brief List of categories and class extensions defined for this class.
-  ///
-  /// Categories are stored as a linked list in the AST, since the categories
-  /// and class extensions come long after the initial interface declaration,
-  /// and we avoid dynamically-resized arrays in the AST wherever possible.
-  ObjCCategoryDecl *CategoryList;
-
-  /// IvarList - List of all ivars defined by this class; including class
-  /// extensions and implementation. This list is built lazily.
-  ObjCIvarDecl *IvarList;
+  /// \brief Contains a pointer to the data associated with this class,
+  /// which will be NULL if this class has not yet been defined.
+  DefinitionData *Definition;
+
+  /// \brief The location of the last location in this declaration, e.g.,
+  /// the '>', '}', or identifier.
+  /// FIXME: This seems like the wrong location to care about.
+  SourceLocation EndLoc; 
 
   /// \brief True if it was initially declared with @class.
   /// Differs with \see ForwardDecl in that \see ForwardDecl will change to
   /// false when we see the @interface, but InitiallyForwardDecl will remain
   /// true.
   bool InitiallyForwardDecl : 1;
-  bool ForwardDecl:1; // declared with @class.
-
-  /// \brief Indicates that the contents of this Objective-C class will be
-  /// completed by the external AST source when required.
-  mutable bool ExternallyCompleted : 1;
 
-  SourceLocation SuperClassLoc; // location of the super class identifier.
-  SourceLocation EndLoc; // marks the '>', '}', or identifier.
-
-  ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                    SourceLocation CLoc, bool FD, bool isInternal);
+  DefinitionData &data() const {
+    assert(Definition != 0 && "Declaration is not a definition!");
+    return *Definition;
+  }
 
-  void LoadExternalDefinition() const;
+  /// \brief Allocate the definition data for this class.
+  void allocateDefinitionData();
+  
 public:
   static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
                                    SourceLocation atLoc,
@@ -604,10 +622,10 @@
   void setExternallyCompleted();
 
   const ObjCProtocolList &getReferencedProtocols() const {
-    if (ExternallyCompleted)
+    if (data().ExternallyCompleted)
       LoadExternalDefinition();
 
-    return ReferencedProtocols;
+    return data().ReferencedProtocols;
   }
 
   ObjCImplementationDecl *getImplementation() const;
@@ -626,55 +644,93 @@
   typedef ObjCProtocolList::iterator protocol_iterator;
 
   protocol_iterator protocol_begin() const {
-    if (ExternallyCompleted)
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return protocol_iterator();
+    
+    if (data().ExternallyCompleted)
       LoadExternalDefinition();
 
-    return ReferencedProtocols.begin();
+    return data().ReferencedProtocols.begin();
   }
   protocol_iterator protocol_end() const {
-    if (ExternallyCompleted)
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return protocol_iterator();
+
+    if (data().ExternallyCompleted)
       LoadExternalDefinition();
 
-    return ReferencedProtocols.end();
+    return data().ReferencedProtocols.end();
   }
 
   typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
 
   protocol_loc_iterator protocol_loc_begin() const {
-    if (ExternallyCompleted)
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return protocol_loc_iterator();
+
+    if (data().ExternallyCompleted)
       LoadExternalDefinition();
 
-    return ReferencedProtocols.loc_begin();
+    return data().ReferencedProtocols.loc_begin();
   }
 
   protocol_loc_iterator protocol_loc_end() const {
-    if (ExternallyCompleted)
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return protocol_loc_iterator();
+
+    if (data().ExternallyCompleted)
       LoadExternalDefinition();
 
-    return ReferencedProtocols.loc_end();
+    return data().ReferencedProtocols.loc_end();
   }
 
   typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
 
   all_protocol_iterator all_referenced_protocol_begin() const {
-    if (ExternallyCompleted)
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return all_protocol_iterator();
+
+    if (data().ExternallyCompleted)
       LoadExternalDefinition();
 
-    return AllReferencedProtocols.empty() ? protocol_begin()
-      : AllReferencedProtocols.begin();
+    return data().AllReferencedProtocols.empty()  
+             ? protocol_begin()
+             : data().AllReferencedProtocols.begin();
   }
   all_protocol_iterator all_referenced_protocol_end() const {
-    if (ExternallyCompleted)
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return all_protocol_iterator();
+    
+    if (data().ExternallyCompleted)
       LoadExternalDefinition();
 
-    return AllReferencedProtocols.empty() ? protocol_end()
-      : AllReferencedProtocols.end();
+    return data().AllReferencedProtocols.empty() 
+             ? protocol_end()
+             : data().AllReferencedProtocols.end();
   }
 
   typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
 
-  ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); }
-  ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); }
+  ivar_iterator ivar_begin() const { 
+    if (const ObjCInterfaceDecl *Def = getDefinition())
+      return ivar_iterator(Def->decls_begin()); 
+    
+    // FIXME: Should make sure no callers ever do this.
+    return ivar_iterator();
+  }
+  ivar_iterator ivar_end() const { 
+    if (const ObjCInterfaceDecl *Def = getDefinition())
+      return ivar_iterator(Def->decls_end()); 
+
+    // FIXME: Should make sure no callers ever do this.
+    return ivar_iterator();
+  }
 
   unsigned ivar_size() const {
     return std::distance(ivar_begin(), ivar_end());
@@ -688,13 +744,13 @@
     // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
     return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
   }
-  void setIvarList(ObjCIvarDecl *ivar) { IvarList = ivar; }
+  void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
 
   /// setProtocolList - Set the list of protocols that this interface
   /// implements.
   void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
                        const SourceLocation *Locs, ASTContext &C) {
-    ReferencedProtocols.set(List, Num, Locs, C);
+    data().ReferencedProtocols.set(List, Num, Locs, C);
   }
 
   /// mergeClassExtensionProtocolList - Merge class extension's protocol list
@@ -706,30 +762,63 @@
   /// \brief True if it was initially declared with @class.
   /// Differs with \see isForwardDecl in that \see isForwardDecl will change to
   /// false when we see the @interface, but this will remain true.
-  bool isInitiallyForwardDecl() const { return InitiallyForwardDecl; }
-
-  bool isForwardDecl() const { return ForwardDecl; }
+  bool isInitiallyForwardDecl() const { 
+    return InitiallyForwardDecl; 
+  }
 
-  void completedForwardDecl();
+  /// \brief Determine whether this declaration is a forward declaration of
+  /// the class.
+  bool isForwardDecl() const { return Definition == 0; }
 
+  /// \brief Determine whether this class has been defined.
+  bool hasDefinition() const { return Definition != 0; }
+  
+  /// \brief Retrieve the definition of this class, or NULL if this class 
+  /// has been forward-declared (with @class) but not yet defined (with 
+  /// @interface).
+  ObjCInterfaceDecl *getDefinition() {
+    return hasDefinition()? this : 0;
+  }
+
+  /// \brief Retrieve the definition of this class, or NULL if this class 
+  /// has been forward-declared (with @class) but not yet defined (with 
+  /// @interface).
+  const ObjCInterfaceDecl *getDefinition() const {
+    return hasDefinition()? this : 0;
+  }
+
+  /// \brief Starts the definition of this Objective-C class, taking it from
+  /// a forward declaration (@class) to a definition (@interface).
+  void startDefinition();
+  
   ObjCInterfaceDecl *getSuperClass() const {
-    if (ExternallyCompleted)
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return 0;
+    
+    if (data().ExternallyCompleted)
       LoadExternalDefinition();
 
-    return SuperClass;
+    return data().SuperClass;
   }
 
-  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
+  void setSuperClass(ObjCInterfaceDecl * superCls) { 
+    data().SuperClass = superCls; 
+  }
 
   ObjCCategoryDecl* getCategoryList() const {
-    if (ExternallyCompleted)
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return 0;
+    
+    if (data().ExternallyCompleted)
       LoadExternalDefinition();
 
-    return CategoryList;
+    return data().CategoryList;
   }
 
   void setCategoryList(ObjCCategoryDecl *category) {
-    CategoryList = category;
+    data().CategoryList = category;
   }
 
   ObjCCategoryDecl* getFirstClassExtension() const;
@@ -744,6 +833,7 @@
     while (I != NULL) {
       if (declaresSameEntity(this, I))
         return true;
+      
       I = I->getSuperClass();
     }
     return false;
@@ -787,8 +877,8 @@
   SourceLocation getLocEnd() const { return EndLoc; }
   void setLocEnd(SourceLocation LE) { EndLoc = LE; }
 
-  void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; }
-  SourceLocation getSuperClassLoc() const { return SuperClassLoc; }
+  void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; }
+  SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; }
 
   /// isImplicitInterfaceDecl - check that this is an implicitly declared
   /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Wed Dec 14 23:27:12 2011
@@ -329,14 +329,16 @@
   /// haven't been loaded yet.
   DeclContextVisibleUpdatesPending PendingVisibleUpdates;
 
-  typedef SmallVector<CXXRecordDecl *, 4> ForwardRefs;
-  typedef llvm::DenseMap<const CXXRecordDecl *, ForwardRefs>
+  typedef SmallVector<Decl *, 4> ForwardRefs;
+  typedef llvm::DenseMap<const Decl *, ForwardRefs>
       PendingForwardRefsMap;
+  
   /// \brief Forward references that have a definition but the definition decl
   /// is still initializing. When the definition gets read it will update
   /// the DefinitionData pointer of all pending references.
   PendingForwardRefsMap PendingForwardRefs;
 
+
   typedef llvm::DenseMap<serialization::DeclID, serialization::DeclID>
       FirstLatestDeclIDMap;
   /// \brief Map of first declarations from a chained PCH that point to the

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Dec 14 23:27:12 2011
@@ -3178,7 +3178,7 @@
   }
   
   ObjCInterfaceDecl *ToIface = MergeWithIface;
-  if (!ToIface || ToIface->isForwardDecl()) {
+  if (!ToIface || !ToIface->hasDefinition()) {
     if (!ToIface) {
       ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
                                           Importer.Import(D->getAtStartLoc()),
@@ -3187,88 +3187,98 @@
                                           D->isImplicitInterfaceDecl());
       ToIface->setLexicalDeclContext(LexicalDC);
       LexicalDC->addDeclInternal(ToIface);
-      if (D->isInitiallyForwardDecl() && !D->isForwardDecl())
-        ToIface->completedForwardDecl();
     }
     Importer.Imported(D, ToIface);
 
-    if (D->getSuperClass()) {
-      ObjCInterfaceDecl *Super
-        = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getSuperClass()));
-      if (!Super)
-        return 0;
+    if (D->hasDefinition()) {
+      if (!ToIface->hasDefinition())
+        ToIface->startDefinition();
       
-      ToIface->setSuperClass(Super);
-      ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
-    }
-    
-    // Import protocols
-    SmallVector<ObjCProtocolDecl *, 4> Protocols;
-    SmallVector<SourceLocation, 4> ProtocolLocs;
-    ObjCInterfaceDecl::protocol_loc_iterator 
-      FromProtoLoc = D->protocol_loc_begin();
-    
-    // FIXME: Should we be usng all_referenced_protocol_begin() here?
-    for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
-                                           FromProtoEnd = D->protocol_end();
-       FromProto != FromProtoEnd;
-       ++FromProto, ++FromProtoLoc) {
-      ObjCProtocolDecl *ToProto
-        = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
-      if (!ToProto)
-        return 0;
-      Protocols.push_back(ToProto);
-      ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+      if (D->getSuperClass()) {
+        ObjCInterfaceDecl *Super
+          = cast_or_null<ObjCInterfaceDecl>(
+              Importer.Import(D->getSuperClass()));
+        if (!Super)
+          return 0;
+        
+        ToIface->setSuperClass(Super);
+        ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
+      }
+      
+      // Import protocols
+      SmallVector<ObjCProtocolDecl *, 4> Protocols;
+      SmallVector<SourceLocation, 4> ProtocolLocs;
+      ObjCInterfaceDecl::protocol_loc_iterator 
+        FromProtoLoc = D->protocol_loc_begin();
+      
+      for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
+                                             FromProtoEnd = D->protocol_end();
+         FromProto != FromProtoEnd;
+         ++FromProto, ++FromProtoLoc) {
+        ObjCProtocolDecl *ToProto
+          = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+        if (!ToProto)
+          return 0;
+        Protocols.push_back(ToProto);
+        ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+      }
+      
+      // FIXME: If we're merging, make sure that the protocol list is the same.
+      ToIface->setProtocolList(Protocols.data(), Protocols.size(),
+                               ProtocolLocs.data(), Importer.getToContext());
     }
     
-    // FIXME: If we're merging, make sure that the protocol list is the same.
-    ToIface->setProtocolList(Protocols.data(), Protocols.size(),
-                             ProtocolLocs.data(), Importer.getToContext());
-    
     // Import @end range
     ToIface->setAtEndRange(Importer.Import(D->getAtEndRange()));
   } else {
     Importer.Imported(D, ToIface);
 
-    // Check for consistency of superclasses.
-    DeclarationName FromSuperName, ToSuperName;
-    
-    // If the superclass hasn't been imported yet, do so before checking.
-    ObjCInterfaceDecl *DSuperClass = D->getSuperClass();
-    ObjCInterfaceDecl *ToIfaceSuperClass = ToIface->getSuperClass();
-    
-    if (DSuperClass && !ToIfaceSuperClass) {
-      Decl *ImportedSuperClass = Importer.Import(DSuperClass);
-      ObjCInterfaceDecl *ImportedSuperIface = cast<ObjCInterfaceDecl>(ImportedSuperClass);
-      ToIface->setSuperClass(ImportedSuperIface);
-    }
-
-    if (D->getSuperClass())
-      FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
-    if (ToIface->getSuperClass())
-      ToSuperName = ToIface->getSuperClass()->getDeclName();
-    if (FromSuperName != ToSuperName) {
-      Importer.ToDiag(ToIface->getLocation(), 
-                      diag::err_odr_objc_superclass_inconsistent)
-        << ToIface->getDeclName();
+    if (D->hasDefinition()) {
+      // Check for consistency of superclasses.
+      DeclarationName FromSuperName, ToSuperName;
+      
+      // If the superclass hasn't been imported yet, do so before checking.
+      ObjCInterfaceDecl *DSuperClass = D->getSuperClass();
+      ObjCInterfaceDecl *ToIfaceSuperClass = ToIface->getSuperClass();
+      
+      if (DSuperClass && !ToIfaceSuperClass) {
+        Decl *ImportedSuperClass = Importer.Import(DSuperClass);
+        ObjCInterfaceDecl *ImportedSuperIface
+          = cast<ObjCInterfaceDecl>(ImportedSuperClass);
+        
+        ToIface->setSuperClass(ImportedSuperIface);
+      }
+
+      if (D->getSuperClass())
+        FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
       if (ToIface->getSuperClass())
-        Importer.ToDiag(ToIface->getSuperClassLoc(), 
-                        diag::note_odr_objc_superclass)
-          << ToIface->getSuperClass()->getDeclName();
-      else
+        ToSuperName = ToIface->getSuperClass()->getDeclName();
+      if (FromSuperName != ToSuperName) {
         Importer.ToDiag(ToIface->getLocation(), 
-                        diag::note_odr_objc_missing_superclass);
-      if (D->getSuperClass())
-        Importer.FromDiag(D->getSuperClassLoc(), 
+                        diag::err_odr_objc_superclass_inconsistent)
+          << ToIface->getDeclName();
+        if (ToIface->getSuperClass())
+          Importer.ToDiag(ToIface->getSuperClassLoc(), 
                           diag::note_odr_objc_superclass)
-          << D->getSuperClass()->getDeclName();
-      else
-        Importer.FromDiag(D->getLocation(), 
+            << ToIface->getSuperClass()->getDeclName();
+        else
+          Importer.ToDiag(ToIface->getLocation(), 
                           diag::note_odr_objc_missing_superclass);
-      return 0;
+        if (D->getSuperClass())
+          Importer.FromDiag(D->getSuperClassLoc(), 
+                            diag::note_odr_objc_superclass)
+            << D->getSuperClass()->getDeclName();
+        else
+          Importer.FromDiag(D->getLocation(), 
+                            diag::note_odr_objc_missing_superclass);
+        return 0;
+      }
     }
   }
   
+  if (!D->hasDefinition())
+    return ToIface;
+  
   // Import categories. When the categories themselves are imported, they'll
   // hook themselves into this interface.
   for (ObjCCategoryDecl *FromCat = D->getCategoryList(); FromCat;
@@ -3279,7 +3289,7 @@
   ImportDeclContext(D);
   
   // If we have an @implementation, import it as well.
-  if (D->getImplementation()) {
+  if ( D->getImplementation()) {
     ObjCImplementationDecl *Impl = cast_or_null<ObjCImplementationDecl>(
                                        Importer.Import(D->getImplementation()));
     if (!Impl)

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Wed Dec 14 23:27:12 2011
@@ -154,7 +154,11 @@
 ObjCPropertyDecl *
 ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
                                             IdentifierInfo *PropertyId) const {
-  if (ExternallyCompleted)
+  // FIXME: Should make sure no callers ever do this.
+  if (!hasDefinition())
+    return 0;
+  
+  if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
   if (ObjCPropertyDecl *PD =
@@ -175,11 +179,12 @@
                               ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
                               ASTContext &C)
 {
-  if (ExternallyCompleted)
+  if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
-  if (AllReferencedProtocols.empty() && ReferencedProtocols.empty()) {
-    AllReferencedProtocols.set(ExtList, ExtNum, C);
+  if (data().AllReferencedProtocols.empty() && 
+      data().ReferencedProtocols.empty()) {
+    data().AllReferencedProtocols.set(ExtList, ExtNum, C);
     return;
   }
   
@@ -214,12 +219,16 @@
     ProtocolRefs.push_back(*p);
   }
 
-  AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(), C);
+  data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
 }
 
-void ObjCInterfaceDecl::completedForwardDecl() {
-  assert(isForwardDecl() && "Only valid to call for forward refs");
-  ForwardDecl = false;
+void ObjCInterfaceDecl::allocateDefinitionData() {
+  assert(!hasDefinition() && "ObjC class already has a definition");
+  Definition = new (getASTContext()) DefinitionData();  
+}
+
+void ObjCInterfaceDecl::startDefinition() {
+  allocateDefinitionData();
   if (ASTMutationListener *L = getASTContext().getASTMutationListener())
     L->CompletedObjCForwardRef(this);
 }
@@ -244,7 +253,11 @@
 
 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
                                               ObjCInterfaceDecl *&clsDeclared) {
-  if (ExternallyCompleted)
+  // FIXME: Should make sure no callers ever do this.
+  if (!hasDefinition())
+    return 0;  
+
+  if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
   ObjCInterfaceDecl* ClassDecl = this;
@@ -271,7 +284,11 @@
 /// the it returns NULL.
 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
                                         const IdentifierInfo*ICName) {
-  if (ExternallyCompleted)
+  // FIXME: Should make sure no callers ever do this.
+  if (!hasDefinition())
+    return 0;
+
+  if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
   ObjCInterfaceDecl* ClassDecl = this;
@@ -287,10 +304,14 @@
 /// the class, its categories, and its super classes (using a linear search).
 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
                                                 bool isInstance) const {
+  // FIXME: Should make sure no callers ever do this.
+  if (!hasDefinition())
+    return 0;
+
   const ObjCInterfaceDecl* ClassDecl = this;
   ObjCMethodDecl *MethodDecl = 0;
 
-  if (ExternallyCompleted)
+  if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
   while (ClassDecl != NULL) {
@@ -328,7 +349,11 @@
 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
                                    const Selector &Sel,
                                    bool Instance) {
-  if (ExternallyCompleted)
+  // FIXME: Should make sure no callers ever do this.
+  if (!hasDefinition())
+    return 0;
+
+  if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
   ObjCMethodDecl *Method = 0;
@@ -651,16 +676,14 @@
 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
                   SourceLocation CLoc, bool FD, bool isInternal)
   : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
-    TypeForDecl(0), SuperClass(0),
-    CategoryList(0), IvarList(0),
-    InitiallyForwardDecl(FD), ForwardDecl(FD),
-    ExternallyCompleted(false) {
+    TypeForDecl(0), Definition(), InitiallyForwardDecl(FD) 
+{
   setImplicit(isInternal);
 }
 
 void ObjCInterfaceDecl::LoadExternalDefinition() const {
-  assert(ExternallyCompleted && "Class is not externally completed");
-  ExternallyCompleted = false;
+  assert(data().ExternallyCompleted && "Class is not externally completed");
+  data().ExternallyCompleted = false;
   getASTContext().getExternalSource()->CompleteType(
                                         const_cast<ObjCInterfaceDecl *>(this));
 }
@@ -668,13 +691,17 @@
 void ObjCInterfaceDecl::setExternallyCompleted() {
   assert(getASTContext().getExternalSource() && 
          "Class can't be externally completed without an external source");
-  assert(!ForwardDecl && 
+  assert(hasDefinition() && 
          "Forward declarations can't be externally completed");
-  ExternallyCompleted = true;
+  data().ExternallyCompleted = true;
 }
 
 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
-  if (ExternallyCompleted)
+  // FIXME: Should make sure no callers ever do this.
+  if (!hasDefinition())
+    return 0;
+      
+  if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
   return getASTContext().getObjCImplementation(
@@ -689,14 +716,18 @@
 /// its extensions and its implementation. Lazily build the list on first
 /// access.
 ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
-  if (IvarList)
-    return IvarList;
+  // FIXME: Should make sure no callers ever do this.
+  if (!hasDefinition())
+    return 0;
+  
+  if (data().IvarList)
+    return data().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)
+    data().IvarList = (*I); ++I;
+    for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
       curIvar->setNextIvar(*I);
   }
   
@@ -705,9 +736,9 @@
     if (!CDecl->ivar_empty()) {
       ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
                                           E = CDecl->ivar_end();
-      if (!IvarList) {
-        IvarList = (*I); ++I;
-        curIvar = IvarList;
+      if (!data().IvarList) {
+        data().IvarList = (*I); ++I;
+        curIvar = data().IvarList;
       }
       for ( ;I != E; curIvar = *I, ++I)
         curIvar->setNextIvar(*I);
@@ -718,15 +749,15 @@
     if (!ImplDecl->ivar_empty()) {
       ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
                                             E = ImplDecl->ivar_end();
-      if (!IvarList) {
-        IvarList = (*I); ++I;
-        curIvar = IvarList;
+      if (!data().IvarList) {
+        data().IvarList = (*I); ++I;
+        curIvar = data().IvarList;
       }
       for ( ;I != E; curIvar = *I, ++I)
         curIvar->setNextIvar(*I);
     }
   }
-  return IvarList;
+  return data().IvarList;
 }
 
 /// FindCategoryDeclaration - Finds category declaration in the list of
@@ -735,7 +766,7 @@
 ///
 ObjCCategoryDecl *
 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
-  if (ExternallyCompleted)
+  if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
   for (ObjCCategoryDecl *Category = getCategoryList();
@@ -770,6 +801,9 @@
 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
                                     bool lookupCategory,
                                     bool RHSIsQualifiedID) {
+  if (!hasDefinition())
+    return false;
+  
   ObjCInterfaceDecl *IDecl = this;
   // 1st, look up the class.
   const ObjCList<ObjCProtocolDecl> &Protocols =
@@ -997,9 +1031,11 @@
   if (IDecl) {
     // Link this category into its class's category list.
     CatDecl->NextClassCategory = IDecl->getCategoryList();
-    IDecl->setCategoryList(CatDecl);
-    if (ASTMutationListener *L = C.getASTMutationListener())
-      L->AddedObjCCategoryToInterface(CatDecl, IDecl);
+    if (IDecl->hasDefinition()) {
+      IDecl->setCategoryList(CatDecl);
+      if (ASTMutationListener *L = C.getASTMutationListener())
+        L->AddedObjCCategoryToInterface(CatDecl, IDecl);
+    }
   }
 
   return CatDecl;

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Wed Dec 14 23:27:12 2011
@@ -905,6 +905,11 @@
   else
     Out << "@interface " << I;
 
+  if (OID->isForwardDecl()) {
+    Out << "@end";
+    return;
+  }
+  
   // Protocols?
   const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
   if (!Protocols.empty()) {

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Dec 14 23:27:12 2011
@@ -4558,7 +4558,7 @@
   }
   
   ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
-  if (!IFace)
+  if (!IFace || !IFace->hasDefinition())
     return;
   
   // Add methods in protocols.
@@ -5783,6 +5783,9 @@
                                      bool InOriginalClass = true) {
   if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
     // Recurse into protocols.
+    if (!IFace->hasDefinition())
+      return;
+    
     const ObjCList<ObjCProtocolDecl> &Protocols
       = IFace->getReferencedProtocols();
     for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Dec 14 23:27:12 2011
@@ -368,10 +368,10 @@
   ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
   if (IDecl) {
     // Class already seen. Is it a forward declaration?
-    if (!IDecl->isForwardDecl()) {
+    if (ObjCInterfaceDecl *Def = IDecl->getDefinition()) {
       IDecl->setInvalidDecl();
       Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
-      Diag(IDecl->getLocation(), diag::note_previous_definition);
+      Diag(Def->getLocation(), diag::note_previous_definition);
 
       // Create a new one; the other may be in a different DeclContex, (e.g.
       // this one may be in a LinkageSpecDecl while the other is not) which
@@ -392,8 +392,6 @@
       IDecl->setLexicalDeclContext(CurContext);
       CurContext->addDecl(IDecl);
 
-      IDecl->completedForwardDecl();
-
       if (AttrList)
         ProcessDeclAttributeList(TUScope, IDecl, AttrList);
     }
@@ -406,6 +404,9 @@
     PushOnScopeChains(IDecl, TUScope);
   }
 
+  if (!IDecl->hasDefinition())
+    IDecl->startDefinition();
+  
   if (SuperName) {
     // Check if a different kind of symbol declared in this scope.
     PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
@@ -942,6 +943,7 @@
     // copy them over.
     IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
                                       ClassName, ClassLoc, false, true);
+    IDecl->startDefinition();
     IDecl->setSuperClass(SDecl);
     IDecl->setLocEnd(ClassLoc);
 
@@ -950,8 +952,8 @@
     // Mark the interface as being completed, even if it was just as
     //   @class ....;
     // declaration; the user cannot reopen it.
-    if (IDecl->isForwardDecl())
-      IDecl->completedForwardDecl();
+    if (!IDecl->hasDefinition())
+      IDecl->startDefinition();
   }
 
   ObjCImplementationDecl* IMPDecl =
@@ -2540,7 +2542,9 @@
 
   void searchFrom(ObjCInterfaceDecl *iface) {
     // A method in a class declaration overrides declarations from
-
+    if (!iface->hasDefinition())
+      return;
+    
     //   - categories,
     for (ObjCCategoryDecl *category = iface->getCategoryList();
            category; category = category->getNextClassCategory())

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Dec 14 23:27:12 2011
@@ -512,6 +512,9 @@
 
 ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
                                               ObjCInterfaceDecl *ClassDecl) {
+  if (!ClassDecl->hasDefinition())
+    return 0;
+
   ObjCMethodDecl *Method = 0;
   while (ClassDecl && !Method) {
     // If we have implementations in scope, check "private" methods.
@@ -1339,12 +1342,10 @@
             return ExprError();
           
           forwardClass = OCIType->getInterfaceDecl();
+          Method = 0;
+        } else {
+          Method = ClassDecl->lookupInstanceMethod(Sel);
         }
-        
-        // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
-        // faster than the following method (which can do *many* linear searches).
-        // The idea is to add class info to MethodPool.
-        Method = ClassDecl->lookupInstanceMethod(Sel);
 
         if (!Method)
           // Search protocol qualifiers.

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Dec 14 23:27:12 2011
@@ -556,43 +556,80 @@
 void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
   VisitObjCContainerDecl(ID);
   ID->setTypeForDecl(Reader.readType(F, Record, Idx).getTypePtrOrNull());
-  ID->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
   
-  // Read the directly referenced protocols and their SourceLocations.
-  unsigned NumProtocols = Record[Idx++];
-  SmallVector<ObjCProtocolDecl *, 16> Protocols;
-  Protocols.reserve(NumProtocols);
-  for (unsigned I = 0; I != NumProtocols; ++I)
-    Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
-  SmallVector<SourceLocation, 16> ProtoLocs;
-  ProtoLocs.reserve(NumProtocols);
-  for (unsigned I = 0; I != NumProtocols; ++I)
-    ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
-  ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(),
-                      Reader.getContext());
+  ObjCInterfaceDecl *Def = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
+  if (ID == Def) {
+    // Read the definition.
+    ID->allocateDefinitionData();
+    
+    ObjCInterfaceDecl::DefinitionData &Data = ID->data();
+    
+    // Read the superclass.
+    Data.SuperClass = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
+    Data.SuperClassLoc = ReadSourceLocation(Record, Idx);
+
+    // Read the directly referenced protocols and their SourceLocations.
+    unsigned NumProtocols = Record[Idx++];
+    SmallVector<ObjCProtocolDecl *, 16> Protocols;
+    Protocols.reserve(NumProtocols);
+    for (unsigned I = 0; I != NumProtocols; ++I)
+      Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+    SmallVector<SourceLocation, 16> ProtoLocs;
+    ProtoLocs.reserve(NumProtocols);
+    for (unsigned I = 0; I != NumProtocols; ++I)
+      ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
+    ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(),
+                        Reader.getContext());
   
-  // Read the transitive closure of protocols referenced by this class.
-  NumProtocols = Record[Idx++];
-  Protocols.clear();
-  Protocols.reserve(NumProtocols);
-  for (unsigned I = 0; I != NumProtocols; ++I)
-    Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
-  ID->AllReferencedProtocols.set(Protocols.data(), NumProtocols,
-                                 Reader.getContext());
+    // Read the transitive closure of protocols referenced by this class.
+    NumProtocols = Record[Idx++];
+    Protocols.clear();
+    Protocols.reserve(NumProtocols);
+    for (unsigned I = 0; I != NumProtocols; ++I)
+      Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+    ID->data().AllReferencedProtocols.set(Protocols.data(), NumProtocols,
+                                          Reader.getContext());
   
-  // Read the ivars.
-  unsigned NumIvars = Record[Idx++];
-  SmallVector<ObjCIvarDecl *, 16> IVars;
-  IVars.reserve(NumIvars);
-  for (unsigned I = 0; I != NumIvars; ++I)
-    IVars.push_back(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
-  ID->setCategoryList(ReadDeclAs<ObjCCategoryDecl>(Record, Idx));
+    // Read the ivars.
+    unsigned NumIvars = Record[Idx++];
+    SmallVector<ObjCIvarDecl *, 16> IVars;
+    IVars.reserve(NumIvars);
+    for (unsigned I = 0; I != NumIvars; ++I)
+      IVars.push_back(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
+    
+    // Read the categories.
+    ID->setCategoryList(ReadDeclAs<ObjCCategoryDecl>(Record, Idx));
+  
+    // We will rebuild this list lazily.
+    ID->setIvarList(0);
+    
+    // If there are any pending forward references, make their definition data
+    // pointers point at the newly-allocated data.
+    ASTReader::PendingForwardRefsMap::iterator
+    FindI = Reader.PendingForwardRefs.find(ID);
+    if (FindI != Reader.PendingForwardRefs.end()) {
+      ASTReader::ForwardRefs &Refs = FindI->second;
+      for (ASTReader::ForwardRefs::iterator I = Refs.begin(), 
+                                            E = Refs.end(); 
+           I != E; ++I)
+        cast<ObjCInterfaceDecl>(*I)->Definition = ID->Definition;
+#ifndef NDEBUG
+      // We later check whether PendingForwardRefs is empty to make sure all
+      // pending references were linked.
+      Reader.PendingForwardRefs.erase(ID);
+#endif
+    
+    } else if (Def) {
+      if (Def->Definition) {
+        ID->Definition = Def->Definition;
+      } else {
+        // The definition is still initializing.
+        Reader.PendingForwardRefs[Def].push_back(ID);
+      }
+    }
+  }
   
-  // We will rebuild this list lazily.
-  ID->setIvarList(0);
   ID->InitiallyForwardDecl = Record[Idx++];
-  ID->ForwardDecl = Record[Idx++];
-  ID->setSuperClassLoc(ReadSourceLocation(Record, Idx));
   ID->setLocEnd(ReadSourceLocation(Record, Idx));
 }
 
@@ -972,7 +1009,7 @@
       ASTReader::ForwardRefs &Refs = FindI->second;
       for (ASTReader::ForwardRefs::iterator
              I = Refs.begin(), E = Refs.end(); I != E; ++I)
-        (*I)->DefinitionData = D->DefinitionData;
+        cast<CXXRecordDecl>(*I)->DefinitionData = D->DefinitionData;
 #ifndef NDEBUG
       // We later check whether PendingForwardRefs is empty to make sure all
       // pending references were linked.

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Dec 14 23:27:12 2011
@@ -449,36 +449,46 @@
 void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
   VisitObjCContainerDecl(D);
   Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
-  Writer.AddDeclRef(D->getSuperClass(), Record);
 
-  // Write out the protocols that are directly referenced by the @interface.
-  Record.push_back(D->ReferencedProtocols.size());
-  for (ObjCInterfaceDecl::protocol_iterator P = D->protocol_begin(),
-         PEnd = D->protocol_end();
-       P != PEnd; ++P)
-    Writer.AddDeclRef(*P, Record);
-  for (ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
+  ObjCInterfaceDecl *Def = D->getDefinition();
+  Writer.AddDeclRef(Def, Record);
+  
+  if (D == Def) {
+    // Write the DefinitionData
+    ObjCInterfaceDecl::DefinitionData &Data = D->data();
+    
+    Writer.AddDeclRef(D->getSuperClass(), Record);
+    Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
+    
+    // Write out the protocols that are directly referenced by the @interface.
+    Record.push_back(Data.ReferencedProtocols.size());
+    for (ObjCInterfaceDecl::protocol_iterator P = D->protocol_begin(),
+                                           PEnd = D->protocol_end();
+         P != PEnd; ++P)
+      Writer.AddDeclRef(*P, Record);
+    for (ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
          PLEnd = D->protocol_loc_end();
-       PL != PLEnd; ++PL)
-    Writer.AddSourceLocation(*PL, Record);
-
-  // Write out the protocols that are transitively referenced.
-  Record.push_back(D->AllReferencedProtocols.size());
-  for (ObjCList<ObjCProtocolDecl>::iterator
-        P = D->AllReferencedProtocols.begin(),
-        PEnd = D->AllReferencedProtocols.end();
-       P != PEnd; ++P)
-    Writer.AddDeclRef(*P, Record);
+         PL != PLEnd; ++PL)
+      Writer.AddSourceLocation(*PL, Record);
+    
+    // Write out the protocols that are transitively referenced.
+    Record.push_back(Data.AllReferencedProtocols.size());
+    for (ObjCList<ObjCProtocolDecl>::iterator
+              P = Data.AllReferencedProtocols.begin(),
+           PEnd = Data.AllReferencedProtocols.end();
+         P != PEnd; ++P)
+      Writer.AddDeclRef(*P, Record);
+    
+    // Write out the ivars.
+    Record.push_back(D->ivar_size());
+    for (ObjCInterfaceDecl::ivar_iterator I = D->ivar_begin(),
+                                       IEnd = D->ivar_end(); I != IEnd; ++I)
+      Writer.AddDeclRef(*I, Record);
+    
+    Writer.AddDeclRef(D->getCategoryList(), Record);
+  }  
   
-  // Write out the ivars.
-  Record.push_back(D->ivar_size());
-  for (ObjCInterfaceDecl::ivar_iterator I = D->ivar_begin(),
-                                     IEnd = D->ivar_end(); I != IEnd; ++I)
-    Writer.AddDeclRef(*I, Record);
-  Writer.AddDeclRef(D->getCategoryList(), Record);
   Record.push_back(D->isInitiallyForwardDecl());
-  Record.push_back(D->isForwardDecl());
-  Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
   Writer.AddSourceLocation(D->getLocEnd(), Record);
   Code = serialization::DECL_OBJC_INTERFACE;
 }

Modified: cfe/trunk/tools/libclang/IndexingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexingContext.cpp?rev=146644&r1=146643&r2=146644&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/IndexingContext.cpp (original)
+++ cfe/trunk/tools/libclang/IndexingContext.cpp Wed Dec 14 23:27:12 2011
@@ -369,7 +369,10 @@
       markEntityOccurrenceInFile(SuperD, SuperLoc);
   }
   
-  ObjCProtocolListInfo ProtInfo(D->getReferencedProtocols(), *this, SA);
+  ObjCProtocolList EmptyProtoList;
+  ObjCProtocolListInfo ProtInfo(D->hasDefinition()? D->getReferencedProtocols()
+                                                  : EmptyProtoList, 
+                                *this, SA);
   
   ObjCInterfaceDeclInfo InterInfo(D);
   InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();





More information about the cfe-commits mailing list