summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Bendersky <eliben@gmail.com>2021-09-13 08:51:21 -0700
committerEli Bendersky <eliben@gmail.com>2021-09-13 08:51:21 -0700
commitb249fc58e530f3dcbfc9a4c35f62e641a5d34757 (patch)
tree8aac9b3207060b150288ac6184d39eab3db018fb
parent0e4f8ae855a54142e812b4604eca20f186db9fe4 (diff)
downloadpycparser-b249fc58e530f3dcbfc9a4c35f62e641a5d34757.tar.gz
Support _Atomic as a qualifier
This adds initial implementation for the _Atomic keyword in C11, only focusing on the use as qualifier (spec section 6.7.3) Based on #431 by vit9696. Updates #430
-rw-r--r--pycparser/c_lexer.py4
-rw-r--r--pycparser/c_parser.py1
-rw-r--r--tests/test_c_generator.py2
-rw-r--r--tests/test_c_lexer.py6
-rwxr-xr-xtests/test_c_parser.py10
5 files changed, 20 insertions, 3 deletions
diff --git a/pycparser/c_lexer.py b/pycparser/c_lexer.py
index 96c4aa7..e7f0cb5 100644
--- a/pycparser/c_lexer.py
+++ b/pycparser/c_lexer.py
@@ -111,13 +111,13 @@ class CLexer(object):
keywords_new = (
'_BOOL', '_COMPLEX',
- '_NORETURN', '_THREAD_LOCAL', '_STATIC_ASSERT'
+ '_NORETURN', '_THREAD_LOCAL', '_STATIC_ASSERT', '_ATOMIC',
)
keyword_map = {}
for keyword in keywords:
- keyword_map[keyword.lower()] = keyword
+ keyword_map[keyword.lower()] = keyword
for keyword in keywords_new:
keyword_map[keyword[:2].upper() + keyword[2:].lower()] = keyword
diff --git a/pycparser/c_parser.py b/pycparser/c_parser.py
index b8ad4b1..5f2818d 100644
--- a/pycparser/c_parser.py
+++ b/pycparser/c_parser.py
@@ -859,6 +859,7 @@ class CParser(PLYParser):
""" type_qualifier : CONST
| RESTRICT
| VOLATILE
+ | _ATOMIC
"""
p[0] = p[1]
diff --git a/tests/test_c_generator.py b/tests/test_c_generator.py
index 4563523..15a3831 100644
--- a/tests/test_c_generator.py
+++ b/tests/test_c_generator.py
@@ -91,6 +91,8 @@ class TestCtoC(unittest.TestCase):
self._assert_ctoc_correct('int** (*a)(void);')
self._assert_ctoc_correct('int** (*a)(void*, int);')
self._assert_ctoc_correct('int (*b)(char * restrict k, float);')
+ self._assert_ctoc_correct('int (*b)(char * _Atomic k, float);')
+ self._assert_ctoc_correct('int (*b)(char * _Atomic volatile k, float);')
self._assert_ctoc_correct('int test(const char* const* arg);')
self._assert_ctoc_correct('int test(const char** const arg);')
diff --git a/tests/test_c_lexer.py b/tests/test_c_lexer.py
index a555dcb..e446434 100644
--- a/tests/test_c_lexer.py
+++ b/tests/test_c_lexer.py
@@ -91,6 +91,10 @@ class TestCLexerNoErrors(unittest.TestCase):
def test_special_names(self):
self.assertTokensTypes('sizeof offsetof', ['SIZEOF', 'OFFSETOF'])
+ def test_new_keywords(self):
+ self.assertTokensTypes('_Bool', ['_BOOL'])
+ self.assertTokensTypes('_Atomic', ['_ATOMIC'])
+
def test_floating_constants(self):
self.assertTokensTypes('1.5f', ['FLOAT_CONST'])
self.assertTokensTypes('01.5', ['FLOAT_CONST'])
@@ -452,7 +456,7 @@ class TestCLexerErrors(unittest.TestCase):
self.assertLexerError("'", ERR_UNMATCHED_QUOTE)
self.assertLexerError("'b\n", ERR_UNMATCHED_QUOTE)
self.assertLexerError("'\\xaa\n'", ERR_UNMATCHED_QUOTE)
-
+
self.assertLexerError(r"'123\12a'", ERR_INVALID_CCONST)
self.assertLexerError(r"'123\xabg'", ERR_INVALID_CCONST)
self.assertLexerError("''", ERR_INVALID_CCONST)
diff --git a/tests/test_c_parser.py b/tests/test_c_parser.py
index f4a3744..8c1ccc5 100755
--- a/tests/test_c_parser.py
+++ b/tests/test_c_parser.py
@@ -441,6 +441,14 @@ class TestCParser_fundamentals(TestCParser_base):
['TypeDecl', ['IdentifierType', ['int']]]]],
['TypeDecl', ['IdentifierType', ['int']]]]]])
+ self.assertEqual(self.get_decl('int (*k)(_Atomic volatile int q);'),
+ ['Decl', 'k',
+ ['PtrDecl',
+ ['FuncDecl',
+ [['Decl', ['_Atomic', 'volatile'], 'q',
+ ['TypeDecl', ['IdentifierType', ['int']]]]],
+ ['TypeDecl', ['IdentifierType', ['int']]]]]])
+
self.assertEqual(self.get_decl('int (*k)(const volatile int* q);'),
['Decl', 'k',
['PtrDecl',
@@ -524,6 +532,8 @@ class TestCParser_fundamentals(TestCParser_base):
assert_qs("extern int p;", 0, [], ['extern'])
assert_qs("_Thread_local int p;", 0, [], ['_Thread_local'])
assert_qs("const long p = 6;", 0, ['const'], [])
+ assert_qs("_Atomic int p;", 0, ['_Atomic'], [])
+ assert_qs("_Atomic restrict int* p;", 0, ['_Atomic', 'restrict'], [])
d1 = "static const int p, q, r;"
for i in range(3):