Skip to content

Commit

Permalink
Support _Atomic as a qualifier
Browse files Browse the repository at this point in the history
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
  • Loading branch information
eliben committed Sep 13, 2021
1 parent 0e4f8ae commit b249fc5
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 3 deletions.
4 changes: 2 additions & 2 deletions pycparser/c_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,13 @@ def _make_tok_location(self, token):

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
Expand Down
1 change: 1 addition & 0 deletions pycparser/c_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ def p_type_qualifier(self, p):
""" type_qualifier : CONST
| RESTRICT
| VOLATILE
| _ATOMIC
"""
p[0] = p[1]

Expand Down
2 changes: 2 additions & 0 deletions tests/test_c_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def test_complex_decls(self):
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);')

Expand Down
6 changes: 5 additions & 1 deletion tests/test_c_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ def test_integer_constants(self):
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'])
Expand Down Expand Up @@ -452,7 +456,7 @@ def test_char_constants(self):
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)
Expand Down
10 changes: 10 additions & 0 deletions tests/test_c_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,14 @@ def test_nested_decls(self): # the fun begins
['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',
Expand Down Expand Up @@ -524,6 +532,8 @@ def assert_qs(txt, index, quals, storage):
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):
Expand Down

0 comments on commit b249fc5

Please sign in to comment.