]> granicus.if.org Git - clang/commitdiff
Introduce clang_getSpellingLocation() into libclang, to provide the
authorDouglas Gregor <dgregor@apple.com>
Tue, 9 Nov 2010 05:28:47 +0000 (05:28 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 9 Nov 2010 05:28:47 +0000 (05:28 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118492 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang-c/Index.h
test/Index/code-complete-errors.c
tools/c-index-test/c-index-test.c
tools/libclang/CIndex.cpp
tools/libclang/CIndexDiagnostic.cpp
tools/libclang/libclang.darwin.exports
tools/libclang/libclang.exports

index b193600d9d61ac4b0927f5aa95ea258ac8d7699a..f3ba9974eb2cf715399a88e770454326ce2a230c 100644 (file)
@@ -257,8 +257,8 @@ CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
  * \brief Identifies a specific source location within a translation
  * unit.
  *
- * Use clang_getInstantiationLocation() to map a source location to a
- * particular file, line, and column.
+ * Use clang_getInstantiationLocation() or clang_getSpellingLocation()
+ * to map a source location to a particular file, line, and column.
  */
 typedef struct {
   void *ptr_data[2];
@@ -325,6 +325,9 @@ CINDEX_LINKAGE CXSourceRange clang_getRange(CXSourceLocation begin,
  * \brief Retrieve the file, line, column, and offset represented by
  * the given source location.
  *
+ * If the location refers into a macro instantiation, retrieves the
+ * location of the macro instantiation.
+ *
  * \param location the location within a source file that will be decomposed
  * into its parts.
  *
@@ -346,6 +349,34 @@ CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location,
                                                    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 instantiation, return where the
+ * location was originally spelled in the source file.
+ *
+ * \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_getSpellingLocation(CXSourceLocation location,
+                                              CXFile *file,
+                                              unsigned *line,
+                                              unsigned *column,
+                                              unsigned *offset);
+
 /**
  * \brief Retrieve a source location representing the first character within a
  * source range.
index 01c298c01d99214ef185ed1b675621c60b107dea..4fe213eca65e039308dea66e7c0f7c5051b690c0 100644 (file)
@@ -10,7 +10,14 @@ int f(int *ptr1, float *ptr2) {
   return ptr1 != ptr2; // CHECK: code-complete-errors.c:10:15:{10:10-10:14}{10:18-10:22}: warning: comparison of distinct pointer types ('int *' and 'float *')
 }
 
+#define expand_to_binary_function(ret, name, parm1, parm2, code) ret name(parm1, parm2) code
+
+expand_to_binary_function(int, g, int *ip, float *fp, {
+// CHECK: code-complete-errors.c:17:15:{17:12-17:14}{17:18-17:20}: warning: comparison of distinct pointer types ('int *' and 'float *')
+    return ip == fp;
+  })
+
 void g() {  }
 
-// RUN: c-index-test -code-completion-at=%s:13:12 -pedantic %s 2> %t
+// RUN: c-index-test -code-completion-at=%s:19:12 -pedantic %s 2> %t
 // RUN: FileCheck -check-prefix=CHECK %s < %t
index 83782fd0b8b7e6e1220e1ef68b82e6b4cc90a0c0..ae36a8e99696cb048e9eff51e32335dfc06db98a 100644 (file)
@@ -192,13 +192,13 @@ static void PrintCursor(CXCursor Cursor) {
             printf(", ");
           
           Loc = clang_getCursorLocation(Ovl);
-          clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+          clang_getSpellingLocation(Loc, 0, &line, &column, 0);
           printf("%d:%d", line, column);          
         }
         printf("]");
       } else {
         CXSourceLocation Loc = clang_getCursorLocation(Referenced);
-        clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+        clang_getSpellingLocation(Loc, 0, &line, &column, 0);
         printf(":%d:%d", line, column);
       }
     }
@@ -251,7 +251,7 @@ static void PrintCursor(CXCursor Cursor) {
     if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) {
       CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf);
       CXString Name = clang_getCursorSpelling(SpecializationOf);
-      clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+      clang_getSpellingLocation(Loc, 0, &line, &column, 0);
       printf(" [Specialization of %s:%d:%d]", 
              clang_getCString(Name), line, column);
       clang_disposeString(Name);
@@ -263,7 +263,7 @@ static void PrintCursor(CXCursor Cursor) {
       printf(" [Overrides ");
       for (I = 0; I != num_overridden; ++I) {
         CXSourceLocation Loc = clang_getCursorLocation(overridden[I]);
-        clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+        clang_getSpellingLocation(Loc, 0, &line, &column, 0);
         if (I)
           printf(", ");
         printf("@%d:%d", line, column);
@@ -285,7 +285,7 @@ static const char* GetCursorSource(CXCursor Cursor) {
   CXSourceLocation Loc = clang_getCursorLocation(Cursor);
   CXString source;
   CXFile file;
-  clang_getInstantiationLocation(Loc, &file, 0, 0, 0);
+  clang_getSpellingLocation(Loc, &file, 0, 0, 0);
   source = clang_getFileName(file);
   if (!clang_getCString(source)) {
     clang_disposeString(source);
@@ -319,8 +319,8 @@ void PrintDiagnostic(CXDiagnostic Diagnostic) {
   fprintf(stderr, "%s\n", clang_getCString(Msg));
   clang_disposeString(Msg);
 
-  clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic),
-                                 &file, 0, 0, 0);
+  clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
+                            &file, 0, 0, 0);
   if (!file)
     return;
 
@@ -332,9 +332,9 @@ void PrintDiagnostic(CXDiagnostic Diagnostic) {
     CXSourceLocation end = clang_getRangeEnd(range);
     unsigned start_line, start_column, end_line, end_column;
     CXFile start_file, end_file;
-    clang_getInstantiationLocation(start, &start_file, &start_line,
-                                   &start_column, 0);
-    clang_getInstantiationLocation(end, &end_file, &end_line, &end_column, 0);
+    clang_getSpellingLocation(start, &start_file, &start_line,
+                              &start_column, 0);
+    clang_getSpellingLocation(end, &end_file, &end_line, &end_column, 0);
     if (clang_equalLocations(start, end)) {
       /* Insertion. */
       if (start_file == file)
@@ -380,10 +380,10 @@ static void PrintCursorExtent(CXCursor C) {
   CXFile begin_file, end_file;
   unsigned begin_line, begin_column, end_line, end_column;
 
-  clang_getInstantiationLocation(clang_getRangeStart(extent),
-                                 &begin_file, &begin_line, &begin_column, 0);
-  clang_getInstantiationLocation(clang_getRangeEnd(extent),
-                                 &end_file, &end_line, &end_column, 0);
+  clang_getSpellingLocation(clang_getRangeStart(extent),
+                            &begin_file, &begin_line, &begin_column, 0);
+  clang_getSpellingLocation(clang_getRangeEnd(extent),
+                            &end_file, &end_line, &end_column, 0);
   if (!begin_file || !end_file)
     return;
 
@@ -405,7 +405,7 @@ enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor,
   if (!Data->Filter || (Cursor.kind == *(enum CXCursorKind *)Data->Filter)) {
     CXSourceLocation Loc = clang_getCursorLocation(Cursor);
     unsigned line, column;
-    clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+    clang_getSpellingLocation(Loc, 0, &line, &column, 0);
     printf("// %s: %s:%d:%d: ", FileCheckPrefix,
            GetCursorSource(Cursor), line, column);
     PrintCursor(Cursor);
@@ -449,7 +449,7 @@ static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor,
       curColumn++;
 
     Loc = clang_getCursorLocation(Cursor);
-    clang_getInstantiationLocation(Loc, &file, 0, 0, 0);
+    clang_getSpellingLocation(Loc, &file, 0, 0, 0);
 
     source = clang_getFileName(file);
     if (clang_getCString(source)) {
@@ -515,8 +515,8 @@ void InclusionVisitor(CXFile includedFile, CXSourceLocation *includeStack,
   for (i = 0; i < includeStackLen; ++i) {
     CXFile includingFile;
     unsigned line, column;
-    clang_getInstantiationLocation(includeStack[i], &includingFile, &line,
-                                   &column, 0);
+    clang_getSpellingLocation(includeStack[i], &includingFile, &line,
+                              &column, 0);
     fname = clang_getFileName(includingFile);
     printf("  %s:%d:%d\n", clang_getCString(fname), line, column);
     clang_disposeString(fname);
@@ -1228,10 +1228,10 @@ int perform_token_annotation(int argc, const char **argv) {
     case CXToken_Literal: kind = "Literal"; break;
     case CXToken_Comment: kind = "Comment"; break;
     }
-    clang_getInstantiationLocation(clang_getRangeStart(extent),
-                                   0, &start_line, &start_column, 0);
-    clang_getInstantiationLocation(clang_getRangeEnd(extent),
-                                   0, &end_line, &end_column, 0);
+    clang_getSpellingLocation(clang_getRangeStart(extent),
+                              0, &start_line, &start_column, 0);
+    clang_getSpellingLocation(clang_getRangeEnd(extent),
+                              0, &end_line, &end_column, 0);
     printf("%s: \"%s\" ", kind, clang_getCString(spelling));
     PrintExtent(stdout, start_line, start_column, end_line, end_column);
     if (!clang_isInvalid(cursors[i].kind)) {
index 496833c7234d8dd2e037c5436576fe998b3f8445..42617f0ce46c821a5f85faf000fd3381c0a42e3b 100644 (file)
@@ -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,42 @@ 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 = SM.getSpellingLoc(Loc);
+  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 };
index 0766548418ebded2b5c198ab9eb126672ae6aa52..036a28b5387b717ed15e326f4094b2afe02f3fcd 100644 (file)
@@ -64,8 +64,8 @@ CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
     // and source ranges.
     CXFile File;
     unsigned Line, Column;
-    clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic),
-                                   &File, &Line, &Column, 0);
+    clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
+                              &File, &Line, &Column, 0);
     if (File) {
       CXString FName = clang_getFileName(File);
       Out << clang_getCString(FName) << ":" << Line << ":";
@@ -81,11 +81,11 @@ CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
           CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
           
           unsigned StartLine, StartColumn, EndLine, EndColumn;
-          clang_getInstantiationLocation(clang_getRangeStart(Range),
-                                         &StartFile, &StartLine, &StartColumn,
-                                         0);
-          clang_getInstantiationLocation(clang_getRangeEnd(Range),
-                                         &EndFile, &EndLine, &EndColumn, 0);
+          clang_getSpellingLocation(clang_getRangeStart(Range),
+                                    &StartFile, &StartLine, &StartColumn,
+                                    0);
+          clang_getSpellingLocation(clang_getRangeEnd(Range),
+                                    &EndFile, &EndLine, &EndColumn, 0);
           
           if (StartFile != EndFile || StartFile != File)
             continue;
index 7d5ae8b7327e7651caf3e56d125b636303632cb1..09f3cf7d21091a0e7aea32ce6f75ac4510142a27 100644 (file)
@@ -88,6 +88,7 @@ _clang_getRangeEnd
 _clang_getRangeStart
 _clang_getResultType
 _clang_getSpecializedCursorTemplate
+_clang_getSpellingLocation
 _clang_getTemplateCursorKind
 _clang_getTokenExtent
 _clang_getTokenKind
index da7f9c851fb66bc2e59c2aeef6259f7ee44da100..6cbd2c63b720942a962c1664f8eec568abc2ba8c 100644 (file)
@@ -88,6 +88,7 @@ clang_getRangeEnd
 clang_getRangeStart
 clang_getResultType
 clang_getSpecializedCursorTemplate
+clang_getSpellingLocation
 clang_getTemplateCursorKind
 clang_getTokenExtent
 clang_getTokenKind