// 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
// 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
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]
// 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
{
}
// 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]
// 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
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)
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:
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;
// 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);
}
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;
}
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];
}
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];
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];
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);