From 7c0c33f10839e5715e4ded5b2ab6ab3fe35b5ccf Mon Sep 17 00:00:00 2001 From: t11230 Date: Fri, 7 Aug 2020 23:18:37 -0400 Subject: [PATCH] Added __volatile__, __volatile and __restrict__ GNU keywords --- pycparserext/ext_c_lexer.py | 33 ++++++++++++++++++++++----------- pycparserext/ext_c_parser.py | 26 ++++++++++++++++++++------ test/test_pycparserext.py | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/pycparserext/ext_c_lexer.py b/pycparserext/ext_c_lexer.py index 1f8126c..2f1b45b 100644 --- a/pycparserext/ext_c_lexer.py +++ b/pycparserext/ext_c_lexer.py @@ -61,16 +61,27 @@ 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'] + +add_lexer_keywords(OpenCLCLexer, _COMMON_KEYWORDS + _CL_BASE_KEYWORDS + ["__"+kw for kw in _CL_BASE_KEYWORDS]) # vim: fdm=marker diff --git a/pycparserext/ext_c_parser.py b/pycparserext/ext_c_parser.py index 51d9b64..4432190 100644 --- a/pycparserext/ext_c_parser.py +++ b/pycparserext/ext_c_parser.py @@ -364,17 +364,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] @@ -452,7 +452,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] @@ -512,6 +515,12 @@ def p_struct_declaration_list_1(self, p): """ struct_declaration_list : empty """ p[0] = None + def p_unified_volatile_gnu(self, p): + """ unified_volatile : VOLATILE + | __VOLATILE + | __VOLATILE__ + """ + p[0] = p[1] # }}} @@ -587,4 +596,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 diff --git a/test/test_pycparserext.py b/test/test_pycparserext.py index f415930..737abf8 100644 --- a/test/test_pycparserext.py +++ b/test/test_pycparserext.py @@ -47,6 +47,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) @@ -374,6 +388,26 @@ def test_double_pointer(): assert gen.visit(ast).find("func_with_p2pp(const char *, Error **)") != -1 +@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) + + import pycparserext.ext_c_parser as ext_c_parser + import pycparserext.ext_c_generator as ext_c_generator + + parser = ext_c_parser.GnuCParser() + ast = parser.parse(src) + gen = ext_c_generator.GnuCGenerator() + print(gen.visit(ast)) + + def test_node_visitor(): from pycparser.c_ast import NodeVisitor