GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 93.3% 364 / 10 / 400
Functions: 93.3% 307 / 5 / 334
Branches: 58.5% 131 / 0 / 224

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