Add support for class and protocol references.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83186 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index cb870c9..90fe3a8 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -393,6 +393,9 @@
         }
       case CXCursor_ObjCClassRef: 
         {
+        if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND)) {
+          return OID->getIdentifier()->getName();
+        }
         ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
         assert(OID && "clang_getCursorLine(): Missing category decl");
         return OID->getClassInterface()->getIdentifier()->getName();
@@ -524,10 +527,20 @@
       } else if (ObjCMessageExpr *MExp = dyn_cast<ObjCMessageExpr>(Stm)) {
         CXCursor C = { CXCursor_ObjCSelectorRef, Dcl, MExp };
         return C;
-      }
+      } 
       // Fall through...treat as a decl, not a ref.
     }
-    CXCursor C = { TranslateKind(Dcl), Dcl, 0 };
+    if (ALoc.isNamedRef()) {
+      if (isa<ObjCInterfaceDecl>(Dcl)) {
+        CXCursor C = { CXCursor_ObjCClassRef, Dcl, ALoc.getParentDecl() };
+        return C;
+      }
+      if (isa<ObjCProtocolDecl>(Dcl)) {
+        CXCursor C = { CXCursor_ObjCProtocolRef, Dcl, ALoc.getParentDecl() };
+        return C;
+      }
+    }
+	  CXCursor C = { TranslateKind(Dcl), Dcl, 0 };
     return C;
   }
   CXCursor C = { CXCursor_NoDeclFound, 0, 0 };
@@ -592,19 +605,34 @@
     return C.decl;
     
   if (clang_isReference(C.kind)) {
-    if (C.stmt)
-      return getDeclFromExpr(static_cast<Stmt *>(C.stmt));
-    else
+    if (C.stmt) {
+      if (C.kind == CXCursor_ObjCClassRef)
+        return static_cast<Stmt *>(C.stmt);
+      else
+        return getDeclFromExpr(static_cast<Stmt *>(C.stmt));
+    } else
       return C.decl;
   }
   return 0;
 }
 
+  
 static SourceLocation getLocationFromCursor(CXCursor C, 
                                             SourceManager &SourceMgr,
                                             NamedDecl *ND) {
   if (clang_isReference(C.kind)) {
     switch (C.kind) {
+      case CXCursor_ObjCClassRef: 
+        {
+        if (isa<ObjCInterfaceDecl>(ND)) {
+          // FIXME: This is a hack (storing the parent decl in the stmt slot).
+          NamedDecl *parentDecl = static_cast<NamedDecl *>(C.stmt);
+          return parentDecl->getLocation();
+        }
+        ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
+        assert(OID && "clang_getCursorLine(): Missing category decl");
+        return OID->getClassInterface()->getLocation();
+        }
       case CXCursor_ObjCSuperClassRef: 
         {
         ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);