diff options
-rw-r--r-- | include/clang-c/Index.h | 65 | ||||
-rw-r--r-- | tools/CIndex/CIndex.cpp | 71 | ||||
-rw-r--r-- | tools/CIndex/CIndex.exports | 5 | ||||
-rw-r--r-- | tools/c-index-test/c-index-test.c | 17 |
4 files changed, 137 insertions, 21 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index b1b763cab5..1086daa123 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -494,6 +494,19 @@ CINDEX_LINKAGE const char *clang_getFileName(CXFile SFile); CINDEX_LINKAGE time_t clang_getFileTime(CXFile SFile); /** + * \brief Retrieve a file handle within the given translation unit. + * + * \param tu the translation unit + * + * \param file_name the name of the file. + * + * \returns the file handle for the named file in the translation unit \p tu, + * or a NULL file handle if the file was not a part of this translation unit. + */ +CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu, + const char *file_name); + +/** * @} */ @@ -535,6 +548,38 @@ typedef struct { } CXSourceRange; /** + * \brief Retrieve a NULL (invalid) source location. + */ +CINDEX_LINKAGE CXSourceLocation clang_getNullLocation(); + +/** + * \determine Determine whether two source locations, which must refer into + * the same translation unit, refer to exactly the same point in the source + * code. + * + * \returns non-zero if the source locations refer to the same location, zero + * if they refer to different locations. + */ +CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1, + CXSourceLocation loc2); + +/** + * \brief Retrieves the source location associated with a given + * file/line/column in a particular translation unit. + */ +CINDEX_LINKAGE CXSourceLocation clang_getLocation(CXTranslationUnit tu, + CXFile file, + unsigned line, + unsigned column); + +/** + * \brief Retrieve a source range given the beginning and ending source + * locations. + */ +CINDEX_LINKAGE CXSourceRange clang_getRange(CXSourceLocation begin, + CXSourceLocation end); + +/** * \brief Retrieve the file, line, and column represented by the * given source location. * @@ -574,13 +619,23 @@ CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range); /* * CXCursor Operations. */ + /** - Usage: clang_getCursor() will translate a source/line/column position - into an AST cursor (to derive semantic information from the source code). + * \brief Map a source location to the cursor that describes the entity at that + * location in the source code. + * + * clang_getCursor() maps an arbitrary source location within a translation + * unit down to the most specific cursor that describes the entity at that + * location. For example, given an expression \c x + y, invoking + * clang_getCursor() with a source location pointing to "x" will return the + * cursor for "x"; similarly for "y". If the cursor points anywhere between + * "x" or "y" (e.g., on the + or the whitespace around it), clang_getCursor() + * will return a cursor referring to the "+" expression. + * + * \returns a cursor representing the entity at the given source location, or + * a NULL cursor if no such entity can be found. */ -CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, - const char *source_name, - unsigned line, unsigned column); +CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, CXSourceLocation); CINDEX_LINKAGE CXCursor clang_getNullCursor(void); diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index 78fdaceb2c..8ce3db63d5 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -134,6 +134,10 @@ static CXSourceRange translateSourceRange(ASTContext &Context, SourceRange R) { return Result; } +static SourceLocation translateSourceLocation(CXSourceLocation L) { + return SourceLocation::getFromRawEncoding(L.int_data); +} + static SourceRange translateSourceRange(CXSourceRange R) { return SourceRange(SourceLocation::getFromRawEncoding(R.begin_int_data), SourceLocation::getFromRawEncoding(R.end_int_data)); @@ -996,6 +1000,42 @@ CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { // CXSourceLocation and CXSourceRange Operations. //===----------------------------------------------------------------------===// +extern "C" { +CXSourceLocation clang_getNullLocation() { + CXSourceLocation Result = { 0, 0 }; + return Result; +} + +unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) { + return loc1.ptr_data == loc2.ptr_data && loc1.int_data == loc2.int_data; +} + +CXSourceLocation clang_getLocation(CXTranslationUnit tu, + CXFile file, + unsigned line, + unsigned column) { + if (!tu) + return clang_getNullLocation(); + + ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); + SourceLocation SLoc + = CXXUnit->getSourceManager().getLocation( + static_cast<const FileEntry *>(file), + line, column); + + return translateSourceLocation(CXXUnit->getASTContext(), SLoc, false); +} + +CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) { + if (begin.ptr_data != end.ptr_data) { + CXSourceRange Result = { 0, 0, 0 }; + return Result; + } + + CXSourceRange Result = { begin.ptr_data, begin.int_data, end.int_data }; + return Result; +} + void clang_getInstantiationLocation(CXSourceLocation location, CXFile *file, unsigned *line, @@ -1066,6 +1106,8 @@ CXSourceLocation clang_getRangeEnd(CXSourceRange range) { return Result; } +} // end: extern "C" + //===----------------------------------------------------------------------===// // CXFile Operations. //===----------------------------------------------------------------------===// @@ -1088,6 +1130,18 @@ time_t clang_getFileTime(CXFile SFile) { FileEntry *FEnt = static_cast<FileEntry *>(SFile); return FEnt->getModificationTime(); } + +CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) { + if (!tu) + return 0; + + ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); + + FileManager &FMgr = CXXUnit->getFileManager(); + const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name)); + return const_cast<FileEntry *>(File); +} + } // end: extern "C" //===----------------------------------------------------------------------===// @@ -1249,20 +1303,13 @@ enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, return CXChildVisit_Recurse; } -CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name, - unsigned line, unsigned column) { - assert(CTUnit && "Passed null CXTranslationUnit"); - ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit); - - FileManager &FMgr = CXXUnit->getFileManager(); - const FileEntry *File = FMgr.getFile(source_name, - source_name+strlen(source_name)); - if (!File) +CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { + if (!TU) return clang_getNullCursor(); - - SourceLocation SLoc = - CXXUnit->getSourceManager().getLocation(File, line, column); + ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); + + SourceLocation SLoc = translateSourceLocation(Loc); CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound); if (SLoc.isValid()) { SourceRange RegionOfInterest(SLoc, diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports index 7151dbe691..ebeab8ec2d 100644 --- a/tools/CIndex/CIndex.exports +++ b/tools/CIndex/CIndex.exports @@ -7,6 +7,7 @@ _clang_disposeIndex _clang_disposeString _clang_disposeTranslationUnit _clang_equalCursors +_clang_equalLocations _clang_getCString _clang_getCompletionChunkCompletionString _clang_getCompletionChunkKind @@ -21,11 +22,15 @@ _clang_getCursorReferenced _clang_getCursorSpelling _clang_getCursorUSR _clang_getDefinitionSpellingAndExtent +_clang_getFile _clang_getFileName _clang_getFileTime _clang_getInstantiationLocation +_clang_getLocation _clang_getNullCursor +_clang_getNullLocation _clang_getNumCompletionChunks +_clang_getRange _clang_getRangeEnd _clang_getRangeStart _clang_getTranslationUnitCursor diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 473773e080..98ed772ec6 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -161,7 +161,9 @@ static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor, clang_getInstantiationLocation(Loc, &file, 0, 0); source = clang_getFileName(file); if (source) { - Ref = clang_getCursor(Data->TU, source, curLine, curColumn); + CXSourceLocation RefLoc + = clang_getLocation(Data->TU, file, curLine, curColumn); + Ref = clang_getCursor(Data->TU, RefLoc); if (Ref.kind == CXCursor_NoDeclFound) { /* Nothing found here; that's fine. */ } else if (Ref.kind != CXCursor_FunctionDecl) { @@ -296,6 +298,7 @@ static int perform_file_scan(const char *ast_file, const char *source_file, FILE *fp; unsigned line; CXCursor prevCursor; + CXFile file; unsigned printed; unsigned start_line, start_col, last_line, last_col; size_t i; @@ -320,6 +323,7 @@ static int perform_file_scan(const char *ast_file, const char *source_file, start_line = last_line = 1; start_col = last_col = 1; + file = clang_getFile(TU, source_file); while (!feof(fp)) { size_t len = 0; int c; @@ -334,7 +338,7 @@ static int perform_file_scan(const char *ast_file, const char *source_file, for (i = 0; i < len ; ++i) { CXCursor cursor; - cursor = clang_getCursor(TU, source_file, line, i+1); + cursor = clang_getCursor(TU, clang_getLocation(TU, file, line, i+1)); if (!clang_equalCursors(cursor, prevCursor) && prevCursor.kind != CXCursor_InvalidFile) { @@ -656,8 +660,13 @@ int inspect_cursor_at(int argc, const char **argv) { } for (Loc = 0; Loc < NumLocations; ++Loc) { - Cursor = clang_getCursor(TU, Locations[Loc].filename, - Locations[Loc].line, Locations[Loc].column); + CXFile file = clang_getFile(TU, Locations[Loc].filename); + if (!file) + continue; + + Cursor = clang_getCursor(TU, + clang_getLocation(TU, file, Locations[Loc].line, + Locations[Loc].column)); PrintCursor(Cursor); printf("\n"); free(Locations[Loc].filename); |