From a3b3c43a76071ac12954321c8ab8a69fd19271e3 Mon Sep 17 00:00:00 2001 From: Patrick Wuttke Date: Fri, 5 Jan 2024 14:49:26 +0100 Subject: [PATCH] Added very basic support for constinit and consteval. --- cxxheaderparser/lexer.py | 2 + cxxheaderparser/parser.py | 4 +- cxxheaderparser/types.py | 3 + tests/test_constinit_consteval.py | 104 ++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 tests/test_constinit_consteval.py diff --git a/cxxheaderparser/lexer.py b/cxxheaderparser/lexer.py index 15dec34..a3f363f 100644 --- a/cxxheaderparser/lexer.py +++ b/cxxheaderparser/lexer.py @@ -86,6 +86,8 @@ class PlyLexer: "concept", "const", "constexpr", + "consteval", + "constinit", "const_cast", "continue", "decltype", diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index bb03dee..42edd6c 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -2148,6 +2148,8 @@ class CxxParser: if fn.constexpr: raise CxxParseError("typedef function may not be constexpr") + if fn.consteval: + raise CxxParseError("typedef function may not be consteval") if fn.extern: raise CxxParseError("typedef function may not be extern") if fn.static: @@ -2318,7 +2320,7 @@ class CxxParser: return dtype # Applies to variables and return values - _type_kwd_both = {"const", "constexpr", "extern", "inline", "static"} + _type_kwd_both = {"const", "consteval", "constexpr", "constinit", "extern", "inline", "static"} # Only found on methods _type_kwd_meth = {"explicit", "virtual"} diff --git a/cxxheaderparser/types.py b/cxxheaderparser/types.py index e078a4a..316e8c4 100644 --- a/cxxheaderparser/types.py +++ b/cxxheaderparser/types.py @@ -721,6 +721,7 @@ class Function: doxygen: typing.Optional[str] = None constexpr: bool = False + consteval: bool = False extern: typing.Union[bool, str] = False static: bool = False inline: bool = False @@ -857,6 +858,7 @@ class Variable: value: typing.Optional[Value] = None constexpr: bool = False + constinit: bool = False extern: typing.Union[bool, str] = False static: bool = False inline: bool = False @@ -883,6 +885,7 @@ class Field: bits: typing.Optional[int] = None constexpr: bool = False + constinit: bool = False mutable: bool = False static: bool = False inline: bool = False diff --git a/tests/test_constinit_consteval.py b/tests/test_constinit_consteval.py new file mode 100644 index 0000000..c1b3db3 --- /dev/null +++ b/tests/test_constinit_consteval.py @@ -0,0 +1,104 @@ +def test_constinit_consteval() -> None: + content = """ + struct S + { + static constinit int i = 5; + + static consteval int func(int i) { return i*i; } + }; + + template + consteval auto getUintType() + { + if constexpr (numBits == 8) { + return std::uint8_t{}; + } + else if constexpr (numBits == 16) { + return std::uint16_t{}; + } + else if constexpr (numBits == 32) { + return std::uint32_t{}; + } + else if constexpr (numBits == 64) { + return std::uint64_t{}; + } + } + """ + data = parse_string(content, cleandoc=True) + + assert data == ParsedData( + namespace=NamespaceScope( + classes=[ + ClassScope( + class_decl=ClassDecl( + typename=PQName( + segments=[NameSpecifier(name="S")], classkey="struct" + ) + ), + fields=[ + Field( + access="public", + type=Type( + typename=PQName( + segments=[FundamentalSpecifier(name="int")] + ) + ), + name="i", + value=Value(tokens=[Token(value="5")]), + constinit=True, + static=True, + ) + ], + methods=[ + Method( + return_type=Type( + typename=PQName( + segments=[FundamentalSpecifier(name="int")] + ) + ), + name=PQName(segments=[NameSpecifier(name="func")]), + parameters=[ + Parameter( + type=Type( + typename=PQName( + segments=[FundamentalSpecifier(name="int")] + ) + ), + name="i", + ) + ], + consteval=True, + static=True, + has_body=True, + access="public", + ) + ], + ) + ], + functions=[ + Function( + return_type=Type(typename=PQName(segments=[AutoSpecifier()])), + name=PQName(segments=[NameSpecifier(name="getUintType")]), + parameters=[], + consteval=True, + has_body=True, + template=TemplateDecl( + params=[ + TemplateNonTypeParam( + type=Type( + typename=PQName( + segments=[ + NameSpecifier(name="std"), + NameSpecifier(name="size_t"), + ] + ) + ), + name="numBits", + ) + ] + ), + ) + ], + ) + ) +