summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Bendersky <eliben@gmail.com>2021-09-14 06:46:04 -0700
committerEli Bendersky <eliben@gmail.com>2021-09-14 06:46:04 -0700
commitf6db111388ab8ac26913a6d6a16a5d6803d950a2 (patch)
treec80e9ee529b9ddb824e3dbca779d9fc7ad502945
parentbdcc186728124e6a90ed865031f11fba84165c19 (diff)
downloadpycparser-f6db111388ab8ac26913a6d6a16a5d6803d950a2.tar.gz
Fix declname for _Atomic specifiers, and add c-to-c tests
Updates #430
-rw-r--r--pycparser/ast_transforms.py7
-rw-r--r--tests/test_c_generator.py25
2 files changed, 30 insertions, 2 deletions
diff --git a/pycparser/ast_transforms.py b/pycparser/ast_transforms.py
index c756c66..367dcf5 100644
--- a/pycparser/ast_transforms.py
+++ b/pycparser/ast_transforms.py
@@ -120,7 +120,9 @@ def fix_atomic_specifiers(decl):
if not found:
break
- # Make sure to add an _Atomic qual on the topmost decl if needed.
+ # Make sure to add an _Atomic qual on the topmost decl if needed. Also
+ # restore the declname on the innermost TypeDecl (it gets placed in the
+ # wrong place during construction).
typ = decl
while not isinstance(typ, c_ast.TypeDecl):
try:
@@ -129,6 +131,8 @@ def fix_atomic_specifiers(decl):
return decl
if '_Atomic' in typ.quals and '_Atomic' not in decl.quals:
decl.quals.append('_Atomic')
+ if typ.declname is None:
+ typ.declname = decl.name
return decl
@@ -158,4 +162,3 @@ def _fix_atomic_specifiers_once(decl):
if '_Atomic' not in node.type.quals:
node.type.quals.append('_Atomic')
return decl, True
-
diff --git a/tests/test_c_generator.py b/tests/test_c_generator.py
index 15a3831..0926b15 100644
--- a/tests/test_c_generator.py
+++ b/tests/test_c_generator.py
@@ -367,6 +367,31 @@ class TestCtoC(unittest.TestCase):
self.assertEqual(generator.visit(ast.ext[0].type.type.type),
'const int')
+ def test_atomic_qual(self):
+ #s = '_Atomic(_Atomic(int)*) x;'
+ #ast = parse_to_ast(s)
+ #print(c_generator.CGenerator().visit(ast))
+
+ self._assert_ctoc_correct('_Atomic int x;')
+ self._assert_ctoc_correct('_Atomic int* x;')
+ self._assert_ctoc_correct('int* _Atomic x;')
+
+ # _Atomic specifier gets turned into qualifier.
+ s1 = '_Atomic(int) x;'
+ c1 = self._run_c_to_c(s1)
+ self.assertEqual(c1, '_Atomic int x;\n')
+ self._assert_ctoc_correct(s1)
+
+ s2 = '_Atomic(int*) x;'
+ c2 = self._run_c_to_c(s2)
+ self.assertEqual(c2, 'int * _Atomic x;\n')
+ self._assert_ctoc_correct(s2)
+
+ s3 = '_Atomic(_Atomic(int)*) x;'
+ c3 = self._run_c_to_c(s3)
+ self.assertEqual(c3, '_Atomic int * _Atomic x;\n')
+ self._assert_ctoc_correct(s3)
+
def test_nested_sizeof(self):
src = '1'
for _ in range(30):