GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 92.4% 339 / 10 / 377
Functions: 92.4% 291 / 5 / 320
Branches: 57.5% 115 / 0 / 200

src/ast/ASTNodes.h
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #pragma once
4
5 #include <cmath>
6 #include <queue>
7 #include <utility>
8 #include <vector>
9
10 #include <ast/ASTVisitor.h>
11 #include <ast/ParallelizableASTVisitor.h>
12 #include <exception/CompilerError.h>
13 #include <model/Function.h>
14 #include <symboltablebuilder/QualType.h>
15 #include <symboltablebuilder/TypeChain.h>
16 #include <symboltablebuilder/TypeQualifiers.h>
17 #include <util/CodeLoc.h>
18 #include <util/GlobalDefinitions.h>
19
20 namespace spice::compiler {
21
22 // Forward declarations
23 class TopLevelDefNode;
24 class Capture;
25 using Arg = std::pair</*type=*/QualType, /*isTemporary=*/bool>;
26 using ArgList = std::vector<Arg>;
27
28 // Macros
29 #define GET_CHILDREN(...) \
30 std::vector<ASTNode *> getChildren() const override { return collectChildren(__VA_ARGS__); }
31
32 // Operator overload function names
33 constexpr const char *const OP_FCT_PREFIX = "op.";
34 constexpr const char *const OP_FCT_PLUS = "op.plus";
35 constexpr const char *const OP_FCT_MINUS = "op.minus";
36 constexpr const char *const OP_FCT_MUL = "op.mul";
37 constexpr const char *const OP_FCT_DIV = "op.div";
38 constexpr const char *const OP_FCT_EQUAL = "op.equal";
39 constexpr const char *const OP_FCT_NOT_EQUAL = "op.notequal";
40 constexpr const char *const OP_FCT_SHL = "op.shl";
41 constexpr const char *const OP_FCT_SHR = "op.shr";
42 constexpr const char *const OP_FCT_PLUS_EQUAL = "op.plusequal";
43 constexpr const char *const OP_FCT_MINUS_EQUAL = "op.minusequal";
44 constexpr const char *const OP_FCT_MUL_EQUAL = "op.mulequal";
45 constexpr const char *const OP_FCT_DIV_EQUAL = "op.divequal";
46 constexpr const char *const OP_FCT_POSTFIX_PLUS_PLUS = "op.plusplus.post";
47 constexpr const char *const OP_FCT_POSTFIX_MINUS_MINUS = "op.minusminus.post";
48 constexpr const char *const OP_FCT_SUBSCRIPT = "op.subscript";
49
50 /**
51 * Saves a constant value for an AST node to realize features like array-out-of-bounds checks
52 */
53 union CompileTimeValue {
54 double_t doubleValue;
55 int32_t intValue;
56 int16_t shortValue;
57 int64_t longValue;
58 int8_t charValue;
59 bool boolValue;
60 size_t stringValueOffset = 0; // Offset into vector of strings in GlobalResourceManager
61 };
62
63 // Make sure we have no unexpected increases in memory consumption
64 static_assert(sizeof(CompileTimeValue) == 8);
65
66 // =========================================================== AstNode ===========================================================
67
68 class ASTNode {
69 public:
70 // Constructors
71 667510 explicit ASTNode(const CodeLoc &codeLoc) : codeLoc(codeLoc) {}
72 667510 virtual ~ASTNode() = default;
73
74 // Prevent copy
75 ASTNode(const ASTNode &) = delete;
76 ASTNode &operator=(const ASTNode &) = delete;
77
78 // Virtual methods
79 virtual std::any accept(AbstractASTVisitor *visitor) = 0;
80 virtual std::any accept(ParallelizableASTVisitor *visitor) const = 0;
81
82 2754534 template <typename... Args> [[nodiscard]] ALWAYS_INLINE std::vector<ASTNode *> collectChildren(Args &&...args) const {
83 2754534 std::vector<ASTNode *> children;
84
85 // Lambda to handle each argument
86 5340669 [[maybe_unused]] const auto addChild = [&children]<typename T>(T &&arg) ALWAYS_INLINE {
87 using TDecayed = std::decay_t<T>;
88 if constexpr (std::is_pointer_v<TDecayed>) {
89
17/18
✓ Branch 3 → 4 taken 826771 times.
✓ Branch 3 → 6 taken 1096463 times.
✓ Branch 9 → 10 taken 765962 times.
✓ Branch 9 → 12 taken 873896 times.
✓ Branch 12 → 13 taken 168 times.
✗ Branch 12 → 15 not taken.
✓ Branch 15 → 16 taken 114763 times.
✓ Branch 15 → 18 taken 895457 times.
✓ Branch 18 → 19 taken 30 times.
✓ Branch 18 → 21 taken 27 times.
✓ Branch 21 → 22 taken 48455 times.
✓ Branch 21 → 24 taken 155987 times.
✓ Branch 27 → 28 taken 17709 times.
✓ Branch 27 → 30 taken 175694 times.
✓ Branch 33 → 34 taken 44908 times.
✓ Branch 33 → 36 taken 148495 times.
✓ Branch 39 → 40 taken 42830 times.
✓ Branch 39 → 42 taken 133054 times.
5340669 if (arg != nullptr)
90
9/18
✓ Branch 4 → 5 taken 826771 times.
✗ Branch 4 → 7 not taken.
✓ Branch 10 → 11 taken 765962 times.
✗ Branch 10 → 13 not taken.
✓ Branch 13 → 14 taken 168 times.
✗ Branch 13 → 16 not taken.
✓ Branch 16 → 17 taken 114763 times.
✗ Branch 16 → 19 not taken.
✓ Branch 19 → 20 taken 30 times.
✗ Branch 19 → 22 not taken.
✓ Branch 22 → 23 taken 48455 times.
✗ Branch 22 → 25 not taken.
✓ Branch 28 → 29 taken 17709 times.
✗ Branch 28 → 31 not taken.
✓ Branch 34 → 35 taken 44908 times.
✗ Branch 34 → 37 not taken.
✓ Branch 40 → 41 taken 42830 times.
✗ Branch 40 → 43 not taken.
1861596 children.push_back(arg);
91 } else if constexpr (is_vector_of_derived_from_v<TDecayed, ASTNode>) {
92
5/10
✓ Branch 7 → 8 taken 517560 times.
✗ Branch 7 → 9 not taken.
✓ Branch 13 → 14 taken 57 times.
✗ Branch 13 → 15 not taken.
✓ Branch 16 → 17 taken 7104 times.
✗ Branch 16 → 18 not taken.
✓ Branch 25 → 26 taken 7299 times.
✗ Branch 25 → 27 not taken.
✓ Branch 31 → 32 taken 3340 times.
✗ Branch 31 → 33 not taken.
535360 children.insert(children.end(), arg.begin(), arg.end());
93 } else {
94 static_assert(false, "Unsupported type");
95 }
96 };
97
98 3435235 (addChild(std::forward<Args>(args)), ...);
99 2440794 return children;
100 }
101
102 [[nodiscard]] virtual std::vector<ASTNode *> getChildren() const = 0;
103
104 1739818 virtual void resizeToNumberOfManifestations(size_t manifestationCount) { // NOLINT(misc-no-recursion)
105 // Resize children
106
3/4
✓ Branch 2 → 3 taken 1739818 times.
✗ Branch 2 → 17 not taken.
✓ Branch 11 → 5 taken 1710345 times.
✓ Branch 11 → 12 taken 1739818 times.
3450163 for (ASTNode *child : getChildren()) {
107
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 1710345 times.
1710345 assert(child != nullptr);
108
1/2
✓ Branch 8 → 9 taken 1710345 times.
✗ Branch 8 → 15 not taken.
1710345 child->resizeToNumberOfManifestations(manifestationCount);
109 1739818 }
110 // Do custom work
111 1739818 customItemsInitialization(manifestationCount);
112 1739818 }
113
114 virtual std::vector<std::vector<const Function *>> *getOpFctPointers() { // LCOV_EXCL_LINE
115 assert_fail("The given node does not overload the getOpFctPointers function"); // LCOV_EXCL_LINE
116 return nullptr; // LCOV_EXCL_LINE
117 } // LCOV_EXCL_LINE
118 [[nodiscard]] virtual const std::vector<std::vector<const Function *>> *getOpFctPointers() const { // LCOV_EXCL_LINE
119 assert_fail("The given node does not overload the getOpFctPointers function"); // LCOV_EXCL_LINE
120 return nullptr; // LCOV_EXCL_LINE
121 } // LCOV_EXCL_LINE
122
123 998868 virtual void customItemsInitialization(size_t) {} // Noop
124
125 9615 [[nodiscard]] virtual bool hasCompileTimeValue(size_t manIdx) const { // NOLINT(misc-no-recursion)
126
1/2
✓ Branch 2 → 3 taken 9615 times.
✗ Branch 2 → 14 not taken.
9615 const std::vector<ASTNode *> children = getChildren();
127
2/2
✓ Branch 4 → 5 taken 4478 times.
✓ Branch 4 → 6 taken 5137 times.
9615 if (children.size() != 1)
128 4478 return false;
129
1/2
✓ Branch 7 → 8 taken 5137 times.
✗ Branch 7 → 12 not taken.
5137 return children.front()->hasCompileTimeValue(manIdx);
130 9615 }
131
132 1831 [[nodiscard]] virtual CompileTimeValue getCompileTimeValue(size_t manIdx) const { // NOLINT(misc-no-recursion)
133
1/2
✓ Branch 2 → 3 taken 1831 times.
✗ Branch 2 → 14 not taken.
1831 const std::vector<ASTNode *> children = getChildren();
134
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 1831 times.
1831 if (children.size() != 1)
135 return {};
136
1/2
✓ Branch 7 → 8 taken 1831 times.
✗ Branch 7 → 12 not taken.
1831 return children.front()->getCompileTimeValue(manIdx);
137 1831 }
138
139 [[nodiscard]] std::string getErrorMessage() const;
140
141 34984 [[nodiscard]] virtual bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable,
142 size_t manIdx) const { // NOLINT(misc-no-recursion)
143
1/2
✓ Branch 2 → 3 taken 34984 times.
✗ Branch 2 → 16 not taken.
34984 const std::vector<ASTNode *> children = getChildren();
144
5/6
✓ Branch 4 → 5 taken 28976 times.
✓ Branch 4 → 9 taken 6008 times.
✓ Branch 6 → 7 taken 28976 times.
✗ Branch 6 → 14 not taken.
✓ Branch 7 → 8 taken 4222 times.
✓ Branch 7 → 9 taken 24754 times.
69968 return children.size() == 1 && children.front()->returnsOnAllControlPaths(doSetPredecessorsUnreachable, manIdx);
145 34984 }
146
147 [[nodiscard]] virtual std::vector<Function *> *getFctManifestations(const std::string &) { // LCOV_EXCL_LINE
148 assert_fail("Must be called on a FctDefNode, ProcDefNode, ExtDeclNode, StructDefNode or SignatureNode"); // LCOV_EXCL_LINE
149 return nullptr; // LCOV_EXCL_LINE
150 } // LCOV_EXCL_LINE
151
152 [[nodiscard]] virtual std::vector<Struct *> *getStructManifestations() { // LCOV_EXCL_LINE
153 assert_fail("Must be called on a StructDefNode"); // LCOV_EXCL_LINE
154 return nullptr; // LCOV_EXCL_LINE
155 } // LCOV_EXCL_LINE
156
157 [[nodiscard]] virtual std::vector<Interface *> *getInterfaceManifestations() { // LCOV_EXCL_LINE
158 assert_fail("Must be called on a InterfaceDefNode"); // LCOV_EXCL_LINE
159 return nullptr; // LCOV_EXCL_LINE
160 } // LCOV_EXCL_LINE
161
162 [[nodiscard]] const StmtLstNode *getNextOuterStmtLst() const;
163
164 186730 [[nodiscard]] virtual bool isFctOrProcDef() const { return false; }
165 155857 [[nodiscard]] virtual bool isStructDef() const { return false; }
166 12 [[nodiscard]] virtual bool isParam() const { return false; }
167 2896 [[nodiscard]] virtual bool isStmtLst() const { return false; }
168 36445 [[nodiscard]] virtual bool isAssignExpr() const { return false; }
169 36121 [[nodiscard]] virtual bool isExprStmt() const { return false; }
170
171 // Public members
172 ASTNode *parent = nullptr;
173 const CodeLoc codeLoc;
174 };
175
176 // Make sure we have no unexpected increases in memory consumption
177 // Note: If this is adjusted, please run UnitBlockAllocator, which depends on the ASTNode size
178 static_assert(sizeof(ASTNode) == 48);
179
180 // ========================================================== EntryNode ==========================================================
181
182 class EntryNode final : public ASTNode {
183 public:
184 // Constructors
185 using ASTNode::ASTNode;
186
187 // Visitor methods
188 6132 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEntry(this); }
189 999 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEntry(this); }
190
191 // Other methods
192 7104 GET_CHILDREN(modAttrs, importDefs, topLevelDefs);
193
194 // Public members
195 std::vector<ModAttrNode *> modAttrs;
196 std::vector<ImportDefNode *> importDefs;
197 std::vector<TopLevelDefNode *> topLevelDefs;
198 };
199
200 // ======================================================= TopLevelDefNode =======================================================
201
202 class TopLevelDefNode : public ASTNode {
203 public:
204 // Constructors
205 using ASTNode::ASTNode;
206
207 // Visitor methods
208 std::any accept(AbstractASTVisitor *visitor) override = 0;
209 std::any accept(ParallelizableASTVisitor *visitor) const override = 0;
210 };
211
212 // =========================================================== StmtNode ==========================================================
213
214 class StmtNode : public ASTNode {
215 public:
216 // Constructors
217 using ASTNode::ASTNode;
218
219 // Visitor methods
220 std::any accept(AbstractASTVisitor *visitor) override = 0;
221 std::any accept(ParallelizableASTVisitor *visitor) const override = 0;
222
223 // Public members
224 bool unreachable = false;
225 };
226
227 // Make sure we have no unexpected increases in memory consumption
228 static_assert(sizeof(StmtNode) == 56);
229
230 // ========================================================== ExprNode ===========================================================
231
232 class ExprNode : public ASTNode {
233 public:
234 // Constructors
235 using ASTNode::ASTNode;
236
237 // Visitor methods
238 std::any accept(AbstractASTVisitor *visitor) override = 0;
239 std::any accept(ParallelizableASTVisitor *visitor) const override = 0;
240
241 // Other methods
242 1059096 void resizeToNumberOfManifestations(size_t manifestationCount) override {
243 // Reserve this node
244
2/4
✓ Branch 2 → 3 taken 1059096 times.
✗ Branch 2 → 6 not taken.
✓ Branch 3 → 4 taken 1059096 times.
✗ Branch 3 → 6 not taken.
1059096 symbolTypes.resize(manifestationCount, QualType(TY_INVALID));
245 // Call parent
246 1059096 ASTNode::resizeToNumberOfManifestations(manifestationCount);
247 1059096 }
248
249 320990 QualType setEvaluatedSymbolType(const QualType &symbolType, const size_t idx) {
250
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 320990 times.
320990 assert(symbolTypes.size() > idx);
251 320990 symbolTypes.at(idx) = symbolType;
252 320990 return symbolType;
253 }
254
255 235809 [[nodiscard]] const QualType &getEvaluatedSymbolType(const size_t idx) const { // NOLINT(misc-no-recursion)
256
7/10
✓ Branch 3 → 4 taken 235809 times.
✗ Branch 3 → 8 not taken.
✓ Branch 4 → 5 taken 235809 times.
✗ Branch 4 → 47 not taken.
✓ Branch 5 → 6 taken 235809 times.
✗ Branch 5 → 47 not taken.
✓ Branch 6 → 7 taken 179739 times.
✓ Branch 6 → 8 taken 56070 times.
✓ Branch 9 → 10 taken 179739 times.
✓ Branch 9 → 12 taken 56070 times.
235809 if (!symbolTypes.empty() && !symbolTypes.at(idx).is(TY_INVALID))
257
1/2
✓ Branch 10 → 11 taken 179739 times.
✗ Branch 10 → 47 not taken.
179739 return symbolTypes.at(idx);
258
1/2
✓ Branch 12 → 13 taken 56070 times.
✗ Branch 12 → 47 not taken.
56070 const std::vector<ASTNode *> children = getChildren();
259
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 23 taken 56070 times.
56070 if (children.size() != 1)
260 throw CompilerError(INTERNAL_ERROR, "Cannot deduce evaluated symbol type");
261
1/2
✓ Branch 24 → 25 taken 56070 times.
✗ Branch 24 → 26 not taken.
56070 const auto expr = spice_pointer_cast<ExprNode *>(children.front());
262
1/2
✓ Branch 31 → 32 taken 56070 times.
✗ Branch 31 → 45 not taken.
56070 return expr->getEvaluatedSymbolType(idx);
263 56070 }
264
265 private:
266 // Private members
267 QualTypeList symbolTypes;
268 };
269
270 // Make sure we have no unexpected increases in memory consumption
271 static_assert(sizeof(ExprNode) == 72);
272
273 // ======================================================== MainFctDefNode =======================================================
274
275 class MainFctDefNode final : public TopLevelDefNode {
276 public:
277 // Constructors
278 using TopLevelDefNode::TopLevelDefNode;
279
280 // Visitor methods
281 1289 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitMainFctDef(this); }
282 264 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitMainFctDef(this); }
283
284 // Other methods
285 828 GET_CHILDREN(attrs, paramLst, body);
286
1/2
✓ Branch 4 → 5 taken 420 times.
✗ Branch 4 → 8 not taken.
1260 [[nodiscard]] static std::string getScopeId() { return "fct:main"; }
287 bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
288 [[nodiscard]] bool isFctOrProcDef() const override { return true; }
289
290 // Public members
291 TopLevelDefinitionAttrNode *attrs = nullptr;
292 ParamLstNode *paramLst = nullptr;
293 StmtLstNode *body = nullptr;
294 bool takesArgs = false;
295 SymbolTableEntry *entry = nullptr;
296 Scope *bodyScope = nullptr;
297 };
298
299 // ========================================================== FctNameNode =======================================================
300
301 class FctNameNode final : public ASTNode {
302 public:
303 // Constructors
304 using ASTNode::ASTNode;
305
306 // Visitor methods
307 12197 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFctName(this); }
308 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFctName(this); }
309
310 // Other methods
311 51385 GET_CHILDREN();
312 [[nodiscard]] constexpr bool isOperatorOverload() const { return name.starts_with(OP_FCT_PREFIX); }
313 [[nodiscard]] bool supportsInverseOperator() const { return name == OP_FCT_EQUAL || name == OP_FCT_NOT_EQUAL; }
314
315 // Public members
316 std::string name;
317 std::string structName;
318 std::string fqName;
319 std::vector<std::string> nameFragments;
320 };
321
322 // ======================================================== FctDefBaseNode =======================================================
323
324 class FctDefBaseNode : public TopLevelDefNode {
325 public:
326 // Constructors
327 using TopLevelDefNode::TopLevelDefNode;
328
329 // Other methods
330 25103 [[nodiscard]] std::string getSymbolTableEntryName() const { return Function::getSymbolTableEntryName(name->name, codeLoc); }
331 2862 std::vector<Function *> *getFctManifestations(const std::string &) override { return &manifestations; }
332 716583 [[nodiscard]] bool isFctOrProcDef() const override { return true; }
333 bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
334
335 // Public members
336 TopLevelDefinitionAttrNode *attrs = nullptr;
337 QualifierLstNode *qualifierLst = nullptr;
338 FctNameNode *name;
339 TypeLstNode *templateTypeLst = nullptr;
340 ParamLstNode *paramLst = nullptr;
341 StmtLstNode *body = nullptr;
342 bool isMethod = false;
343 bool hasTemplateTypes = false;
344 bool hasParams = false;
345 TypeQualifiers qualifiers = TypeQualifiers::of(TY_FUNCTION);
346 SymbolTableEntry *entry = nullptr;
347 Scope *structScope = nullptr;
348 Scope *scope = nullptr;
349 std::vector<Function *> manifestations;
350 };
351
352 // ========================================================== FctDefNode =========================================================
353
354 class FctDefNode final : public FctDefBaseNode {
355 public:
356 // Constructors
357 using FctDefBaseNode::FctDefBaseNode;
358
359 // Visitor methods
360 42120 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFctDef(this); }
361 7787 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFctDef(this); }
362
363 // Other methods
364 35188 GET_CHILDREN(attrs, qualifierLst, returnType, name, templateTypeLst, paramLst, body);
365
2/4
✓ Branch 2 → 3 taken 17258 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 17258 times.
✗ Branch 3 → 8 not taken.
17258 [[nodiscard]] std::string getScopeId() const { return "fct:" + codeLoc.toString(); }
366
367 // Public members
368 DataTypeNode *returnType = nullptr;
369 };
370
371 // ========================================================== ProcDefNode ========================================================
372
373 class ProcDefNode final : public FctDefBaseNode {
374 public:
375 // Constructors
376 using FctDefBaseNode::FctDefBaseNode;
377
378 // Visitor methods
379 21823 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitProcDef(this); }
380 4037 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitProcDef(this); }
381
382 // Other methods
383 17519 GET_CHILDREN(attrs, qualifierLst, name, templateTypeLst, paramLst, body);
384
2/4
✓ Branch 2 → 3 taken 8802 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 8802 times.
✗ Branch 3 → 8 not taken.
8802 [[nodiscard]] std::string getScopeId() const { return "proc:" + codeLoc.toString(); }
385
386 // Public members
387 bool isCtor = false;
388 };
389
390 // ========================================================= StructDefNode =======================================================
391
392 class StructDefNode final : public TopLevelDefNode {
393 public:
394 // Constructors
395 using TopLevelDefNode::TopLevelDefNode;
396
397 // Visitor methods
398 3341 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitStructDef(this); }
399 653 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitStructDef(this); }
400
401 // Other methods
402 3340 GET_CHILDREN(attrs, qualifierLst, templateTypeLst, interfaceTypeLst, fields);
403 26768 std::vector<Struct *> *getStructManifestations() override { return &structManifestations; }
404 511 std::vector<Function *> *getFctManifestations(const std::string &fctName) override {
405
2/2
✓ Branch 3 → 4 taken 337 times.
✓ Branch 3 → 10 taken 174 times.
511 if (!defaultFctManifestations.contains(fctName))
406
2/4
✓ Branch 5 → 6 taken 337 times.
✗ Branch 5 → 15 not taken.
✓ Branch 6 → 7 taken 337 times.
✗ Branch 6 → 13 not taken.
337 defaultFctManifestations.insert({fctName, {}});
407 511 return &defaultFctManifestations.at(fctName);
408 }
409 32699 [[nodiscard]] bool isStructDef() const override { return true; }
410
411 // Public members
412 TopLevelDefinitionAttrNode *attrs = nullptr;
413 QualifierLstNode *qualifierLst = nullptr;
414 TypeLstNode *templateTypeLst = nullptr;
415 TypeLstNode *interfaceTypeLst = nullptr;
416 std::vector<FieldNode *> fields;
417 bool hasTemplateTypes = false;
418 bool hasInterfaces = false;
419 bool emitVTable = false;
420 TypeQualifiers qualifiers = TypeQualifiers::of(TY_STRUCT);
421 std::string structName;
422 uint64_t typeId;
423 SymbolTableEntry *entry = nullptr;
424 std::vector<Struct *> structManifestations;
425 std::map<const std::string, std::vector<Function *>> defaultFctManifestations;
426 Scope *structScope = nullptr;
427 };
428
429 // ======================================================= InterfaceDefNode ======================================================
430
431 class InterfaceDefNode final : public TopLevelDefNode {
432 public:
433 // Constructors
434 using TopLevelDefNode::TopLevelDefNode;
435
436 // Visitor methods
437 417 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitInterfaceDef(this); }
438 91 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitInterfaceDef(this); }
439
440 // Other methods
441 195 GET_CHILDREN(attrs, qualifierLst, templateTypeLst, signatures);
442 165 std::vector<Interface *> *getInterfaceManifestations() override { return &interfaceManifestations; }
443
444 // Public members
445 TopLevelDefinitionAttrNode *attrs = nullptr;
446 QualifierLstNode *qualifierLst = nullptr;
447 TypeLstNode *templateTypeLst = nullptr;
448 std::vector<SignatureNode *> signatures;
449 bool hasTemplateTypes = false;
450 TypeQualifiers qualifiers = TypeQualifiers::of(TY_INTERFACE);
451 std::string interfaceName;
452 uint64_t typeId;
453 SymbolTableEntry *entry = nullptr;
454 std::vector<Interface *> interfaceManifestations;
455 Scope *interfaceScope = nullptr;
456 };
457
458 // ========================================================== EnumDefNode ========================================================
459
460 class EnumDefNode final : public TopLevelDefNode {
461 public:
462 // Constructors
463 using TopLevelDefNode::TopLevelDefNode;
464
465 // Visitor methods
466 352 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEnumDef(this); }
467 72 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEnumDef(this); }
468
469 // Other methods
470 140 GET_CHILDREN(qualifierLst, itemLst);
471
472 // Public members
473 QualifierLstNode *qualifierLst = nullptr;
474 EnumItemLstNode *itemLst = nullptr;
475 TypeQualifiers qualifiers = TypeQualifiers::of(TY_ENUM);
476 std::string enumName;
477 uint64_t typeId;
478 SymbolTableEntry *entry = nullptr;
479 Scope *enumScope;
480 };
481
482 // ====================================================== GenericTypeDefNode =====================================================
483
484 class GenericTypeDefNode final : public TopLevelDefNode {
485 public:
486 // Constructors
487 using TopLevelDefNode::TopLevelDefNode;
488
489 // Visitor methods
490 5063 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitGenericTypeDef(this); }
491 920 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitGenericTypeDef(this); }
492
493 // Other methods
494 1943 GET_CHILDREN(typeAltsLst);
495
496 // Public members
497 TypeAltsLstNode *typeAltsLst = nullptr;
498 std::string typeName;
499 SymbolTableEntry *entry = nullptr;
500 };
501
502 // ========================================================= AliasDefNode ========================================================
503
504 class AliasDefNode final : public TopLevelDefNode {
505 public:
506 // Constructors
507 using TopLevelDefNode::TopLevelDefNode;
508
509 // Visitor methods
510 449 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAliasDef(this); }
511 103 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAliasDef(this); }
512
513 // Other methods
514 201 GET_CHILDREN(qualifierLst, dataType);
515
516 // Public members
517 QualifierLstNode *qualifierLst = nullptr;
518 DataTypeNode *dataType = nullptr;
519 TypeQualifiers qualifiers = TypeQualifiers::of(TY_ALIAS);
520 std::string aliasName;
521 std::string dataTypeString;
522 uint64_t typeId;
523 SymbolTableEntry *entry = nullptr;
524 SymbolTableEntry *aliasedTypeContainerEntry = nullptr;
525 };
526
527 // ======================================================= GlobalVarDefNode ======================================================
528
529 class GlobalVarDefNode final : public TopLevelDefNode {
530 public:
531 // Constructors
532 using TopLevelDefNode::TopLevelDefNode;
533
534 // Visitor methods
535 5162 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitGlobalVarDef(this); }
536 1164 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitGlobalVarDef(this); }
537
538 // Other methods
539 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override { return true; }
540 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
541
542 // Other methods
543 2357 GET_CHILDREN(dataType, constant);
544
545 // Public members
546 DataTypeNode *dataType = nullptr;
547 ConstantNode *constant = nullptr;
548 bool hasValue = false;
549 std::string varName;
550 SymbolTableEntry *entry = nullptr;
551 };
552
553 // ========================================================== ExtDeclNode ========================================================
554
555 class ExtDeclNode final : public TopLevelDefNode {
556 public:
557 // Constructors
558 using TopLevelDefNode::TopLevelDefNode;
559
560 // Visitor methods
561 5323 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitExtDecl(this); }
562 1042 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitExtDecl(this); }
563
564 // Other methods
565 2143 GET_CHILDREN(attrs, returnType, argTypeLst);
566 79 std::vector<Function *> *getFctManifestations(const std::string &) override { return &extFunctionManifestations; }
567 2152 [[nodiscard]] std::string getScopeId() const {
568
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2152 times.
2152 const char *prefix = hasReturnType ? "func:" : "proc:";
569
2/4
✓ Branch 5 → 6 taken 2152 times.
✗ Branch 5 → 13 not taken.
✓ Branch 6 → 7 taken 2152 times.
✗ Branch 6 → 11 not taken.
2152 return prefix + codeLoc.toString();
570 }
571
572 // Public members
573 TopLevelDefinitionAttrNode *attrs = nullptr;
574 DataTypeNode *returnType = nullptr;
575 TypeLstWithEllipsisNode *argTypeLst = nullptr;
576 bool hasArgs = false;
577 bool hasReturnType = false;
578 std::string extFunctionName;
579 SymbolTableEntry *entry = nullptr;
580 Function *extFunction = nullptr;
581 std::vector<Function *> extFunctionManifestations;
582 };
583
584 // ======================================================== ImportDefNode ========================================================
585
586 class ImportDefNode final : public TopLevelDefNode {
587 public:
588 // Constructors
589 using TopLevelDefNode::TopLevelDefNode;
590
591 // Visitor methods
592 3537 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitImportDef(this); }
593 602 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitImportDef(this); }
594
595 // Other methods
596 2354 GET_CHILDREN();
597
598 // Public members
599 std::string importPath;
600 std::string importName;
601 SymbolTableEntry *entry = nullptr;
602 };
603
604 // ======================================================== UnsafeBlockNode ======================================================
605
606 class UnsafeBlockNode final : public StmtNode {
607 public:
608 // Constructors
609 using StmtNode::StmtNode;
610
611 // Visitor methods
612 7806 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitUnsafeBlock(this); }
613 2237 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitUnsafeBlockDef(this); }
614
615 // Other methods
616 14724 GET_CHILDREN(body);
617
2/4
✓ Branch 2 → 3 taken 7344 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 7344 times.
✗ Branch 3 → 8 not taken.
7344 [[nodiscard]] std::string getScopeId() const { return "unsafe:" + codeLoc.toString(); }
618
619 // Public members
620 StmtLstNode *body = nullptr;
621 Scope *bodyScope = nullptr;
622 };
623
624 // ========================================================== ForLoopNode ========================================================
625
626 class ForLoopNode final : public StmtNode {
627 public:
628 // Constructors
629 using StmtNode::StmtNode;
630
631 // Visitor methods
632 4287 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitForLoop(this); }
633 1324 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitForLoop(this); }
634
635 // Other methods
636 6652 GET_CHILDREN(initDecl, condAssign, incAssign, body);
637
2/4
✓ Branch 2 → 3 taken 4205 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 4205 times.
✗ Branch 3 → 8 not taken.
4205 [[nodiscard]] std::string getScopeId() const { return "for:" + codeLoc.toString(); }
638 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
639
640 // Public members
641 DeclStmtNode *initDecl = nullptr;
642 ExprNode *condAssign = nullptr;
643 ExprNode *incAssign = nullptr;
644 StmtLstNode *body = nullptr;
645 Scope *bodyScope = nullptr;
646 };
647
648 // ======================================================== ForeachLoopNode ======================================================
649
650 class ForeachLoopNode final : public StmtNode {
651 public:
652 // Constructors
653 using StmtNode::StmtNode;
654
655 // Visitor methods
656 320 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitForeachLoop(this); }
657 114 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitForeachLoop(this); }
658
659 // Other methods
660 541 GET_CHILDREN(idxVarDecl, itemVarDecl, iteratorAssign, body);
661
2/4
✓ Branch 2 → 3 taken 356 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 356 times.
✗ Branch 3 → 8 not taken.
356 [[nodiscard]] std::string getScopeId() const { return "foreach:" + codeLoc.toString(); }
662
663 // Public members
664 DeclStmtNode *idxVarDecl = nullptr;
665 DeclStmtNode *itemVarDecl = nullptr;
666 ExprNode *iteratorAssign = nullptr;
667 StmtLstNode *body = nullptr;
668 Scope *bodyScope = nullptr;
669 Function *getIteratorFct = nullptr;
670 Function *getFct = nullptr;
671 Function *getIdxFct = nullptr;
672 Function *isValidFct = nullptr;
673 Function *nextFct = nullptr;
674 Function *calledItemCopyCtor = nullptr;
675 };
676
677 // ========================================================= WhileLoopNode =======================================================
678
679 class WhileLoopNode final : public StmtNode {
680 public:
681 // Constructors
682 using StmtNode::StmtNode;
683
684 // Visitor methods
685 2455 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitWhileLoop(this); }
686 753 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitWhileLoop(this); }
687
688 // Other methods
689 3978 GET_CHILDREN(condition, body);
690
2/4
✓ Branch 2 → 3 taken 2396 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 2396 times.
✗ Branch 3 → 8 not taken.
2396 [[nodiscard]] std::string getScopeId() const { return "while:" + codeLoc.toString(); }
691 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
692
693 // Public members
694 ExprNode *condition = nullptr;
695 StmtLstNode *body = nullptr;
696 Scope *bodyScope = nullptr;
697 };
698
699 // ======================================================== DoWhileLoopNode ======================================================
700
701 class DoWhileLoopNode final : public StmtNode {
702 public:
703 // Constructors
704 using StmtNode::StmtNode;
705
706 // Visitor methods
707 18 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitDoWhileLoop(this); }
708 7 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitDoWhileLoop(this); }
709
710 // Other methods
711 20 GET_CHILDREN(body, condition);
712
2/4
✓ Branch 2 → 3 taken 23 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 23 times.
✗ Branch 3 → 8 not taken.
23 [[nodiscard]] std::string getScopeId() const { return "dowhile:" + codeLoc.toString(); }
713 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
714
715 // Public members
716 StmtLstNode *body = nullptr;
717 ExprNode *condition = nullptr;
718 Scope *bodyScope = nullptr;
719 };
720
721 // ========================================================== IfStmtNode =========================================================
722
723 class IfStmtNode final : public StmtNode {
724 public:
725 // Constructors
726 using StmtNode::StmtNode;
727
728 // Visitor methods
729 13412 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitIfStmt(this); }
730 4417 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitIfStmt(this); }
731
732 // Other methods
733 19994 GET_CHILDREN(condition, thenBody, elseStmt);
734
2/4
✓ Branch 2 → 3 taken 13485 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 13485 times.
✗ Branch 3 → 8 not taken.
13485 [[nodiscard]] std::string getScopeId() const { return "if:" + codeLoc.toString(); }
735 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
736
737 // Public members
738 bool compileThenBranch = true;
739 bool compileElseBranch = true;
740 ExprNode *condition = nullptr;
741 StmtLstNode *thenBody = nullptr;
742 ElseStmtNode *elseStmt = nullptr;
743 Scope *thenBodyScope = nullptr;
744 };
745
746 // ========================================================= ElseStmtNode ========================================================
747
748 class ElseStmtNode final : public StmtNode {
749 public:
750 // Constructors
751 using StmtNode::StmtNode;
752
753 // Visitor methods
754 692 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitElseStmt(this); }
755 203 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitElseStmt(this); }
756
757 // Other methods
758 1087 GET_CHILDREN(ifStmt, body);
759
2/4
✓ Branch 2 → 3 taken 463 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 463 times.
✗ Branch 3 → 8 not taken.
463 [[nodiscard]] std::string getScopeId() const { return "if:" + codeLoc.toString(); }
760 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
761
762 // Public members
763 bool isElseIf = false;
764 IfStmtNode *ifStmt = nullptr;
765 StmtLstNode *body = nullptr;
766 Scope *elseBodyScope = nullptr;
767 };
768
769 // ======================================================== SwitchStmtNode =======================================================
770
771 class SwitchStmtNode final : public StmtNode {
772 public:
773 // Constructors
774 using StmtNode::StmtNode;
775
776 // Visitor methods
777 29 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitSwitchStmt(this); }
778 8 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitSwitchStmt(this); }
779
780 // Other methods
781 57 GET_CHILDREN(assignExpr, caseBranches, defaultBranch);
782 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
783
784 // Public members
785 ExprNode *assignExpr = nullptr;
786 std::vector<CaseBranchNode *> caseBranches;
787 DefaultBranchNode *defaultBranch = nullptr;
788 bool hasDefaultBranch = false;
789 };
790
791 // ======================================================== CaseBranchNode =======================================================
792
793 class CaseBranchNode final : public ASTNode {
794 public:
795 // Constructors
796 using ASTNode::ASTNode;
797
798 // Visitor methods
799 137 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitCaseBranch(this); }
800 49 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitCaseBranch(this); }
801
802 // Other methods
803 168 GET_CHILDREN(caseConstants, body);
804
2/4
✓ Branch 2 → 3 taken 155 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 155 times.
✗ Branch 3 → 8 not taken.
155 [[nodiscard]] std::string getScopeId() const { return "case:" + codeLoc.toString(); }
805 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
806
807 // Public members
808 std::vector<CaseConstantNode *> caseConstants;
809 StmtLstNode *body = nullptr;
810 Scope *bodyScope = nullptr;
811 };
812
813 // ======================================================= DefaultBranchNode =====================================================
814
815 class DefaultBranchNode final : public ASTNode {
816 public:
817 // Constructors
818 using ASTNode::ASTNode;
819
820 // Visitor methods
821 15 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitDefaultBranch(this); }
822 4 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitDefaultBranch(this); }
823
824 // Other methods
825 18 GET_CHILDREN(body);
826
2/4
✓ Branch 2 → 3 taken 16 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 16 times.
✗ Branch 3 → 8 not taken.
16 [[nodiscard]] std::string getScopeId() const { return "default:" + codeLoc.toString(); }
827 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
828
829 // Public members
830 StmtLstNode *body = nullptr;
831 Scope *bodyScope = nullptr;
832 };
833
834 // ==================================================== AnonymousBlockStmtNode ===================================================
835
836 class AnonymousBlockStmtNode final : public StmtNode {
837 public:
838 // Constructors
839 using StmtNode::StmtNode;
840
841 // Visitor methods
842 66 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAnonymousBlockStmt(this); }
843 33 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAnonymousBlockStmt(this); }
844
845 // Other methods
846 99 GET_CHILDREN(body);
847
2/4
✓ Branch 2 → 3 taken 99 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 99 times.
✗ Branch 3 → 8 not taken.
99 [[nodiscard]] std::string getScopeId() const { return "anon:" + codeLoc.toString(); }
848
849 // Public members
850 StmtLstNode *body = nullptr;
851 Scope *bodyScope = nullptr;
852 };
853
854 // ========================================================= StmtLstNode =========================================================
855
856 class StmtLstNode final : public ASTNode {
857 public:
858 // Structs
859 struct ResourcesForManifestationToCleanup {
860 std::vector<std::pair<SymbolTableEntry *, Function *>> dtorFunctionsToCall;
861 std::vector<SymbolTableEntry *> heapVarsToFree;
862 };
863
864 // Constructors
865 using ASTNode::ASTNode;
866
867 // Visitor methods
868 66517 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitStmtLst(this); }
869 20731 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitStmtLst(this); }
870
871 // Other methods
872 121203 GET_CHILDREN(statements);
873 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
874 74222 void customItemsInitialization(const size_t manifestationCount) override { resourcesToCleanup.resize(manifestationCount); }
875 21455 [[nodiscard]] bool isStmtLst() const override { return true; }
876
877 // Public members
878 std::vector<StmtNode *> statements;
879 size_t complexity = 0;
880 std::vector<ResourcesForManifestationToCleanup> resourcesToCleanup;
881 CodeLoc closingBraceCodeLoc = CodeLoc(1, 0);
882 };
883
884 // ========================================================= TypeLstNode =========================================================
885
886 class TypeLstNode final : public ASTNode {
887 public:
888 // Constructors
889 using ASTNode::ASTNode;
890
891 // Visitor methods
892 9503 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTypeLst(this); }
893 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTypeLst(this); }
894
895 // Other methods
896 31935 GET_CHILDREN(dataTypes);
897
898 // Public members
899 std::vector<DataTypeNode *> dataTypes;
900 };
901
902 // =================================================== TypeLstWithEllipsisNode ===================================================
903
904 class TypeLstWithEllipsisNode final : public ASTNode {
905 public:
906 // Constructors
907 using ASTNode::ASTNode;
908
909 // Visitor methods
910 1029 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTypeLstWithEllipsis(this); }
911 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTypeLstWithEllipsis(this); }
912
913 // Other methods
914 2065 GET_CHILDREN(typeLst);
915
916 // Public members
917 TypeLstNode *typeLst;
918 bool hasEllipsis = false;
919 };
920
921 // ======================================================= TypeAltsLstNode =======================================================
922
923 class TypeAltsLstNode final : public ASTNode {
924 public:
925 // Constructors
926 using ASTNode::ASTNode;
927
928 // Visitor methods
929 948 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTypeAltsLst(this); }
930 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTypeAltsLst(this); }
931
932 // Other methods
933 1943 GET_CHILDREN(dataTypes);
934
935 // Public members
936 std::vector<DataTypeNode *> dataTypes;
937 };
938
939 // ======================================================== ParamLstNode =========================================================
940
941 class ParamLstNode final : public ASTNode {
942 public:
943 // Constructors
944 using ASTNode::ASTNode;
945
946 // Visitor methods
947 37756 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitParamLst(this); }
948 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitParamLst(this); }
949
950 // Other methods
951 49103 GET_CHILDREN(params);
952
953 // Public members
954 std::vector<DeclStmtNode *> params;
955 };
956
957 // ========================================================== ArgLstNode =========================================================
958
959 class ArgLstNode final : public ASTNode {
960 public:
961 // Structs
962 struct ArgInfo {
963 Function *copyCtor = nullptr;
964 };
965
966 // Constructors
967 using ASTNode::ASTNode;
968
969 // Visitor methods
970 29419 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitArgLst(this); }
971 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitArgLst(this); }
972
973 // Other methods
974 80144 GET_CHILDREN(args);
975
976 // Public members
977 std::vector<ExprNode *> args;
978 std::vector<ArgInfo> argInfos;
979 };
980
981 // ======================================================== EnumItemLstNode ======================================================
982
983 class EnumItemLstNode final : public ASTNode {
984 public:
985 // Constructors
986 using ASTNode::ASTNode;
987
988 // Visitor methods
989 142 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEnumItemLst(this); }
990 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEnumItemLst(this); }
991
992 // Other methods
993 215 GET_CHILDREN(items);
994
995 // Public members
996 std::vector<EnumItemNode *> items;
997 };
998
999 // ========================================================= EnumItemNode ========================================================
1000
1001 class EnumItemNode final : public ASTNode {
1002 public:
1003 // Constructors
1004 using ASTNode::ASTNode;
1005
1006 // Visitor methods
1007 1533 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEnumItem(this); }
1008 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEnumItem(this); }
1009
1010 // Other methods
1011 1527 GET_CHILDREN();
1012 37 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override {
1013 37 return {.intValue = static_cast<int32_t>(itemValue)};
1014 }
1015
1016 // Public members
1017 bool hasValue = false;
1018 uint32_t itemValue;
1019 std::string itemName;
1020 SymbolTableEntry *entry = nullptr;
1021 EnumDefNode *enumDef = nullptr;
1022 };
1023
1024 // ========================================================== FieldNode ==========================================================
1025
1026 class FieldNode final : public ASTNode {
1027 public:
1028 // Constructors
1029 using ASTNode::ASTNode;
1030
1031 // Visitor methods
1032 4490 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitField(this); }
1033 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitField(this); }
1034
1035 // Other methods
1036 5754 GET_CHILDREN(dataType, defaultValue);
1037
1038 // Public members
1039 DataTypeNode *dataType = nullptr;
1040 ExprNode *defaultValue = nullptr;
1041 std::string fieldName;
1042 };
1043
1044 // ======================================================== SignatureNode ========================================================
1045
1046 class SignatureNode final : public ASTNode {
1047 public:
1048 // Enums
1049 enum class SignatureType : uint8_t {
1050 TYPE_NONE,
1051 TYPE_FUNCTION,
1052 TYPE_PROCEDURE,
1053 };
1054
1055 // Constructors
1056 using ASTNode::ASTNode;
1057
1058 // Visitor methods
1059 708 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitSignature(this); }
1060 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitSignature(this); }
1061
1062 // Other methods
1063 466 GET_CHILDREN(qualifierLst, returnType, templateTypeLst, paramTypeLst);
1064 std::vector<Function *> *getFctManifestations(const std::string &) override { return &signatureManifestations; }
1065
1066 // Public members
1067 QualifierLstNode *qualifierLst = nullptr;
1068 DataTypeNode *returnType = nullptr;
1069 TypeLstNode *templateTypeLst = nullptr;
1070 TypeLstNode *paramTypeLst = nullptr;
1071 bool hasReturnType = false;
1072 bool hasTemplateTypes = false;
1073 bool hasParams = false;
1074 SignatureType signatureType = SignatureType::TYPE_NONE;
1075 TypeQualifiers signatureQualifiers;
1076 std::string methodName;
1077 SymbolTableEntry *entry = nullptr;
1078 std::vector<Function *> signatureManifestations;
1079 };
1080
1081 // ========================================================= DeclStmtNode ========================================================
1082
1083 class DeclStmtNode final : public StmtNode {
1084 public:
1085 // Constructors
1086 using StmtNode::StmtNode;
1087
1088 // Visitor methods
1089 81001 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitDeclStmt(this); }
1090 8660 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitDeclStmt(this); }
1091
1092 // Other methods
1093 98762 GET_CHILDREN(dataType, assignExpr);
1094 70647 void customItemsInitialization(const size_t manifestationCount) override { entries.resize(manifestationCount); }
1095 838 [[nodiscard]] bool isParam() const override { return isFctParam; }
1096
1097 // Public members
1098 DataTypeNode *dataType = nullptr;
1099 ExprNode *assignExpr = nullptr;
1100 bool hasAssignment = false;
1101 bool isFctParam = false;
1102 bool isForEachItem = false;
1103 bool isCtorCallRequired = false; // For struct, in case there are reference fields, we need to call a user-defined ctor
1104 std::string varName;
1105 std::vector<SymbolTableEntry *> entries;
1106 Function *calledInitCtor = nullptr;
1107 Function *calledCopyCtor = nullptr;
1108 };
1109
1110 // ========================================================= ExprStmtNode ========================================================
1111
1112 class ExprStmtNode final : public StmtNode {
1113 public:
1114 // Constructors
1115 using StmtNode::StmtNode;
1116
1117 // Visitor methods
1118 43483 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitExprStmt(this); }
1119 13553 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitExprStmt(this); }
1120
1121 // Other methods
1122 120161 GET_CHILDREN(expr);
1123 324 [[nodiscard]] bool isExprStmt() const override { return true; }
1124
1125 // Public members
1126 ExprNode *expr = nullptr;
1127 };
1128
1129 // ======================================================= QualifierLstNode ======================================================
1130
1131 class QualifierLstNode final : public ASTNode {
1132 public:
1133 // Constructors
1134 using ASTNode::ASTNode;
1135
1136 // Visitor methods
1137 35302 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitQualifierLst(this); }
1138 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitQualifierLst(this); }
1139
1140 // Other methods
1141 133486 GET_CHILDREN(qualifiers);
1142
1143 // Public members
1144 std::vector<QualifierNode *> qualifiers;
1145 };
1146
1147 // ========================================================= QualifierNode =======================================================
1148
1149 class QualifierNode final : public ASTNode {
1150 public:
1151 // Enums
1152 enum class QualifierType : uint8_t {
1153 TY_NONE,
1154 TY_CONST,
1155 TY_SIGNED,
1156 TY_UNSIGNED,
1157 TY_INLINE,
1158 TY_PUBLIC,
1159 TY_HEAP,
1160 TY_COMPOSITION,
1161 };
1162
1163 // Constructors
1164 using ASTNode::ASTNode;
1165
1166 // Visitor methods
1167 41895 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitQualifier(this); }
1168 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitQualifier(this); }
1169
1170 // Other methods
1171 158462 GET_CHILDREN();
1172
1173 // Public members
1174 QualifierType type = QualifierType::TY_NONE;
1175 };
1176
1177 // ========================================================== ModAttrNode ========================================================
1178
1179 class ModAttrNode final : public ASTNode {
1180 public:
1181 // Constructors
1182 using ASTNode::ASTNode;
1183
1184 // Visitor methods
1185 2092 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitModAttr(this); }
1186 343 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitModAttr(this); }
1187
1188 // Other methods
1189 2090 GET_CHILDREN(attrLst);
1190
1191 // Public members
1192 AttrLstNode *attrLst = nullptr;
1193 };
1194
1195 // =================================================== TopLevelDefinitionAttrNode ================================================
1196
1197 class TopLevelDefinitionAttrNode final : public ASTNode {
1198 public:
1199 // Constructors
1200 using ASTNode::ASTNode;
1201
1202 // Visitor methods
1203 1020 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTopLevelDefinitionAttr(this); }
1204 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTopLevelDefinitionAttr(this); }
1205
1206 // Other methods
1207 2421 GET_CHILDREN(attrLst);
1208
1209 // Public members
1210 AttrLstNode *attrLst = nullptr;
1211 };
1212
1213 // ========================================================= LambdaAttrNode ======================================================
1214
1215 class LambdaAttrNode final : public ASTNode {
1216 public:
1217 // Constructors
1218 using ASTNode::ASTNode;
1219
1220 // Visitor methods
1221 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLambdaAttr(this); }
1222 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLambdaAttr(this); }
1223
1224 // Other methods
1225 10 GET_CHILDREN(attrLst);
1226
1227 // Public members
1228 AttrLstNode *attrLst = nullptr;
1229 };
1230
1231 // ========================================================== AttrLstNode ========================================================
1232
1233 class AttrLstNode final : public ASTNode {
1234 public:
1235 // Constructors
1236 using ASTNode::ASTNode;
1237
1238 // Visitor methods
1239 2737 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAttrLst(this); }
1240 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAttrLst(this); }
1241
1242 // Other methods
1243 4521 GET_CHILDREN(attributes);
1244 [[nodiscard]] std::vector<const CompileTimeValue *> getAttrValuesByName(const std::string &key) const;
1245 [[nodiscard]] const CompileTimeValue *getAttrValueByName(const std::string &key) const;
1246 [[nodiscard]] bool hasAttr(const std::string &key) const;
1247
1248 // Public members
1249 std::vector<AttrNode *> attributes;
1250 };
1251
1252 // ============================================================ AttrNode =========================================================
1253
1254 class AttrNode final : public ASTNode {
1255 public:
1256 // Enums
1257 enum AttrTarget : uint8_t {
1258 TARGET_INVALID = 0,
1259 TARGET_MODULE = 1 << 0,
1260 TARGET_STRUCT = 1 << 1,
1261 TARGET_INTERFACE = 1 << 2,
1262 TARGET_FCT_PROC = 1 << 3,
1263 TARGET_EXT_DECL = 1 << 4,
1264 TARGET_LAMBDA = 1 << 5,
1265 };
1266
1267 enum class AttrType : uint8_t {
1268 ATTR_TYPE_INVALID,
1269 TYPE_STRING,
1270 TYPE_BOOL,
1271 TYPE_INT,
1272 };
1273
1274 // Constructors
1275 using ASTNode::ASTNode;
1276
1277 // Visitor methods
1278 3871 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAttr(this); }
1279 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAttr(this); }
1280
1281 // Other methods
1282 4735 GET_CHILDREN(value);
1283 [[nodiscard]] const CompileTimeValue *getValue() const;
1284
1285 // Public members
1286 ConstantNode *value = nullptr;
1287 AttrType type = AttrType::ATTR_TYPE_INVALID;
1288 AttrTarget target = TARGET_INVALID;
1289 std::string key;
1290 };
1291
1292 // ======================================================== CaseConstantNode =====================================================
1293
1294 class CaseConstantNode final : public ExprNode {
1295 public:
1296 // Constructors
1297 using ExprNode::ExprNode;
1298
1299 // Visitor methods
1300 188 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitCaseConstant(this); }
1301 66 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitCaseConstant(this); }
1302
1303 // Other methods
1304 236 GET_CHILDREN(constant);
1305
1306 // Public members
1307 ConstantNode *constant = nullptr;
1308 std::vector<std::string> identifierFragments;
1309 std::string fqIdentifier;
1310 const SymbolTableEntry *entry = nullptr;
1311 };
1312
1313 // ======================================================== ReturnStmtNode =======================================================
1314
1315 class ReturnStmtNode final : public StmtNode {
1316 public:
1317 // Constructors
1318 using StmtNode::StmtNode;
1319
1320 // Visitor methods
1321 30052 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitReturnStmt(this); }
1322 9730 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitReturnStmt(this); }
1323
1324 // Other methods
1325 54141 GET_CHILDREN(assignExpr);
1326 9538 [[nodiscard]] bool returnsOnAllControlPaths(bool *, size_t) const override { return true; }
1327
1/2
✓ Branch 2 → 3 taken 9730 times.
✗ Branch 2 → 4 not taken.
19460 [[nodiscard]] StmtLstNode *getParentScopeNode() const { return spice_pointer_cast<StmtLstNode *>(parent); }
1328
1329 // Public members
1330 ExprNode *assignExpr = nullptr;
1331 QualType returnType;
1332 Function *calledCopyCtor = nullptr;
1333 bool hasReturnValue = false;
1334 };
1335
1336 // ======================================================== BreakStmtNode ========================================================
1337
1338 class BreakStmtNode final : public StmtNode {
1339 public:
1340 // Constructors
1341 using StmtNode::StmtNode;
1342
1343 // Visitor methods
1344 376 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBreakStmt(this); }
1345 122 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBreakStmt(this); }
1346
1347 // Other methods
1348 669 GET_CHILDREN();
1349
1350 // Public members
1351 int breakTimes = 1;
1352 };
1353
1354 // ======================================================= ContinueStmtNode ======================================================
1355
1356 class ContinueStmtNode final : public StmtNode {
1357 public:
1358 // Constructors
1359 using StmtNode::StmtNode;
1360
1361 // Visitor methods
1362 830 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitContinueStmt(this); }
1363 381 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitContinueStmt(this); }
1364
1365 // Other methods
1366 1183 GET_CHILDREN();
1367
1368 // Public members
1369 int continueTimes = 1;
1370 };
1371
1372 // ====================================================== FallthroughStmtNode ====================================================
1373
1374 class FallthroughStmtNode final : public StmtNode {
1375 public:
1376 // Constructors
1377 using StmtNode::StmtNode;
1378
1379 // Visitor methods
1380 12 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFallthroughStmt(this); }
1381 4 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFallthroughStmt(this); }
1382
1383 // Other methods
1384 21 GET_CHILDREN();
1385 };
1386
1387 // ======================================================== AssertStmtNode =======================================================
1388
1389 class AssertStmtNode final : public StmtNode {
1390 public:
1391 // Constructors
1392 using StmtNode::StmtNode;
1393
1394 // Visitor methods
1395 2116 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAssertStmt(this); }
1396 1226 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAssertStmt(this); }
1397
1398 // Other methods
1399 2761 GET_CHILDREN(assignExpr);
1400 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
1401
1402 // Public members
1403 ExprNode *assignExpr = nullptr;
1404 std::string expressionString;
1405 };
1406
1407 // ======================================================= AssignExprNode ========================================================
1408
1409 class AssignExprNode final : public ExprNode {
1410 public:
1411 // Enums
1412 enum class AssignOp : uint8_t {
1413 OP_NONE,
1414 OP_ASSIGN,
1415 OP_PLUS_EQUAL,
1416 OP_MINUS_EQUAL,
1417 OP_MUL_EQUAL,
1418 OP_DIV_EQUAL,
1419 OP_REM_EQUAL,
1420 OP_SHL_EQUAL,
1421 OP_SHR_EQUAL,
1422 OP_AND_EQUAL,
1423 OP_OR_EQUAL,
1424 OP_XOR_EQUAL
1425 };
1426
1427 // Constructors
1428 using ExprNode::ExprNode;
1429
1430 // Visitor methods
1431 22926 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAssignExpr(this); }
1432 6617 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAssignExpr(this); }
1433
1434 // Other methods
1435 43843 GET_CHILDREN(lhs, rhs, ternaryExpr);
1436 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
1437 1128 [[nodiscard]] bool isAssignExpr() const override { return true; }
1438 292 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1439 994 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1440
2/4
✓ Branch 4 → 5 taken 26742 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 26742 times.
✗ Branch 5 → 9 not taken.
80226 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1441 AtomicExprNode *getLhsAtomicNode() const;
1442
1443 // Public members
1444 ExprNode *lhs = nullptr;
1445 ExprNode *rhs = nullptr;
1446 ExprNode *ternaryExpr = nullptr;
1447 AssignOp op = AssignOp::OP_NONE;
1448 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1449 };
1450
1451 // ======================================================= TernaryExprNode =======================================================
1452
1453 class TernaryExprNode final : public ExprNode {
1454 public:
1455 // Constructors
1456 using ExprNode::ExprNode;
1457
1458 // Visitor methods
1459 1426 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTernaryExpr(this); }
1460 499 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTernaryExpr(this); }
1461
1462 // Other methods
1463 2537 GET_CHILDREN(condition, trueExpr, falseExpr);
1464 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1465 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1466
1467 // Public members
1468 ExprNode *condition = nullptr;
1469 ExprNode *trueExpr = nullptr;
1470 ExprNode *falseExpr = nullptr;
1471 Function *calledCopyCtor = nullptr;
1472 bool trueSideCallsCopyCtor = false;
1473 bool falseSideCallsCopyCtor = false;
1474 bool isShortened = false;
1475 };
1476
1477 // ===================================================== LogicalOrExprNode =======================================================
1478
1479 class LogicalOrExprNode final : public ExprNode {
1480 public:
1481 // Constructors
1482 using ExprNode::ExprNode;
1483
1484 // Visitor methods
1485 3091 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLogicalOrExpr(this); }
1486 978 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLogicalOrExpr(this); }
1487
1488 // Other methods
1489 6527 GET_CHILDREN(operands);
1490
1491 // Public members
1492 std::vector<ExprNode *> operands;
1493 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1494 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1495 };
1496
1497 // ===================================================== LogicalAndExprNode ======================================================
1498
1499 class LogicalAndExprNode final : public ExprNode {
1500 public:
1501 // Constructors
1502 using ExprNode::ExprNode;
1503
1504 // Visitor methods
1505 703 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLogicalAndExpr(this); }
1506 187 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLogicalAndExpr(this); }
1507
1508 // Other methods
1509 1330 GET_CHILDREN(operands);
1510
1511 // Public members
1512 std::vector<ExprNode *> operands;
1513 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1514 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1515 };
1516
1517 // ===================================================== BitwiseOrExprNode =======================================================
1518
1519 class BitwiseOrExprNode final : public ExprNode {
1520 public:
1521 // Constructors
1522 using ExprNode::ExprNode;
1523
1524 // Visitor methods
1525 258 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBitwiseOrExpr(this); }
1526 89 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBitwiseOrExpr(this); }
1527
1528 // Other methods
1529 358 GET_CHILDREN(operands);
1530
1531 // Public members
1532 std::vector<ExprNode *> operands;
1533 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1534 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1535 };
1536
1537 // ==================================================== BitwiseXorExprNode =======================================================
1538
1539 class BitwiseXorExprNode final : public ExprNode {
1540 public:
1541 // Constructors
1542 using ExprNode::ExprNode;
1543
1544 // Visitor methods
1545 33 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBitwiseXorExpr(this); }
1546 14 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBitwiseXorExpr(this); }
1547
1548 // Other methods
1549 50 GET_CHILDREN(operands);
1550
1551 // Public members
1552 std::vector<ExprNode *> operands;
1553 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1554 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1555 };
1556
1557 // ==================================================== BitwiseAndExprNode =======================================================
1558
1559 class BitwiseAndExprNode final : public ExprNode {
1560 public:
1561 // Constructors
1562 using ExprNode::ExprNode;
1563
1564 // Visitor methods
1565 99 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBitwiseAndExpr(this); }
1566 44 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBitwiseAndExpr(this); }
1567
1568 // Other methods
1569 124 GET_CHILDREN(operands);
1570
1571 // Public members
1572 std::vector<ExprNode *> operands;
1573 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1574 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1575 };
1576
1577 // ===================================================== EqualityExprNode ========================================================
1578
1579 class EqualityExprNode final : public ExprNode {
1580 public:
1581 // Enums
1582 enum class EqualityOp : uint8_t {
1583 OP_NONE,
1584 OP_EQUAL,
1585 OP_NOT_EQUAL,
1586 };
1587
1588 // Constructors
1589 using ExprNode::ExprNode;
1590
1591 // Visitor methods
1592 16514 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEqualityExpr(this); }
1593 5823 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEqualityExpr(this); }
1594
1595 // Other methods
1596 28223 GET_CHILDREN(operands);
1597 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1598 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1599 928 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1600 12078 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1601
2/4
✓ Branch 4 → 5 taken 17074 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 17074 times.
✗ Branch 5 → 9 not taken.
51222 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1602
1603 // Public members
1604 std::vector<ExprNode *> operands;
1605 EqualityOp op = EqualityOp::OP_NONE;
1606 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1607 };
1608
1609 // ==================================================== RelationalExprNode =======================================================
1610
1611 class RelationalExprNode final : public ExprNode {
1612 public:
1613 // Enums
1614 enum class RelationalOp : uint8_t {
1615 OP_NONE,
1616 OP_LESS,
1617 OP_GREATER,
1618 OP_LESS_EQUAL,
1619 OP_GREATER_EQUAL,
1620 };
1621
1622 // Constructors
1623 using ExprNode::ExprNode;
1624
1625 // Visitor methods
1626 10846 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitRelationalExpr(this); }
1627 3871 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitRelationalExpr(this); }
1628
1629 // Other methods
1630 21383 GET_CHILDREN(operands);
1631 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1632 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1633
1634 // Public members
1635 std::vector<ExprNode *> operands;
1636 RelationalOp op = RelationalOp::OP_NONE;
1637 };
1638
1639 // ====================================================== ShiftExprNode ==========================================================
1640
1641 class ShiftExprNode final : public ExprNode {
1642 public:
1643 // Enums
1644 enum class ShiftOp : uint8_t {
1645 OP_NONE,
1646 OP_SHIFT_LEFT,
1647 OP_SHIFT_RIGHT,
1648 };
1649
1650 // Typedefs
1651 using OpQueue = std::queue<std::pair<ShiftOp, QualType>>;
1652
1653 // Constructors
1654 using ExprNode::ExprNode;
1655
1656 // Visitor methods
1657 318 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitShiftExpr(this); }
1658 131 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitShiftExpr(this); }
1659
1660 // Other methods
1661 494 GET_CHILDREN(operands);
1662 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1663 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1664 168 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1665 422 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1666
2/4
✓ Branch 4 → 5 taken 273 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 273 times.
✗ Branch 5 → 9 not taken.
819 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1667
1668 // Public members
1669 std::vector<ExprNode *> operands;
1670 OpQueue opQueue;
1671 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1672 };
1673
1674 // ==================================================== AdditiveExprNode =========================================================
1675
1676 class AdditiveExprNode final : public ExprNode {
1677 public:
1678 // Enums
1679 enum class AdditiveOp : uint8_t {
1680 OP_PLUS,
1681 OP_MINUS,
1682 };
1683
1684 // Typedefs
1685 using OpQueue = std::queue<std::pair<AdditiveOp, QualType>>;
1686
1687 // Constructors
1688 using ExprNode::ExprNode;
1689
1690 // Visitor methods
1691 12063 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAdditiveExpr(this); }
1692 4279 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAdditiveExpr(this); }
1693
1694 // Other methods
1695 21648 GET_CHILDREN(operands);
1696 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1697 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1698 142 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1699 9815 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1700
2/4
✓ Branch 4 → 5 taken 13976 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 13976 times.
✗ Branch 5 → 9 not taken.
41928 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1701
1702 // Public members
1703 std::vector<ExprNode *> operands;
1704 OpQueue opQueue;
1705 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1706 };
1707
1708 // ================================================== MultiplicativeExprNode =====================================================
1709
1710 class MultiplicativeExprNode final : public ExprNode {
1711 public:
1712 // Enums
1713 enum class MultiplicativeOp : uint8_t {
1714 OP_MUL,
1715 OP_DIV,
1716 OP_REM,
1717 };
1718
1719 // Typedefs
1720 using OpQueue = std::queue<std::pair<MultiplicativeOp, QualType>>;
1721
1722 // Constructors
1723 using ExprNode::ExprNode;
1724
1725 // Visitor methods
1726 3632 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitMultiplicativeExpr(this); }
1727 933 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitMultiplicativeExpr(this); }
1728
1729 // Other methods
1730 7601 GET_CHILDREN(operands);
1731 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1732 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1733 24 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1734 1868 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1735
2/4
✓ Branch 4 → 5 taken 4940 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 4940 times.
✗ Branch 5 → 9 not taken.
14820 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1736
1737 // Public members
1738 std::vector<ExprNode *> operands;
1739 OpQueue opQueue;
1740 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1741 };
1742
1743 // ======================================================= CastExprNode ==========================================================
1744
1745 class CastExprNode final : public ExprNode {
1746 public:
1747 // Constructors
1748 using ExprNode::ExprNode;
1749
1750 // Visitor methods
1751 8428 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitCastExpr(this); }
1752 2650 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitCastExpr(this); }
1753
1754 // Other methods
1755 15301 GET_CHILDREN(prefixUnaryExpr, dataType, assignExpr);
1756 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1757 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1758
1759 // Public members
1760 ExprNode *prefixUnaryExpr = nullptr;
1761 DataTypeNode *dataType = nullptr;
1762 ExprNode *assignExpr = nullptr;
1763 bool isCast = false;
1764 };
1765
1766 // ==================================================== PrefixUnaryExprNode ======================================================
1767
1768 class PrefixUnaryExprNode final : public ExprNode {
1769 public:
1770 // Enums
1771 enum class PrefixUnaryOp : uint8_t {
1772 OP_NONE,
1773 OP_MINUS,
1774 OP_PLUS_PLUS,
1775 OP_MINUS_MINUS,
1776 OP_NOT,
1777 OP_BITWISE_NOT,
1778 OP_DEREFERENCE,
1779 OP_ADDRESS_OF,
1780 };
1781
1782 // Constructors
1783 using ExprNode::ExprNode;
1784
1785 // Visitor methods
1786 4763 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitPrefixUnaryExpr(this); }
1787 2075 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitPrefixUnaryExpr(this); }
1788
1789 // Other methods
1790 7363 GET_CHILDREN(prefixUnaryExpr, postfixUnaryExpr);
1791 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1792 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1793
1794 // Public members
1795 ExprNode *prefixUnaryExpr = nullptr;
1796 ExprNode *postfixUnaryExpr = nullptr;
1797 PrefixUnaryOp op = PrefixUnaryOp::OP_NONE;
1798 };
1799
1800 // =================================================== PostfixUnaryExprNode ======================================================
1801
1802 class PostfixUnaryExprNode final : public ExprNode {
1803 public:
1804 // Enums
1805 enum class PostfixUnaryOp : uint8_t {
1806 OP_NONE,
1807 OP_SUBSCRIPT,
1808 OP_MEMBER_ACCESS,
1809 OP_PLUS_PLUS,
1810 OP_MINUS_MINUS,
1811 };
1812
1813 // Constructors
1814 using ExprNode::ExprNode;
1815
1816 // Visitor methods
1817 72948 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitPostfixUnaryExpr(this); }
1818 21926 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitPostfixUnaryExpr(this); }
1819
1820 // Other methods
1821 146198 GET_CHILDREN(atomicExpr, postfixUnaryExpr, subscriptIndexExpr);
1822 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1823 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1824 282 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1825 15770 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1826
2/4
✓ Branch 4 → 5 taken 90362 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 90362 times.
✗ Branch 5 → 9 not taken.
271086 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1827
1828 // Public members
1829 ExprNode *atomicExpr = nullptr;
1830 ExprNode *postfixUnaryExpr = nullptr;
1831 ExprNode *subscriptIndexExpr = nullptr;
1832 PostfixUnaryOp op = PostfixUnaryOp::OP_NONE;
1833 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1834 std::string identifier; // Only set when operator is member access
1835 };
1836
1837 // ====================================================== AtomicExprNode =========================================================
1838
1839 class AtomicExprNode final : public ExprNode {
1840 public:
1841 // Structs
1842 struct VarAccessData {
1843 SymbolTableEntry *entry = nullptr;
1844 Scope *accessScope = nullptr;
1845 Capture *capture = nullptr;
1846 };
1847
1848 // Constructors
1849 using ExprNode::ExprNode;
1850
1851 // Visitor methods
1852 287038 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAtomicExpr(this); }
1853 95794 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAtomicExpr(this); }
1854
1855 // Other methods
1856 574690 GET_CHILDREN(constant, value, assignExpr);
1857 323242 void customItemsInitialization(const size_t manifestationCount) override { data.resize(manifestationCount); }
1858
1859 // Public members
1860 ConstantNode *constant = nullptr;
1861 ValueNode *value = nullptr;
1862 ExprNode *assignExpr = nullptr;
1863 std::vector<std::string> identifierFragments;
1864 std::string fqIdentifier;
1865 std::vector<VarAccessData> data; // Only set if identifier is set as well
1866 };
1867
1868 // ======================================================== ValueNode ============================================================
1869
1870 class ValueNode final : public ExprNode {
1871 public:
1872 // Constructors
1873 using ExprNode::ExprNode;
1874
1875 // Visitor methods
1876 62228 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitValue(this); }
1877 20875 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitValue(this); }
1878
1879 // Other methods
1880 140696 GET_CHILDREN(fctCall, arrayInitialization, structInstantiation, lambdaFunc, lambdaProc, lambdaExpr, nilType);
1881 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1882 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1883
1884 // Public members
1885 FctCallNode *fctCall = nullptr;
1886 ArrayInitializationNode *arrayInitialization = nullptr;
1887 StructInstantiationNode *structInstantiation = nullptr;
1888 LambdaFuncNode *lambdaFunc = nullptr;
1889 LambdaProcNode *lambdaProc = nullptr;
1890 LambdaExprNode *lambdaExpr = nullptr;
1891 DataTypeNode *nilType = nullptr;
1892 bool isNil = false;
1893 };
1894
1895 // ====================================================== ConstantNode ===========================================================
1896
1897 class ConstantNode final : public ExprNode {
1898 public:
1899 // Enum
1900 enum class PrimitiveValueType : uint8_t {
1901 TYPE_NONE,
1902 TYPE_DOUBLE,
1903 TYPE_INT,
1904 TYPE_SHORT,
1905 TYPE_LONG,
1906 TYPE_CHAR,
1907 TYPE_STRING,
1908 TYPE_BOOL
1909 };
1910
1911 // Constructors
1912 using ExprNode::ExprNode;
1913
1914 // Visitor methods
1915 59067 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitConstant(this); }
1916 18466 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitConstant(this); }
1917
1918 // Other methods
1919 98139 GET_CHILDREN();
1920 20316 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override { return compileTimeValue; }
1921 2183 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override { return true; }
1922
1923 // Public members
1924 PrimitiveValueType type = PrimitiveValueType::TYPE_NONE;
1925 CompileTimeValue compileTimeValue;
1926 };
1927
1928 // ====================================================== FctCallNode ============================================================
1929
1930 class FctCallNode final : public ExprNode {
1931 public:
1932 // Enums
1933 enum class FctCallType : uint8_t {
1934 TYPE_ORDINARY,
1935 TYPE_METHOD,
1936 TYPE_CTOR,
1937 TYPE_FCT_PTR,
1938 };
1939
1940 // Structs
1941 struct FctCallData {
1942 // Members
1943 FctCallType callType = FctCallType::TYPE_ORDINARY;
1944 bool isImported = false;
1945 QualTypeList templateTypes;
1946 QualType thisType = QualType(TY_DYN); // Is filled if method or ctor call
1947 ArgList args;
1948 Function *callee = nullptr; // Stays nullptr if function pointer call
1949 Scope *calleeParentScope = nullptr;
1950 CompileTimeValue compileTimeValue;
1951 bool compileTimeValueSet = false;
1952
1953 // Methods
1954 22486 [[nodiscard]] bool isOrdinaryCall() const { return callType == FctCallType::TYPE_ORDINARY; }
1955 60154 [[nodiscard]] bool isMethodCall() const { return callType == FctCallType::TYPE_METHOD; }
1956
4/4
✓ Branch 3 → 4 taken 7522 times.
✓ Branch 3 → 7 taken 12453 times.
✓ Branch 5 → 6 taken 36 times.
✓ Branch 5 → 7 taken 7486 times.
19975 [[nodiscard]] bool isVirtualMethodCall() const { return isMethodCall() && thisType.isBase(TY_INTERFACE); }
1957 77377 [[nodiscard]] bool isCtorCall() const { return callType == FctCallType::TYPE_CTOR; }
1958 200973 [[nodiscard]] bool isFctPtrCall() const { return callType == FctCallType::TYPE_FCT_PTR; }
1959
1960 216 void setCompileTimeValue(const CompileTimeValue &value) {
1961 216 compileTimeValue = value;
1962 216 compileTimeValueSet = true;
1963 216 }
1964
1965 [[nodiscard]] bool hasCompileTimeValue() const { return compileTimeValueSet; }
1966 };
1967
1968 // Constructors
1969 using ExprNode::ExprNode;
1970
1971 // Visitor methods
1972 56469 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFctCall(this); }
1973 18893 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFctCall(this); }
1974
1975 // Other methods
1976 98515 GET_CHILDREN(templateTypeLst, argLst);
1977 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1978 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1979 void setCompileTimeValue(const CompileTimeValue &value, size_t manIdx);
1980 [[nodiscard]] bool returnsOnAllControlPaths(bool *overrideUnreachable, size_t manIdx) const override;
1981 61560 void customItemsInitialization(const size_t manifestationCount) override { data.resize(manifestationCount); }
1982 [[nodiscard]] bool hasReturnValueReceiver() const;
1983
1984 // Public members
1985 TypeLstNode *templateTypeLst = nullptr;
1986 ArgLstNode *argLst = nullptr;
1987 bool hasArgs = false;
1988 bool hasTemplateTypes = false;
1989 std::string fqFunctionName;
1990 std::vector<std::string> functionNameFragments;
1991 std::vector<FctCallData> data;
1992 };
1993
1994 // ================================================= ArrayInitializationNode =====================================================
1995
1996 class ArrayInitializationNode final : public ExprNode {
1997 public:
1998 // Constructors
1999 using ExprNode::ExprNode;
2000
2001 // Visitor methods
2002 157 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitArrayInitialization(this); }
2003 59 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitArrayInitialization(this); }
2004
2005 // Other methods
2006 236 GET_CHILDREN(itemLst);
2007
2008 // Public members
2009 ArgLstNode *itemLst = nullptr;
2010 size_t actualSize = 0z;
2011 };
2012
2013 // ================================================= StructInstantiationNode =====================================================
2014
2015 class StructInstantiationNode final : public ExprNode {
2016 public:
2017 // Constructors
2018 using ExprNode::ExprNode;
2019
2020 // Visitor methods
2021 713 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitStructInstantiation(this); }
2022 290 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitStructInstantiation(this); }
2023
2024 // Other methods
2025 1193 GET_CHILDREN(templateTypeLst, fieldLst);
2026 617 void customItemsInitialization(const size_t manifestationCount) override { instantiatedStructs.resize(manifestationCount); }
2027
2028 // Public members
2029 TypeLstNode *templateTypeLst = nullptr;
2030 ArgLstNode *fieldLst = nullptr;
2031 bool hasTemplateTypes = false;
2032 std::string fqStructName;
2033 std::vector<std::string> structNameFragments;
2034 std::vector<Struct *> instantiatedStructs;
2035 };
2036
2037 // ====================================================== LambdaBaseNode =========================================================
2038
2039 class LambdaBaseNode : public ExprNode {
2040 public:
2041 // Constructors
2042 using ExprNode::ExprNode;
2043
2044 // Other methods
2045
2/4
✓ Branch 2 → 3 taken 106 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 106 times.
✗ Branch 3 → 8 not taken.
106 [[nodiscard]] std::string getScopeId() const { return "lambda:" + codeLoc.toString(); }
2046 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override { return false; }
2047 90 void customItemsInitialization(size_t manifestationCount) override { manifestations.resize(manifestationCount); }
2048
2049 // Public members
2050 ParamLstNode *paramLst = nullptr;
2051 bool hasParams = false;
2052 Scope *bodyScope = nullptr;
2053 std::vector<Function> manifestations;
2054 };
2055
2056 // ====================================================== LambdaFuncNode =========================================================
2057
2058 class LambdaFuncNode final : public LambdaBaseNode {
2059 public:
2060 // Constructors
2061 using LambdaBaseNode::LambdaBaseNode;
2062
2063 // Visit methods
2064 32 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLambdaFunc(this); }
2065 12 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLambdaFunc(this); }
2066
2067 // Other methods
2068 40 GET_CHILDREN(returnType, paramLst, body, lambdaAttr);
2069 [[nodiscard]] bool returnsOnAllControlPaths(bool *overrideUnreachable, size_t manIdx) const override;
2070
2071 // Public members
2072 DataTypeNode *returnType = nullptr;
2073 StmtLstNode *body = nullptr;
2074 LambdaAttrNode *lambdaAttr = nullptr;
2075 };
2076
2077 // ====================================================== LambdaProcNode =========================================================
2078
2079 class LambdaProcNode final : public LambdaBaseNode {
2080 public:
2081 // Constructors
2082 using LambdaBaseNode::LambdaBaseNode;
2083
2084 // Visit methods
2085 42 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLambdaProc(this); }
2086 19 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLambdaProc(this); }
2087
2088 // Other methods
2089 49 GET_CHILDREN(paramLst, body, lambdaAttr);
2090 bool returnsOnAllControlPaths(bool *overrideUnreachable, size_t manIdx) const override;
2091
2092 // Public members
2093 StmtLstNode *body = nullptr;
2094 LambdaAttrNode *lambdaAttr = nullptr;
2095 };
2096
2097 // ====================================================== LambdaExprNode =========================================================
2098
2099 class LambdaExprNode final : public LambdaBaseNode {
2100 public:
2101 // Constructors
2102 using LambdaBaseNode::LambdaBaseNode;
2103
2104 // Visit methods
2105 2 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLambdaExpr(this); }
2106 1 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLambdaExpr(this); }
2107
2108 // Other methods
2109 2 GET_CHILDREN(paramLst, lambdaExpr);
2110
2111 // Public members
2112 ExprNode *lambdaExpr = nullptr;
2113 };
2114
2115 // ======================================================= DataTypeNode ==========================================================
2116
2117 class DataTypeNode final : public ExprNode {
2118 public:
2119 // Enums
2120 enum class TypeModifierType : uint8_t {
2121 TYPE_PTR,
2122 TYPE_REF,
2123 TYPE_ARRAY,
2124 };
2125
2126 // Structs
2127 struct TypeModifier {
2128 TypeModifierType modifierType = TypeModifierType::TYPE_PTR;
2129 bool hasSize = false;
2130 unsigned int hardcodedSize = 0;
2131 std::string sizeVarName;
2132 };
2133
2134 // Constructors
2135 using ExprNode::ExprNode;
2136
2137 // Visitor methods
2138 123840 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitDataType(this); }
2139 2777 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitDataType(this); }
2140
2141 // Other methods
2142 204986 GET_CHILDREN(qualifierLst, baseDataType);
2143 void setFieldTypeRecursive();
2144
2145 // Public members
2146 QualifierLstNode *qualifierLst = nullptr;
2147 BaseDataTypeNode *baseDataType = nullptr;
2148 bool isParamType = false;
2149 bool isGlobalType = false;
2150 bool isFieldType = false;
2151 bool isReturnType = false;
2152 std::queue<TypeModifier> tmQueue;
2153 };
2154
2155 // ==================================================== BaseDataTypeNode =========================================================
2156
2157 class BaseDataTypeNode final : public ExprNode {
2158 public:
2159 // Enums
2160 enum class Type : uint8_t {
2161 TYPE_NONE,
2162 TYPE_DOUBLE,
2163 TYPE_INT,
2164 TYPE_SHORT,
2165 TYPE_LONG,
2166 TYPE_BYTE,
2167 TYPE_CHAR,
2168 TYPE_STRING,
2169 TYPE_BOOL,
2170 TYPE_DYN,
2171 TYPE_CUSTOM,
2172 TYPE_FUNCTION
2173 };
2174
2175 // Constructors
2176 using ExprNode::ExprNode;
2177
2178 // Visitor methods
2179 123840 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBaseDataType(this); }
2180 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBaseDataType(this); }
2181
2182 // Other methods
2183 204973 GET_CHILDREN(customDataType, functionDataType);
2184
2185 // Public members
2186 CustomDataTypeNode *customDataType = nullptr;
2187 FunctionDataTypeNode *functionDataType = nullptr;
2188 Type type = Type::TYPE_NONE;
2189 };
2190
2191 // ==================================================== CustomDataTypeNode =======================================================
2192
2193 class CustomDataTypeNode final : public ExprNode {
2194 public:
2195 // Constructors
2196 using ExprNode::ExprNode;
2197
2198 // Visitor methods
2199 45537 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitCustomDataType(this); }
2200 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitCustomDataType(this); }
2201
2202 // Other methods
2203 77679 GET_CHILDREN(templateTypeLst);
2204 56964 void customItemsInitialization(const size_t manifestationCount) override { customTypes.resize(manifestationCount); }
2205
2206 // Public members
2207 TypeLstNode *templateTypeLst = nullptr;
2208 std::string fqTypeName;
2209 std::vector<std::string> typeNameFragments;
2210 std::vector<SymbolTableEntry *> customTypes;
2211 };
2212
2213 // =================================================== FunctionDataTypeNode ======================================================
2214
2215 class FunctionDataTypeNode final : public ExprNode {
2216 public:
2217 // Constructors
2218 using ExprNode::ExprNode;
2219
2220 // Visitor methods
2221 204 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFunctionDataType(this); }
2222 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFunctionDataType(this); }
2223
2224 // Other methods
2225 307 GET_CHILDREN(returnType, paramTypeLst);
2226 241 void customItemsInitialization(const size_t manifestationCount) override { customTypes.resize(manifestationCount); }
2227
2228 // Public members
2229 DataTypeNode *returnType = nullptr;
2230 TypeLstNode *paramTypeLst = nullptr;
2231 bool isFunction = false; // Function or procedure
2232 std::vector<SymbolTableEntry *> customTypes;
2233 };
2234
2235 } // namespace spice::compiler
2236