From 2b67a900d605693e3d8af6e86abf4a43e8b62b80 Mon Sep 17 00:00:00 2001 From: Eldar Khayrullin Date: Sun, 29 Jun 2025 20:48:23 +0300 Subject: [PATCH 1/6] Consume attributes after declaration name --- cxxheaderparser/parser.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index 7cea0ea..36656f5 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -2679,6 +2679,11 @@ def _parse_declarations( # Unset the doxygen, location doxygen = None + tok = self.lex.token_if_in_set(self._attribute_start_tokens) + while tok: + self._consume_attribute(tok) + tok = self.lex.token_if_in_set(self._attribute_start_tokens) + # Check for multiple declarations tok = self._next_token_must_be(",", ";") location = tok.location From 2243ea0281cf335d0d0a51402c0a1890cb2e6a9d Mon Sep 17 00:00:00 2001 From: Eldar Khayrullin Date: Sun, 29 Jun 2025 21:32:58 +0300 Subject: [PATCH 2/6] Consume __restrict in function parameters --- cxxheaderparser/lexer.py | 1 + cxxheaderparser/parser.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/cxxheaderparser/lexer.py b/cxxheaderparser/lexer.py index 17caf92..66c904d 100644 --- a/cxxheaderparser/lexer.py +++ b/cxxheaderparser/lexer.py @@ -124,6 +124,7 @@ class PlyLexer: "public", "register", "reinterpret_cast", + "__restrict", "requires", "return", "short", diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index 36656f5..92abdf8 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -1791,6 +1791,9 @@ def _parse_parameter( dtype = self._parse_cv_ptr(parsed_type) + # optional __restrict + tok = self.lex.token_if("__restrict") + # optional parameter pack if self.lex.token_if("ELLIPSIS"): param_pack = True From b6f16ae2c9ac6909fa9a850656084dc01a7c325d Mon Sep 17 00:00:00 2001 From: Eldar Khayrullin Date: Sun, 29 Jun 2025 22:04:12 +0300 Subject: [PATCH 3/6] Consume __asm from function declaration --- cxxheaderparser/lexer.py | 1 + cxxheaderparser/parser.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/cxxheaderparser/lexer.py b/cxxheaderparser/lexer.py index 66c904d..0d6d982 100644 --- a/cxxheaderparser/lexer.py +++ b/cxxheaderparser/lexer.py @@ -73,6 +73,7 @@ class PlyLexer: "alignas", "alignof", "asm", + "__asm", "auto", "bool", "break", diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index 92abdf8..fc06f00 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -879,6 +879,12 @@ def _parse_requires_segment( # Let the caller decide return tok + def _consume_asm( + self, doxygen: typing.Optional[str] = None + ) -> None: + tok = self._next_token_must_be("(") + self._consume_balanced_tokens(tok) + # # Attributes # @@ -2682,6 +2688,9 @@ def _parse_declarations( # Unset the doxygen, location doxygen = None + if self.lex.token_if("__asm"): + self._consume_asm() + tok = self.lex.token_if_in_set(self._attribute_start_tokens) while tok: self._consume_attribute(tok) From ab9304069299b7a8738afb693ba06ebbe467db18 Mon Sep 17 00:00:00 2001 From: Eldar Khayrullin Date: Sun, 29 Jun 2025 22:19:56 +0300 Subject: [PATCH 4/6] Fix previous --- cxxheaderparser/parser.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index fc06f00..bbdffd9 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -880,7 +880,7 @@ def _parse_requires_segment( return tok def _consume_asm( - self, doxygen: typing.Optional[str] = None + self, tok: LexToken, doxygen: typing.Optional[str] = None ) -> None: tok = self._next_token_must_be("(") self._consume_balanced_tokens(tok) @@ -2688,8 +2688,9 @@ def _parse_declarations( # Unset the doxygen, location doxygen = None - if self.lex.token_if("__asm"): - self._consume_asm() + tok = self.lex.token_if("__asm") + if tok: + self._consume_asm(tok) tok = self.lex.token_if_in_set(self._attribute_start_tokens) while tok: From 5ef2af6704d3abcce8602673c65fb30b7b27c7c8 Mon Sep 17 00:00:00 2001 From: Eldar Khayrullin Date: Sun, 29 Jun 2025 22:25:26 +0300 Subject: [PATCH 5/6] Consume __extension__ --- cxxheaderparser/lexer.py | 1 + cxxheaderparser/parser.py | 1 + 2 files changed, 2 insertions(+) diff --git a/cxxheaderparser/lexer.py b/cxxheaderparser/lexer.py index 0d6d982..28839d9 100644 --- a/cxxheaderparser/lexer.py +++ b/cxxheaderparser/lexer.py @@ -100,6 +100,7 @@ class PlyLexer: "enum", "explicit", "export", + "__extension__", "extern", "false", "final", diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index bbdffd9..3c78b1b 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -302,6 +302,7 @@ def parse(self) -> None: ] = { "__attribute__": self._consume_gcc_attribute, "__declspec": self._consume_declspec, + "__extension__": lambda _1, _2: None, "alignas": self._consume_attribute_specifier_seq, "extern": self._parse_extern, "friend": self._parse_friend_decl, From 65dafc53073d0b529970b0af9aae72a8e31092c3 Mon Sep 17 00:00:00 2001 From: Eldar Khayrullin Date: Sun, 29 Jun 2025 22:43:47 +0300 Subject: [PATCH 6/6] Bitfield use const expr as bit-width --- cxxheaderparser/parser.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index 3c78b1b..76a04d1 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -1401,8 +1401,15 @@ def _discard_ctor_initializer(self) -> None: def _parse_bitfield(self) -> int: # is a integral constant expression... for now, just do integers - tok = self._next_token_must_be("INT_CONST_DEC") - return int(tok.value) + const_expr = '' + while True: + tok = self.lex.token_if_not("=", ";") + if tok: + const_expr += tok.value + else: + break + + return int(eval(const_expr)) def _parse_field( self,