Eliminate cursor kinds used to express definitions. Instead, provide

CIndex functions that (1) map from a reference or declaration to the
corresponding definition, if available, and (2) determine whether a
given declaration cursor is also a definition. This eliminates a lot
of duplication in the cursor kinds, and maps more closely to the Clang
ASTs.

This is another API + ABI breaker with no deprecation. Yay, progress.

llvm-svn: 93893
This commit is contained in:
Douglas Gregor 2010-01-19 19:34:47 +00:00
parent fefcb1531c
commit 6b8232ff82
11 changed files with 347 additions and 94 deletions

View File

@ -72,17 +72,10 @@ enum CXCursorKind {
CXCursor_ObjCIvarDecl = 15,
CXCursor_ObjCInstanceMethodDecl = 16,
CXCursor_ObjCClassMethodDecl = 17,
CXCursor_LastDecl = 17,
CXCursor_ObjCImplementationDecl = 18,
CXCursor_ObjCCategoryImplDecl = 19,
CXCursor_LastDecl = 19,
/* Definitions */
CXCursor_FirstDefn = 32,
CXCursor_FunctionDefn = 32,
CXCursor_ObjCClassDefn = 33,
CXCursor_ObjCCategoryDefn = 34,
CXCursor_ObjCInstanceMethodDefn = 35,
CXCursor_ObjCClassMethodDefn = 36,
CXCursor_LastDefn = 36,
/* References */
CXCursor_FirstRef = 40, /* Decl references */
CXCursor_ObjCSuperClassRef = 40,
@ -388,7 +381,6 @@ CINDEX_LINKAGE CXString clang_getCursorUSR(CXCursor);
CINDEX_LINKAGE enum CXCursorKind clang_getCursorKind(CXCursor);
CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind);
CINDEX_LINKAGE unsigned clang_isReference(enum CXCursorKind);
CINDEX_LINKAGE unsigned clang_isDefinition(enum CXCursorKind);
CINDEX_LINKAGE unsigned clang_isInvalid(enum CXCursorKind);
CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor);
@ -407,7 +399,8 @@ CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor);
*/
CINDEX_LINKAGE CXSourceLocation clang_getCursorLocation(CXCursor);
/** \brief Retrieve the physical extent of the source construct referenced by
/**
* \brief Retrieve the physical extent of the source construct referenced by
* the given cursor.
*
* The extent of a cursor starts with the file/line/column pointing at the
@ -430,7 +423,43 @@ CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor);
* Othewise, returns the NULL cursor.
*/
CINDEX_LINKAGE CXCursor clang_getCursorReferenced(CXCursor);
/**
* \brief For a cursor that is either a reference to or a declaration
* of some entity, retrieve a cursor that describes the definition of
* that entity.
*
* Some entities can be declared multiple times within a translation
* unit, but only one of those declarations can also be a
* definition. For example, given:
*
* \code
* int f(int, int);
* int g(int x, int y) { return f(x, y); }
* int f(int a, int b) { return a + b; }
* int f(int, int);
* \endcode
*
* there are three declarations of the function "f", but only the
* second one is a definition. The clang_getCursorDefinition()
* function will take any cursor pointing to a declaration of "f"
* (the first or fourth lines of the example) or a cursor referenced
* that uses "f" (the call to "f' inside "g") and will return a
* declaration cursor pointing to the definition (the second "f"
* declaration).
*
* If given a cursor for which there is no corresponding definition,
* e.g., because there is no definition of that entity within this
* translation unit, returns a NULL cursor.
*/
CINDEX_LINKAGE CXCursor clang_getCursorDefinition(CXCursor);
/**
* \brief Determine whether the declaration pointed to by this cursor
* is also a definition of that entity.
*/
CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor);
/* for debug/testing */
CINDEX_LINKAGE const char *clang_getCursorKindSpelling(enum CXCursorKind Kind);
CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor,

View File

@ -572,11 +572,11 @@ CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
break;
case Decl::ObjCImplementation:
Kind = CXCursor_ObjCClassDefn;
Kind = CXCursor_ObjCImplementationDecl;
break;
case Decl::ObjCCategoryImpl:
Kind = CXCursor_ObjCCategoryDefn;
Kind = CXCursor_ObjCCategoryImplDecl;
break;
default:

View File

@ -21,18 +21,18 @@ void function(Foo * arg)
// 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=1 end_line=13 end_col=4} FunctionDecl=function:13:6 (Definition)
// 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=6 end_line=13 end_col=14} FunctionDecl=function:13:6 (Definition)
// 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=18 end_line=13 end_col=18} FunctionDecl=function:13:6 (Definition)
// 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=13 start_col=20 end_line=13 end_col=20} FunctionDecl=function:13:6 (Definition)
// CHECK-scan: {start_line=13 start_col=21 end_line=13 end_col=23} ParmDecl=arg:13:21
// CHECK-scan: {start_line=13 start_col=24 end_line=16 end_col=1} FunctionDefn=function:13:6
// CHECK-scan: {start_line=13 start_col=24 end_line=16 end_col=1} FunctionDecl=function:13:6 (Definition)
// CHECK-scan: {start_line=16 start_col=2 end_line=38 end_col=1} Invalid Cursor => NoDeclFound
// CHECK-load: TestClassDecl.m:10:12: ObjCInterfaceDecl=Foo:10:12 [Extent=10:1:11:4]
// CHECK-load: TestClassDecl.m:13:6: FunctionDefn=function:13:6 [Extent=13:6:16:1]
// CHECK-load: TestClassDecl.m:13:21: ParmDecl=arg:13:21 [Extent=13:21:13:23]
// CHECK-load: TestClassDecl.m:13:6: FunctionDecl=function:13:6 (Definition) [Extent=13:6:16:1]
// CHECK-load: TestClassDecl.m:13:21: ParmDecl=arg:13:21 (Definition) [Extent=13:21:13:23]

View File

@ -16,15 +16,15 @@ void function(Foo * arg)
// 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:8
// 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=10 end_col=4} FunctionDefn=function:10:6
// CHECK-scan: {start_line=10 start_col=1 end_line=10 end_col=4} FunctionDecl=function:10:6 (Definition)
// 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=6 end_line=10 end_col=14} FunctionDecl=function:10:6 (Definition)
// CHECK-scan: {start_line=10 start_col=15 end_line=10 end_col=17} ObjCClassRef=Foo:8:8
// 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=18 end_line=10 end_col=18} FunctionDecl=function:10:6 (Definition)
// 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
// CHECK-scan: {start_line=10 start_col=20 end_line=10 end_col=20} FunctionDecl=function:10:6 (Definition)
// CHECK-scan: {start_line=10 start_col=21 end_line=10 end_col=23} ParmDecl=arg:10:21
// CHECK-scan: {start_line=10 start_col=24 end_line=13 end_col=1} FunctionDefn=function:10:6
// CHECK-scan: {start_line=10 start_col=24 end_line=13 end_col=1} FunctionDecl=function:10:6 (Definition)
// CHECK-scan: {start_line=13 start_col=2 end_line=46 end_col=1} Invalid Cursor => NoDeclFound
@ -41,6 +41,6 @@ void function(Foo * arg)
// CHECK-load: TestClassForwardDecl.m:10:6: FunctionDefn=function:10:6
// CHECK-load: TestClassForwardDecl.m:10:6: FunctionDecl=function:10:6 (Definition)
// CHECK-load: TestClassForwardDecl.m:10:21: ParmDecl=arg:10:21

View File

@ -62,24 +62,24 @@ int main (int argc, const char * argv[]) {
// CHECK: c-index-api-loadTU-test.m:19:12: ObjCClassRef=Foo:4:12 [Extent=19:12:19:14]
// CHECK: c-index-api-loadTU-test.m:20:1: ObjCInstanceMethodDecl=catMethodWithFloat::20:1 [Extent=20:1:20:40]
// CHECK: c-index-api-loadTU-test.m:21:1: ObjCInstanceMethodDecl=floatMethod:21:1 [Extent=21:1:21:22]
// CHECK: c-index-api-loadTU-test.m:24:1: ObjCProtocolDecl=Proto:24:1 [Extent=24:1:26:4]
// CHECK: c-index-api-loadTU-test.m:24:1: ObjCProtocolDecl=Proto:24:1 (Definition) [Extent=24:1:26:4]
// CHECK: c-index-api-loadTU-test.m:25:1: ObjCInstanceMethodDecl=pMethod:25:1 [Extent=25:1:25:10]
// CHECK: c-index-api-loadTU-test.m:28:1: ObjCProtocolDecl=SubP:28:1 [Extent=28:1:30:4]
// CHECK: c-index-api-loadTU-test.m:28:1: ObjCProtocolDecl=SubP:28:1 (Definition) [Extent=28:1:30:4]
// CHECK: c-index-api-loadTU-test.m:28:17: ObjCProtocolRef=Proto:24:1 [Extent=28:17:28:21]
// CHECK: c-index-api-loadTU-test.m:29:1: ObjCInstanceMethodDecl=spMethod:29:1 [Extent=29:1:29:11]
// CHECK: c-index-api-loadTU-test.m:32:12: ObjCInterfaceDecl=Baz:32:12 [Extent=32:1:39:4]
// CHECK: c-index-api-loadTU-test.m:32:18: ObjCSuperClassRef=Bar:13:12 [Extent=32:18:32:20]
// CHECK: c-index-api-loadTU-test.m:32:23: ObjCProtocolRef=SubP:28:1 [Extent=32:23:32:26]
// CHECK: c-index-api-loadTU-test.m:34:9: ObjCIvarDecl=_anIVar:34:9 [Extent=34:9:34:15]
// CHECK: c-index-api-loadTU-test.m:34:9: ObjCIvarDecl=_anIVar:34:9 (Definition) [Extent=34:9:34:15]
// CHECK: c-index-api-loadTU-test.m:37:1: ObjCInstanceMethodDecl=bazMethod:37:1 [Extent=37:1:37:20]
// CHECK: c-index-api-loadTU-test.m:41:1: EnumDecl=:41:1 [Extent=41:1:43:1]
// CHECK: c-index-api-loadTU-test.m:42:3: EnumConstantDecl=someEnum:42:3 [Extent=42:3:42:10]
// CHECK: c-index-api-loadTU-test.m:45:5: FunctionDefn=main:45:5 [Extent=45:5:54:1]
// CHECK: c-index-api-loadTU-test.m:45:15: ParmDecl=argc:45:15 [Extent=45:15:45:18]
// CHECK: c-index-api-loadTU-test.m:45:34: ParmDecl=argv:45:34 [Extent=45:34:45:37]
// CHECK: c-index-api-loadTU-test.m:46:8: VarDecl=bee:46:8 [Extent=46:8:46:10]
// CHECK: c-index-api-loadTU-test.m:47:5: VarDecl=a:47:5 [Extent=47:5:47:17]
// CHECK: c-index-api-loadTU-test.m:48:12: VarDecl=c:48:12 [Extent=48:12:48:25]
// CHECK: c-index-api-loadTU-test.m:49:13: VarDecl=d:49:13 [Extent=49:13:49:13]
// CHECK: c-index-api-loadTU-test.m:41:1: EnumDecl=:41:1 (Definition) [Extent=41:1:43:1]
// CHECK: c-index-api-loadTU-test.m:42:3: EnumConstantDecl=someEnum:42:3 (Definition) [Extent=42:3:42:10]
// CHECK: c-index-api-loadTU-test.m:45:5: FunctionDecl=main:45:5 (Definition) [Extent=45:5:54:1]
// CHECK: c-index-api-loadTU-test.m:45:15: ParmDecl=argc:45:15 (Definition) [Extent=45:15:45:18]
// CHECK: c-index-api-loadTU-test.m:45:34: ParmDecl=argv:45:34 (Definition) [Extent=45:34:45:37]
// CHECK: c-index-api-loadTU-test.m:46:8: VarDecl=bee:46:8 (Definition) [Extent=46:8:46:10]
// CHECK: c-index-api-loadTU-test.m:47:5: VarDecl=a:47:5 (Definition) [Extent=47:5:47:17]
// CHECK: c-index-api-loadTU-test.m:48:12: VarDecl=c:48:12 (Definition) [Extent=48:12:48:25]
// CHECK: c-index-api-loadTU-test.m:49:13: VarDecl=d:49:13 (Definition) [Extent=49:13:49:13]

View File

@ -91,57 +91,57 @@ int main (int argc, const char * argv[]) {
// CHECK: {start_line=41 start_col=3 end_line=41 end_col=10} EnumConstantDecl=someEnum:41:3
// CHECK: {start_line=41 start_col=11 end_line=42 end_col=1} EnumDecl=:40:1
// CHECK: {start_line=42 start_col=2 end_line=43 end_col=1} Invalid Cursor => NoDeclFound
// CHECK: {start_line=44 start_col=1 end_line=44 end_col=3} FunctionDefn=main:44:5
// CHECK: {start_line=44 start_col=1 end_line=44 end_col=3} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=44 start_col=4 end_line=44 end_col=4} Invalid Cursor => NoDeclFound
// CHECK: {start_line=44 start_col=5 end_line=44 end_col=10} FunctionDefn=main:44:5
// CHECK: {start_line=44 start_col=5 end_line=44 end_col=10} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=44 start_col=11 end_line=44 end_col=13} ParmDecl=argc:44:15
// CHECK: {start_line=44 start_col=14 end_line=44 end_col=14} FunctionDefn=main:44:5
// CHECK: {start_line=44 start_col=14 end_line=44 end_col=14} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=44 start_col=15 end_line=44 end_col=18} ParmDecl=argc:44:15
// CHECK: {start_line=44 start_col=19 end_line=44 end_col=26} FunctionDefn=main:44:5
// CHECK: {start_line=44 start_col=19 end_line=44 end_col=26} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=44 start_col=27 end_line=44 end_col=30} ParmDecl=argv:44:34
// CHECK: {start_line=44 start_col=31 end_line=44 end_col=31} FunctionDefn=main:44:5
// CHECK: {start_line=44 start_col=31 end_line=44 end_col=31} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=44 start_col=32 end_line=44 end_col=32} ParmDecl=argv:44:34
// CHECK: {start_line=44 start_col=33 end_line=44 end_col=33} FunctionDefn=main:44:5
// CHECK: {start_line=44 start_col=33 end_line=44 end_col=33} FunctionDecl=main:44:5 (Definition)
// 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=44 start_col=40 end_line=45 end_col=1} FunctionDecl=main:44:5 (Definition)
// 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=5 end_line=45 end_col=5} FunctionDecl=main:44:5 (Definition)
// 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
// CHECK: {start_line=45 start_col=7 end_line=45 end_col=7} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=45 start_col=8 end_line=45 end_col=10} VarDecl=bee:45:8
// CHECK: {start_line=45 start_col=11 end_line=46 end_col=1} FunctionDefn=main:44:5
// CHECK: {start_line=45 start_col=11 end_line=46 end_col=1} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=46 start_col=2 end_line=46 end_col=3} TypedefDecl=id:0:0
// CHECK: {start_line=46 start_col=4 end_line=46 end_col=4} FunctionDefn=main:44:5
// CHECK: {start_line=46 start_col=4 end_line=46 end_col=4} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=46 start_col=5 end_line=46 end_col=8} VarDecl=a:46:5
// CHECK: {start_line=46 start_col=9 end_line=46 end_col=9} ObjCSelectorRef=foo:7:1
// CHECK: {start_line=46 start_col=10 end_line=46 end_col=12} VarRef=bee:45:8
// CHECK: {start_line=46 start_col=13 end_line=46 end_col=17} ObjCSelectorRef=foo:7:1
// CHECK: {start_line=46 start_col=18 end_line=47 end_col=1} FunctionDefn=main:44:5
// CHECK: {start_line=46 start_col=18 end_line=47 end_col=1} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=47 start_col=2 end_line=47 end_col=3} TypedefDecl=id:0:0
// CHECK: {start_line=47 start_col=4 end_line=47 end_col=4} FunctionDefn=main:44:5
// CHECK: {start_line=47 start_col=4 end_line=47 end_col=4} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=47 start_col=5 end_line=47 end_col=5} VarDecl=c:47:12
// CHECK: {start_line=47 start_col=6 end_line=47 end_col=9} ObjCProtocolRef=SubP:27:1
// CHECK: {start_line=47 start_col=10 end_line=47 end_col=10} VarDecl=c:47:12
// CHECK: {start_line=47 start_col=11 end_line=47 end_col=11} FunctionDefn=main:44:5
// CHECK: {start_line=47 start_col=11 end_line=47 end_col=11} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=47 start_col=12 end_line=47 end_col=15} VarDecl=c:47:12
// CHECK: {start_line=47 start_col=16 end_line=47 end_col=25} ObjCSelectorRef=fooC:8:1
// CHECK: {start_line=47 start_col=26 end_line=48 end_col=1} FunctionDefn=main:44:5
// CHECK: {start_line=47 start_col=26 end_line=48 end_col=1} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=48 start_col=2 end_line=48 end_col=3} TypedefDecl=id:0:0
// CHECK: {start_line=48 start_col=4 end_line=48 end_col=4} FunctionDefn=main:44:5
// CHECK: {start_line=48 start_col=4 end_line=48 end_col=4} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=48 start_col=5 end_line=48 end_col=5} VarDecl=d:48:13
// CHECK: {start_line=48 start_col=6 end_line=48 end_col=10} ObjCProtocolRef=Proto:23:1
// CHECK: {start_line=48 start_col=11 end_line=48 end_col=11} VarDecl=d:48:13
// CHECK: {start_line=48 start_col=12 end_line=48 end_col=12} FunctionDefn=main:44:5
// CHECK: {start_line=48 start_col=12 end_line=48 end_col=12} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=48 start_col=13 end_line=48 end_col=13} VarDecl=d:48:13
// CHECK: {start_line=48 start_col=14 end_line=49 end_col=1} FunctionDefn=main:44:5
// CHECK: {start_line=48 start_col=14 end_line=49 end_col=1} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=49 start_col=2 end_line=49 end_col=2} VarRef=d:48:13
// CHECK: {start_line=49 start_col=3 end_line=49 end_col=5} FunctionDefn=main:44:5
// CHECK: {start_line=49 start_col=3 end_line=49 end_col=5} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=49 start_col=6 end_line=49 end_col=6} VarRef=c:47:12
// CHECK: {start_line=49 start_col=7 end_line=50 end_col=1} FunctionDefn=main:44:5
// CHECK: {start_line=49 start_col=7 end_line=50 end_col=1} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=50 start_col=2 end_line=50 end_col=2} ObjCSelectorRef=pMethod:24:1
// CHECK: {start_line=50 start_col=3 end_line=50 end_col=3} VarRef=d:48:13
// CHECK: {start_line=50 start_col=4 end_line=50 end_col=12} ObjCSelectorRef=pMethod:24:1
// CHECK: {start_line=50 start_col=13 end_line=51 end_col=1} FunctionDefn=main:44:5
// CHECK: {start_line=50 start_col=13 end_line=51 end_col=1} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=51 start_col=2 end_line=51 end_col=2} ObjCSelectorRef=catMethodWithFloat::19:1
// CHECK: {start_line=51 start_col=3 end_line=51 end_col=5} VarRef=bee:45:8
// CHECK: {start_line=51 start_col=6 end_line=51 end_col=25} ObjCSelectorRef=catMethodWithFloat::19:1
@ -149,12 +149,12 @@ int main (int argc, const char * argv[]) {
// CHECK: {start_line=51 start_col=27 end_line=51 end_col=29} VarRef=bee:45:8
// CHECK: {start_line=51 start_col=30 end_line=51 end_col=42} ObjCSelectorRef=floatMethod:20:1
// CHECK: {start_line=51 start_col=43 end_line=51 end_col=43} ObjCSelectorRef=catMethodWithFloat::19:1
// CHECK: {start_line=51 start_col=44 end_line=52 end_col=2} FunctionDefn=main:44:5
// CHECK: {start_line=51 start_col=44 end_line=52 end_col=2} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=52 start_col=3 end_line=52 end_col=6} FunctionRef=main:44:5
// CHECK: {start_line=52 start_col=7 end_line=52 end_col=7} FunctionDefn=main:44:5
// CHECK: {start_line=52 start_col=7 end_line=52 end_col=7} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=52 start_col=8 end_line=52 end_col=15} EnumConstantRef=someEnum:41:3
// CHECK: {start_line=52 start_col=16 end_line=52 end_col=32} FunctionDefn=main:44:5
// CHECK: {start_line=52 start_col=16 end_line=52 end_col=32} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=52 start_col=33 end_line=52 end_col=35} VarRef=bee:45:8
// CHECK: {start_line=52 start_col=36 end_line=53 end_col=1} FunctionDefn=main:44:5
// CHECK: {start_line=52 start_col=36 end_line=53 end_col=1} FunctionDecl=main:44:5 (Definition)
// CHECK: {start_line=53 start_col=2 end_line=160 end_col=1} Invalid Cursor => NoDeclFound

View File

@ -24,7 +24,7 @@ struct S {
// CHECK: VarDecl=top_var
// CHECK: FunctionDecl=top_func_decl
// CHECK: ParmDecl=param1
// CHECK: FunctionDefn=top_func_def
// CHECK: FunctionDecl=top_func_def:7:6 (Definition)
// CHECK: ParmDecl=param2
// CHECK: VarDecl=local_var1
// CHECK: VarDecl=for_var

View File

@ -365,13 +365,11 @@ void CDeclVisitor::VisitObjCIvarDecl(ObjCIvarDecl *ND) {
}
void CDeclVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
if (ND->getBody()) {
Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDefn
: CXCursor_ObjCClassMethodDefn, ND);
Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDecl
: CXCursor_ObjCClassMethodDecl, ND);
if (ND->getBody())
VisitDeclContext(dyn_cast<DeclContext>(ND));
} else
Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDecl
: CXCursor_ObjCClassMethodDecl, ND);
}
void CDeclVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *ND) {
@ -772,7 +770,6 @@ const char *clang_getCursorKindSpelling(enum CXCursorKind Kind) {
case CXCursor_UnionDecl: return "UnionDecl";
case CXCursor_ClassDecl: return "ClassDecl";
case CXCursor_FieldDecl: return "FieldDecl";
case CXCursor_FunctionDefn: return "FunctionDefn";
case CXCursor_VarDecl: return "VarDecl";
case CXCursor_ParmDecl: return "ParmDecl";
case CXCursor_ObjCInterfaceDecl: return "ObjCInterfaceDecl";
@ -783,10 +780,8 @@ const char *clang_getCursorKindSpelling(enum CXCursorKind Kind) {
case CXCursor_ObjCIvarRef: return "ObjCIvarRef";
case CXCursor_ObjCInstanceMethodDecl: return "ObjCInstanceMethodDecl";
case CXCursor_ObjCClassMethodDecl: return "ObjCClassMethodDecl";
case CXCursor_ObjCInstanceMethodDefn: return "ObjCInstanceMethodDefn";
case CXCursor_ObjCCategoryDefn: return "ObjCCategoryDefn";
case CXCursor_ObjCClassMethodDefn: return "ObjCClassMethodDefn";
case CXCursor_ObjCClassDefn: return "ObjCClassDefn";
case CXCursor_ObjCImplementationDecl: return "ObjCImplementationDecl";
case CXCursor_ObjCCategoryImplDecl: return "ObjCCategoryImplDecl";
case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef";
case CXCursor_ObjCProtocolRef: return "ObjCProtocolRef";
case CXCursor_ObjCClassRef: return "ObjCClassRef";
@ -878,16 +873,12 @@ unsigned clang_isReference(enum CXCursorKind K) {
return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
}
unsigned clang_isDefinition(enum CXCursorKind K) {
return K >= CXCursor_FirstDefn && K <= CXCursor_LastDefn;
}
CXCursorKind clang_getCursorKind(CXCursor C) {
return C.kind;
}
CXDecl clang_getCursorDecl(CXCursor C) {
if (clang_isDeclaration(C.kind) || clang_isDefinition(C.kind))
if (clang_isDeclaration(C.kind))
return getCursorDecl(C);
if (clang_isReference(C.kind)) {
@ -1008,7 +999,7 @@ CXSourceRange clang_getCursorExtent(CXCursor C) {
}
CXCursor clang_getCursorReferenced(CXCursor C) {
if (clang_isDeclaration(C.kind) || clang_isDefinition(C.kind))
if (clang_isDeclaration(C.kind))
return C;
if (!clang_isReference(C.kind))
@ -1046,6 +1037,238 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
return clang_getNullCursor();
}
CXCursor clang_getCursorDefinition(CXCursor C) {
bool WasReference = false;
if (clang_isReference(C.kind)) {
C = clang_getCursorReferenced(C);
WasReference = true;
}
if (!clang_isDeclaration(C.kind))
return clang_getNullCursor();
Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullCursor();
switch (D->getKind()) {
// Declaration kinds that don't really separate the notions of
// declaration and definition.
case Decl::Namespace:
case Decl::Typedef:
case Decl::TemplateTypeParm:
case Decl::EnumConstant:
case Decl::Field:
case Decl::ObjCIvar:
case Decl::ObjCAtDefsField:
case Decl::ImplicitParam:
case Decl::ParmVar:
case Decl::NonTypeTemplateParm:
case Decl::TemplateTemplateParm:
case Decl::ObjCCategoryImpl:
case Decl::ObjCImplementation:
case Decl::LinkageSpec:
case Decl::ObjCPropertyImpl:
case Decl::FileScopeAsm:
case Decl::StaticAssert:
case Decl::Block:
return C;
// Declaration kinds that don't make any sense here, but are
// nonetheless harmless.
case Decl::TranslationUnit:
case Decl::Template:
case Decl::ObjCContainer:
break;
// Declaration kinds for which the definition is not resolvable.
case Decl::UnresolvedUsingTypename:
case Decl::UnresolvedUsingValue:
break;
case Decl::UsingDirective:
return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace());
case Decl::NamespaceAlias:
return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace());
case Decl::Enum:
case Decl::Record:
case Decl::CXXRecord:
case Decl::ClassTemplateSpecialization:
case Decl::ClassTemplatePartialSpecialization:
if (TagDecl *Def = cast<TagDecl>(D)->getDefinition(D->getASTContext()))
return MakeCXCursor(Def);
return clang_getNullCursor();
case Decl::Function:
case Decl::CXXMethod:
case Decl::CXXConstructor:
case Decl::CXXDestructor:
case Decl::CXXConversion: {
const FunctionDecl *Def = 0;
if (cast<FunctionDecl>(D)->getBody(Def))
return MakeCXCursor(const_cast<FunctionDecl *>(Def));
return clang_getNullCursor();
}
case Decl::Var: {
VarDecl *Var = cast<VarDecl>(D);
// Variables with initializers have definitions.
const VarDecl *Def = 0;
if (Var->getDefinition(Def))
return MakeCXCursor(const_cast<VarDecl *>(Def));
// extern and private_extern variables are not definitions.
if (Var->hasExternalStorage())
return clang_getNullCursor();
// In-line static data members do not have definitions.
if (Var->isStaticDataMember() && !Var->isOutOfLine())
return clang_getNullCursor();
// All other variables are themselves definitions.
return C;
}
case Decl::FunctionTemplate: {
const FunctionDecl *Def = 0;
if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
return MakeCXCursor(Def->getDescribedFunctionTemplate());
return clang_getNullCursor();
}
case Decl::ClassTemplate: {
if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
->getDefinition(D->getASTContext()))
return MakeCXCursor(
cast<CXXRecordDecl>(Def)->getDescribedClassTemplate());
return clang_getNullCursor();
}
case Decl::Using: {
UsingDecl *Using = cast<UsingDecl>(D);
CXCursor Def = clang_getNullCursor();
for (UsingDecl::shadow_iterator S = Using->shadow_begin(),
SEnd = Using->shadow_end();
S != SEnd; ++S) {
if (Def != clang_getNullCursor()) {
// FIXME: We have no way to return multiple results.
return clang_getNullCursor();
}
Def = clang_getCursorDefinition(MakeCXCursor((*S)->getTargetDecl()));
}
return Def;
}
case Decl::UsingShadow:
return clang_getCursorDefinition(
MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl()));
case Decl::ObjCMethod: {
ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
if (Method->isThisDeclarationADefinition())
return C;
// Dig out the method definition in the associated
// @implementation, if we have it.
// FIXME: The ASTs should make finding the definition easier.
if (ObjCInterfaceDecl *Class
= dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
Method->isInstanceMethod()))
if (Def->isThisDeclarationADefinition())
return MakeCXCursor(Def);
return clang_getNullCursor();
}
case Decl::ObjCCategory:
if (ObjCCategoryImplDecl *Impl
= cast<ObjCCategoryDecl>(D)->getImplementation())
return MakeCXCursor(Impl);
return clang_getNullCursor();
case Decl::ObjCProtocol:
if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
return C;
return clang_getNullCursor();
case Decl::ObjCInterface:
// There are two notions of a "definition" for an Objective-C
// class: the interface and its implementation. When we resolved a
// reference to an Objective-C class, produce the @interface as
// the definition; when we were provided with the interface,
// produce the @implementation as the definition.
if (WasReference) {
if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
return C;
} else if (ObjCImplementationDecl *Impl
= cast<ObjCInterfaceDecl>(D)->getImplementation())
return MakeCXCursor(Impl);
return clang_getNullCursor();
case Decl::ObjCProperty:
// FIXME: We don't really know where to find the
// ObjCPropertyImplDecls that implement this property.
return clang_getNullCursor();
case Decl::ObjCCompatibleAlias:
if (ObjCInterfaceDecl *Class
= cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
if (!Class->isForwardDecl())
return MakeCXCursor(Class);
return clang_getNullCursor();
case Decl::ObjCForwardProtocol: {
ObjCForwardProtocolDecl *Forward = cast<ObjCForwardProtocolDecl>(D);
if (Forward->protocol_size() == 1)
return clang_getCursorDefinition(
MakeCXCursor(*Forward->protocol_begin()));
// FIXME: Cannot return multiple definitions.
return clang_getNullCursor();
}
case Decl::ObjCClass: {
ObjCClassDecl *Class = cast<ObjCClassDecl>(D);
if (Class->size() == 1) {
ObjCInterfaceDecl *IFace = Class->begin()->getInterface();
if (!IFace->isForwardDecl())
return MakeCXCursor(IFace);
return clang_getNullCursor();
}
// FIXME: Cannot return multiple definitions.
return clang_getNullCursor();
}
case Decl::Friend:
if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
return clang_getCursorDefinition(MakeCXCursor(Friend));
return clang_getNullCursor();
case Decl::FriendTemplate:
if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
return clang_getCursorDefinition(MakeCXCursor(Friend));
return clang_getNullCursor();
}
return clang_getNullCursor();
}
unsigned clang_isCursorDefinition(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
return clang_getCursorDefinition(C) == C;
}
void clang_getDefinitionSpellingAndExtent(CXCursor C,
const char **startBuf,
const char **endBuf,

View File

@ -13,6 +13,7 @@ _clang_getCompletionChunkKind
_clang_getCompletionChunkText
_clang_getCursor
_clang_getCursorDecl
_clang_getCursorDefinition
_clang_getCursorExtent
_clang_getCursorFromDecl
_clang_getCursorKind
@ -36,8 +37,8 @@ _clang_getFileTime
_clang_getNullCursor
_clang_getNumCompletionChunks
_clang_getTranslationUnitSpelling
_clang_isCursorDefinition
_clang_isDeclaration
_clang_isDefinition
_clang_isInvalid
_clang_isReference
_clang_loadDeclaration

View File

@ -39,17 +39,16 @@ static CXCursorKind GetCursorKind(Decl *D) {
case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
case Decl::Field: return CXCursor_FieldDecl;
case Decl::Function:
return cast<FunctionDecl>(D)->isThisDeclarationADefinition()
? CXCursor_FunctionDefn : CXCursor_FunctionDecl;
return CXCursor_FunctionDecl;
case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryDefn;
case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
case Decl::ObjCClass:
// FIXME
return CXCursor_NotImplemented;
case Decl::ObjCForwardProtocol:
// FIXME
return CXCursor_NotImplemented;
case Decl::ObjCImplementation: return CXCursor_ObjCClassDefn;
case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
case Decl::ObjCMethod:
@ -160,11 +159,8 @@ ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
case CXCursor_ObjCIvarDecl:
case CXCursor_ObjCInstanceMethodDecl:
case CXCursor_ObjCClassMethodDecl:
case CXCursor_FunctionDefn:
case CXCursor_ObjCClassDefn:
case CXCursor_ObjCCategoryDefn:
case CXCursor_ObjCInstanceMethodDefn:
case CXCursor_ObjCClassMethodDefn:
case CXCursor_ObjCImplementationDecl:
case CXCursor_ObjCCategoryImplDecl:
return static_cast<Decl *>(Cursor.data[0])->getASTContext();
case CXCursor_ObjCSuperClassRef:

View File

@ -59,6 +59,9 @@ static void PrintCursor(CXCursor Cursor) {
CXSourceLocation Loc = clang_getCursorLocation(Referenced);
printf(":%d:%d", Loc.line, Loc.column);
}
if (clang_isCursorDefinition(Cursor))
printf(" (Definition)");
}
}
@ -125,7 +128,8 @@ static void FunctionScanVisitor(CXTranslationUnit Unit, CXCursor Cursor,
unsigned startLine, startColumn, endLine, endColumn, curLine, curColumn;
CXCursor Ref;
if (Cursor.kind != CXCursor_FunctionDefn)
if (Cursor.kind != CXCursor_FunctionDecl ||
!clang_isCursorDefinition(Cursor))
return;
clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf,