diff options
author | Eli Bendersky <eliben@gmail.com> | 2021-09-13 08:51:21 -0700 |
---|---|---|
committer | Eli Bendersky <eliben@gmail.com> | 2021-09-13 08:51:21 -0700 |
commit | b249fc58e530f3dcbfc9a4c35f62e641a5d34757 (patch) | |
tree | 8aac9b3207060b150288ac6184d39eab3db018fb | |
parent | 0e4f8ae855a54142e812b4604eca20f186db9fe4 (diff) | |
download | pycparser-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.py | 4 | ||||
-rw-r--r-- | pycparser/c_parser.py | 1 | ||||
-rw-r--r-- | tests/test_c_generator.py | 2 | ||||
-rw-r--r-- | tests/test_c_lexer.py | 6 | ||||
-rwxr-xr-x | tests/test_c_parser.py | 10 |
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): |