diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-11-09 06:24:54 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-11-09 06:24:54 +0000 |
commit | a9b06d4c246d6c301e3dd1844f5dba669ed9c631 (patch) | |
tree | 250b364482b355d61c7306c371105fd26e031519 /tools/libclang/CIndex.cpp | |
parent | 27a31fe6fac7eb98ece172bf83af93a3a103f5b4 (diff) |
ntroduce clang_getSpellingLocation() into libclang, to provide the
location where we're spelling a token even within a
macro. clang_getInstantiationLocation() tells where we instantiated
the macro.
I'm still not thrilled with the CXSourceLocation/CXSourceRange APIs,
since they gloss over macro-instantiation information.
Take 2: this time, adjusted tests appropriately and used a "simple"
approach to the spelling location.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118495 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/libclang/CIndex.cpp')
-rw-r--r-- | tools/libclang/CIndex.cpp | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 496833c723..454255516f 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -104,8 +104,9 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM, const CharSourceRange &R) { // We want the last character in this location, so we will adjust the // location accordingly. - // FIXME: How do do this with a macro instantiation location? SourceLocation EndLoc = R.getEnd(); + if (EndLoc.isValid() && EndLoc.isMacroID()) + EndLoc = SM.getSpellingLoc(EndLoc); if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) { unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts); EndLoc = EndLoc.getFileLocWithOffset(Length); @@ -2455,6 +2456,51 @@ void clang_getInstantiationLocation(CXSourceLocation location, *offset = SM.getDecomposedLoc(InstLoc).second; } +void clang_getSpellingLocation(CXSourceLocation location, + CXFile *file, + unsigned *line, + unsigned *column, + unsigned *offset) { + SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); + + if (!location.ptr_data[0] || Loc.isInvalid()) { + if (file) + *file = 0; + if (line) + *line = 0; + if (column) + *column = 0; + if (offset) + *offset = 0; + return; + } + + const SourceManager &SM = + *static_cast<const SourceManager*>(location.ptr_data[0]); + SourceLocation SpellLoc = Loc; + if (SpellLoc.isMacroID()) { + SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc); + if (SimpleSpellingLoc.isFileID() && + SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first)) + SpellLoc = SimpleSpellingLoc; + else + SpellLoc = SM.getInstantiationLoc(SpellLoc); + } + + std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc); + FileID FID = LocInfo.first; + unsigned FileOffset = LocInfo.second; + + if (file) + *file = (void *)SM.getFileEntryForID(FID); + if (line) + *line = SM.getLineNumber(FID, FileOffset); + if (column) + *column = SM.getColumnNumber(FID, FileOffset); + if (offset) + *offset = FileOffset; +} + CXSourceLocation clang_getRangeStart(CXSourceRange range) { CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, range.begin_int_data }; |