Skip to content

Commit d0e2b83

Browse files
author
Thomas Wucher
committed
[libclang/python] Retrieve BinaryOperator::getOpcode and BinaryOperator::getOpcodeStr via libclang and its python interface
1 parent 8b7263b commit d0e2b83

19 files changed

+1655
-771
lines changed

clang/bindings/python/clang/cindex.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,6 +1892,18 @@ def availability(self):
18921892

18931893
return AvailabilityKind.from_id(self._availability)
18941894

1895+
@property
1896+
def binary_operator(self):
1897+
"""
1898+
Retrieves the opcode if this cursor points to a binary operator
1899+
:return:
1900+
"""
1901+
1902+
if not hasattr(self, '_binopcode'):
1903+
self._binopcode = conf.lib.clang_Cursor_getBinaryOpcode(self)
1904+
1905+
return BinaryOperator.from_id(self._binopcode)
1906+
18951907
@property
18961908
def access_specifier(self):
18971909
"""
@@ -2181,6 +2193,60 @@ def from_cursor_result(res, fn, args):
21812193
res._tu = args[0]._tu
21822194
return res
21832195

2196+
class BinaryOperator(BaseEnumeration):
2197+
"""
2198+
Describes the BinaryOperator of a declaration
2199+
"""
2200+
2201+
# The unique kind objects, index by id.
2202+
_kinds = []
2203+
_name_map = None
2204+
2205+
def __nonzero__(self):
2206+
""" Allows checks of the kind ```if cursor.binary_operator:```"""
2207+
return self.value != 0
2208+
2209+
@property
2210+
def is_assignment(self):
2211+
return BinaryOperator.Assign.value <= self.value < BinaryOperator.Comma.value
2212+
2213+
def __repr__(self):
2214+
return 'BinaryOperator.%s' % (self.name,)
2215+
2216+
BinaryOperator.Invalid = BinaryOperator(0)
2217+
BinaryOperator.PtrMemD = BinaryOperator(1)
2218+
BinaryOperator.PtrMemI = BinaryOperator(2)
2219+
BinaryOperator.Mul = BinaryOperator(3)
2220+
BinaryOperator.Div = BinaryOperator(4)
2221+
BinaryOperator.Rem = BinaryOperator(5)
2222+
BinaryOperator.Add = BinaryOperator(6)
2223+
BinaryOperator.Sub = BinaryOperator(7)
2224+
BinaryOperator.Shl = BinaryOperator(8)
2225+
BinaryOperator.Shr = BinaryOperator(9)
2226+
BinaryOperator.Cmp = BinaryOperator(10)
2227+
BinaryOperator.LT = BinaryOperator(11)
2228+
BinaryOperator.GT = BinaryOperator(12)
2229+
BinaryOperator.LE = BinaryOperator(13)
2230+
BinaryOperator.GE = BinaryOperator(14)
2231+
BinaryOperator.EQ = BinaryOperator(15)
2232+
BinaryOperator.NE = BinaryOperator(16)
2233+
BinaryOperator.And = BinaryOperator(17)
2234+
BinaryOperator.Xor = BinaryOperator(18)
2235+
BinaryOperator.Or = BinaryOperator(19)
2236+
BinaryOperator.LAnd = BinaryOperator(20)
2237+
BinaryOperator.LOr = BinaryOperator(21)
2238+
BinaryOperator.Assign = BinaryOperator(22)
2239+
BinaryOperator.MulAssign = BinaryOperator(23)
2240+
BinaryOperator.DivAssign = BinaryOperator(24)
2241+
BinaryOperator.RemAssign = BinaryOperator(25)
2242+
BinaryOperator.AddAssign = BinaryOperator(26)
2243+
BinaryOperator.SubAssign = BinaryOperator(27)
2244+
BinaryOperator.ShlAssign = BinaryOperator(28)
2245+
BinaryOperator.ShrAssign = BinaryOperator(29)
2246+
BinaryOperator.AndAssign = BinaryOperator(30)
2247+
BinaryOperator.XorAssign = BinaryOperator(31)
2248+
BinaryOperator.OrAssign = BinaryOperator(32)
2249+
BinaryOperator.Comma = BinaryOperator(33)
21842250

21852251
class StorageClass:
21862252
"""

clang/bindings/python/tests/cindex/test_cursor.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from clang.cindex import TemplateArgumentKind
1414
from clang.cindex import TranslationUnit
1515
from clang.cindex import TypeKind
16+
from clang.cindex import BinaryOperator
1617
from .util import get_cursor
1718
from .util import get_cursors
1819
from .util import get_tu
@@ -54,6 +55,64 @@ class C {
5455
void foo<-7, float, true>();
5556
"""
5657

58+
kBinops = """\
59+
struct C {
60+
int m;
61+
};
62+
63+
void func(void){
64+
int a, b;
65+
int C::* p = &C::
66+
67+
C c;
68+
c.*p;
69+
70+
C* pc;
71+
pc->*p;
72+
73+
a * b;
74+
a / b;
75+
a % b;
76+
a + b;
77+
a - b;
78+
79+
a << b;
80+
a >> b;
81+
82+
a < b;
83+
a > b;
84+
85+
a <= b;
86+
a >= b;
87+
a == b;
88+
a != b;
89+
90+
a & b;
91+
a ^ b;
92+
a | b;
93+
94+
a && b;
95+
a || b;
96+
97+
a = b;
98+
99+
a *= b;
100+
a /= b;
101+
a %= b;
102+
a += b;
103+
a -= b;
104+
105+
a <<= b;
106+
a >>= b;
107+
108+
a &= b;
109+
a ^= b;
110+
a |= b;
111+
a , b;
112+
113+
}
114+
"""
115+
57116

58117
class TestCursor(unittest.TestCase):
59118
def test_get_children(self):
@@ -695,3 +754,48 @@ def test_mangled_name(self):
695754
self.assertIn(
696755
foo.mangled_name, ("_Z3fooii", "__Z3fooii", "?foo@@YAHHH", "?foo@@YAHHH@Z")
697756
)
757+
758+
def test_binop(self):
759+
tu = get_tu(kBinops, lang="cpp")
760+
761+
operators = {
762+
# not exposed yet
763+
# ".*" : BinaryOperator.PtrMemD,
764+
"->*": BinaryOperator.PtrMemI,
765+
"*": BinaryOperator.Mul,
766+
"/": BinaryOperator.Div,
767+
"%": BinaryOperator.Rem,
768+
"+": BinaryOperator.Add,
769+
"-": BinaryOperator.Sub,
770+
"<<": BinaryOperator.Shl,
771+
">>": BinaryOperator.Shr,
772+
# tests do not run in C++2a mode so this operator is not available
773+
# "<=>" : BinaryOperator.Cmp,
774+
"<": BinaryOperator.LT,
775+
">": BinaryOperator.GT,
776+
"<=": BinaryOperator.LE,
777+
">=": BinaryOperator.GE,
778+
"==": BinaryOperator.EQ,
779+
"!=": BinaryOperator.NE,
780+
"&": BinaryOperator.And,
781+
"^": BinaryOperator.Xor,
782+
"|": BinaryOperator.Or,
783+
"&&": BinaryOperator.LAnd,
784+
"||": BinaryOperator.LOr,
785+
"=": BinaryOperator.Assign,
786+
"*=": BinaryOperator.MulAssign,
787+
"/=": BinaryOperator.DivAssign,
788+
"%=": BinaryOperator.RemAssign,
789+
"+=": BinaryOperator.AddAssign,
790+
"-=": BinaryOperator.SubAssign,
791+
"<<=": BinaryOperator.ShlAssign,
792+
">>=": BinaryOperator.ShrAssign,
793+
"&=": BinaryOperator.AndAssign,
794+
"^=": BinaryOperator.XorAssign,
795+
"|=": BinaryOperator.OrAssign,
796+
",": BinaryOperator.Comma,
797+
}
798+
799+
for op, typ in operators.items():
800+
c = get_cursor(tu, op)
801+
assert c.binary_operator == typ

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,8 @@ Python Binding Changes
12891289
- Exposed `CXRewriter` API as `class Rewriter`.
12901290
- Add some missing kinds from Index.h (CursorKind: 149-156, 272-320, 420-437.
12911291
TemplateArgumentKind: 5-9. TypeKind: 161-175 and 178).
1292+
- Add support for retrieving binary operator information through
1293+
Cursor.binary_operator().
12921294

12931295
OpenMP Support
12941296
--------------

clang/include/clang-c/Index.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3750,6 +3750,59 @@ enum CX_StorageClass {
37503750
CX_SC_Register
37513751
};
37523752

3753+
/**
3754+
* Represents a specific kind of binary operator which can appear at a cursor.
3755+
*/
3756+
enum CX_BinaryOperatorKind {
3757+
CX_BO_Invalid = 0,
3758+
CX_BO_PtrMemD = 1,
3759+
CX_BO_PtrMemI = 2,
3760+
CX_BO_Mul = 3,
3761+
CX_BO_Div = 4,
3762+
CX_BO_Rem = 5,
3763+
CX_BO_Add = 6,
3764+
CX_BO_Sub = 7,
3765+
CX_BO_Shl = 8,
3766+
CX_BO_Shr = 9,
3767+
CX_BO_Cmp = 10,
3768+
CX_BO_LT = 11,
3769+
CX_BO_GT = 12,
3770+
CX_BO_LE = 13,
3771+
CX_BO_GE = 14,
3772+
CX_BO_EQ = 15,
3773+
CX_BO_NE = 16,
3774+
CX_BO_And = 17,
3775+
CX_BO_Xor = 18,
3776+
CX_BO_Or = 19,
3777+
CX_BO_LAnd = 20,
3778+
CX_BO_LOr = 21,
3779+
CX_BO_Assign = 22,
3780+
CX_BO_MulAssign = 23,
3781+
CX_BO_DivAssign = 24,
3782+
CX_BO_RemAssign = 25,
3783+
CX_BO_AddAssign = 26,
3784+
CX_BO_SubAssign = 27,
3785+
CX_BO_ShlAssign = 28,
3786+
CX_BO_ShrAssign = 29,
3787+
CX_BO_AndAssign = 30,
3788+
CX_BO_XorAssign = 31,
3789+
CX_BO_OrAssign = 32,
3790+
CX_BO_Comma = 33,
3791+
CX_BO_LAST = CX_BO_Comma
3792+
};
3793+
3794+
/**
3795+
* \brief Returns the operator code for the binary operator.
3796+
*/
3797+
CINDEX_LINKAGE enum CX_BinaryOperatorKind
3798+
clang_Cursor_getBinaryOpcode(CXCursor C);
3799+
3800+
/**
3801+
* \brief Returns a string containing the spelling of the binary operator.
3802+
*/
3803+
CINDEX_LINKAGE CXString
3804+
clang_Cursor_getBinaryOpcodeStr(enum CX_BinaryOperatorKind Op);
3805+
37533806
/**
37543807
* Returns the storage class for a function or variable declaration.
37553808
*

clang/test/Index/binop.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// RUN: c-index-test -test-print-binops %s | FileCheck %s
2+
3+
struct C {
4+
int m;
5+
};
6+
7+
void func(void) {
8+
#pragma clang diagnostic push
9+
#pragma clang diagnostic ignored "-Wunused-value"
10+
int a, b;
11+
int C::*p = &C::m;
12+
13+
C c;
14+
c.*p;
15+
16+
C *pc;
17+
pc->*p;
18+
19+
a *b;
20+
a / b;
21+
a % b;
22+
a + b;
23+
a - b;
24+
25+
a << b;
26+
a >> b;
27+
28+
a < b;
29+
a > b;
30+
31+
a <= b;
32+
a >= b;
33+
a == b;
34+
a != b;
35+
36+
a &b;
37+
a ^ b;
38+
a | b;
39+
40+
a &&b;
41+
a || b;
42+
43+
a = b;
44+
45+
a *= b;
46+
a /= b;
47+
a %= b;
48+
a += b;
49+
a -= b;
50+
51+
a <<= b;
52+
a >>= b;
53+
54+
a &= b;
55+
a ^= b;
56+
a |= b;
57+
a, b;
58+
#pragma clang diagnostic pop
59+
}
60+
61+
// CHECK: BinaryOperator=.* BinOp=.* 1
62+
// CHECK: BinaryOperator=->* BinOp=->* 2
63+
// CHECK: BinaryOperator=* BinOp=* 3
64+
// CHECK: BinaryOperator=/ BinOp=/ 4
65+
// CHECK: BinaryOperator=% BinOp=% 5
66+
// CHECK: BinaryOperator=+ BinOp=+ 6
67+
// CHECK: BinaryOperator=- BinOp=- 7
68+
// CHECK: BinaryOperator=<< BinOp=<< 8
69+
// CHECK: BinaryOperator=>> BinOp=>> 9
70+
// CHECK: BinaryOperator=< BinOp=< 11
71+
// CHECK: BinaryOperator=> BinOp=> 12
72+
// CHECK: BinaryOperator=<= BinOp=<= 13
73+
// CHECK: BinaryOperator=>= BinOp=>= 14
74+
// CHECK: BinaryOperator=== BinOp=== 15
75+
// CHECK: BinaryOperator=!= BinOp=!= 16
76+
// CHECK: BinaryOperator=& BinOp=& 17
77+
// CHECK: BinaryOperator=^ BinOp=^ 18
78+
// CHECK: BinaryOperator=| BinOp=| 19
79+
// CHECK: BinaryOperator=&& BinOp=&& 20
80+
// CHECK: BinaryOperator=|| BinOp=|| 21
81+
// CHECK: BinaryOperator== BinOp== 22
82+
// CHECK: CompoundAssignOperator=*= BinOp=*= 23
83+
// CHECK: CompoundAssignOperator=/= BinOp=/= 24
84+
// CHECK: CompoundAssignOperator=%= BinOp=%= 25
85+
// CHECK: CompoundAssignOperator=+= BinOp=+= 26
86+
// CHECK: CompoundAssignOperator=-= BinOp=-= 27
87+
// CHECK: CompoundAssignOperator=<<= BinOp=<<= 28
88+
// CHECK: CompoundAssignOperator=>>= BinOp=>>= 29
89+
// CHECK: CompoundAssignOperator=&= BinOp=&= 30
90+
// CHECK: CompoundAssignOperator=^= BinOp=^= 31
91+
// CHECK: CompoundAssignOperator=|= BinOp=|= 32
92+
// CHECK: BinaryOperator=, BinOp=, 33

clang/test/Index/blocks.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@ void test() {
2323
// CHECK: blocks.c:9:18: TypeRef=struct foo:4:8 Extent=[9:18 - 9:21]
2424
// CHECK: blocks.c:9:28: CompoundStmt= Extent=[9:28 - 9:58]
2525
// CHECK: blocks.c:9:30: ReturnStmt= Extent=[9:30 - 9:55]
26-
// CHECK: blocks.c:9:37: BinaryOperator= Extent=[9:37 - 9:55]
26+
// CHECK: blocks.c:9:37: BinaryOperator=+ Extent=[9:37 - 9:55]
2727
// CHECK: blocks.c:9:37: CStyleCastExpr= Extent=[9:37 - 9:51]
2828
// CHECK: blocks.c:9:38: TypeRef=int_t:3:13 Extent=[9:38 - 9:43]
2929
// CHECK: blocks.c:9:50: MemberRefExpr=x:4:19 SingleRefName=[9:50 - 9:51] RefName=[9:50 - 9:51] Extent=[9:45 - 9:51]
3030
// CHECK: blocks.c:9:45: DeclRefExpr=foo:9:23 Extent=[9:45 - 9:48]
3131
// CHECK: blocks.c:9:54: DeclRefExpr=i:8:11 Extent=[9:54 - 9:55]
3232
// CHECK: blocks.c:9:59: UnaryOperator= Extent=[9:59 - 9:64]
3333
// CHECK: blocks.c:9:60: DeclRefExpr=_foo:7:21 Extent=[9:60 - 9:64]
34-

clang/test/Index/c-index-api-loadTU-test.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ @interface TestAttributes()
130130
// CHECK: c-index-api-loadTU-test.m:50:13: VarDecl=d:50:13 (Definition) Extent=[50:2 - 50:14]
131131
// CHECK: c-index-api-loadTU-test.m:50:2: TypeRef=id:0:0 Extent=[50:2 - 50:4]
132132
// CHECK: c-index-api-loadTU-test.m:50:6: ObjCProtocolRef=Proto:25:11 Extent=[50:6 - 50:11]
133-
// CHECK: c-index-api-loadTU-test.m:51:2: BinaryOperator= Extent=[51:2 - 51:7]
133+
// CHECK: c-index-api-loadTU-test.m:51:2: BinaryOperator== Extent=[51:2 - 51:7]
134134
// CHECK: c-index-api-loadTU-test.m:51:2: DeclRefExpr=d:50:13 Extent=[51:2 - 51:3]
135135
// CHECK: c-index-api-loadTU-test.m:51:6: UnexposedExpr=c:49:12 Extent=[51:6 - 51:7]
136136
// CHECK: c-index-api-loadTU-test.m:51:6: UnexposedExpr=c:49:12 Extent=[51:6 - 51:7]

0 commit comments

Comments
 (0)