Use a sane encoding for CXCursor_ObjCProtocolRef, using the actual
source locations where the protocols were referenced rather than the
location of some random enclosing declaration.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93637 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index e58a08a..c08243e 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -262,7 +262,10 @@
 void CDeclVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
   // Issue callbacks for the containing class.
   Call(CXCursor_ObjCClassRef, ND);
-  // FIXME: Issue callbacks for protocol refs.
+  ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
+  for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
+         E = ND->protocol_end(); I != E; ++I, ++PL)
+    Callback(CDecl, MakeCursorObjCProtocolRef(*I, *PL), CData);
   VisitDeclContext(dyn_cast<DeclContext>(ND));
 }
 
@@ -282,9 +285,10 @@
                                          D->getSuperClassLoc()), 
              CData);
   
-  for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
-       E = D->protocol_end(); I != E; ++I)
-    Call(CXCursor_ObjCProtocolRef, *I);
+  ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
+  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
+         E = D->protocol_end(); I != E; ++I, ++PL)
+    Callback(CDecl, MakeCursorObjCProtocolRef(*I, *PL), CData);
   VisitDeclContext(dyn_cast<DeclContext>(D));
 }
 
@@ -307,9 +311,10 @@
 }
 
 void CDeclVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
+  ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
   for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
-       E = PID->protocol_end(); I != E; ++I)
-    Call(CXCursor_ObjCProtocolRef, *I);
+         E = PID->protocol_end(); I != E; ++I, ++PL)
+    Callback(CDecl, MakeCursorObjCProtocolRef(*I, *PL), CData);
   
   VisitDeclContext(dyn_cast<DeclContext>(PID));
 }
@@ -346,12 +351,8 @@
     }
     case CXCursor_ObjCSuperClassRef:
       return getCursorObjCSuperClassRef(C).second;
-
-    case CXCursor_ObjCProtocolRef: {
-      ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
-      assert(OID && "clang_getCursorLine(): Missing protocol decl");
-      return OID->getLocation();
-    }
+    case CXCursor_ObjCProtocolRef:
+      return getCursorObjCProtocolRef(C).second;
     case CXCursor_ObjCSelectorRef: {
       ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(getCursorStmt(C));
       assert(OME && "clang_getCursorLine(): Missing message expr");
@@ -776,7 +777,7 @@
                             ->getNameStart());
     }
     case CXCursor_ObjCProtocolRef: {
-      ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
+      ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
       assert(OID && "clang_getCursorLine(): Missing protocol decl");
       return CIndexer::createCXString(OID->getIdentifier()->getNameStart());
     }
@@ -884,10 +885,8 @@
         CXCursor C = { CXCursor_ObjCClassRef, { Dcl, ALoc.getParentDecl(), 0 }};
         return C;
       }
-      if (isa<ObjCProtocolDecl>(Dcl)) {
-        CXCursor C = {CXCursor_ObjCProtocolRef, {Dcl, ALoc.getParentDecl(), 0}};
-        return C;
-      }
+      if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(Dcl))
+        return MakeCursorObjCProtocolRef(Proto, ALoc.AsNamedRef().Loc);
     }
     return MakeCXCursor(Dcl);
   }
@@ -933,8 +932,7 @@
 
   if (clang_isReference(C.kind)) {
     if (getCursorStmt(C)) {
-      if (C.kind == CXCursor_ObjCClassRef ||
-          C.kind == CXCursor_ObjCProtocolRef)
+      if (C.kind == CXCursor_ObjCClassRef)
         return getCursorStmt(C);
       else
         return getDeclFromExpr(getCursorStmt(C));