[cfe-commits] r112691 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/ASTContext.cpp lib/AST/ASTImporter.cpp lib/AST/DeclObjC.cpp lib/CodeGen/CGObjCMac.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaObjCProperty.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp test/Index/local-symbols.m

Ted Kremenek kremenek at apple.com
Tue Aug 31 18:21:15 PDT 2010


Author: kremenek
Date: Tue Aug 31 20:21:15 2010
New Revision: 112691

URL: http://llvm.org/viewvc/llvm-project?rev=112691&view=rev
Log:
Split ObjCInterfaceDecl::ReferencedProtocols into two lists: ReferencedProtocols and AllReferencedProtocols.  ReferencedProtocols
(and thus protocol_begin(), protocol_end()) now only contains the list of protocols that were directly referenced in
an @interface declaration.  'all_referenced_protocol_[begin,end]()' now returns the set of protocols that were referenced
in both the @interface and class extensions.  The latter is needed for semantic analysis/codegen, while the former is
needed to maintain the lexical information of the original source.

Fixes <rdar://problem/8380046>.

Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/test/Index/local-symbols.m

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Aug 31 20:21:15 2010
@@ -443,8 +443,11 @@
   /// Class's super class.
   ObjCInterfaceDecl *SuperClass;
 
-  /// Protocols referenced in interface header declaration
+  /// Protocols referenced in the @interface  declaration
   ObjCProtocolList ReferencedProtocols;
+  
+  /// Protocols reference in both the @interface and class extensions.
+  ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
 
   /// List of categories defined for this class.
   /// FIXME: Why is this a linked list??
@@ -489,23 +492,44 @@
   }
 
   typedef ObjCProtocolList::iterator protocol_iterator;
-  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
-  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+  
+  protocol_iterator protocol_begin() const {
+    return ReferencedProtocols.begin();
+  }
+  protocol_iterator protocol_end() const {
+    return ReferencedProtocols.end();
+  }
+
   typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+
   protocol_loc_iterator protocol_loc_begin() const { 
     return ReferencedProtocols.loc_begin(); 
   }
+
   protocol_loc_iterator protocol_loc_end() const { 
     return ReferencedProtocols.loc_end(); 
   }
-  unsigned protocol_size() const { return ReferencedProtocols.size(); }
+  
+  typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
+  
+  all_protocol_iterator all_referenced_protocol_begin() const {
+    return AllReferencedProtocols.empty() ? protocol_begin()
+      : AllReferencedProtocols.begin();
+  }
+  all_protocol_iterator all_referenced_protocol_end() const {
+    return AllReferencedProtocols.empty() ? protocol_end() 
+      : 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()); }
+
   unsigned ivar_size() const {
     return std::distance(ivar_begin(), ivar_end());
   }
+  
   bool ivar_empty() const { return ivar_begin() == ivar_end(); }
   
   ObjCIvarDecl  *all_declared_ivar_begin();
@@ -522,7 +546,6 @@
   /// into the protocol list for this class.
   void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, 
                                        unsigned Num,
-                                       const SourceLocation *Locs,
                                        ASTContext &C);
 
   bool isForwardDecl() const { return ForwardDecl; }
@@ -604,6 +627,9 @@
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const ObjCInterfaceDecl *D) { return true; }
   static bool classofKind(Kind K) { return K == ObjCInterface; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Aug 31 20:21:15 2010
@@ -897,8 +897,10 @@
 void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
                           llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols) {
   if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
-    for (ObjCInterfaceDecl::protocol_iterator P = OI->protocol_begin(),
-         PE = OI->protocol_end(); P != PE; ++P) {
+    // We can use protocol_iterator here instead of
+    // all_referenced_protocol_iterator since we are walking all categories.    
+    for (ObjCInterfaceDecl::all_protocol_iterator P = OI->all_referenced_protocol_begin(),
+         PE = OI->all_referenced_protocol_end(); P != PE; ++P) {
       ObjCProtocolDecl *Proto = (*P);
       Protocols.insert(Proto);
       for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
@@ -918,7 +920,7 @@
         SD = SD->getSuperClass();
       }
   } else if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
-    for (ObjCInterfaceDecl::protocol_iterator P = OC->protocol_begin(),
+    for (ObjCCategoryDecl::protocol_iterator P = OC->protocol_begin(),
          PE = OC->protocol_end(); P != PE; ++P) {
       ObjCProtocolDecl *Proto = (*P);
       Protocols.insert(Proto);

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Aug 31 20:21:15 2010
@@ -2553,6 +2553,8 @@
     llvm::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;

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Tue Aug 31 20:21:15 2010
@@ -120,8 +120,9 @@
             return P;
 
       // Look through protocols.
-      for (ObjCInterfaceDecl::protocol_iterator
-            I = OID->protocol_begin(), E = OID->protocol_end(); I != E; ++I)
+      for (ObjCInterfaceDecl::all_protocol_iterator
+            I = OID->all_referenced_protocol_begin(),
+            E = OID->all_referenced_protocol_end(); I != E; ++I)
         if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
           return P;
 
@@ -157,8 +158,9 @@
     return PD;
 
   // Look through protocols.
-  for (ObjCInterfaceDecl::protocol_iterator
-        I = protocol_begin(), E = protocol_end(); I != E; ++I)
+  for (ObjCInterfaceDecl::all_protocol_iterator
+        I = all_referenced_protocol_begin(),
+        E = all_referenced_protocol_end(); I != E; ++I)
     if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
       return P;
 
@@ -167,23 +169,23 @@
 
 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
                               ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
-                              const SourceLocation *Locs,
                               ASTContext &C)
 {
-  if (ReferencedProtocols.empty()) {
-    ReferencedProtocols.set(ExtList, ExtNum, Locs, C);
+  if (AllReferencedProtocols.empty() && ReferencedProtocols.empty()) {
+    AllReferencedProtocols.set(ExtList, ExtNum, C);
     return;
   }
+  
   // Check for duplicate protocol in class's protocol list.
-  // This is (O)2. But it is extremely rare and number of protocols in
+  // This is O(n*m). But it is extremely rare and number of protocols in
   // class or its extension are very few.
   llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
-  llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
   for (unsigned i = 0; i < ExtNum; i++) {
     bool protocolExists = false;
     ObjCProtocolDecl *ProtoInExtension = ExtList[i];
-    for (protocol_iterator p = protocol_begin(), e = protocol_end();
-         p != e; p++) {
+    for (all_protocol_iterator
+          p = all_referenced_protocol_begin(),
+          e = all_referenced_protocol_end(); p != e; ++p) {
       ObjCProtocolDecl *Proto = (*p);
       if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
         protocolExists = true;
@@ -192,22 +194,20 @@
     }
     // Do we want to warn on a protocol in extension class which
     // already exist in the class? Probably not.
-    if (!protocolExists) {
+    if (!protocolExists)
       ProtocolRefs.push_back(ProtoInExtension);
-      ProtocolLocs.push_back(Locs[i]);
-    }
   }
+
   if (ProtocolRefs.empty())
     return;
+
   // Merge ProtocolRefs into class's protocol list;
-  protocol_loc_iterator pl = protocol_loc_begin();
-  for (protocol_iterator p = protocol_begin(), e = protocol_end();
-       p != e; ++p, ++pl) {
+  for (all_protocol_iterator p = all_referenced_protocol_begin(), 
+        e = all_referenced_protocol_end(); p != e; ++p) {
     ProtocolRefs.push_back(*p);
-    ProtocolLocs.push_back(*pl);
   }
-  unsigned NumProtoRefs = ProtocolRefs.size();
-  setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
+
+  AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(), C);
 }
 
 /// getFirstClassExtension - Find first class extension of the given class.

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Aug 31 20:21:15 2010
@@ -1990,8 +1990,9 @@
                                                    Prop));
   }
   if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
-    for (ObjCInterfaceDecl::protocol_iterator P = OID->protocol_begin(),
-         E = OID->protocol_end(); P != E; ++P)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         P = OID->all_referenced_protocol_begin(),
+         E = OID->all_referenced_protocol_end(); P != E; ++P)
       PushProtocolProperties(PropertySet, Properties, Container, (*P), 
                              ObjCTypes);
   }
@@ -2179,8 +2180,8 @@
     const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
   llvm::Constant *Protocols =
     EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
-                     Interface->protocol_begin(),
-                     Interface->protocol_end());
+                     Interface->all_referenced_protocol_begin(),
+                     Interface->all_referenced_protocol_end());
   unsigned Flags = eClassFlags_Factory;
   if (ID->getNumIvarInitializers())
     Flags |= eClassFlags_HasCXXStructors;
@@ -4804,8 +4805,8 @@
   assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
   Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
                                 + OID->getName(),
-                                OID->protocol_begin(),
-                                OID->protocol_end());
+                                OID->all_referenced_protocol_begin(),
+                                OID->all_referenced_protocol_end());
 
   if (flags & CLS_META)
     Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Aug 31 20:21:15 2010
@@ -2686,9 +2686,9 @@
     }
     
     // Look through protocols.
-    for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
-                                              E = IFace->protocol_end(); 
-         I != E; ++I)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         I = IFace->all_referenced_protocol_begin(),
+         E = IFace->all_referenced_protocol_end(); I != E; ++I)
       AddObjCProperties(*I, AllowCategories, CurContext, Results);
     
     // Look in the superclass.
@@ -2698,8 +2698,8 @@
   } else if (const ObjCCategoryDecl *Category
                                     = dyn_cast<ObjCCategoryDecl>(Container)) {
     // Look through protocols.
-    for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
-                                           PEnd = Category->protocol_end(); 
+    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
+                                          PEnd = Category->protocol_end(); 
          P != PEnd; ++P)
       AddObjCProperties(*P, AllowCategories, CurContext, Results);
   }

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Tue Aug 31 20:21:15 2010
@@ -485,8 +485,7 @@
     // Protocols in the class extension belong to the class.
     if (CDecl->IsClassExtension())
      IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl**)ProtoRefs, 
-                                            NumProtoRefs, ProtoLocs,
-                                            Context); 
+                                            NumProtoRefs, Context); 
   }
 
   CheckObjCDeclScope(CDecl);
@@ -924,8 +923,9 @@
   }
   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
     // Check for any implementation of a methods declared in protocol.
-    for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
-         E = I->protocol_end(); PI != E; ++PI)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+          PI = I->all_referenced_protocol_begin(),
+          E = I->all_referenced_protocol_end(); PI != E; ++PI)
       MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
                                  IMPDecl,
                                  (*PI), IncompleteImpl, false);
@@ -971,8 +971,9 @@
   // implemented in the implementation class.
 
   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
-    for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
-         E = I->protocol_end(); PI != E; ++PI)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+          PI = I->all_referenced_protocol_begin(),
+          E = I->all_referenced_protocol_end(); PI != E; ++PI)
       CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
                               InsMap, ClsMap, I);
     // Check class extensions (unnamed categories)

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Aug 31 20:21:15 2010
@@ -2502,8 +2502,9 @@
     }
 
     // Traverse protocols.
-    for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
-         E = IFace->protocol_end(); I != E; ++I) {
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         I = IFace->all_referenced_protocol_begin(),
+         E = IFace->all_referenced_protocol_end(); I != E; ++I) {
       ShadowContextRAII Shadow(Visited);
       LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer, 
                          Visited);

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Tue Aug 31 20:21:15 2010
@@ -731,15 +731,17 @@
   }
 
   if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
-    for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
-         E = MDecl->protocol_end(); P != E; ++P)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+          P = MDecl->all_referenced_protocol_begin(),
+          E = MDecl->all_referenced_protocol_end(); P != E; ++P)
       // Match properties of class IDecl with those of protocol (*P).
       MatchOneProtocolPropertiesInClass(IDecl, *P);
 
     // Go thru the list of protocols for this class and recursively match
     // their properties with those declared in the class.
-    for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
-         E = IDecl->protocol_end(); P != E; ++P)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+          P = IDecl->all_referenced_protocol_begin(),
+          E = IDecl->all_referenced_protocol_end(); P != E; ++P)
       CompareProperties(IDecl, *P);
   } else {
     ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
@@ -812,8 +814,9 @@
       PropMap[Prop->getIdentifier()] = Prop;
     }
     // scan through class's protocols.
-    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
-         E = IDecl->protocol_end(); PI != E; ++PI)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         PI = IDecl->all_referenced_protocol_begin(),
+         E = IDecl->all_referenced_protocol_end(); PI != E; ++PI)
         CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
   if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
@@ -824,7 +827,7 @@
         PropMap[Prop->getIdentifier()] = Prop;
       }
     // scan through class's protocols.
-    for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
+    for (ObjCCategoryDecl::protocol_iterator PI = CATDecl->protocol_begin(),
          E = CATDecl->protocol_end(); PI != E; ++PI)
       CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
@@ -859,8 +862,9 @@
       ObjCPropertyDecl *Prop = (*P);
       PropMap[Prop->getIdentifier()] = Prop;
     }
-    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
-         E = IDecl->protocol_end(); PI != E; ++PI)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         PI = IDecl->all_referenced_protocol_begin(),
+         E = IDecl->all_referenced_protocol_end(); PI != E; ++PI)
       CollectClassPropertyImplementations((*PI), PropMap);
   }
   else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
@@ -902,8 +906,9 @@
         return Prop;
     }
     // scan through class's protocols.
-    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
-         E = IDecl->protocol_end(); PI != E; ++PI) {
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         PI = IDecl->all_referenced_protocol_begin(),
+         E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) {
       ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
       if (Prop)
         return Prop;

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Aug 31 20:21:15 2010
@@ -374,6 +374,8 @@
   ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
   ID->setSuperClass(cast_or_null<ObjCInterfaceDecl>
                        (Reader.GetDecl(Record[Idx++])));
+  
+  // Read the directly referenced protocols and their SourceLocations.
   unsigned NumProtocols = Record[Idx++];
   llvm::SmallVector<ObjCProtocolDecl *, 16> Protocols;
   Protocols.reserve(NumProtocols);
@@ -385,6 +387,17 @@
     ProtoLocs.push_back(SourceLocation::getFromRawEncoding(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(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+  ID->AllReferencedProtocols.set(Protocols.data(), NumProtocols,
+                                 *Reader.getContext());
+  
+  // Read the ivars.
   unsigned NumIvars = Record[Idx++];
   llvm::SmallVector<ObjCIvarDecl *, 16> IVars;
   IVars.reserve(NumIvars);

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Aug 31 20:21:15 2010
@@ -343,7 +343,9 @@
   VisitObjCContainerDecl(D);
   Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
   Writer.AddDeclRef(D->getSuperClass(), Record);
-  Record.push_back(D->protocol_size());
+
+  // 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)
@@ -352,6 +354,16 @@
          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);
+  
+  // 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)

Modified: cfe/trunk/test/Index/local-symbols.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/local-symbols.m?rev=112691&r1=112690&r2=112691&view=diff
==============================================================================
--- cfe/trunk/test/Index/local-symbols.m (original)
+++ cfe/trunk/test/Index/local-symbols.m Tue Aug 31 20:21:15 2010
@@ -15,6 +15,17 @@
 }
 @end
 
+// From: <rdar://problem/8380046>
+
+ at protocol Prot8380046
+ at end
+
+ at interface R8380046
+ at end
+
+ at interface R8380046 () <Prot8380046>
+ at end
+
 // CHECK: local-symbols.m:6:12: ObjCInterfaceDecl=Foo:6:12 Extent=[6:1 - 10:5]
 // CHECK: local-symbols.m:7:6: ObjCIvarDecl=x:7:6 (Definition) Extent=[7:6 - 7:7]
 // CHECK: local-symbols.m:7:3: TypeRef=id:0:0 Extent=[7:3 - 7:5]
@@ -23,4 +34,11 @@
 // CHECK: local-symbols.m:12:1: ObjCImplementationDecl=Foo:12:1 (Definition) Extent=[12:1 - 16:2]
 // CHECK: local-symbols.m:13:1: ObjCInstanceMethodDecl=bar:13:1 (Definition) Extent=[13:1 - 15:2]
 // CHECK: local-symbols.m:13:4: TypeRef=id:0:0 Extent=[13:4 - 13:6]
+// CHECK: local-symbols.m:14:10: UnexposedExpr= Extent=[14:10 - 14:11]
+// CHECK: local-symbols.m:14:10: UnexposedExpr= Extent=[14:10 - 14:11]
+// CHECK: local-symbols.m:20:1: ObjCProtocolDecl=Prot8380046:20:1 (Definition) Extent=[20:1 - 21:5]
+// CHECK: local-symbols.m:23:12: ObjCInterfaceDecl=R8380046:23:12 Extent=[23:1 - 24:5]
+// CHECK: local-symbols.m:26:12: ObjCCategoryDecl=:26:12 Extent=[26:1 - 27:5]
+// CHECK: local-symbols.m:26:12: ObjCClassRef=R8380046:23:12 Extent=[26:12 - 26:20]
+// CHECK: local-symbols.m:26:25: ObjCProtocolRef=Prot8380046:20:1 Extent=[26:25 - 26:36]
 





More information about the cfe-commits mailing list