aboutsummaryrefslogtreecommitdiff
path: root/tools/libclang/CIndex.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-11-09 06:24:54 +0000
committerDouglas Gregor <dgregor@apple.com>2010-11-09 06:24:54 +0000
commita9b06d4c246d6c301e3dd1844f5dba669ed9c631 (patch)
tree250b364482b355d61c7306c371105fd26e031519 /tools/libclang/CIndex.cpp
parent27a31fe6fac7eb98ece172bf83af93a3a103f5b4 (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.cpp48
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 };