]> granicus.if.org Git - clang/commitdiff
Give ObjCClassRef cursors a sane representation, which is encapsulated
authorDouglas Gregor <dgregor@apple.com>
Sat, 16 Jan 2010 17:14:40 +0000 (17:14 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 16 Jan 2010 17:14:40 +0000 (17:14 +0000)
in CXCursor.cpp. With this sane representation, fix the class
reference that is part of Objective-C category declarations so that
the cursor's location matches up with the reference, not the class
being referred to.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93640 91177308-0d34-0410-b5e6-96231b3b80d8

test/Index/TestClassDecl.m
test/Index/TestClassForwardDecl.m
test/Index/c-index-api-fn-scan.m
test/Index/c-index-api-loadTU-test.m
test/Index/c-index-getCursor-test.m
tools/CIndex/CIndex.cpp
tools/CIndex/CXCursor.cpp
tools/CIndex/CXCursor.h

index 0ec5c75af577c0f2e6cd6435d77a045fc8424ac6..9737ec213fb42902110e837e8cbe578d663c44af 100644 (file)
@@ -17,14 +17,14 @@ void function(Foo * arg)
 
 // CHECK-scan: {start_line=1 start_col=1 end_line=7 end_col=1} Invalid Cursor => NoDeclFound
 // CHECK-scan: {start_line=8 start_col=1 end_line=8 end_col=7} Invalid Cursor => NotImplemented
-// CHECK-scan: {start_line=8 start_col=8 end_line=8 end_col=10} ObjCClassRef=Foo:8:1
+// CHECK-scan: {start_line=8 start_col=8 end_line=8 end_col=10} ObjCClassRef=Foo:10:1
 // CHECK-scan: {start_line=8 start_col=11 end_line=9 end_col=1} Invalid Cursor => NoDeclFound
 // CHECK-scan: {start_line=10 start_col=1 end_line=11 end_col=4} ObjCInterfaceDecl=Foo:10:1
 // CHECK-scan: {start_line=11 start_col=5 end_line=12 end_col=1} Invalid Cursor => NoDeclFound
 // CHECK-scan: {start_line=13 start_col=1 end_line=13 end_col=4} FunctionDefn=function:13:6
 // CHECK-scan: {start_line=13 start_col=5 end_line=13 end_col=5} Invalid Cursor => NoDeclFound
 // CHECK-scan: {start_line=13 start_col=6 end_line=13 end_col=14} FunctionDefn=function:13:6
-// CHECK-scan: {start_line=13 start_col=15 end_line=13 end_col=17} ObjCClassRef=Foo:13:21
+// CHECK-scan: {start_line=13 start_col=15 end_line=13 end_col=17} ObjCClassRef=Foo:10:1
 // CHECK-scan: {start_line=13 start_col=18 end_line=13 end_col=18} FunctionDefn=function:13:6
 // CHECK-scan: {start_line=13 start_col=19 end_line=13 end_col=19} ParmDecl=arg:13:21
 // CHECK-scan: {start_line=13 start_col=20 end_line=13 end_col=20} FunctionDefn=function:13:6
index 8bb437ca6f50dac2689dd91409f654b6017d0e3d..76c0b6cffa17c252d397756c4b7e1dd726c313fc 100644 (file)
@@ -19,7 +19,7 @@ void function(Foo * arg)
 // CHECK-scan: {start_line=10 start_col=1 end_line=10 end_col=4} FunctionDefn=function:10:6
 // CHECK-scan: {start_line=10 start_col=5 end_line=10 end_col=5} Invalid Cursor => NoDeclFound
 // CHECK-scan: {start_line=10 start_col=6 end_line=10 end_col=14} FunctionDefn=function:10:6
-// CHECK-scan: {start_line=10 start_col=15 end_line=10 end_col=17} ObjCClassRef=Foo:10:21
+// CHECK-scan: {start_line=10 start_col=15 end_line=10 end_col=17} ObjCClassRef=Foo:8:1
 // CHECK-scan: {start_line=10 start_col=18 end_line=10 end_col=18} FunctionDefn=function:10:6
 // CHECK-scan: {start_line=10 start_col=19 end_line=10 end_col=19} ParmDecl=arg:10:21
 // CHECK-scan: {start_line=10 start_col=20 end_line=10 end_col=20} FunctionDefn=function:10:6
index 3db836ffaeb0508c12bca43ac247e49fda7a3375..b0728ec90bc4df2c51b1bd0008d685fe76221e96 100644 (file)
@@ -91,9 +91,9 @@ int main (int argc, const char * argv[]) {
   main(someEnum, (const char **)bee);
 }
 
-// CHECK: c-index-api-fn-scan.m:84:2: ObjCClassRef=Baz:84:8 [Context:Baz]
-// CHECK: c-index-api-fn-scan.m:84:3: ObjCClassRef=Baz:84:8 [Context:Baz]
-// CHECK: c-index-api-fn-scan.m:84:4: ObjCClassRef=Baz:84:8 [Context:Baz]
+// CHECK: c-index-api-fn-scan.m:84:2: ObjCClassRef=Baz:48:1 [Context:Baz]
+// CHECK: c-index-api-fn-scan.m:84:3: ObjCClassRef=Baz:48:1 [Context:Baz]
+// CHECK: c-index-api-fn-scan.m:84:4: ObjCClassRef=Baz:48:1 [Context:Baz]
 // CHECK: c-index-api-fn-scan.m:84:6: VarDecl=bee:84:8 [Context:bee]
 // CHECK: c-index-api-fn-scan.m:84:8: VarDecl=bee:84:8 [Context:bee]
 // CHECK: c-index-api-fn-scan.m:84:9: VarDecl=bee:84:8 [Context:bee]
index 7ab435fa8591026206d3cad76d947bed052efec7..62485430b0220749899bc5738d21547453601091 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -emit-pch -x objective-c %s -o %t.ast
 // RUN: c-index-test -test-load-tu %t.ast all | FileCheck %s
-// XFAIL: *
+
 @interface Foo 
 {
 }
@@ -58,8 +58,8 @@ int main (int argc, const char * argv[]) {
 // CHECK: c-index-api-loadTU-test.m:9:1: ObjCClassMethodDecl=fooC:9:1 [Context=Foo] [Extent=9:1:9:7]
 // CHECK: c-index-api-loadTU-test.m:13:12: ObjCInterfaceDecl=Bar:13:1 [Context=c-index-api-loadTU-test.m] [Extent=13:1:17:4]
 // CHECK: c-index-api-loadTU-test.m:13:18: ObjCSuperClassRef=Foo:4:1 [Context=Bar] [Extent=4:1:11:4]
-// CHECK: c-index-api-loadTU-test.m:19:1: ObjCCategoryDecl=FooCat:19:1 [Context=c-index-api-loadTU-test.m] [Extent=19:1:22:4]
-// CHECK: c-index-api-loadTU-test.m:4:1: ObjCClassRef=Foo:19:1 [Context=FooCat] [Extent=19:1:22:4]
+// CHECK: c-index-api-loadTU-test.m:19:12: ObjCCategoryDecl=FooCat:19:12 [Context=c-index-api-loadTU-test.m] [Extent=19:1:22:4]
+// CHECK: c-index-api-loadTU-test.m:19:12: ObjCClassRef=Foo:4:1 [Context=FooCat] [Extent=4:1:11:4]
 // CHECK: c-index-api-loadTU-test.m:20:1: ObjCInstanceMethodDecl=catMethodWithFloat::20:1 [Context=FooCat] [Extent=20:1:20:40]
 // CHECK: c-index-api-loadTU-test.m:21:1: ObjCInstanceMethodDecl=floatMethod:21:1 [Context=FooCat] [Extent=21:1:21:22]
 // CHECK: c-index-api-loadTU-test.m:24:1: ObjCProtocolDecl=Proto:24:1 [Context=c-index-api-loadTU-test.m] [Extent=24:1:26:4]
index 10f905fa3f8bf9410d6f380c5b02c857117b4d47..7ea996f76c709a1e8213b855acfc8690ab501b53 100644 (file)
@@ -104,7 +104,7 @@ int main (int argc, const char * argv[]) {
 // CHECK: {start_line=44 start_col=33 end_line=44 end_col=33} FunctionDefn=main:44:5
 // CHECK: {start_line=44 start_col=34 end_line=44 end_col=39} ParmDecl=argv:44:34
 // CHECK: {start_line=44 start_col=40 end_line=45 end_col=1} FunctionDefn=main:44:5
-// CHECK: {start_line=45 start_col=2 end_line=45 end_col=4} ObjCClassRef=Baz:45:8
+// CHECK: {start_line=45 start_col=2 end_line=45 end_col=4} ObjCClassRef=Baz:31:1
 // CHECK: {start_line=45 start_col=5 end_line=45 end_col=5} FunctionDefn=main:44:5
 // CHECK: {start_line=45 start_col=6 end_line=45 end_col=6} VarDecl=bee:45:8
 // CHECK: {start_line=45 start_col=7 end_line=45 end_col=7} FunctionDefn=main:44:5
index c08243e79c5ed029fcad5cf6b5525cfb9c088af9..36919f701127489d67b01e16999428ef9a7109ae 100644 (file)
@@ -261,7 +261,9 @@ void CDeclVisitor::VisitFunctionDecl(FunctionDecl *ND) {
 
 void CDeclVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
   // Issue callbacks for the containing class.
-  Call(CXCursor_ObjCClassRef, ND);
+  Callback(CDecl, 
+           MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation()),
+           CData);
   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)
@@ -340,15 +342,8 @@ static SourceLocation getLocationFromCursor(CXCursor C,
       return D->getLocation();
     
     switch (C.kind) {
-    case CXCursor_ObjCClassRef: {
-      if (isa<ObjCInterfaceDecl>(ND)) {
-        NamedDecl *parentDecl = getCursorInterfaceParent(C);
-        return parentDecl->getLocation();
-      }
-      ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
-      assert(OID && "clang_getCursorLine(): Missing category decl");
-      return OID->getClassInterface()->getLocation();
-    }
+    case CXCursor_ObjCClassRef:
+      return getCursorObjCClassRef(C).second;
     case CXCursor_ObjCSuperClassRef:
       return getCursorObjCSuperClassRef(C).second;
     case CXCursor_ObjCProtocolRef:
@@ -768,13 +763,8 @@ CXString clang_getCursorSpelling(CXCursor C) {
       return CIndexer::createCXString(Super->getIdentifier()->getNameStart());
     }
     case CXCursor_ObjCClassRef: {
-      if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND))
-        return CIndexer::createCXString(OID->getIdentifier()->getNameStart());
-
-      ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(ND);
-      assert(OCD && "clang_getCursorLine(): Missing category decl");
-      return CIndexer::createCXString(OCD->getClassInterface()->getIdentifier()
-                            ->getNameStart());
+      ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
+      return CIndexer::createCXString(Class->getIdentifier()->getNameStart());
     }
     case CXCursor_ObjCProtocolRef: {
       ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
@@ -881,10 +871,8 @@ CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
       // Fall through...treat as a decl, not a ref.
     }
     if (ALoc.isNamedRef()) {
-      if (isa<ObjCInterfaceDecl>(Dcl)) {
-        CXCursor C = { CXCursor_ObjCClassRef, { Dcl, ALoc.getParentDecl(), 0 }};
-        return C;
-      }
+      if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(Dcl))
+        return MakeCursorObjCClassRef(Class, ALoc.AsNamedRef().Loc);
       if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(Dcl))
         return MakeCursorObjCProtocolRef(Proto, ALoc.AsNamedRef().Loc);
     }
@@ -931,13 +919,10 @@ CXDecl clang_getCursorDecl(CXCursor C) {
     return getCursorDecl(C);
 
   if (clang_isReference(C.kind)) {
-    if (getCursorStmt(C)) {
-      if (C.kind == CXCursor_ObjCClassRef)
-        return getCursorStmt(C);
-      else
-        return getDeclFromExpr(getCursorStmt(C));
-    } else
-      return getCursorDecl(C);
+    if (getCursorStmt(C))
+      return getDeclFromExpr(getCursorStmt(C));
+
+    return getCursorDecl(C);
   }
   return 0;
 }
index 01d809a8db8126a0cd52cf06b0c4a9e965a1d4ad..8211cb0088907452b523bdb8c80612824a371f8f 100644 (file)
@@ -105,6 +105,21 @@ cxcursor::getCursorObjCProtocolRef(CXCursor C) {
                                       reinterpret_cast<uintptr_t>(C.data[1])));
 }
 
+CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, 
+                                         SourceLocation Loc) {
+  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+  CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, 0 } };
+  return C;    
+}
+
+std::pair<ObjCInterfaceDecl *, SourceLocation> 
+cxcursor::getCursorObjCClassRef(CXCursor C) {
+  assert(C.kind == CXCursor_ObjCClassRef);
+  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];
 }
@@ -115,7 +130,8 @@ Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
 
 Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
   if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
-      Cursor.kind == CXCursor_ObjCProtocolRef)
+      Cursor.kind == CXCursor_ObjCProtocolRef ||
+      Cursor.kind == CXCursor_ObjCClassRef)
     return 0;
 
   return (Stmt *)Cursor.data[1];
@@ -125,13 +141,6 @@ 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];
index 26bbc7d59c81adf931797f0449e4e78fd1483789..ff474edade4587d66d40e52a429a79403c110f14 100644 (file)
@@ -50,11 +50,18 @@ CXCursor MakeCursorObjCProtocolRef(ObjCProtocolDecl *Proto, SourceLocation Loc);
 std::pair<ObjCProtocolDecl *, SourceLocation> 
   getCursorObjCProtocolRef(CXCursor C);
 
+/// \brief Create an Objective-C class reference at the given location.
+CXCursor MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, SourceLocation Loc);
+
+/// \brief Unpack an ObjCClassRef cursor into the class it references
+/// and optionally the location where the reference occurred.
+std::pair<ObjCInterfaceDecl *, SourceLocation> 
+  getCursorObjCClassRef(CXCursor C);
+
 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);