From: Douglas Gregor Date: Sat, 16 Jan 2010 17:14:40 +0000 (+0000) Subject: Give ObjCClassRef cursors a sane representation, which is encapsulated X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1adb082a709f7b588f03672999294e061234b2cf;p=clang Give ObjCClassRef cursors a sane representation, which is encapsulated 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 --- diff --git a/test/Index/TestClassDecl.m b/test/Index/TestClassDecl.m index 0ec5c75af5..9737ec213f 100644 --- a/test/Index/TestClassDecl.m +++ b/test/Index/TestClassDecl.m @@ -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 diff --git a/test/Index/TestClassForwardDecl.m b/test/Index/TestClassForwardDecl.m index 8bb437ca6f..76c0b6cffa 100644 --- a/test/Index/TestClassForwardDecl.m +++ b/test/Index/TestClassForwardDecl.m @@ -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 diff --git a/test/Index/c-index-api-fn-scan.m b/test/Index/c-index-api-fn-scan.m index 3db836ffae..b0728ec90b 100644 --- a/test/Index/c-index-api-fn-scan.m +++ b/test/Index/c-index-api-fn-scan.m @@ -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] diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m index 7ab435fa85..62485430b0 100644 --- a/test/Index/c-index-api-loadTU-test.m +++ b/test/Index/c-index-api-loadTU-test.m @@ -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] diff --git a/test/Index/c-index-getCursor-test.m b/test/Index/c-index-getCursor-test.m index 10f905fa3f..7ea996f76c 100644 --- a/test/Index/c-index-getCursor-test.m +++ b/test/Index/c-index-getCursor-test.m @@ -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 diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index c08243e79c..36919f7011 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -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(ND)) { - NamedDecl *parentDecl = getCursorInterfaceParent(C); - return parentDecl->getLocation(); - } - ObjCCategoryDecl *OID = dyn_cast(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(ND)) - return CIndexer::createCXString(OID->getIdentifier()->getNameStart()); - - ObjCCategoryDecl *OCD = dyn_cast(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(Dcl)) { - CXCursor C = { CXCursor_ObjCClassRef, { Dcl, ALoc.getParentDecl(), 0 }}; - return C; - } + if (ObjCInterfaceDecl *Class = dyn_cast(Dcl)) + return MakeCursorObjCClassRef(Class, ALoc.AsNamedRef().Loc); if (ObjCProtocolDecl *Proto = dyn_cast(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; } diff --git a/tools/CIndex/CXCursor.cpp b/tools/CIndex/CXCursor.cpp index 01d809a8db..8211cb0088 100644 --- a/tools/CIndex/CXCursor.cpp +++ b/tools/CIndex/CXCursor.cpp @@ -105,6 +105,21 @@ cxcursor::getCursorObjCProtocolRef(CXCursor C) { reinterpret_cast(C.data[1]))); } +CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, + SourceLocation Loc) { + void *RawLoc = reinterpret_cast(Loc.getRawEncoding()); + CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, 0 } }; + return C; +} + +std::pair +cxcursor::getCursorObjCClassRef(CXCursor C) { + assert(C.kind == CXCursor_ObjCClassRef); + return std::make_pair(static_cast(C.data[0]), + SourceLocation::getFromRawEncoding( + reinterpret_cast(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(getCursorDecl(Cursor))); - // FIXME: This is a hack (storing the parent decl in the stmt slot). - return static_cast(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]; diff --git a/tools/CIndex/CXCursor.h b/tools/CIndex/CXCursor.h index 26bbc7d59c..ff474edade 100644 --- a/tools/CIndex/CXCursor.h +++ b/tools/CIndex/CXCursor.h @@ -50,11 +50,18 @@ CXCursor MakeCursorObjCProtocolRef(ObjCProtocolDecl *Proto, SourceLocation Loc); std::pair 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 + 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);