aboutsummaryrefslogtreecommitdiff
path: root/bindings
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-04-11 01:20:11 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-04-11 01:20:11 +0000
commit411d33aa0b0d3bc9b2faec40cd821bdd836094ab (patch)
treead773459e753fb37a1418cf90c351148e0a698c1 /bindings
parent1fd1e288d0f45b86d191d8f53f569e5143f3a18a (diff)
[libclang] Expose record layout info via new libclang functions:
clang_Type_getAlignOf clang_Type_getSizeOf clang_Type_getOffsetOf clang_Cursor_isBitField Patch by Loïc Jaquemet! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179251 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'bindings')
-rw-r--r--bindings/python/clang/cindex.py50
-rw-r--r--bindings/python/tests/cindex/test_type.py63
-rw-r--r--bindings/python/tests/cindex/util.py4
3 files changed, 115 insertions, 2 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 70f4f36a2c..36761bd859 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -1314,6 +1314,18 @@ class Cursor(Structure):
"""
return TokenGroup.get_tokens(self._tu, self.extent)
+ def is_bitfield(self):
+ """
+ Check if the field is a bitfield.
+ """
+ return conf.lib.clang_Cursor_isBitField(self)
+
+ def get_bitfield_width(self):
+ """
+ Retrieve the width of a bitfield.
+ """
+ return conf.lib.clang_getFieldDeclBitWidth(self)
+
@staticmethod
def from_result(res, fn, args):
assert isinstance(res, Cursor)
@@ -1613,6 +1625,24 @@ class Type(Structure):
"""
return conf.lib.clang_getArraySize(self)
+ def get_align(self):
+ """
+ Retrieve the alignment of the record.
+ """
+ return conf.lib.clang_Type_getAlignOf(self)
+
+ def get_size(self):
+ """
+ Retrieve the size of the record.
+ """
+ return conf.lib.clang_Type_getSizeOf(self)
+
+ def get_offset(self, fieldname):
+ """
+ Retrieve the offset of a field in the record.
+ """
+ return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname))
+
def __eq__(self, other):
if type(other) != type(self):
return False
@@ -2623,6 +2653,10 @@ functionList = [
[Type],
c_longlong),
+ ("clang_getFieldDeclBitWidth",
+ [Cursor],
+ c_int),
+
("clang_getCanonicalCursor",
[Cursor],
Cursor,
@@ -3038,6 +3072,22 @@ functionList = [
[Cursor, c_uint],
Cursor,
Cursor.from_result),
+
+ ("clang_Cursor_isBitField",
+ [Cursor],
+ c_long),
+
+ ("clang_Type_getAlignOf",
+ [Type],
+ c_longlong),
+
+ ("clang_Type_getOffsetOf",
+ [Type, c_char_p],
+ c_longlong),
+
+ ("clang_Type_getSizeOf",
+ [Type],
+ c_ulonglong),
]
class LibclangError(Exception):
diff --git a/bindings/python/tests/cindex/test_type.py b/bindings/python/tests/cindex/test_type.py
index 28e4411c77..9bbed5aa94 100644
--- a/bindings/python/tests/cindex/test_type.py
+++ b/bindings/python/tests/cindex/test_type.py
@@ -298,3 +298,66 @@ def test_is_restrict_qualified():
assert isinstance(i.type.is_restrict_qualified(), bool)
assert i.type.is_restrict_qualified()
assert not j.type.is_restrict_qualified()
+
+def test_record_layout():
+ """Ensure Cursor.type.get_size, Cursor.type.get_align and
+ Cursor.type.get_offset works."""
+
+ source ="""
+struct a {
+ long a1;
+ long a2:3;
+ long a3:4;
+ long long a4;
+};
+"""
+ tries=[(['-target','i386-linux-gnu'],(4,16,0,32,35,64)),
+ (['-target','nvptx64-unknown-unknown'],(8,24,0,64,67,128)),
+ (['-target','i386-pc-win32'],(8,16,0,32,35,64)),
+ (['-target','msp430-none-none'],(2,14,0,32,35,48))]
+ for flags, values in tries:
+ align,total,a1,a2,a3,a4 = values
+
+ tu = get_tu(source, flags=flags)
+ teststruct = get_cursor(tu, 'a')
+ fields = list(teststruct.get_children())
+
+ assert teststruct.type.get_align() == align
+ assert teststruct.type.get_size() == total
+ assert teststruct.type.get_offset(fields[0].spelling) == a1
+ assert teststruct.type.get_offset(fields[1].spelling) == a2
+ assert teststruct.type.get_offset(fields[2].spelling) == a3
+ assert teststruct.type.get_offset(fields[3].spelling) == a4
+ assert fields[0].is_bitfield() == False
+ assert fields[1].is_bitfield() == True
+ assert fields[1].get_bitfield_width() == 3
+ assert fields[2].is_bitfield() == True
+ assert fields[2].get_bitfield_width() == 4
+ assert fields[3].is_bitfield() == False
+
+def test_offset():
+ """Ensure Cursor.get_record_field_offset works in anonymous records"""
+ source="""
+struct Test {
+ struct {
+ int bariton;
+ union {
+ int foo;
+ };
+ };
+ int bar;
+};"""
+ tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64)),
+ (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64)),
+ (['-target','i386-pc-win32'],(8,16,0,32,64)),
+ (['-target','msp430-none-none'],(2,14,0,32,64))]
+ for flags, values in tries:
+ align,total,bariton,foo,bar = values
+ tu = get_tu(source)
+ teststruct = get_cursor(tu, 'Test')
+ fields = list(teststruct.get_children())
+ assert teststruct.type.get_offset("bariton") == bariton
+ assert teststruct.type.get_offset("foo") == foo
+ assert teststruct.type.get_offset("bar") == bar
+
+
diff --git a/bindings/python/tests/cindex/util.py b/bindings/python/tests/cindex/util.py
index 2323839306..8614b02ad2 100644
--- a/bindings/python/tests/cindex/util.py
+++ b/bindings/python/tests/cindex/util.py
@@ -3,7 +3,7 @@
from clang.cindex import Cursor
from clang.cindex import TranslationUnit
-def get_tu(source, lang='c', all_warnings=False):
+def get_tu(source, lang='c', all_warnings=False, flags=[]):
"""Obtain a translation unit from source and language.
By default, the translation unit is created from source file "t.<ext>"
@@ -14,8 +14,8 @@ def get_tu(source, lang='c', all_warnings=False):
all_warnings is a convenience argument to enable all compiler warnings.
"""
+ args = list(flags)
name = 't.c'
- args = []
if lang == 'cpp':
name = 't.cpp'
args.append('-std=c++11')