Skip to content

Commit 468cc11

Browse files
committed
[libclang/python] Retrieve BinaryOperator::getOpcode and BinaryOperator::getOpcodeStr via libclang and its python interface
1 parent a4cdd94 commit 468cc11

20 files changed

+1655
-771
lines changed

clang/bindings/python/clang/cindex.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,18 @@ def availability(self):
18201820

18211821
return AvailabilityKind.from_id(self._availability)
18221822

1823+
@property
1824+
def binary_operator(self):
1825+
"""
1826+
Retrieves the opcode if this cursor points to a binary operator
1827+
:return:
1828+
"""
1829+
1830+
if not hasattr(self, "_binopcode"):
1831+
self._binopcode = conf.lib.clang_Cursor_getBinaryOpcode(self)
1832+
1833+
return BinaryOperator.from_id(self._binopcode)
1834+
18231835
@property
18241836
def access_specifier(self):
18251837
"""
@@ -2110,6 +2122,55 @@ def from_cursor_result(res, fn, args):
21102122
return res
21112123

21122124

2125+
class BinaryOperator(BaseEnumeration):
2126+
"""
2127+
Describes the BinaryOperator of a declaration
2128+
"""
2129+
2130+
def __nonzero__(self):
2131+
"""Allows checks of the kind ```if cursor.binary_operator:```"""
2132+
return self.value != 0
2133+
2134+
@property
2135+
def is_assignment(self):
2136+
return BinaryOperator.Assign.value <= self.value < BinaryOperator.Comma.value
2137+
2138+
Invalid = 0
2139+
PtrMemD = 1
2140+
PtrMemI = 2
2141+
Mul = 3
2142+
Div = 4
2143+
Rem = 5
2144+
Add = 6
2145+
Sub = 7
2146+
Shl = 8
2147+
Shr = 9
2148+
Cmp = 10
2149+
LT = 11
2150+
GT = 12
2151+
LE = 13
2152+
GE = 14
2153+
EQ = 15
2154+
NE = 16
2155+
And = 17
2156+
Xor = 18
2157+
Or = 19
2158+
LAnd = 20
2159+
LOr = 21
2160+
Assign = 22
2161+
MulAssign = 23
2162+
DivAssign = 24
2163+
RemAssign = 25
2164+
AddAssign = 26
2165+
SubAssign = 27
2166+
ShlAssign = 28
2167+
ShrAssign = 29
2168+
AndAssign = 30
2169+
XorAssign = 31
2170+
OrAssign = 32
2171+
Comma = 33
2172+
2173+
21132174
class StorageClass(BaseEnumeration):
21142175
"""
21152176
Describes the storage class of a declaration
@@ -3847,6 +3908,7 @@ def write_main_file_to_stdout(self):
38473908
("clang_Cursor_getTemplateArgumentUnsignedValue", [Cursor, c_uint], c_ulonglong),
38483909
("clang_Cursor_isAnonymous", [Cursor], bool),
38493910
("clang_Cursor_isBitField", [Cursor], bool),
3911+
("clang_Cursor_getBinaryOpcode", [Cursor], c_int),
38503912
("clang_Cursor_getBriefCommentText", [Cursor], _CXString, _CXString.from_result),
38513913
("clang_Cursor_getRawCommentText", [Cursor], _CXString, _CXString.from_result),
38523914
("clang_Cursor_getOffsetOfField", [Cursor], c_longlong),
@@ -4016,6 +4078,7 @@ def function_exists(self, name):
40164078

40174079
__all__ = [
40184080
"AvailabilityKind",
4081+
"BinaryOperator",
40194082
"Config",
40204083
"CodeCompletionResults",
40214084
"CompilationDatabase",

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/bindings/python/tests/cindex/test_enums.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
LinkageKind,
1313
TLSKind,
1414
StorageClass,
15+
BinaryOperator,
1516
)
1617

1718

@@ -28,6 +29,7 @@ class TestEnums(unittest.TestCase):
2829
LinkageKind,
2930
TLSKind,
3031
StorageClass,
32+
BinaryOperator,
3133
]
3234

3335
def test_from_id(self):

clang/docs/ReleaseNotes.rst

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

13021304
OpenMP Support
13031305
--------------

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

0 commit comments

Comments
 (0)