frutiger created this revision.

o) Enhance 'CursorLocation' with four additional properties that can

  retrieve spelling location information.

o) Update the implementation to use 'clang_getExpansionLocation'

  instead of the deprecated 'clang_getInstantiationLocation', which
  has been present since 2011.

o) Update the implementation of 'clang_getSpellingLocation' to actually

  obtain spelling location instead of file location.


https://reviews.llvm.org/D37905

Files:
  bindings/python/clang/cindex.py
  bindings/python/tests/cindex/test_location.py
  tools/libclang/CXSourceLocation.cpp

Index: tools/libclang/CXSourceLocation.cpp
===================================================================
--- tools/libclang/CXSourceLocation.cpp
+++ tools/libclang/CXSourceLocation.cpp
@@ -319,7 +319,7 @@
   const SourceManager &SM =
   *static_cast<const SourceManager*>(location.ptr_data[0]);
   // FIXME: This should call SourceManager::getSpellingLoc().
-  SourceLocation SpellLoc = SM.getFileLoc(Loc);
+  SourceLocation SpellLoc = SM.getSpellingLoc(Loc);
   std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
   FileID FID = LocInfo.first;
   unsigned FileOffset = LocInfo.second;
Index: bindings/python/tests/cindex/test_location.py
===================================================================
--- bindings/python/tests/cindex/test_location.py
+++ bindings/python/tests/cindex/test_location.py
@@ -93,3 +93,10 @@
     location3 = SourceLocation.from_position(tu, file, 1, 6)
     range3 = SourceRange.from_locations(location1, location3)
     assert range1 != range3
+
+def test_spelling_location():
+    tu = get_tu('''#define ONE int one
+ONE;''')
+    one = get_cursor(tu, 'one')
+    assert one.location.spelling_line == 1
+    assert one.location.line == 2
Index: bindings/python/clang/cindex.py
===================================================================
--- bindings/python/clang/cindex.py
+++ bindings/python/clang/cindex.py
@@ -217,19 +217,48 @@
     A SourceLocation represents a particular location within a source file.
     """
     _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
-    _data = None
-
-    def _get_instantiation(self):
-        if self._data is None:
-            f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
-            conf.lib.clang_getInstantiationLocation(self, byref(f), byref(l),
-                    byref(c), byref(o))
-            if f:
-                f = File(f)
-            else:
-                f = None
-            self._data = (f, int(l.value), int(c.value), int(o.value))
-        return self._data
+    _expansion_data = None
+    _spelling_data  = None
+
+    def _get_expansion(self):
+        if self._expansion_data is None:
+            expansion_file   = c_object_p()
+            expansion_line   = c_uint()
+            expansion_column = c_uint()
+            expansion_offset = c_uint()
+            conf.lib.clang_getExpansionLocation(self,
+                                                byref(expansion_file),
+                                                byref(expansion_line),
+                                                byref(expansion_column),
+                                                byref(expansion_offset))
+
+            self._expansion_data = {
+                'file':   File(expansion_file) if expansion_file else None,
+                'line':   int(expansion_line.value),
+                'column': int(expansion_column.value),
+                'offset': int(expansion_offset.value),
+            }
+        return self._expansion_data
+
+    def _get_spelling(self):
+        if self._spelling_data is None:
+            spelling_file   = c_object_p()
+            spelling_line   = c_uint()
+            spelling_column = c_uint()
+            spelling_offset = c_uint()
+            conf.lib.clang_getSpellingLocation(self,
+                                               byref(spelling_file),
+                                               byref(spelling_line),
+                                               byref(spelling_column),
+                                               byref(spelling_offset))
+
+            self._spelling_data = {
+                'file':   File(spelling_file) if spelling_file else None,
+                'line':   int(spelling_line.value),
+                'column': int(spelling_column.value),
+                'offset': int(spelling_offset.value),
+            }
+        return self._spelling_data
 
     @staticmethod
     def from_position(tu, file, line, column):
@@ -252,22 +281,42 @@
     @property
     def file(self):
         """Get the file represented by this source location."""
-        return self._get_instantiation()[0]
+        return self._get_expansion()['file']
 
     @property
     def line(self):
         """Get the line represented by this source location."""
-        return self._get_instantiation()[1]
+        return self._get_expansion()['line']
 
     @property
     def column(self):
         """Get the column represented by this source location."""
-        return self._get_instantiation()[2]
+        return self._get_expansion()['column']
 
     @property
     def offset(self):
         """Get the file offset represented by this source location."""
-        return self._get_instantiation()[3]
+        return self._get_expansion()['offset']
+
+    @property
+    def spelling_file(self):
+        """Get the file represented by the spelling of this source location."""
+        return self._get_spelling()['file']
+
+    @property
+    def spelling_line(self):
+        """Get the line represented by the spelling of this source location."""
+        return self._get_spelling()['line']
+
+    @property
+    def spelling_column(self):
+        """Get the column represented by the spelling of this source location."""
+        return self._get_spelling()['column']
+
+    @property
+    def spelling_offset(self):
+        """Get the file offset represented by the spelling of this source location."""
+        return self._get_spelling()['offset']
 
     def __eq__(self, other):
         return conf.lib.clang_equalLocations(self, other)
@@ -3629,7 +3678,11 @@
   ("clang_getInclusions",
    [TranslationUnit, callbacks['translation_unit_includes'], py_object]),
 
-  ("clang_getInstantiationLocation",
+  ("clang_getExpansionLocation",
+   [SourceLocation, POINTER(c_object_p), POINTER(c_uint), POINTER(c_uint),
+    POINTER(c_uint)]),
+
+  ("clang_getSpellingLocation",
    [SourceLocation, POINTER(c_object_p), POINTER(c_uint), POINTER(c_uint),
     POINTER(c_uint)]),
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to