summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bindings/python/clang/cindex.py120
-rw-r--r--bindings/python/tests/cindex/test_location.py7
-rw-r--r--tools/libclang/CXSourceLocation.cpp3
3 files changed, 104 insertions, 26 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index d72dd14ef9..3f70bba493 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -214,25 +214,45 @@ class _CXString(Structure):
assert isinstance(res, _CXString)
return conf.lib.clang_getCString(res)
+class Location(object):
+ """A Location is a specific kind of source location. A SourceLocation
+ refers to several kinds of locations (e.g. spelling location vs. expansion
+ location)."""
+
+ def __init__(self, file, line, column, offset):
+ self._file = File(file) if file else None
+ self._line = int(line.value)
+ self._column = int(column.value)
+ self._offset = int(offset.value)
+
+
+ @property
+ def file(self):
+ """Get the file represented by this source location."""
+ return self._file
+
+ @property
+ def line(self):
+ """Get the line represented by this source location."""
+ return self._line
+
+ @property
+ def column(self):
+ """Get the column represented by this source location."""
+ return self._column
+
+ @property
+ def offset(self):
+ """Get the file offset represented by this source location."""
+ return self._offset
class SourceLocation(Structure):
"""
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 = None
+ _spelling = None
@staticmethod
def from_position(tu, file, line, column):
@@ -253,24 +273,72 @@ class SourceLocation(Structure):
return conf.lib.clang_getLocationForOffset(tu, file, offset)
@property
+ def expansion(self):
+ """
+ The source location where then entity this object is referring to is
+ expanded.
+ """
+ if not self._expansion:
+ file = c_object_p()
+ line = c_uint()
+ column = c_uint()
+ offset = c_uint()
+ conf.lib.clang_getExpansionLocation(self,
+ byref(file),
+ byref(line),
+ byref(column),
+ byref(offset))
+
+ self._expansion = Location(file, line, column, offset)
+ return self._expansion
+
+ @property
+ def spelling(self):
+ """
+ The source location where then entity this object is referring to is
+ written.
+ """
+ if not self._spelling:
+ file = c_object_p()
+ line = c_uint()
+ column = c_uint()
+ offset = c_uint()
+ conf.lib.clang_getSpellingLocation(self,
+ byref(file),
+ byref(line),
+ byref(column),
+ byref(offset))
+
+ self._spelling = Location(file, line, column, offset)
+ return self._spelling
+
+ @property
def file(self):
- """Get the file represented by this source location."""
- return self._get_instantiation()[0]
+ """Get the file represented by this source location.
+
+ DEPRECATED: use expansion.file."""
+ return self.expansion.file
@property
def line(self):
- """Get the line represented by this source location."""
- return self._get_instantiation()[1]
+ """Get the line represented by this source location.
+
+ DEPRECATED: use expansion.line."""
+ return self.expansion.line
@property
def column(self):
- """Get the column represented by this source location."""
- return self._get_instantiation()[2]
+ """Get the column represented by this source location.
+
+ DEPRECATED: use expansion.column."""
+ return self.expansion.column
@property
def offset(self):
- """Get the file offset represented by this source location."""
- return self._get_instantiation()[3]
+ """Get the file offset represented by this source location.
+
+ DEPRECATED: use expansion.offset."""
+ return self.expansion.offset
def __eq__(self, other):
return conf.lib.clang_equalLocations(self, other)
@@ -1543,8 +1611,7 @@ class Cursor(Structure):
@property
def location(self):
"""
- Return the source location (the starting character) of the entity
- pointed at by the cursor.
+ Return the source locations of the entity pointed at by the cursor.
"""
if not hasattr(self, '_loc'):
self._loc = conf.lib.clang_getCursorLocation(self)
@@ -3692,7 +3759,11 @@ functionList = [
("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)]),
@@ -4154,6 +4225,7 @@ __all__ = [
'FixIt',
'Index',
'LinkageKind',
+ 'Location',
'SourceLocation',
'SourceRange',
'TLSKind',
diff --git a/bindings/python/tests/cindex/test_location.py b/bindings/python/tests/cindex/test_location.py
index 9e9ef487af..d6875330ec 100644
--- a/bindings/python/tests/cindex/test_location.py
+++ b/bindings/python/tests/cindex/test_location.py
@@ -93,3 +93,10 @@ def test_extent():
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.expansion.line == 2
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index 2e0ea4e440..b1637e01ab 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -318,8 +318,7 @@ void clang_getSpellingLocation(CXSourceLocation location,
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;