Skip to content

Commit eba2db2

Browse files
retifinducer
authored andcommitted
Fix attribute handling for pointer declarators
1 parent 71fcc36 commit eba2db2

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

pycparserext/ext_c_parser.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -429,24 +429,30 @@ def p_xxx_declarator_2(self, p):
429429
decl = p[3]
430430

431431
if asm_label or attr_decl.exprs:
432-
if isinstance(decl, (c_ast.ArrayDecl, c_ast.FuncDecl)):
433-
decl_ext = to_decl_ext(decl.type)
434-
435-
elif isinstance(decl, c_ast.TypeDecl):
436-
decl_ext = to_decl_ext(decl)
437-
438-
else:
439-
raise NotImplementedError(
440-
"cannot attach asm or attributes to nodes of type '%s'"
441-
% type(p[1]))
432+
innermost_decl = decl
433+
while not isinstance(innermost_decl, c_ast.TypeDecl):
434+
try:
435+
innermost_decl = innermost_decl.type
436+
except AttributeError:
437+
raise NotImplementedError(
438+
"cannot attach asm or attributes to "
439+
"nodes of type '%s'"
440+
% type(innermost_decl))
441+
442+
decl_ext = to_decl_ext(innermost_decl)
442443

443444
if asm_label:
444445
decl_ext.asm = asm_label
445-
446446
if attr_decl.exprs:
447447
decl_ext.attributes = attr_decl
448448

449-
p[1] = decl_ext
449+
if innermost_decl is decl:
450+
decl = decl_ext
451+
else:
452+
parent = decl
453+
while parent.type is not innermost_decl:
454+
parent = parent.type
455+
parent.type = decl_ext
450456

451457
p[0] = self._type_modify_decl(decl, p[1])
452458

@@ -557,6 +563,14 @@ def p_gnu_unary_expression(self, p):
557563
p[2] if len(p) == 3 else p[3],
558564
self._token_coord(p, 1))
559565

566+
def p_gnu_unary_expression(self, p):
567+
""" unary_expression : __ALIGNOF__ LPAREN type_name RPAREN
568+
"""
569+
p[0] = c_ast.UnaryOp(
570+
p[1],
571+
p[2] if len(p) == 3 else p[3],
572+
self._token_coord(p, 1))
573+
560574
def p_statement(self, p):
561575
""" statement : labeled_statement
562576
| expression_statement

test/test_pycparserext.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,12 @@ def test_typedef():
649649
assert gen == "int"
650650

651651

652+
def test_pointer_to_function_with_attribute():
653+
# https://github.com/inducer/pycparserext/issues/66
654+
src = "void (*f)(void) __attribute__((unused));"
655+
assert _round_trip_matches(src)
656+
657+
652658
if __name__ == "__main__":
653659
import sys
654660
if len(sys.argv) > 1:

0 commit comments

Comments
 (0)