cameron314 created this revision.
cameron314 added a reviewer: rsmith.
cameron314 added a subscriber: cfe-commits.
All the libclang functions for expanding a location, namely
`clang_getExpansionLocation`, `clang_getPresumedLocation`,
`clang_getInstantiationLocation`, and most surprisingly
`clang_getSpellingLocation` return expansion locations, not spelling locations.
As it turns out, there is no way to get a spelling location via libclang. This
patch adds such a function.
Note that there's a FIXME in `clang_getSpellingLocation` about this, but
changing `clang_getSpellingLocation` to actually return a spelling location
would almost certainly break a large body of existing (third-party) code,
mostly in subtle ways. I think it's better to introduce a new function, though
I know it's ugly. But, this is what we've been using for the past year, and
we've gotten quite comfortable with it.
http://reviews.llvm.org/D20125
Files:
include/clang-c/Index.h
tools/libclang/CXSourceLocation.cpp
Index: tools/libclang/CXSourceLocation.cpp
===================================================================
--- tools/libclang/CXSourceLocation.cpp
+++ tools/libclang/CXSourceLocation.cpp
@@ -346,6 +346,42 @@
*offset = FileOffset;
}
+void clang_getRealSpellingLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset) {
+
+ if (!isASTUnitSourceLocation(location)) {
+ CXLoadedDiagnostic::decodeLocation(location, file, line, column, offset);
+ return;
+ }
+
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
+
+ if (!location.ptr_data[0] || Loc.isInvalid())
+ return createNullLocation(file, line, column, offset);
+
+ const SourceManager &SM =
+ *static_cast<const SourceManager*>(location.ptr_data[0]);
+ SourceLocation SpellLoc = SM.getSpellingLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
+ FileID FID = LocInfo.first;
+ unsigned FileOffset = LocInfo.second;
+
+ if (FID.isInvalid())
+ return createNullLocation(file, line, column, offset);
+
+ if (file)
+ *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
+ if (line)
+ *line = SM.getLineNumber(FID, FileOffset);
+ if (column)
+ *column = SM.getColumnNumber(FID, FileOffset);
+ if (offset)
+ *offset = FileOffset;
+}
+
void clang_getFileLocation(CXSourceLocation location,
CXFile *file,
unsigned *line,
Index: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -568,6 +568,36 @@
* \brief Retrieve the file, line, column, and offset represented by
* the given source location.
*
+ * If the location refers into a macro instantiation, return where the
+ * location was originally spelled in the source file (i.e. where the token
+ * text is located). clang_getSpellingLocation() is supposed to do this
+ * but doesn't, hence this function.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the
given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getRealSpellingLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset);
+
+/**
+ * \brief Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
* If the location refers into a macro expansion, return where the macro was
* expanded or where the macro argument was written, if the location points at
* a macro argument.
Index: tools/libclang/CXSourceLocation.cpp
===================================================================
--- tools/libclang/CXSourceLocation.cpp
+++ tools/libclang/CXSourceLocation.cpp
@@ -346,6 +346,42 @@
*offset = FileOffset;
}
+void clang_getRealSpellingLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset) {
+
+ if (!isASTUnitSourceLocation(location)) {
+ CXLoadedDiagnostic::decodeLocation(location, file, line, column, offset);
+ return;
+ }
+
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
+
+ if (!location.ptr_data[0] || Loc.isInvalid())
+ return createNullLocation(file, line, column, offset);
+
+ const SourceManager &SM =
+ *static_cast<const SourceManager*>(location.ptr_data[0]);
+ SourceLocation SpellLoc = SM.getSpellingLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
+ FileID FID = LocInfo.first;
+ unsigned FileOffset = LocInfo.second;
+
+ if (FID.isInvalid())
+ return createNullLocation(file, line, column, offset);
+
+ if (file)
+ *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
+ if (line)
+ *line = SM.getLineNumber(FID, FileOffset);
+ if (column)
+ *column = SM.getColumnNumber(FID, FileOffset);
+ if (offset)
+ *offset = FileOffset;
+}
+
void clang_getFileLocation(CXSourceLocation location,
CXFile *file,
unsigned *line,
Index: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -568,6 +568,36 @@
* \brief Retrieve the file, line, column, and offset represented by
* the given source location.
*
+ * If the location refers into a macro instantiation, return where the
+ * location was originally spelled in the source file (i.e. where the token
+ * text is located). clang_getSpellingLocation() is supposed to do this
+ * but doesn't, hence this function.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getRealSpellingLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset);
+
+/**
+ * \brief Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
* If the location refers into a macro expansion, return where the macro was
* expanded or where the macro argument was written, if the location points at
* a macro argument.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits