Introduce clang_getCursorReferenced, to get a cursor pointing at the
entity that a particular cursor references.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93830 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 9e74083..355b80d 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -1006,7 +1006,46 @@
   Decl *D = getCursorDecl(C);
   return translateSourceRange(D->getASTContext(), D->getSourceRange());
 }
+
+CXCursor clang_getCursorReferenced(CXCursor C) {
+  if (clang_isDeclaration(C.kind) || clang_isDefinition(C.kind))
+    return C;
   
+  if (!clang_isReference(C.kind))
+    return clang_getNullCursor();
+  
+  switch (C.kind) {
+    case CXCursor_ObjCSuperClassRef:
+      return MakeCXCursor(getCursorObjCSuperClassRef(C).first);
+      
+    case CXCursor_ObjCProtocolRef: {       
+      return MakeCXCursor(getCursorObjCProtocolRef(C).first);
+      
+    case CXCursor_ObjCClassRef:      
+      return MakeCXCursor(getCursorObjCClassRef(C).first);
+      
+    case CXCursor_ObjCSelectorRef:
+    case CXCursor_ObjCIvarRef:
+    case CXCursor_VarRef:
+    case CXCursor_FunctionRef:
+    case CXCursor_EnumConstantRef:
+    case CXCursor_MemberRef: {
+      Decl *D = getDeclFromExpr(getCursorExpr(C));
+      if (D)
+        return MakeCXCursor(D);
+      break;
+    }
+      
+    default:
+      // We would prefer to enumerate all non-reference cursor kinds here.
+      llvm_unreachable("Unhandled reference cursor kind");
+      break;
+    }
+  }
+  
+  return clang_getNullCursor();
+}
+
 void clang_getDefinitionSpellingAndExtent(CXCursor C,
                                           const char **startBuf,
                                           const char **endBuf,
diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports
index 0272f37..71522fd 100644
--- a/tools/CIndex/CIndex.exports
+++ b/tools/CIndex/CIndex.exports
@@ -18,6 +18,7 @@
 _clang_getCursorKind
 _clang_getCursorKindSpelling
 _clang_getCursorLocation
+_clang_getCursorReferenced
 _clang_getCursorSpelling
 _clang_getCursorUSR
 _clang_getDeclColumn
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 2f113cf..34332d3 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -47,16 +47,18 @@
   if (clang_isInvalid(Cursor.kind))
     printf("Invalid Cursor => %s", clang_getCursorKindSpelling(Cursor.kind));
   else {
-    CXDecl DeclReferenced;
     CXString string;
+    CXCursor Referenced;
     string = clang_getCursorSpelling(Cursor);
     printf("%s=%s", clang_getCursorKindSpelling(Cursor.kind),
                       clang_getCString(string));
     clang_disposeString(string);
-    DeclReferenced = clang_getCursorDecl(Cursor);
-    if (DeclReferenced)
-      printf(":%d:%d", clang_getDeclLine(DeclReferenced),
-                       clang_getDeclColumn(DeclReferenced));
+    
+    Referenced = clang_getCursorReferenced(Cursor);
+    if (!clang_equalCursors(Referenced, clang_getNullCursor())) {
+      CXSourceLocation Loc = clang_getCursorLocation(Referenced);
+      printf(":%d:%d", Loc.line, Loc.column);
+    }
   }
 }