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>.

llvm-svn: 112691
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 8c61b5c..574ada3 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -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);
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index eee41a6..2edd09c 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -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;
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index 28c7a49..d952cc3 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -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.