Skip to content

Commit

Permalink
Added __volatile__, __volatile and __restrict__ GNU keywords
Browse files Browse the repository at this point in the history
  • Loading branch information
t11230 committed Aug 9, 2020
1 parent 9365b81 commit 42e3942
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 18 deletions.
8 changes: 7 additions & 1 deletion pycparserext/ext_c_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ def _generate_type(self, n, modifiers=[]):
if isinstance(modifier, c_ast.ArrayDecl):
if (i != 0 and isinstance(modifiers[i - 1], c_ast.PtrDecl)):
nstr = '(' + nstr + ')'
nstr += '[' + self.visit(modifier.dim) + ']'

# BUG FIX: pycparser ignores quals
dim_quals = (' '.join(modifier.dim_quals) + ' '
if modifier.dim_quals else '')

nstr += '[' + dim_quals + self.visit(modifier.dim) + ']'

elif isinstance(modifier, c_ast.FuncDecl):
if (i != 0 and isinstance(modifiers[i - 1], c_ast.PtrDecl)):
nstr = '(' + nstr + ')'
Expand Down
36 changes: 25 additions & 11 deletions pycparserext/ext_c_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,30 @@ def add_lexer_keywords(cls, keywords):
kw.upper() for kw in keywords)


add_lexer_keywords(GnuCLexer, [
'__attribute__', '__asm__', '__asm', '__typeof__',
'__real__', '__imag__', '__builtin_types_compatible_p',
'__const', '__restrict', '__inline', '__inline__',
'__extension__', 'asm', '__attribute'])

_CL_KEYWORDS = ['kernel', 'constant', 'global', 'local', 'private',
"read_only", "write_only", "read_write"]
add_lexer_keywords(OpenCLCLexer, [
'__attribute__', '__attribute', '__asm__', '__asm', 'asm']
+ _CL_KEYWORDS + ["__"+kw for kw in _CL_KEYWORDS])
_COMMON_KEYWORDS = [
'__attribute__', '__attribute',
'__asm__', '__asm', 'asm']

_GNU_KEYWORDS = [
'__typeof__',
'__real__', '__imag__',
'__builtin_types_compatible_p',
'__const',
'__restrict__', '__restrict',
'__inline__', '__inline',
'__extension__',
'__volatile', '__volatile__']

add_lexer_keywords(GnuCLexer, _COMMON_KEYWORDS + _GNU_KEYWORDS)

# These will be added as unadorned keywords and keywords with '__' prepended
_CL_BASE_KEYWORDS = [
'kernel', 'constant', 'global', 'local', 'private',
'read_only', 'write_only', 'read_write']

_CL_KEYWORDS = _COMMON_KEYWORDS
_CL_KEYWORDS += _CL_BASE_KEYWORDS + ["__"+kw for kw in _CL_BASE_KEYWORDS]

add_lexer_keywords(OpenCLCLexer, _CL_KEYWORDS)

# vim: fdm=marker
26 changes: 20 additions & 6 deletions pycparserext/ext_c_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,17 +387,17 @@ def p_asm_4(self, p):
p[0] = Asm(p[1], p[3], p[5], p[7], p[9], coord=self._coord(p.lineno(2)))

def p_asm_keyword(self, p):
""" asm_keyword : __ASM__ asm_volatile
| __ASM asm_volatile
| ASM asm_volatile
""" asm_keyword : __ASM__ asm_volatile_opt
| __ASM asm_volatile_opt
| ASM asm_volatile_opt
"""
p[0] = p[1]
if p[2]:
p[0] += ' ' + p[2]

def p_asm_volatile(self, p):
""" asm_volatile : VOLATILE
| empty
def p_asm_volatile_opt(self, p):
""" asm_volatile_opt : unified_volatile
| empty
"""
p[0] = p[1]

Expand Down Expand Up @@ -475,7 +475,10 @@ def p_function_specifier_gnu(self, p):
def p_type_qualifier_gnu(self, p):
""" type_qualifier : __CONST
| __RESTRICT
| __RESTRICT__
| __EXTENSION__
| __VOLATILE
| __VOLATILE__
"""
p[0] = p[1]

Expand Down Expand Up @@ -540,6 +543,12 @@ def p_range_designator(self, p):
"""
p[0] = RangeExpression(p[2], p[4], coord=self._coord(p.lineno(1)))

def p_unified_volatile_gnu(self, p):
""" unified_volatile : VOLATILE
| __VOLATILE
| __VOLATILE__
"""
p[0] = p[1]
# }}}


Expand Down Expand Up @@ -615,4 +624,9 @@ def p_function_specifier_cl(self, p):
"""
p[0] = p[1]

def p_unified_volatile_cl(self, p):
""" unified_volatile : VOLATILE
"""
p[0] = p[1]

# vim: fdm=marker
27 changes: 27 additions & 0 deletions test/test_pycparserext.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ def test_asm_volatile_3():
print(GnuCGenerator().visit(ast))


def test_asm_volatile_4():
src = """
void barrier(void) {
__asm__ __volatile__("": : :"memory");
} """
from pycparserext.ext_c_parser import GnuCParser
p = GnuCParser()
ast = p.parse(src)
ast.show()

from pycparserext.ext_c_generator import GnuCGenerator
print(GnuCGenerator().visit(ast))


def test_funky_header_code():
src = """
extern __inline int __attribute__ ((__nothrow__)) __signbitf (float __x)
Expand Down Expand Up @@ -438,6 +452,19 @@ def test_designated_initializers():
assert _round_trip_matches(src)


@pytest.mark.parametrize("restrict_kw", ["restrict", "__restrict__", "__restrict"])
def test_restrict(restrict_kw):
src = """
void f(int n, int * {0} p, int * {0} q)
{{
}}
typedef int *array_t[10];
{0} array_t a;
void f(int m, int n, float a[{0} m][n], float b[{0} m][n]);
""" .format(restrict_kw)
assert _round_trip_matches(src)


def test_node_visitor():
from pycparser.c_ast import NodeVisitor

Expand Down

0 comments on commit 42e3942

Please # to comment.