*/
CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor);
+/**
+ * \brief Retrieve a range for a piece that forms the cursors spelling name.
+ * Most of the times there is only one range for the complete spelling but for
+ * objc methods and objc message expressions, there are multiple pieces for each
+ * selector identifier.
+ *
+ * \param pieceIndex the index of the spelling name piece. If this is greater
+ * than the actual number of pieces, it will return a NULL (invalid) range.
+ *
+ * \param options Reserved.
+ */
+CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor,
+ unsigned pieceIndex,
+ unsigned options);
+
/**
* \brief Retrieve the display name for the entity referenced by this cursor.
*
++test2.implicitProp;
}
+@interface Test3
+-(void)setFoo:(int)x withBar:(int)y;
+@end
+
+void foo3(Test3 *test3) {
+ [test3 setFoo:2 withBar:4];
+}
+
// RUN: c-index-test -cursor-at=%s:4:28 -cursor-at=%s:5:28 %s | FileCheck -check-prefix=CHECK-PROP %s
// CHECK-PROP: ObjCPropertyDecl=foo1:4:26
// CHECK-PROP: ObjCPropertyDecl=foo2:5:27
// RUN: c-index-test -cursor-at=%s:38:6 -cursor-at=%s:40:11 \
// RUN: -cursor-at=%s:50:20 -cursor-at=%s:51:15 -cursor-at=%s:52:20 %s | FileCheck -check-prefix=CHECK-MEMBERREF %s
// CHECK-MEMBERREF: 38:6 MemberRefExpr=x:34:16 SingleRefName=[38:6 - 38:7] RefName=[38:6 - 38:7] Extent=[38:3 - 38:7]
-// CHECK-MEMBERREF: 40:9 MemberRefExpr=name:23:21 Extent=[40:3 - 40:13] Spelling=name
-// CHECK-MEMBERREF: 50:17 MemberRefExpr=implicitProp:45:7 Extent=[50:11 - 50:29] Spelling=implicitProp
-// CHECK-MEMBERREF: 51:9 MemberRefExpr=setImplicitProp::46:8 Extent=[51:3 - 51:21]
-// CHECK-MEMBERREF: 52:11 MemberRefExpr=setImplicitProp::46:8 Extent=[52:5 - 52:23]
+// CHECK-MEMBERREF: 40:9 MemberRefExpr=name:23:21 Extent=[40:3 - 40:13] Spelling=name ([40:9 - 40:13])
+// CHECK-MEMBERREF: 50:17 MemberRefExpr=implicitProp:45:7 Extent=[50:11 - 50:29] Spelling=implicitProp ([50:17 - 50:29])
+// CHECK-MEMBERREF: 51:9 MemberRefExpr=setImplicitProp::46:8 Extent=[51:3 - 51:21] Spelling=setImplicitProp: ([51:9 - 51:21])
+// CHECK-MEMBERREF: 52:11 MemberRefExpr=setImplicitProp::46:8 Extent=[52:5 - 52:23] Spelling=setImplicitProp: ([52:11 - 52:23])
+
+// RUN: c-index-test -cursor-at=%s:56:24 -cursor-at=%s:60:14 \
+// RUN: %s | FileCheck -check-prefix=CHECK-SPELLRANGE %s
+// CHECK-SPELLRANGE: 56:8 ObjCInstanceMethodDecl=setFoo:withBar::56:8 Extent=[56:1 - 56:37] Spelling=setFoo:withBar: ([56:8 - 56:14][56:22 - 56:29])
+// CHECK-SPELLRANGE: 60:3 ObjCMessageExpr=setFoo:withBar::56:8 Extent=[60:3 - 60:29] Spelling=setFoo:withBar: ([60:10 - 60:16][60:19 - 60:26])
if (!begin_file || !end_file)
return;
- printf(" %s=", str);
+ if (str)
+ printf(" %s=", str);
PrintExtent(stdout, begin_line, begin_column, end_line, end_column);
}
PrintCursorExtent(Cursor);
Spelling = clang_getCursorSpelling(Cursor);
cspell = clang_getCString(Spelling);
- if (cspell && strlen(cspell) != 0)
- printf(" Spelling=%s", cspell);
+ if (cspell && strlen(cspell) != 0) {
+ unsigned pieceIndex;
+ CXSourceRange range, extent;
+ extent = clang_getCursorExtent(Cursor);
+ printf(" Spelling=%s (", cspell);
+ for (pieceIndex = 0; ; ++pieceIndex) {
+ range = clang_Cursor_getSpellingNameRange(Cursor, pieceIndex, 0);
+ if (clang_Range_isNull(range))
+ break;
+ PrintRange(range, 0);
+ }
+ printf(")");
+ }
clang_disposeString(Spelling);
if (completionString != NULL) {
printf("\nCompletion string: ");
return createCXString("");
}
+CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
+ unsigned pieceIndex,
+ unsigned options) {
+ if (clang_Cursor_isNull(C))
+ return clang_getNullRange();
+
+ ASTContext &Ctx = getCursorContext(C);
+
+ if (clang_isStatement(C.kind)) {
+ Stmt *S = getCursorStmt(C);
+ if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
+ if (pieceIndex > 0)
+ return clang_getNullRange();
+ return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
+ }
+
+ return clang_getNullRange();
+ }
+
+ if (C.kind == CXCursor_ObjCMessageExpr) {
+ if (ObjCMessageExpr *
+ ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
+ if (pieceIndex >= ME->getNumSelectorLocs())
+ return clang_getNullRange();
+ return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
+ }
+ }
+
+ if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
+ C.kind == CXCursor_ObjCClassMethodDecl) {
+ if (ObjCMethodDecl *
+ MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
+ if (pieceIndex >= MD->getNumSelectorLocs())
+ return clang_getNullRange();
+ return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
+ }
+ }
+
+ // FIXME: A CXCursor_InclusionDirective should give the location of the
+ // filename, but we don't keep track of this.
+
+ // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
+ // but we don't keep track of this.
+
+ // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
+ // but we don't keep track of this.
+
+ // Default handling, give the location of the cursor.
+
+ if (pieceIndex > 0)
+ return clang_getNullRange();
+
+ CXSourceLocation CXLoc = clang_getCursorLocation(C);
+ SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
+ return cxloc::translateSourceRange(Ctx, Loc);
+}
+
CXString clang_getCursorDisplayName(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getCursorSpelling(C);
clang_CXIndex_setGlobalOptions
clang_CXXMethod_isStatic
clang_CXXMethod_isVirtual
+clang_Cursor_getSpellingNameRange
clang_Cursor_getTranslationUnit
clang_Cursor_isNull
clang_IndexAction_create