mimic++ v10.0.1
Loading...
Searching...
No Matches
ParserState.hpp
Go to the documentation of this file.
1// Copyright Dominic (DNKpp) Koepke 2026.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef MIMICPP_PRINTING_TYPE_PARSER_STATE_HPP
7#define MIMICPP_PRINTING_TYPE_PARSER_STATE_HPP
8
9#pragma once
10
15
16#ifndef MIMICPP_DETAIL_IS_MODULE
17 #include <array>
18 #include <functional>
19 #include <optional>
20 #include <utility>
21 #include <variant>
22 #include <vector>
23#endif
24
26{
27 struct TypeId;
28
29 template <typename T>
31 {
32 public:
33 constexpr ~Recursive();
34 constexpr Recursive(Recursive const&);
35 constexpr Recursive& operator=(Recursive const&);
36 constexpr Recursive(Recursive&&) noexcept;
37 constexpr Recursive& operator=(Recursive&&) noexcept;
38
39 [[nodiscard]]
40 explicit(false) constexpr Recursive(T value)
41 : m_inner{std::move(value)}
42 {
43 }
44
45 [[nodiscard]]
46 constexpr T& operator*() noexcept
47 {
48 return *m_inner;
49 }
50
51 [[nodiscard]]
52 constexpr T const& operator*() const noexcept
53 {
54 return *m_inner;
55 }
56
57 [[nodiscard]]
58 constexpr bool operator==(Recursive const&) const;
59
60 private:
62 };
63
64 template <typename T>
66
67 template <typename T>
69
70 // see: https://eel.is/c++draft/class.pre#nt:class-key
77
78 // see: https://eel.is/c++draft/dcl.enum#nt:enum-key
85
86 enum class CVQualifier
87 {
90 };
91
93 {
94 bool isConst{false};
95 bool isVolatile{false};
96
97 [[nodiscard]]
98 bool operator==(CVQualifierSeq const&) const = default;
99
100 [[nodiscard]]
101 constexpr bool apply(CVQualifier const qualifier) noexcept
102 {
103 switch (qualifier)
104 {
106 return !std::exchange(isConst, true);
107
109 return !std::exchange(isVolatile, true);
110
111 default:
113 }
114 }
115 };
116
118 {
121 };
122
124
126 {
127 std::string_view content{};
128 bool isSynthetic{false};
129
130 [[nodiscard]]
131 bool operator==(Identifier const&) const = default;
132 };
133
135 {
136 std::vector<Recursive<TypeId>> params{};
138 std::optional<RefQualifier> refQualifier{};
139 bool isNoexcept{false};
140
141 [[nodiscard]]
142 bool operator==(FunctionDeclarator const&) const = default;
143 };
144
145 using TemplateArgument = std::variant<
148
149 using TemplateArgumentList = std::vector<TemplateArgument>;
150
152 {
153 using Symbol = std::variant<
155 std::pair<lexing::keyword, bool /*isArray*/>,
156 std::array<lexing::operator_or_punctuator, 2u>>;
158
159 [[nodiscard]]
160 constexpr bool is_call() const noexcept
161 {
162 if (auto const* const doubleOp = std::get_if<std::array<lexing::operator_or_punctuator, 2u>>(&symbol))
163 {
164 return lexing::operator_or_punctuator{"("} == doubleOp->front()
165 && lexing::operator_or_punctuator{")"} == doubleOp->back();
166 }
167
168 return false;
169 }
170
171 [[nodiscard]]
172 bool operator==(OperatorFunctionId const&) const = default;
173 };
174
176 {
178
179 [[nodiscard]]
180 bool operator==(ConversionFunctionId const&) const = default;
181 };
182
184 {
185 std::string_view content;
186 bool isMutable{false};
187
188 [[nodiscard]]
189 bool operator==(LambdaFunctionId const&) const = default;
190 };
191
193 {
195
196 [[nodiscard]]
197 bool operator==(DestructorFunctionId const&) const = default;
198 };
199
201 {
202 using Name = std::variant<
209 std::optional<TemplateArgumentList> templateArgs{};
210 std::optional<FunctionDeclarator> functionDeclarator{};
211
212 [[nodiscard]]
213 bool operator==(UnqualifiedId const&) const = default;
214 };
215
216 // This models more or less: https://eel.is/c++draft/expr.prim.id.qual#nt:nested-name-specifier
218 {
220 std::vector<UnqualifiedId> scopes{};
221
222 [[nodiscard]]
223 bool operator==(ScopeSequence const&) const = default;
224 };
225
226 using TypeKey = std::variant<ClassKey, EnumKey>;
227
228 // see: https://eel.is/c++draft/expr.prim.id.qual#nt:qualified-id
230 {
233 std::optional<TypeKey> typeKey{};
234
235 [[nodiscard]]
236 bool operator==(QualifiedId const&) const = default;
237 };
238
240 {
241 std::optional<ConstantExpression> size{};
242
243 [[nodiscard]]
244 bool operator==(ArrayDeclarator const&) const = default;
245 };
246
248 {
250
251 [[nodiscard]]
252 bool operator==(CallConvention const&) const = default;
253 };
254
256 {
257 std::optional<CVQualifierSeq> qualifiers{};
258 std::optional<ScopeSequence> scopes{};
259 std::optional<CallConvention> callConvention{};
260
261 [[nodiscard]]
262 bool operator==(PointerDeclarator const&) const = default;
263 };
264
266 {
268
269 [[nodiscard]]
270 bool operator==(ReferenceDeclarator const&) const = default;
271 };
272
273 using PtrOperator = std::variant<
276
278 {
279 struct Layer
280 {
281 std::vector<PtrOperator> decorations{};
282 std::optional<Recursive<Layer>> nested{};
283 std::optional<FunctionDeclarator> function{};
284 std::vector<ArrayDeclarator> arrays{};
285
286 [[nodiscard]]
287 bool operator==(Layer const&) const = default;
288 };
289
291
292 [[nodiscard]]
293 bool operator==(AbstractDeclarator const&) const = default;
294 };
295
297 {
298 std::optional<lexing::keyword> base{};
299
300 enum class SizeSpec : std::int8_t
301 {
302 id_short = 0,
303 id_long,
304 id_longlong
305 };
306
307 std::optional<SizeSpec> sizeSpec{};
308
309 enum class SignedSpec : std::int8_t
310 {
311 id_signed = 0,
312 id_unsigned
313 };
314
315 std::optional<SignedSpec> signedSpec{};
316
317 [[nodiscard]]
319 {
320 return try_apply_size_spec(keyword)
321 || try_apply_signed_spec(keyword)
322 || try_apply_base(keyword);
323 }
324
325 [[nodiscard]]
326 bool operator==(BuiltinType const&) const = default;
327
328 private:
329 [[nodiscard]]
330 constexpr bool try_apply_base(lexing::keyword const& keyword) noexcept
331 {
332 // Todo: verify correct type keywords
333 if (!base)
334 {
335 base = keyword;
336 return true;
337 }
338
339 return false;
340 }
341
342 [[nodiscard]]
343 MIMICPP_DETAIL_CONSTEXPR_PRETTY_TYPES bool try_apply_signed_spec(lexing::keyword const& keyword) noexcept
344 {
345 std::optional const spec = std::invoke([&]() -> std::optional<SignedSpec> {
346 if (lexing::keyword{"unsigned"} == keyword)
347 {
349 }
350
351 if (lexing::keyword{"signed"} == keyword)
352 {
354 }
355
356 return std::nullopt;
357 });
358
359 if (spec
360 && !signedSpec)
361 {
362 signedSpec = spec;
363 return true;
364 }
365
366 return false;
367 }
368
369 [[nodiscard]]
370 MIMICPP_DETAIL_CONSTEXPR_PRETTY_TYPES bool try_apply_size_spec(lexing::keyword const& keyword) noexcept
371 {
372 std::optional const spec = std::invoke([&]() -> std::optional<SizeSpec> {
373 if (lexing::keyword{"long"} == keyword)
374 {
375 return SizeSpec::id_long;
376 }
377
378 if (lexing::keyword{"short"} == keyword)
379 {
380 return SizeSpec::id_short;
381 }
382
383 // This is a msvc symbol
384 if (lexing::keyword{"__int64"} == keyword)
385 {
387 }
388
389 return std::nullopt;
390 });
391
392 if (spec)
393 {
394 if (!sizeSpec)
395 {
396 sizeSpec = spec;
397 return true;
398 }
399
401 && *spec == SizeSpec::id_long)
402 {
404 return true;
405 }
406 }
407
408 return false;
409 }
410 };
411
412 using BaseType = std::variant<
415
416 struct TypeId
417 {
421
422 [[nodiscard]]
423 bool operator==(TypeId const&) const = default;
424 };
425
427 {
428 std::optional<TypeId> returnType{};
429 std::optional<CallConvention> callConvention{};
431
432 [[nodiscard]]
433 bool operator==(FunctionId const&) const = default;
434 };
435
436 template <typename T>
437 constexpr Recursive<T>::~Recursive() = default;
438 template <typename T>
439 constexpr Recursive<T>::Recursive(Recursive const&) = default;
440 template <typename T>
441 constexpr Recursive<T>& Recursive<T>::operator=(Recursive const&) = default;
442 template <typename T>
443 constexpr Recursive<T>::Recursive(Recursive&&) noexcept = default;
444 template <typename T>
445 constexpr Recursive<T>& Recursive<T>::operator=(Recursive&&) noexcept = default;
446 template <typename T>
447 constexpr bool Recursive<T>::operator==(Recursive const&) const = default;
448}
449
450#endif
#define MIMICPP_DETAIL_CONSTEXPR_PRETTY_TYPES
Definition Config.hpp:93
constexpr T const & operator*() const noexcept
Definition ParserState.hpp:52
constexpr T & operator*() noexcept
Definition ParserState.hpp:46
constexpr bool operator==(Recursive const &) const
explicit(false) const expr Recursive(T value)
Definition ParserState.hpp:40
constexpr Recursive & operator=(Recursive const &)
constexpr Recursive(Recursive &&) noexcept
Simple copyable value type, which owns a heap-allocated value.
Definition CopyableBox.hpp:31
Definition ParserState.hpp:26
EnumKey
Definition ParserState.hpp:80
@ id_enum_class
Definition ParserState.hpp:82
@ id_enum
Definition ParserState.hpp:81
@ id_enum_struct
Definition ParserState.hpp:83
lexing::literal ConstantExpression
Definition ParserState.hpp:123
std::vector< TemplateArgument > TemplateArgumentList
Definition ParserState.hpp:149
std::variant< ReferenceDeclarator, PointerDeclarator > PtrOperator
Definition ParserState.hpp:273
std::variant< ClassKey, EnumKey > TypeKey
Definition ParserState.hpp:226
RefQualifier
Definition ParserState.hpp:118
@ id_ref
Definition ParserState.hpp:119
@ id_refref
Definition ParserState.hpp:120
std::variant< QualifiedId, BuiltinType > BaseType
Definition ParserState.hpp:412
ClassKey
Definition ParserState.hpp:72
@ id_union
Definition ParserState.hpp:75
@ id_struct
Definition ParserState.hpp:74
@ id_class
Definition ParserState.hpp:73
std::variant< ConstantExpression, Recursive< TypeId > > TemplateArgument
Definition ParserState.hpp:145
CVQualifier
Definition ParserState.hpp:87
void unreachable()
Invokes undefined behavior.
Definition C++23Backports.hpp:40
std::optional< Recursive< Layer > > nested
Definition ParserState.hpp:282
std::vector< PtrOperator > decorations
Definition ParserState.hpp:281
std::optional< FunctionDeclarator > function
Definition ParserState.hpp:283
std::vector< ArrayDeclarator > arrays
Definition ParserState.hpp:284
bool operator==(AbstractDeclarator const &) const =default
bool operator==(ArrayDeclarator const &) const =default
std::optional< ConstantExpression > size
Definition ParserState.hpp:241
std::optional< SignedSpec > signedSpec
Definition ParserState.hpp:315
MIMICPP_DETAIL_CONSTEXPR_PRETTY_TYPES bool try_apply(lexing::keyword const &keyword)
Definition ParserState.hpp:318
std::optional< SizeSpec > sizeSpec
Definition ParserState.hpp:307
std::optional< lexing::keyword > base
Definition ParserState.hpp:298
bool operator==(BuiltinType const &) const =default
constexpr bool apply(CVQualifier const qualifier) noexcept
Definition ParserState.hpp:101
bool operator==(CVQualifierSeq const &) const =default
bool operator==(CallConvention const &) const =default
lexing::identifier name
Definition ParserState.hpp:249
Recursive< TypeId > target
Definition ParserState.hpp:177
bool operator==(ConversionFunctionId const &) const =default
bool operator==(DestructorFunctionId const &) const =default
Identifier name
Definition ParserState.hpp:194
CVQualifierSeq qualifiers
Definition ParserState.hpp:137
bool operator==(FunctionDeclarator const &) const =default
std::vector< Recursive< TypeId > > params
Definition ParserState.hpp:136
std::optional< RefQualifier > refQualifier
Definition ParserState.hpp:138
bool operator==(FunctionId const &) const =default
QualifiedId identifier
Definition ParserState.hpp:430
std::optional< TypeId > returnType
Definition ParserState.hpp:428
std::optional< CallConvention > callConvention
Definition ParserState.hpp:429
std::string_view content
Definition ParserState.hpp:127
bool operator==(Identifier const &) const =default
bool isSynthetic
Definition ParserState.hpp:128
bool operator==(LambdaFunctionId const &) const =default
std::string_view content
Definition ParserState.hpp:185
constexpr bool is_call() const noexcept
Definition ParserState.hpp:160
bool operator==(OperatorFunctionId const &) const =default
std::variant< lexing::operator_or_punctuator, std::pair< lexing::keyword, bool >, std::array< lexing::operator_or_punctuator, 2u > > Symbol
Definition ParserState.hpp:153
std::optional< ScopeSequence > scopes
Definition ParserState.hpp:258
std::optional< CVQualifierSeq > qualifiers
Definition ParserState.hpp:257
bool operator==(PointerDeclarator const &) const =default
std::optional< CallConvention > callConvention
Definition ParserState.hpp:259
UnqualifiedId identifier
Definition ParserState.hpp:232
bool operator==(QualifiedId const &) const =default
std::optional< TypeKey > typeKey
Definition ParserState.hpp:233
ScopeSequence scopes
Definition ParserState.hpp:231
RefQualifier qualifier
Definition ParserState.hpp:267
bool operator==(ReferenceDeclarator const &) const =default
bool explicitRoot
Definition ParserState.hpp:219
bool operator==(ScopeSequence const &) const =default
std::vector< UnqualifiedId > scopes
Definition ParserState.hpp:220
CVQualifierSeq qualifications
Definition ParserState.hpp:418
AbstractDeclarator declarator
Definition ParserState.hpp:420
bool operator==(TypeId const &) const =default
BaseType base
Definition ParserState.hpp:419
bool operator==(UnqualifiedId const &) const =default
std::variant< Identifier, OperatorFunctionId, ConversionFunctionId, LambdaFunctionId, DestructorFunctionId > Name
Definition ParserState.hpp:202
std::optional< FunctionDeclarator > functionDeclarator
Definition ParserState.hpp:210
std::optional< TemplateArgumentList > templateArgs
Definition ParserState.hpp:209