diff --git a/pycparser/c_parser.py b/pycparser/c_parser.py index d31574a5..fa56c389 100644 --- a/pycparser/c_parser.py +++ b/pycparser/c_parser.py @@ -1530,6 +1530,20 @@ def p_direct_abstract_declarator_7(self, p): type=c_ast.TypeDecl(None, None, None, None), coord=self._token_coord(p, 1)) + def p_direct_abstract_declarator_8(self, p): + """ direct_abstract_declarator : LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET + | LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET + """ + listed_quals = [item if isinstance(item, list) else [item] + for item in [p[2],p[3]]] + quals = [qual for sublist in listed_quals for qual in sublist + if qual is not None] + p[0] = c_ast.ArrayDecl( + type=c_ast.TypeDecl(None, None, None, None), + dim=p[4], + dim_quals=quals, + coord=self._token_coord(p, 1)) + # declaration is a list, statement isn't. To make it consistent, block_item # will always be a list # diff --git a/tests/test_c_parser.py b/tests/test_c_parser.py index 25682ad6..13529852 100755 --- a/tests/test_c_parser.py +++ b/tests/test_c_parser.py @@ -483,6 +483,21 @@ def test_func_decls_with_array_dim_qualifiers(self): [['Decl', 'p', ['ArrayDecl', '10', ['static'], ['TypeDecl', ['IdentifierType', ['int']]]]]], ['TypeDecl', ['IdentifierType', ['int']]]]]) + # anonymous function parameter + self.assertEqual(self.get_decl('int zz(int [static 10]);'), + ['Decl', 'zz', + ['FuncDecl', + [['Typename', + ['ArrayDecl', '10', ['static'], + ['TypeDecl', ['IdentifierType', ['int']]]]]], + ['TypeDecl', ['IdentifierType', ['int']]]]]) + self.assertEqual(self.get_decl('int zz(int [static const restrict 10]);'), + ['Decl', 'zz', + ['FuncDecl', + [['Typename', + ['ArrayDecl', '10', ['static', 'const', 'restrict'], + ['TypeDecl', ['IdentifierType', ['int']]]]]], + ['TypeDecl', ['IdentifierType', ['int']]]]]) self.assertEqual(self.get_decl('int zz(int p[const 10]);'), ['Decl', 'zz',