Skip to content

Commit 834b63e

Browse files
retifgoogle-labs-jules[bot]II Assistant
authored
Fix #33: Support asm labels on register variables (#94)
* fix(parser): Correctly handle asm attributes on register variables Adds support for `asm` attributes on `register` variables by allowing `asm` and `attributes` to be added to `TypeDeclExt` and `ArrayDeclExt` nodes. This was preventing the parser from attaching `asm` labels to declarations with storage-class specifiers like `register`. A new test case, `test_register_asm_label`, is added to verify that declarations like `register int my_var asm("my_reg");` are now parsed correctly. * test: Add comprehensive round-trip tests for register asm labels This commit enhances the test_register_asm_label test to include round-trip testing, which was the main issue reported in #33. The original issue stated: 'when I convert it back to C-Code then no C-Code is created for this line.' This fix adds: - Round-trip test for basic asm syntax - Round-trip test for __asm__ variant - Round-trip test for different type specifiers All tests verify that parsing and code generation work correctly. * style: Fix ruff linting issues - Change single quotes to double quotes in __slots__ declarations - Fix import ordering (pycparser before pycparserext) - Standardize quote style in test assertions --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: II Assistant <assistant@example.com>
1 parent 51ce930 commit 834b63e

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

pycparserext/ext_c_parser.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ def __iter__(self):
187187
# These are the same as pycparser's, but it does *not* declare __slots__--
188188
# so we can poke in attributes at our leisure.
189189
class TypeDeclExt(c_ast.TypeDecl):
190+
__slots__ = ("asm", "attributes", "init")
191+
190192
@staticmethod
191193
def from_pycparser(td):
192194
assert isinstance(td, c_ast.TypeDecl)
@@ -201,6 +203,8 @@ def from_pycparser(td):
201203

202204

203205
class ArrayDeclExt(c_ast.ArrayDecl):
206+
__slots__ = ("asm", "attributes", "init")
207+
204208
@staticmethod
205209
def from_pycparser(ad):
206210
assert isinstance(ad, c_ast.ArrayDecl)

test/test_pycparserext.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,38 @@ def test_asm_label():
125125
assert _round_trip_matches(src)
126126

127127

128+
def test_register_asm_label():
129+
from pycparser import c_ast
130+
131+
from pycparserext.ext_c_parser import GnuCParser, TypeDeclExt
132+
src = 'register int my_var asm("my_reg");'
133+
p = GnuCParser()
134+
ast = p.parse(src)
135+
decl = ast.ext[0]
136+
assert isinstance(decl, c_ast.Decl)
137+
138+
# The asm attribute should be on the TypeDeclExt, not the Decl
139+
assert not hasattr(decl, "asm")
140+
141+
# The declarator part of the Decl should be a TypeDeclExt
142+
# with the asm attribute.
143+
assert isinstance(decl.type, TypeDeclExt)
144+
assert hasattr(decl.type, "asm")
145+
assert decl.type.asm is not None
146+
assert decl.type.asm.template.value == '"my_reg"'
147+
148+
# Test round-trip: the main issue in #33 was that no C code was generated
149+
assert _round_trip_matches(src)
150+
151+
# Test with __asm__ variant
152+
src2 = 'register int foo __asm__("bar");'
153+
assert _round_trip_matches(src2)
154+
155+
# Test with different types
156+
src3 = 'register unsigned int counter asm("r0");'
157+
assert _round_trip_matches(src3)
158+
159+
128160
def test_pointer_with_attr():
129161
# https://github.com/inducer/pycparserext/issues/86
130162
src = "typedef float * __attribute__((abc)) b;"

0 commit comments

Comments
 (0)