Give CXCursor_ObjCSuperClassRef a sane encoding, which is only known
to CXCursor.cpp.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93634 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 0ecb54a..e58a08a 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -209,6 +209,7 @@
     CXCursor C = { CK, { ND, 0, 0 } };
     Callback(CDecl, C, CData);
   }
+
 public:
   CDeclVisitor(CXDecl C, CXDeclIterator cback, CXClientData D,
                unsigned MaxPCHLevel) :
@@ -276,7 +277,10 @@
 void CDeclVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
   // Issue callbacks for super class.
   if (D->getSuperClass())
-    Call(CXCursor_ObjCSuperClassRef, D);
+    Callback(CDecl, 
+             MakeCursorObjCSuperClassRef(D->getSuperClass(),
+                                         D->getSuperClassLoc()), 
+             CData);
   
   for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
        E = D->protocol_end(); I != E; ++I)
@@ -340,11 +344,9 @@
       assert(OID && "clang_getCursorLine(): Missing category decl");
       return OID->getClassInterface()->getLocation();
     }
-    case CXCursor_ObjCSuperClassRef: {
-      ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
-      assert(OID && "clang_getCursorLine(): Missing interface decl");
-      return OID->getSuperClassLoc();
-    }
+    case CXCursor_ObjCSuperClassRef:
+      return getCursorObjCSuperClassRef(C).second;
+
     case CXCursor_ObjCProtocolRef: {
       ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
       assert(OID && "clang_getCursorLine(): Missing protocol decl");
@@ -761,10 +763,8 @@
   if (clang_isReference(C.kind)) {
     switch (C.kind) {
     case CXCursor_ObjCSuperClassRef: {
-      ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
-      assert(OID && "clang_getCursorLine(): Missing interface decl");
-      return CIndexer::createCXString(OID->getSuperClass()->getIdentifier()
-                                      ->getNameStart());
+      ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
+      return CIndexer::createCXString(Super->getIdentifier()->getNameStart());
     }
     case CXCursor_ObjCClassRef: {
       if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND))
diff --git a/tools/CIndex/CXCursor.cpp b/tools/CIndex/CXCursor.cpp
index a8f3eb1..d6c3867 100644
--- a/tools/CIndex/CXCursor.cpp
+++ b/tools/CIndex/CXCursor.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file defines routines for manipulating CXCursors.
+// This file defines routines for manipulating CXCursors. It should be the
+// only file that has internal knowledge of the encoding of the data in
+// CXCursor.
 //
 //===----------------------------------------------------------------------===//
 
@@ -73,6 +75,21 @@
   return MakeCXCursor(GetCursorKind(D), D);
 }
 
+CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, 
+                                         SourceLocation Loc) {
+  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+  CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, 0 } };
+  return C;    
+}
+
+std::pair<ObjCInterfaceDecl *, SourceLocation> 
+cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
+  assert(C.kind == CXCursor_ObjCSuperClassRef);
+  return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
+           SourceLocation::getFromRawEncoding(
+                                      reinterpret_cast<uintptr_t>(C.data[1])));
+}
+
 Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
   return (Decl *)Cursor.data[0];
 }
@@ -82,6 +99,9 @@
 }
 
 Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
+  if (Cursor.kind == CXCursor_ObjCSuperClassRef)
+    return 0;
+
   return (Stmt *)Cursor.data[1];
 }
 
@@ -99,4 +119,4 @@
 bool cxcursor::operator==(CXCursor X, CXCursor Y) {
   return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
          X.data[2] == Y.data[2];
-}
\ No newline at end of file
+}
diff --git a/tools/CIndex/CXCursor.h b/tools/CIndex/CXCursor.h
index da51f13..c2f8de3 100644
--- a/tools/CIndex/CXCursor.h
+++ b/tools/CIndex/CXCursor.h
@@ -15,12 +15,15 @@
 #define LLVM_CLANG_CXCursor_H
 
 #include "clang-c/Index.h"
+#include "clang/Basic/SourceLocation.h"
+#include <utility>
 
 namespace clang {
 
 class Decl;
 class Expr;
 class NamedDecl;
+class ObjCInterfaceDecl;
 class Stmt;
 
 namespace cxcursor {
@@ -29,6 +32,15 @@
 CXCursor MakeCXCursor(CXCursorKind K, clang::Decl *D, clang::Stmt *S);
 CXCursor MakeCXCursor(clang::Decl *D);
 
+/// \brief Create an Objective-C superclass reference at the given location.
+CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, 
+                                     SourceLocation Loc);
+
+/// \brief Unpack an ObjCSuperClassRef cursor into the interface it references
+/// and optionally the location where the reference occurred.
+std::pair<ObjCInterfaceDecl *, SourceLocation> 
+getCursorObjCSuperClassRef(CXCursor C);
+
 Decl *getCursorDecl(CXCursor Cursor);
 Expr *getCursorExpr(CXCursor Cursor);
 Stmt *getCursorStmt(CXCursor Cursor);