Skip to content

Commit eda65f9

Browse files
authored
Merge pull request #2 from avakar/master
Various additions and fixes.
2 parents 66bc329 + e0e9578 commit eda65f9

File tree

5 files changed

+69
-34
lines changed

5 files changed

+69
-34
lines changed

cppmangle/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
from .mangle import mangle, demangle
2-
from .cdecl import cdecl_sym
2+
from .cdecl import cdecl_sym, cdecl_qname
33
from .ast import *

cppmangle/ast.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,32 @@ def __init__(self, cv, basic_type):
2020
class BasicType(_Enum):
2121
pass
2222

23+
t_none = BasicType('none')
2324
t_void = BasicType('void')
2425
t_bool = BasicType('bool')
2526
t_char = BasicType('char')
2627
t_schar = BasicType('signed char')
2728
t_uchar = BasicType('unsigned char')
2829
t_sshort = BasicType('short int')
29-
t_ushort = BasicType('unsigned short int')
30+
t_ushort = BasicType('unsigned short')
3031
t_sint = BasicType('int')
3132
t_uint = BasicType('unsigned int')
3233
t_slong = BasicType('long')
3334
t_ulong = BasicType('unsigned long')
34-
t_slonglong = BasicType('long long')
35-
t_ulonglong = BasicType('unsigned long long')
35+
t_slonglong = BasicType('__int64')
36+
t_ulonglong = BasicType('unsigned __int64')
3637
t_wchar = BasicType('wchar_t')
3738
t_float = BasicType('float')
3839
t_double = BasicType('double')
3940
t_longdouble = BasicType('long double')
4041
t_ellipsis = BasicType('...')
4142

4243
class PtrType(Type):
43-
def __init__(self, cv, target, ref):
44+
def __init__(self, cv, target, ref, addr_space):
4445
super(PtrType, self).__init__(cv)
4546
self.target = target
4647
self.ref = ref
48+
self.addr_space = addr_space
4749

4850
k_union = 0
4951
k_struct = 1
@@ -80,9 +82,9 @@ def __init__(self, desc):
8082
def __repr__(self):
8183
return 'SpecialName({!r})'.format(self.desc)
8284

83-
n_constructor = SpecialName("<constructor>")
84-
n_def_constr_closure = SpecialName("<default constructor closure>")
85-
n_destructor = SpecialName("<destructor>")
85+
n_constructor = SpecialName("`constructor'")
86+
n_def_constr_closure = SpecialName("`default constructor closure'")
87+
n_destructor = SpecialName("`destructor'")
8688
n_op_subscript = SpecialName("operator[]")
8789
n_op_call = SpecialName("operator()")
8890
n_op_member = SpecialName("operator->")
@@ -157,9 +159,15 @@ class FunctionKind(_Enum):
157159
fn_virtual = FunctionKind('<virtual member fn>')
158160
fn_class_static = FunctionKind('<static member fn>')
159161

162+
class AddressSpace(_Enum):
163+
pass
164+
as_default = AddressSpace('<default>')
165+
as_msvc_x64_absolute = AddressSpace('absolute')
166+
160167
class Function(object):
161-
def __init__(self, qname, type, kind, access_spec):
168+
def __init__(self, qname, type, kind, access_spec, addr_space):
162169
self.qname = qname
163170
self.type = type
164171
self.kind = kind
165172
self.access_spec = access_spec
173+
self.addr_space = addr_space

cppmangle/cdecl.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from ast import *
1+
from .ast import *
22

33
_cvs = ('', 'const ', 'volatile ', 'const volatile ')
44
_class_kinds = ('union', 'struct', 'class', 'enum')
@@ -8,15 +8,24 @@ def _cdecl_templ_arg(arg):
88
return str(arg)
99
return cdecl_type(arg)
1010

11-
def _cdecl_name(name):
11+
def _cdecl_name(name, prev):
12+
if name == n_constructor:
13+
return prev, None
14+
if name == n_destructor:
15+
return '~{}'.format(prev), None
1216
if isinstance(name, SpecialName):
13-
return name.desc
17+
return name.desc, None
1418
if isinstance(name, TemplateId):
15-
return '{}<{}>'.format(name.name, ', '.join(_cdecl_templ_arg(arg) for arg in name.args))
16-
return name
19+
return '{}<{}>'.format(name.name, ','.join(_cdecl_templ_arg(arg) for arg in name.args)), name.name
20+
return name, name
1721

18-
def _cdecl_qname(qname):
19-
return '::'.join(_cdecl_name(name) for name in qname)
22+
def cdecl_qname(qname):
23+
names = []
24+
base_name = None
25+
for name in qname:
26+
full_name, base_name = _cdecl_name(name, base_name)
27+
names.append(full_name)
28+
return '::'.join(names)
2029

2130
def cdecl_type(type, obj_name=''):
2231
prefixes = []
@@ -28,14 +37,18 @@ def cdecl_type(type, obj_name=''):
2837

2938
while True:
3039
if isinstance(type, SimpleType):
40+
if type.basic_type == t_none:
41+
break
42+
3143
prefixes.append(_cvs[type.cv])
3244
prefixes.append(' ')
3345
prefixes.append(type.basic_type.desc)
3446
break
3547

3648
if isinstance(type, ClassType):
49+
prefixes.append(_cvs[type.cv])
3750
prefixes.append(' ')
38-
prefixes.append(_cdecl_qname(type.qname))
51+
prefixes.append(cdecl_qname(type.qname))
3952
prefixes.append(' ')
4053
prefixes.append(_class_kinds[type.kind])
4154
break
@@ -55,19 +68,24 @@ def cdecl_type(type, obj_name=''):
5568
if type.ref:
5669
prefixes.append('& ')
5770
else:
71+
prefixes.append(_cvs[type.cv])
5872
prefixes.append('* ')
5973
type = type.target
6074
continue
6175

6276
if isinstance(type, FunctionType):
63-
prefixes.append('__{} '.format(type.cconv.desc))
77+
if not prefixes or prefixes[-1][0] != '*':
78+
prefixes.append(' ')
79+
prefixes.append('__{}'.format(type.cconv.desc))
6480
if prio != 0:
6581
prefixes.append('(')
6682
suffixes.append(')')
6783
prio = 0
6884
suffixes.append('(')
69-
suffixes.append(', '.join(cdecl_type(param) for param in type.params))
85+
suffixes.append(','.join(cdecl_type(param) for param in type.params))
7086
suffixes.append(')')
87+
if type.this_cv is not None:
88+
suffixes.append(_cvs[type.this_cv])
7189
type = type.ret_type
7290
continue
7391

@@ -84,6 +102,6 @@ def cdecl_sym(sym):
84102
r.append('virtual ')
85103
if sym.kind == fn_class_static:
86104
r.append('static ')
87-
r.append(cdecl_type(sym.type, _cdecl_qname(sym.qname)))
105+
r.append(cdecl_type(sym.type, cdecl_qname(sym.qname)))
88106
return ''.join(r)
89107
raise RuntimeError('unk')

cppmangle/msvc.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import speg
2-
from ast import *
2+
from .ast import *
33

44
def _transpose(m):
55
return dict((m[k], k) for k in m)
66

7-
_noncv_member_funcs = frozenset([n_constructor, n_destructor])
8-
97
_basic_type_map = {
8+
'@': t_none,
109
'X': t_void,
1110
'_N': t_bool,
1211
'D': t_char,
@@ -153,7 +152,7 @@ def _p_qname(p):
153152
return tuple(qname[::-1])
154153

155154
def _p_basic_type(p):
156-
c = p(r'[XDCEFGHIJKMNOZ]|_[NJKW]')
155+
c = p(r'[@XDCEFGHIJKMNOZ]|_[NJKW]')
157156
return SimpleType(0, _basic_type_map[c]), len(c) >= 2
158157

159158
_cvs = [0, cv_const, cv_volatile, cv_const | cv_volatile]
@@ -177,17 +176,18 @@ def _p_type(p):
177176
# pointer to fn
178177
cv = _cvs[ord(p('[PQRS]6')[0]) - ord('P')]
179178
fn_type = p(_p_fn_type)
180-
return PtrType(cv, fn_type, False), True
179+
return PtrType(cv, fn_type, False, as_default), True
181180

182181
with p:
183182
# pointer types
184-
kind = p('[APQRS]E?')[0]
183+
kind = p('[APQRS]')
184+
addr_space = as_msvc_x64_absolute if p('E?') else as_default
185185
target_cv = p('[A-D]')
186186
target, reg = p(_p_type)
187187
target.cv = _cvs[ord(target_cv) - ord('A')]
188188

189189
cv = _cvs[ord(kind) - ord('P')] if kind != 'A' else 0
190-
return PtrType(cv, target, kind == 'A'), True
190+
return PtrType(cv, target, kind == 'A', addr_space), True
191191

192192
return p(_p_basic_type)
193193

@@ -249,15 +249,21 @@ def _p_root(p):
249249
else:
250250
kind = fn_instance
251251

252-
can_have_cv = kind in (fn_instance, fn_virtual) and qname[-1] not in _noncv_member_funcs
253-
this_cv = ord(p('[A-D]')) - ord('A') if can_have_cv else None
252+
253+
can_have_cv = kind in (fn_instance, fn_virtual)
254+
if can_have_cv:
255+
addr_space = as_msvc_x64_absolute if p('E?') else as_default
256+
this_cv = ord(p('[A-D]')) - ord('A')
257+
else:
258+
addr_space = as_default
259+
this_cv = None
254260

255261
type = p(_p_fn_type)
256262
p(p.eof)
257263

258264
type.this_cv = this_cv
259265

260-
return Function(qname, type, kind, access_class)
266+
return Function(qname, type, kind, access_class, addr_space)
261267

262268
def msvc_demangle(s):
263269
return speg.peg(s, _p_root)
@@ -317,7 +323,7 @@ def _m_type(type, nl, tl):
317323
if isinstance(type.target, FunctionType):
318324
return '{}6{}'.format(kind, _m_fn_type(type.target, nl, tl))
319325
else:
320-
return '{}{}{}'.format(kind, 'ABCD'[type.target.cv], _m_type(type.target, nl, tl))
326+
return '{}{}{}{}'.format(kind, 'E' if type.addr_space == as_msvc_x64_absolute else '', 'ABCD'[type.target.cv], _m_type(type.target, nl, tl))
321327
if isinstance(type, ArrayType):
322328
return 'Y{}{}{}'.format(_m_int(len(type.dims)), ''.join(_m_int(dim) for dim in type.dims), _m_type(type.target, nl, tl))
323329
if isinstance(type, ClassType):
@@ -379,9 +385,10 @@ def msvc_mangle(obj):
379385

380386
modif = chr(ord('A') + modif)
381387

382-
can_have_cv = obj.kind in (fn_instance, fn_virtual) and obj.qname[-1] not in _noncv_member_funcs
388+
addr_space = 'E' if obj.addr_space == as_msvc_x64_absolute else ''
389+
can_have_cv = obj.kind in (fn_instance, fn_virtual)
383390
this_cv = 'ABCD'[obj.type.this_cv] if can_have_cv else ''
384391

385-
return '?{}{}{}{}'.format(qname, modif, this_cv, type)
392+
return '?{}{}{}{}{}'.format(qname, modif, addr_space, this_cv, type)
386393

387394
raise RuntimeError('unknown obj')

setup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55

66
setup(
77
name='cppmangle',
8-
version='0.1',
8+
version='0.2',
99

1010
description='A parser for mangled C++ names',
1111
author='AVG Technologies CZ, s.r.o.',
1212
url='https://github.com/AVGTechnologies/cppmangle',
1313
license='Apache 2.0',
1414

1515
packages=['cppmangle'],
16+
install_requires=['speg>=0.3'],
17+
1618
entry_points={
1719
'console_scripts': [
1820
'cppdemangle=cppmangle.__main__:main'

0 commit comments

Comments
 (0)