Make CXCursor's data opaque.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93561 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index c1f05a8..4e7e86a 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -190,7 +190,7 @@
     if (ND->isImplicit())
       return;
 
-    CXCursor C = { CK, ND, 0, 0 };
+    CXCursor C = { CK, { ND, 0, 0 } };
     Callback(Root, C, CData);
   }
 
@@ -291,7 +291,7 @@
     if (ND->getPCHLevel() > MaxPCHLevel)
       return;
 
-    CXCursor C = { CK, ND, 0, 0 };
+    CXCursor C = { CK, { ND, 0, 0 } };
     Callback(CDecl, C, CData);
   }
 public:
@@ -412,14 +412,13 @@
                                             NamedDecl *ND) {
   if (clang_isReference(C.kind)) {
     
-    if (Decl *D = static_cast<Decl*>(C.referringDecl))
+    if (Decl *D = getCursorReferringDecl(C))
       return D->getLocation();
     
     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);
+        NamedDecl *parentDecl = getCursorInterfaceParent(C);
         return parentDecl->getLocation();
       }
       ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
@@ -437,16 +436,14 @@
       return OID->getLocation();
     }
     case CXCursor_ObjCSelectorRef: {
-      ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(
-        static_cast<Stmt *>(C.stmt));
+      ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(getCursorStmt(C));
       assert(OME && "clang_getCursorLine(): Missing message expr");
       return OME->getLeftLoc(); /* FIXME: should be a range */
     }
     case CXCursor_VarRef:
     case CXCursor_FunctionRef:
     case CXCursor_EnumConstantRef: {
-      DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
-        static_cast<Stmt *>(C.stmt));
+      DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(getCursorStmt(C));
       assert(DRE && "clang_getCursorLine(): Missing decl ref expr");
       return DRE->getLocation();
     }
@@ -868,9 +865,8 @@
 
 extern "C" {
 CXString clang_getCursorSpelling(CXCursor C) {
-  assert(C.decl && "CXCursor has null decl");
-  NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
-
+  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
+  assert(ND && "CXCursor has null decl");
   if (clang_isReference(C.kind)) {
     switch (C.kind) {
     case CXCursor_ObjCSuperClassRef: {
@@ -894,8 +890,7 @@
       return CIndexer::createCXString(OID->getIdentifier()->getNameStart());
     }
     case CXCursor_ObjCSelectorRef: {
-      ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(
-        static_cast<Stmt *>(C.stmt));
+      ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(getCursorStmt(C));
       assert(OME && "clang_getCursorLine(): Missing message expr");
       return CIndexer::createCXString(OME->getSelector().getAsString().c_str(),
                                       true);
@@ -903,8 +898,7 @@
     case CXCursor_VarRef:
     case CXCursor_FunctionRef:
     case CXCursor_EnumConstantRef: {
-      DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
-        static_cast<Stmt *>(C.stmt));
+      DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(getCursorStmt(C));
       assert(DRE && "clang_getCursorLine(): Missing decl ref expr");
       return CIndexer::createCXString(DRE->getDecl()->getIdentifier()
                                       ->getNameStart());
@@ -913,7 +907,7 @@
       return CIndexer::createCXString("<not implemented>");
     }
   }
-  return clang_getDeclSpelling(C.decl);
+  return clang_getDeclSpelling(getCursorDecl(C));
 }
 
 const char *clang_getCursorKindSpelling(enum CXCursorKind Kind) {
@@ -993,11 +987,11 @@
     }
     if (ALoc.isNamedRef()) {
       if (isa<ObjCInterfaceDecl>(Dcl)) {
-        CXCursor C = { CXCursor_ObjCClassRef, Dcl, ALoc.getParentDecl(), 0 };
+        CXCursor C = { CXCursor_ObjCClassRef, { Dcl, ALoc.getParentDecl(), 0 }};
         return C;
       }
       if (isa<ObjCProtocolDecl>(Dcl)) {
-        CXCursor C = { CXCursor_ObjCProtocolRef, Dcl, ALoc.getParentDecl(), 0 };
+        CXCursor C = {CXCursor_ObjCProtocolRef, {Dcl, ALoc.getParentDecl(), 0}};
         return C;
       }
     }
@@ -1011,8 +1005,7 @@
 }
 
 unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
-  return X.kind == Y.kind && X.decl == Y.decl && X.stmt == Y.stmt &&
-         X.referringDecl == Y.referringDecl;
+  return X == Y;
 }
 
 CXCursor clang_getCursorFromDecl(CXDecl AnonDecl) {
@@ -1043,24 +1036,24 @@
 
 CXDecl clang_getCursorDecl(CXCursor C) {
   if (clang_isDeclaration(C.kind))
-    return C.decl;
+    return getCursorDecl(C);
 
   if (clang_isReference(C.kind)) {
-    if (C.stmt) {
+    if (getCursorStmt(C)) {
       if (C.kind == CXCursor_ObjCClassRef ||
           C.kind == CXCursor_ObjCProtocolRef)
-        return static_cast<Stmt *>(C.stmt);
+        return getCursorStmt(C);
       else
-        return getDeclFromExpr(static_cast<Stmt *>(C.stmt));
+        return getDeclFromExpr(getCursorStmt(C));
     } else
-      return C.decl;
+      return getCursorDecl(C);
   }
   return 0;
 }
 
 unsigned clang_getCursorLine(CXCursor C) {
-  assert(C.decl && "CXCursor has null decl");
-  NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
+  assert(getCursorDecl(C) && "CXCursor has null decl");
+  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
   SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
 
   SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
@@ -1068,8 +1061,8 @@
 }
   
 unsigned clang_getCursorColumn(CXCursor C) {
-  assert(C.decl && "CXCursor has null decl");
-  NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
+  assert(getCursorDecl(C) && "CXCursor has null decl");
+  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
   SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
   
   SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
@@ -1077,8 +1070,8 @@
 }
 
 const char *clang_getCursorSource(CXCursor C) {
-  assert(C.decl && "CXCursor has null decl");
-  NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
+  assert(getCursorDecl(C) && "CXCursor has null decl");
+  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
   SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
   
   SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
@@ -1100,8 +1093,8 @@
 }
 
 CXFile clang_getCursorSourceFile(CXCursor C) {
-  assert(C.decl && "CXCursor has null decl");
-  NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
+  assert(getCursorDecl(C) && "CXCursor has null decl");
+  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
   SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
   
   return (void *)
@@ -1116,8 +1109,8 @@
                                           unsigned *startColumn,
                                           unsigned *endLine,
                                           unsigned *endColumn) {
-  assert(C.decl && "CXCursor has null decl");
-  NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
+  assert(getCursorDecl(C) && "CXCursor has null decl");
+  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
   FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
   CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
   
diff --git a/tools/CIndex/CXCursor.cpp b/tools/CIndex/CXCursor.cpp
index a7a7dfc..0c72e96 100644
--- a/tools/CIndex/CXCursor.cpp
+++ b/tools/CIndex/CXCursor.cpp
@@ -13,17 +13,46 @@
 
 #include "CXCursor.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
 
 using namespace clang;
 
 CXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D) {
-  CXCursor C = { K, D, 0, 0 };
+  CXCursor C = { K, { D, 0, 0 } };
   return C;  
 }
 
 CXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D, Stmt *S) {
   assert(clang_isReference(K));
-  CXCursor C = { K, D, S, 0 };
+  CXCursor C = { K, { D, S, 0 } };
   return C;  
 }
 
+Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
+  return (Decl *)Cursor.data[0];
+}
+
+Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
+  return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
+}
+
+Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
+  return (Stmt *)Cursor.data[1];
+}
+
+Decl *cxcursor::getCursorReferringDecl(CXCursor Cursor) {
+  return (Decl *)Cursor.data[2];
+}
+
+NamedDecl *cxcursor::getCursorInterfaceParent(CXCursor Cursor) {
+  assert(Cursor.kind == CXCursor_ObjCClassRef);
+  assert(isa<ObjCInterfaceDecl>(getCursorDecl(Cursor)));
+  // FIXME: This is a hack (storing the parent decl in the stmt slot).
+  return static_cast<NamedDecl *>(Cursor.data[1]);
+}
+
+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 f1829f4..be1ac8b 100644
--- a/tools/CIndex/CXCursor.h
+++ b/tools/CIndex/CXCursor.h
@@ -19,6 +19,8 @@
 namespace clang {
 
 class Decl;
+class Expr;
+class NamedDecl;
 class Stmt;
 
 namespace cxcursor {
@@ -26,6 +28,18 @@
 CXCursor MakeCXCursor(CXCursorKind K, clang::Decl *D);  
 CXCursor MakeCXCursor(CXCursorKind K, clang::Decl *D, clang::Stmt *S);
 
+Decl *getCursorDecl(CXCursor Cursor);
+Expr *getCursorExpr(CXCursor Cursor);
+Stmt *getCursorStmt(CXCursor Cursor);
+Decl *getCursorReferringDecl(CXCursor Cursor);
+NamedDecl *getCursorInterfaceParent(CXCursor Cursor);
+  
+bool operator==(CXCursor X, CXCursor Y);
+  
+inline bool operator!=(CXCursor X, CXCursor Y) {
+  return !(X == Y);
+}
+
 }} // end namespace: clang::cxcursor
 
 #endif