[cfe-commits] r93823 - in /cfe/trunk: include/clang-c/Index.h test/Index/c-index-api-loadTU-test.m tools/CIndex/CIndex.cpp tools/CIndex/CIndex.exports tools/c-index-test/c-index-test.c
Douglas Gregor
dgregor at apple.com
Mon Jan 18 16:34:46 PST 2010
Author: dgregor
Date: Mon Jan 18 18:34:46 2010
New Revision: 93823
URL: http://llvm.org/viewvc/llvm-project?rev=93823&view=rev
Log:
Implement clang_getCursorExtent, which provides a source range for the
cursor itself. In particular, for references this returns the source
range of the reference rather than the source range of the thing it
refers to.
Switch c-index-test from clang_getDeclExtent (which will eventually be
deprecated and removed) over to clang_getCursorExtent. The source
ranges we print for references now make sense; fix up the tests
appropriately.
Modified:
cfe/trunk/include/clang-c/Index.h
cfe/trunk/test/Index/c-index-api-loadTU-test.m
cfe/trunk/tools/CIndex/CIndex.cpp
cfe/trunk/tools/CIndex/CIndex.exports
cfe/trunk/tools/c-index-test/c-index-test.c
Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=93823&r1=93822&r2=93823&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Mon Jan 18 18:34:46 2010
@@ -407,6 +407,17 @@
*/
CINDEX_LINKAGE CXSourceLocation clang_getCursorLocation(CXCursor);
+/** \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
+ * first character within the source construct that the cursor refers to and
+ * ends with the last character withinin that source construct. For a
+ * declaration, the extent covers the declaration itself. For a reference,
+ * the extent covers the location of the reference (e.g., where the referenced
+ * entity was actually used).
+ */
+CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor);
/* for debug/testing */
CINDEX_LINKAGE const char *clang_getCursorKindSpelling(enum CXCursorKind Kind);
Modified: cfe/trunk/test/Index/c-index-api-loadTU-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/c-index-api-loadTU-test.m?rev=93823&r1=93822&r2=93823&view=diff
==============================================================================
--- cfe/trunk/test/Index/c-index-api-loadTU-test.m (original)
+++ cfe/trunk/test/Index/c-index-api-loadTU-test.m Mon Jan 18 18:34:46 2010
@@ -57,19 +57,19 @@
// CHECK: c-index-api-loadTU-test.m:8:1: ObjCInstanceMethodDecl=foo:8:1 [Extent=8:1:8:6]
// CHECK: c-index-api-loadTU-test.m:9:1: ObjCClassMethodDecl=fooC:9:1 [Extent=9:1:9:7]
// CHECK: c-index-api-loadTU-test.m:13:12: ObjCInterfaceDecl=Bar:13:1 [Extent=13:1:17:4]
-// CHECK: c-index-api-loadTU-test.m:13:18: ObjCSuperClassRef=Foo:4:1 [Extent=4:1:11:4]
+// CHECK: c-index-api-loadTU-test.m:13:18: ObjCSuperClassRef=Foo:4:1 [Extent=13:18:13:20]
// CHECK: c-index-api-loadTU-test.m:19:12: ObjCCategoryDecl=FooCat:19:12 [Extent=19:1:22:4]
-// CHECK: c-index-api-loadTU-test.m:19:12: ObjCClassRef=Foo:4:1 [Extent=4:1:11:4]
+// CHECK: c-index-api-loadTU-test.m:19:12: ObjCClassRef=Foo:4:1 [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: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:17: ObjCProtocolRef=Proto:24:1 [Extent=24:1:26: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:1 [Extent=32:1:39:4]
-// CHECK: c-index-api-loadTU-test.m:32:18: ObjCSuperClassRef=Bar:13:1 [Extent=13:1:17:4]
-// CHECK: c-index-api-loadTU-test.m:32:23: ObjCProtocolRef=SubP:28:1 [Extent=28:1:30:4]
+// CHECK: c-index-api-loadTU-test.m:32:18: ObjCSuperClassRef=Bar:13:1 [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: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]
Modified: cfe/trunk/tools/CIndex/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=93823&r1=93822&r2=93823&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Mon Jan 18 18:34:46 2010
@@ -130,6 +130,55 @@
return Result;
}
+/// \brief Translate a Clang source range into a CIndex source range.
+static CXSourceRange translateSourceRange(ASTContext &Context,
+ SourceRange R) {
+ if (R.isInvalid()) {
+ CXSourceRange extent = { { 0, 0, 0 }, { 0, 0, 0 } };
+ return extent;
+ }
+
+ // FIXME: This is largely copy-paste from
+ ///TextDiagnosticPrinter::HighlightRange. When it is clear that this is
+ // what we want the two routines should be refactored.
+
+ SourceManager &SM = Context.getSourceManager();
+ SourceLocation Begin = SM.getInstantiationLoc(R.getBegin());
+ SourceLocation End = SM.getInstantiationLoc(R.getEnd());
+
+ // If the End location and the start location are the same and are a macro
+ // location, then the range was something that came from a macro expansion
+ // or _Pragma. If this is an object-like macro, the best we can do is to
+ // get the range. If this is a function-like macro, we'd also like to
+ // get the arguments.
+ if (Begin == End && R.getEnd().isMacroID())
+ End = SM.getInstantiationRange(R.getEnd()).second;
+
+ unsigned StartLineNo = SM.getInstantiationLineNumber(Begin);
+ unsigned EndLineNo = SM.getInstantiationLineNumber(End);
+
+ // Compute the column number of the start. Keep the column based at 1.
+ unsigned StartColNo = SM.getInstantiationColumnNumber(Begin);
+
+ // Compute the column number of the end.
+ unsigned EndColNo = SM.getInstantiationColumnNumber(End);
+ if (EndColNo) {
+ // Offset the end column by 1 so that we point to the last character
+ // in the last token.
+ --EndColNo;
+
+ // Add in the length of the token, so that we cover multi-char tokens.
+ EndColNo += Lexer::MeasureTokenLength(End, SM, Context.getLangOptions());
+ }
+
+ // Package up the line/column data and return to the caller.
+ const FileEntry *BeginFile = SM.getFileEntryForID(SM.getFileID(Begin));
+ const FileEntry *EndFile = SM.getFileEntryForID(SM.getFileID(End));
+ CXSourceRange extent = { { (void *)BeginFile, StartLineNo, StartColNo },
+ { (void *)EndFile, EndLineNo, EndColNo } };
+ return extent;
+}
+
//===----------------------------------------------------------------------===//
// Visitors.
//===----------------------------------------------------------------------===//
@@ -609,57 +658,7 @@
}
CXSourceRange clang_getDeclExtent(CXDecl AnonDecl) {
- assert(AnonDecl && "Passed null CXDecl");
- NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
- SourceManager &SM = ND->getASTContext().getSourceManager();
- SourceRange R = ND->getSourceRange();
-
- SourceLocation Begin = SM.getInstantiationLoc(R.getBegin());
- SourceLocation End = SM.getInstantiationLoc(R.getEnd());
-
- if (!Begin.isValid()) {
- CXSourceRange extent = { { 0, 0, 0 }, { 0, 0, 0 } };
- return extent;
- }
-
- // FIXME: This is largely copy-paste from
- ///TextDiagnosticPrinter::HighlightRange. When it is clear that this is
- // what we want the two routines should be refactored.
-
- // If the End location and the start location are the same and are a macro
- // location, then the range was something that came from a macro expansion
- // or _Pragma. If this is an object-like macro, the best we can do is to
- // get the range. If this is a function-like macro, we'd also like to
- // get the arguments.
- if (Begin == End && R.getEnd().isMacroID())
- End = SM.getInstantiationRange(R.getEnd()).second;
-
- assert(SM.getFileID(Begin) == SM.getFileID(End));
- unsigned StartLineNo = SM.getInstantiationLineNumber(Begin);
- unsigned EndLineNo = SM.getInstantiationLineNumber(End);
-
- // Compute the column number of the start. Keep the column based at 1.
- unsigned StartColNo = SM.getInstantiationColumnNumber(Begin);
-
- // Compute the column number of the end.
- unsigned EndColNo = SM.getInstantiationColumnNumber(End);
- if (EndColNo) {
- // Offset the end column by 1 so that we point to the last character
- // in the last token.
- --EndColNo;
-
- // Add in the length of the token, so that we cover multi-char tokens.
- ASTContext &Ctx = ND->getTranslationUnitDecl()->getASTContext();
- const LangOptions &LOpts = Ctx.getLangOptions();
-
- EndColNo += Lexer::MeasureTokenLength(End, SM, LOpts);
- }
-
- // Package up the line/column data and return to the caller.
- const FileEntry *FEntry = SM.getFileEntryForID(SM.getFileID(Begin));
- CXSourceRange extent = { { (void *)FEntry, StartLineNo, StartColNo },
- { (void *)FEntry, EndLineNo, EndColNo } };
- return extent;
+ return clang_getCursorExtent(clang_getCursorFromDecl(AnonDecl));
}
const char *clang_getDeclSource(CXDecl AnonDecl) {
@@ -961,6 +960,52 @@
Loc = Class->getClassLoc();
return translateSourceLocation(SM, Loc);
}
+
+CXSourceRange clang_getCursorExtent(CXCursor C) {
+ if (clang_isReference(C.kind)) {
+ switch (C.kind) {
+ case CXCursor_ObjCSuperClassRef: {
+ std::pair<ObjCInterfaceDecl *, SourceLocation> P
+ = getCursorObjCSuperClassRef(C);
+ return translateSourceRange(P.first->getASTContext(), P.second);
+ }
+
+ case CXCursor_ObjCProtocolRef: {
+ std::pair<ObjCProtocolDecl *, SourceLocation> P
+ = getCursorObjCProtocolRef(C);
+ return translateSourceRange(P.first->getASTContext(), P.second);
+ }
+
+ case CXCursor_ObjCClassRef: {
+ std::pair<ObjCInterfaceDecl *, SourceLocation> P
+ = getCursorObjCClassRef(C);
+
+ return translateSourceRange(P.first->getASTContext(), P.second);
+ }
+
+ case CXCursor_ObjCSelectorRef:
+ case CXCursor_ObjCIvarRef:
+ case CXCursor_VarRef:
+ case CXCursor_FunctionRef:
+ case CXCursor_EnumConstantRef:
+ case CXCursor_MemberRef:
+ return translateSourceRange(getCursorContext(C),
+ getCursorExpr(C)->getSourceRange());
+
+ default:
+ // FIXME: Need a way to enumerate all non-reference cases.
+ llvm_unreachable("Missed a reference kind");
+ }
+ }
+
+ if (!getCursorDecl(C)) {
+ CXSourceRange empty = { { 0, 0, 0 }, { 0, 0, 0 } };
+ return empty;
+ }
+
+ Decl *D = getCursorDecl(C);
+ return translateSourceRange(D->getASTContext(), D->getSourceRange());
+}
void clang_getDefinitionSpellingAndExtent(CXCursor C,
const char **startBuf,
Modified: cfe/trunk/tools/CIndex/CIndex.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.exports?rev=93823&r1=93822&r2=93823&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.exports (original)
+++ cfe/trunk/tools/CIndex/CIndex.exports Mon Jan 18 18:34:46 2010
@@ -13,6 +13,7 @@
_clang_getCompletionChunkText
_clang_getCursor
_clang_getCursorDecl
+_clang_getCursorExtent
_clang_getCursorFromDecl
_clang_getCursorKind
_clang_getCursorKindSpelling
Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=93823&r1=93822&r2=93823&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Mon Jan 18 18:34:46 2010
@@ -73,11 +73,11 @@
static const char *FileCheckPrefix = "CHECK";
-static void PrintDeclExtent(CXDecl Dcl) {
- CXSourceRange extent;
- if (!Dcl)
+static void PrintCursorExtent(CXCursor C) {
+ CXSourceRange extent = clang_getCursorExtent(C);
+ /* FIXME: Better way to check for empty extents? */
+ if (!extent.begin.file)
return;
- extent = clang_getDeclExtent(Dcl);
printf(" [Extent=%d:%d:%d:%d]", extent.begin.line, extent.begin.column,
extent.end.line, extent.end.column);
}
@@ -89,8 +89,8 @@
if (!source)
source = "<invalid loc>";
printf("// %s: %s:%d:%d: ", FileCheckPrefix, source, Loc.line, Loc.column);
- PrintCursor(Cursor);
- PrintDeclExtent(clang_getCursorDecl(Cursor));
+ PrintCursor(Cursor);
+ PrintCursorExtent(Cursor);
printf("\n");
}
@@ -111,7 +111,7 @@
return;
}
- PrintDeclExtent(D);
+ PrintCursorExtent(Cursor);
printf("\n");
clang_loadDeclaration(D, DeclVisitor, 0);
}
@@ -173,7 +173,7 @@
return;
}
printf("// %s: %s %s", FileCheckPrefix, GetCursorSource(C), USR.Spelling);
- PrintDeclExtent(clang_getCursorDecl(C));
+ PrintCursorExtent(C);
printf("\n");
clang_disposeString(USR);
}
More information about the cfe-commits
mailing list