Fix <rdar://problem/6144382> [sema] gcc inconsistency w.r.t. forward protocol declarations.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66161 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 55b0d16..d90f2ad 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -215,6 +215,25 @@
   return AliasDecl;
 }
 
+void Sema::CheckForwardProtocolDeclarationForCircularDependency(
+  IdentifierInfo *PName,
+  SourceLocation &Ploc, SourceLocation PrevLoc,
+  const ObjCList<ObjCProtocolDecl> &PList) 
+{
+  for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(),
+       E = PList.end(); I != E; ++I) {
+       
+    if (ObjCProtocolDecl *PDecl = ObjCProtocols[(*I)->getIdentifier()]) {
+      if (PDecl->getIdentifier() == PName) {
+        Diag(Ploc, diag::err_protocol_has_circular_dependency);
+        Diag(PrevLoc, diag::note_previous_definition);
+      }
+      CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc, 
+        PDecl->getLocation(), PDecl->getReferencedProtocols());
+    }
+  }
+}
+
 Sema::DeclTy *
 Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
                                   IdentifierInfo *ProtocolName,
@@ -236,6 +255,12 @@
       // FIXME: don't leak the objects passed in!
       return PDecl;
     }
+    ObjCList<ObjCProtocolDecl> PList;
+    PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context); 
+    CheckForwardProtocolDeclarationForCircularDependency(
+      ProtocolName, ProtocolLoc, PDecl->getLocation(), PList);
+    PList.Destroy(Context);
+    
     // Make sure the cached decl gets a valid start location.
     PDecl->setLocation(AtProtoInterfaceLoc);
     PDecl->setForwardDecl(false);