GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 93.0% 374 / 14 / 416
Functions: 92.9% 315 / 7 / 346
Branches: 57.8% 134 / 0 / 232

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 4989694 explicit ASTNode(const CodeLoc &codeLoc) : codeLoc(codeLoc) {}
77 4989694 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 39131523 template <typename... Args> [[nodiscard]] ALWAYS_INLINE std::vector<ASTNode *> collectChildren(Args &&...args) const {
88 39131523 std::vector<ASTNode *> children;
89
90 // Lambda to handle each argument
91 74923375 [[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 74923375 if (arg != nullptr)
95
9/18
✓ Branch 5 → 6 taken 11693849 times.
✗ Branch 5 → 8 not taken.
✓ Branch 12 → 13 taken 10955493 times.
✗ Branch 12 → 15 not taken.
✓ Branch 17 → 18 taken 27335 times.
✗ Branch 17 → 20 not taken.
✓ Branch 19 → 20 taken 1456455 times.
✗ Branch 19 → 22 not taken.
✓ Branch 24 → 25 taken 3255 times.
✗ Branch 24 → 27 not taken.
✓ Branch 26 → 27 taken 689710 times.
✗ Branch 26 → 29 not taken.
✓ Branch 33 → 34 taken 251707 times.
✗ Branch 33 → 36 not taken.
✓ Branch 40 → 41 taken 615197 times.
✗ Branch 40 → 43 not taken.
✓ Branch 47 → 48 taken 690447 times.
✗ Branch 47 → 50 not taken.
26383448 children.push_back(arg);
96 } else if constexpr (is_vector_of_derived_from_v<TDecayed, ASTNode>) {
97
6/12
✓ Branch 10 → 11 taken 7151997 times.
✗ Branch 10 → 12 not taken.
✓ Branch 17 → 18 taken 3717 times.
✗ Branch 17 → 19 not taken.
✓ Branch 22 → 23 taken 68128 times.
✗ Branch 22 → 24 not taken.
✓ Branch 31 → 32 taken 6445 times.
✗ Branch 31 → 33 not taken.
✓ Branch 34 → 35 taken 68128 times.
✗ Branch 34 → 36 not taken.
✓ Branch 38 → 39 taken 85573 times.
✗ Branch 38 → 40 not taken.
14767972 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 11693849 times.
✓ Branch 4 → 7 taken 15655577 times.
✓ Branch 11 → 12 taken 10955493 times.
✓ Branch 11 → 14 taken 12034396 times.
✓ Branch 16 → 17 taken 27335 times.
✗ Branch 16 → 19 not taken.
✓ Branch 18 → 19 taken 1456455 times.
✓ Branch 18 → 21 taken 11810439 times.
✓ Branch 23 → 24 taken 3255 times.
✓ Branch 23 → 26 taken 462 times.
✓ Branch 25 → 26 taken 689710 times.
✓ Branch 25 → 28 taken 2350823 times.
✓ Branch 32 → 33 taken 251707 times.
✓ Branch 32 → 35 taken 2589718 times.
✓ Branch 39 → 40 taken 615197 times.
✓ Branch 39 → 42 taken 2226228 times.
✓ Branch 46 → 47 taken 690447 times.
✓ Branch 46 → 49 taken 1872284 times.
82307363 (addChild(std::forward<Args>(args)), ...);
104 34501424 return children;
105 ✗ }
106
107 [[nodiscard]] virtual std::vector<ASTNode *> getChildren() const = 0;
108
109 14415609 virtual void resizeToNumberOfManifestations(size_t manifestationCount) { // NOLINT(misc-no-recursion)
110 // Resize children
111
3/4
✓ Branch 2 → 3 taken 14415609 times.
✗ Branch 2 → 25 not taken.
✓ Branch 19 → 5 taken 14170039 times.
✓ Branch 19 → 20 taken 14415609 times.
43001257 for (ASTNode *child : getChildren()) {
112
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 14170039 times.
14170039 assert(child != nullptr);
113
1/2
✓ Branch 9 → 10 taken 14170039 times.
✗ Branch 9 → 23 not taken.
14170039 child->resizeToNumberOfManifestations(manifestationCount);
114 14415609 }
115 // Do custom work
116 14415609 customItemsInitialization(manifestationCount);
117 14415609 }
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 8139965 virtual void customItemsInitialization(size_t) {} // Noop
129
130 113862 [[nodiscard]] virtual bool hasCompileTimeValue(size_t manIdx) const { // NOLINT(misc-no-recursion)
131
1/2
✓ Branch 2 → 3 taken 113862 times.
✗ Branch 2 → 14 not taken.
113862 const std::vector<ASTNode *> children = getChildren();
132
2/2
✓ Branch 4 → 5 taken 52101 times.
✓ Branch 4 → 6 taken 61761 times.
113862 if (children.size() != 1)
133 52101 return false;
134
1/2
✓ Branch 7 → 8 taken 61761 times.
✗ Branch 7 → 12 not taken.
61761 return children.front()->hasCompileTimeValue(manIdx);
135 113862 }
136
137 17570 [[nodiscard]] virtual CompileTimeValue getCompileTimeValue(size_t manIdx) const { // NOLINT(misc-no-recursion)
138
1/2
✓ Branch 2 → 3 taken 17570 times.
✗ Branch 2 → 14 not taken.
17570 const std::vector<ASTNode *> children = getChildren();
139
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 17570 times.
17570 if (children.size() != 1)
140 ✗ return {};
141
1/2
✓ Branch 7 → 8 taken 17570 times.
✗ Branch 7 → 12 not taken.
17570 return children.front()->getCompileTimeValue(manIdx);
142 17570 }
143
144 [[nodiscard]] std::string getErrorMessage() const;
145
146 318706 [[nodiscard]] virtual bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable,
147 size_t manIdx) const { // NOLINT(misc-no-recursion)
148
1/2
✓ Branch 2 → 3 taken 318706 times.
✗ Branch 2 → 15 not taken.
318706 const std::vector<ASTNode *> children = getChildren();
149
5/6
✓ Branch 4 → 5 taken 258280 times.
✓ Branch 4 → 9 taken 60426 times.
✓ Branch 6 → 7 taken 258280 times.
✗ Branch 6 → 13 not taken.
✓ Branch 7 → 8 taken 27299 times.
✓ Branch 7 → 9 taken 230981 times.
637412 return children.size() == 1 && children.front()->returnsOnAllControlPaths(doSetPredecessorsUnreachable, manIdx);
150 318706 }
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]] virtual std::vector<Union *> *getUnionManifestations() { // LCOV_EXCL_LINE
168 − assert_fail("Must be called on a UnionDefNode"); // LCOV_EXCL_LINE
169 return nullptr; // LCOV_EXCL_LINE
170 } // LCOV_EXCL_LINE
171
172 [[nodiscard]] const StmtLstNode *getNextOuterStmtLst() const;
173 [[nodiscard]] std::string getEnclosingFunctionSignature(size_t manIdx) const;
174
175 4655860 [[nodiscard]] virtual bool isFctOrProcDef() const { return false; }
176 − [[nodiscard]] virtual std::string getFunctionSignature(size_t manIdx) const { // LCOV_EXCL_LINE
177 − assert_fail("Must be called on a function/procedure def node"); // LCOV_EXCL_LINE
178 return ""; // LCOV_EXCL_LINE
179 } // LCOV_EXCL_LINE
180 3970501 [[nodiscard]] virtual bool isStructDef() const { return false; }
181 3970501 [[nodiscard]] virtual bool isUnionDef() const { return false; }
182 97 [[nodiscard]] virtual bool isParam() const { return false; }
183 193081 [[nodiscard]] virtual bool isStmtLst() const { return false; }
184 422703 [[nodiscard]] virtual bool isAssignExpr() const { return false; }
185 411605 [[nodiscard]] virtual bool isExprStmt() const { return false; }
186
187 // Public members
188 ASTNode *parent = nullptr;
189 const CodeLoc codeLoc;
190 };
191
192 // Make sure we have no unexpected increases in memory consumption
193 // Note: If this is adjusted, please run UnitBlockAllocator, which depends on the ASTNode size
194 static_assert(sizeof(ASTNode) == 48);
195
196 // ========================================================== EntryNode ==========================================================
197
198 class EntryNode final : public ASTNode {
199 public:
200 // Constructors
201 using ASTNode::ASTNode;
202
203 // Visitor methods
204 61390 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEntry(this); }
205 6788 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEntry(this); }
206
207 // Other methods
208 68128 GET_CHILDREN(modAttrs, importDefs, topLevelDefs);
209
210 // Public members
211 std::vector<ModAttrNode *> modAttrs;
212 std::vector<ImportDefNode *> importDefs;
213 std::vector<TopLevelDefNode *> topLevelDefs;
214 };
215
216 // ======================================================= TopLevelDefNode =======================================================
217
218 class TopLevelDefNode : public ASTNode {
219 public:
220 // Constructors
221 using ASTNode::ASTNode;
222
223 // Visitor methods
224 std::any accept(AbstractASTVisitor *visitor) override = 0;
225 std::any accept(ParallelizableASTVisitor *visitor) const override = 0;
226 };
227
228 // =========================================================== StmtNode ==========================================================
229
230 class StmtNode : public ASTNode {
231 public:
232 // Constructors
233 using ASTNode::ASTNode;
234
235 // Visitor methods
236 std::any accept(AbstractASTVisitor *visitor) override = 0;
237 std::any accept(ParallelizableASTVisitor *visitor) const override = 0;
238
239 // Public members
240 bool unreachable = false;
241 };
242
243 // Make sure we have no unexpected increases in memory consumption
244 static_assert(sizeof(StmtNode) == 56);
245
246 // ========================================================== ExprNode ===========================================================
247
248 class ExprNode : public ASTNode {
249 public:
250 // Constructors
251 using ASTNode::ASTNode;
252
253 // Visitor methods
254 std::any accept(AbstractASTVisitor *visitor) override = 0;
255 std::any accept(ParallelizableASTVisitor *visitor) const override = 0;
256
257 // Other methods
258 8802145 void resizeToNumberOfManifestations(size_t manifestationCount) override {
259 // Reserve this node
260
2/4
✓ Branch 2 → 3 taken 8802145 times.
✗ Branch 2 → 6 not taken.
✓ Branch 3 → 4 taken 8802145 times.
✗ Branch 3 → 6 not taken.
8802145 symbolTypes.resize(manifestationCount, QualType(TY_INVALID));
261 // Call parent
262 8802145 ASTNode::resizeToNumberOfManifestations(manifestationCount);
263 8802145 }
264
265 3191396 QualType setEvaluatedSymbolType(const QualType &symbolType, const size_t idx) {
266
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 3191396 times.
3191396 assert(symbolTypes.size() > idx);
267 3191396 symbolTypes.at(idx) = symbolType;
268 3191396 return symbolType;
269 }
270
271 2327098 [[nodiscard]] const QualType &getEvaluatedSymbolType(const size_t idx) const { // NOLINT(misc-no-recursion)
272
7/10
✓ Branch 3 → 4 taken 2327098 times.
✗ Branch 3 → 8 not taken.
✓ Branch 4 → 5 taken 2327098 times.
✗ Branch 4 → 49 not taken.
✓ Branch 5 → 6 taken 2327098 times.
✗ Branch 5 → 49 not taken.
✓ Branch 6 → 7 taken 1755798 times.
✓ Branch 6 → 8 taken 571300 times.
✓ Branch 9 → 10 taken 1755798 times.
✓ Branch 9 → 12 taken 571300 times.
2327098 if (!symbolTypes.empty() && !symbolTypes.at(idx).is(TY_INVALID))
273
1/2
✓ Branch 10 → 11 taken 1755798 times.
✗ Branch 10 → 49 not taken.
1755798 return symbolTypes.at(idx);
274
1/2
✓ Branch 12 → 13 taken 571300 times.
✗ Branch 12 → 49 not taken.
571300 const std::vector<ASTNode *> children = getChildren();
275
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 23 taken 571300 times.
571300 if (children.size() != 1)
276 ✗ throw CompilerError(INTERNAL_ERROR, "Cannot deduce evaluated symbol type");
277
1/2
✓ Branch 24 → 25 taken 571300 times.
✗ Branch 24 → 26 not taken.
571300 const auto expr = spice_pointer_cast<ExprNode *>(children.front());
278
1/2
✓ Branch 33 → 34 taken 571300 times.
✗ Branch 33 → 47 not taken.
571300 return expr->getEvaluatedSymbolType(idx);
279 571300 }
280
281 // Id of the expression scope, that holds the temporaries of this expression. Only some expressions have such a scope, see
282 // ExprScopeHandle.
283
2/4
✓ Branch 2 → 3 taken 285738 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 285738 times.
✗ Branch 3 → 8 not taken.
571476 [[nodiscard]] std::string getExprScopeId() const { return "expr:" + codeLoc.toString(); }
284
285 private:
286 // Private members
287 QualTypeList symbolTypes;
288 };
289
290 // Make sure we have no unexpected increases in memory consumption
291 static_assert(sizeof(ExprNode) == 72);
292
293 // ======================================================== MainFctDefNode =======================================================
294
295 class MainFctDefNode final : public TopLevelDefNode {
296 public:
297 // Constructors
298 using TopLevelDefNode::TopLevelDefNode;
299
300 // Visitor methods
301 4799 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitMainFctDef(this); }
302 964 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitMainFctDef(this); }
303
304 // Other methods
305 3405 GET_CHILDREN(attrs, paramLst, body);
306
1/2
✓ Branch 4 → 5 taken 1265 times.
✗ Branch 4 → 9 not taken.
3795 [[nodiscard]] static std::string getScopeId() { return "fct:main"; }
307 bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
308 ✗ [[nodiscard]] bool isFctOrProcDef() const override { return true; }
309 ✗ [[nodiscard]] std::string getFunctionSignature(size_t /*manIdx*/) const override { return "f<int> main()"; }
310
311 // Public members
312 TopLevelDefAttrNode *attrs = nullptr;
313 ParamLstNode *paramLst = nullptr;
314 StmtLstNode *body = nullptr;
315 bool takesArgs = false;
316 SymbolTableEntry *entry = nullptr;
317 Scope *bodyScope = nullptr;
318 };
319
320 // ========================================================== FctNameNode =======================================================
321
322 class FctNameNode final : public ASTNode {
323 public:
324 // Constructors
325 using ASTNode::ASTNode;
326
327 // Visitor methods
328 459287 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFctName(this); }
329 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFctName(this); }
330
331 // Other methods
332 777638 GET_CHILDREN();
333 14 [[nodiscard]] constexpr bool isOperatorOverload() const { return name.starts_with(OP_FCT_PREFIX); }
334 [[nodiscard]] bool supportsInverseOperator() const { return name == OP_FCT_EQUAL || name == OP_FCT_NOT_EQUAL; }
335
336 // Public members
337 std::string name;
338 std::string structName;
339 std::string fqName;
340 std::vector<std::string> nameFragments;
341 };
342
343 // ======================================================== FctDefBaseNode =======================================================
344
345 class FctDefBaseNode : public TopLevelDefNode {
346 public:
347 // Constructors
348 using TopLevelDefNode::TopLevelDefNode;
349
350 // Other methods
351 202924 [[nodiscard]] std::string getSymbolTableEntryName() const { return Function::getSymbolTableEntryName(name->name, codeLoc); }
352 40672 std::vector<Function *> *getFctManifestations(const std::string &) override { return &manifestations; }
353 14563031 [[nodiscard]] bool isFctOrProcDef() const override { return true; }
354 16 [[nodiscard]] std::string getFunctionSignature(size_t manIdx) const override {
355
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 16 times.
16 assert(manIdx < manifestations.size());
356 16 return manifestations.at(manIdx)->getSignature();
357 }
358 bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
359
360 // Public members
361 TopLevelDefAttrNode *attrs = nullptr;
362 QualifierLstNode *qualifierLst = nullptr;
363 FctNameNode *name;
364 TypeLstNode *templateTypeLst = nullptr;
365 ParamLstNode *paramLst = nullptr;
366 StmtLstNode *body = nullptr;
367 bool isMethod = false;
368 bool hasTemplateTypes = false;
369 bool hasParams = false;
370 TypeQualifiers qualifiers = TypeQualifiers::of(TY_FUNCTION);
371 SymbolTableEntry *entry = nullptr;
372 Scope *structScope = nullptr;
373 Scope *scope = nullptr;
374 std::vector<Function *> manifestations;
375 };
376
377 // ========================================================== FctDefNode =========================================================
378
379 class FctDefNode final : public FctDefBaseNode {
380 public:
381 // Constructors
382 using FctDefBaseNode::FctDefBaseNode;
383
384 // Visitor methods
385 564668 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFctDef(this); }
386 64557 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFctDef(this); }
387
388 // Other methods
389 515358 GET_CHILDREN(attrs, qualifierLst, returnType, name, templateTypeLst, paramLst, body);
390
2/4
✓ Branch 2 → 3 taken 136572 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 136572 times.
✗ Branch 3 → 8 not taken.
273144 [[nodiscard]] std::string getScopeId() const { return "fct:" + codeLoc.toString(); }
391
392 // Public members
393 DataTypeNode *returnType = nullptr;
394 };
395
396 // ========================================================== ProcDefNode ========================================================
397
398 class ProcDefNode final : public FctDefBaseNode {
399 public:
400 // Constructors
401 using FctDefBaseNode::FctDefBaseNode;
402
403 // Visitor methods
404 314445 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitProcDef(this); }
405 34895 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitProcDef(this); }
406
407 // Other methods
408 278694 GET_CHILDREN(attrs, qualifierLst, name, templateTypeLst, paramLst, body);
409
2/4
✓ Branch 2 → 3 taken 73306 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 73306 times.
✗ Branch 3 → 8 not taken.
146612 [[nodiscard]] std::string getScopeId() const { return "proc:" + codeLoc.toString(); }
410
411 // Public members
412 bool isCtor = false;
413 };
414
415 // ========================================================= StructDefNode =======================================================
416
417 class StructDefNode final : public TopLevelDefNode {
418 public:
419 // Constructors
420 using TopLevelDefNode::TopLevelDefNode;
421
422 // Visitor methods
423 85575 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitStructDef(this); }
424 9381 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitStructDef(this); }
425
426 // Other methods
427 85573 GET_CHILDREN(attrs, qualifierLst, templateTypeLst, interfaceTypeLst, fields);
428 28062782 std::vector<Struct *> *getStructManifestations() override { return &structManifestations; }
429 12034 std::vector<Function *> *getFctManifestations(const std::string &fctName) override {
430
2/2
✓ Branch 3 → 4 taken 10315 times.
✓ Branch 3 → 8 taken 1719 times.
12034 if (!defaultFctManifestations.contains(fctName))
431
1/2
✓ Branch 5 → 6 taken 10315 times.
✗ Branch 5 → 11 not taken.
10315 defaultFctManifestations.emplace(fctName, std::vector<Function *>());
432 12034 return &defaultFctManifestations.at(fctName);
433 }
434 755300 [[nodiscard]] bool isStructDef() const override { return true; }
435
436 // Public members
437 TopLevelDefAttrNode *attrs = nullptr;
438 QualifierLstNode *qualifierLst = nullptr;
439 TypeLstNode *templateTypeLst = nullptr;
440 TypeLstNode *interfaceTypeLst = nullptr;
441 std::vector<FieldNode *> fields;
442 bool hasTemplateTypes = false;
443 bool hasInterfaces = false;
444 bool emitVTable = false;
445 TypeQualifiers qualifiers = TypeQualifiers::of(TY_STRUCT);
446 std::string structName;
447 uint64_t typeId;
448 SymbolTableEntry *entry = nullptr;
449 std::vector<Struct *> structManifestations;
450 std::map<const std::string, std::vector<Function *>> defaultFctManifestations;
451 Scope *structScope = nullptr;
452 };
453
454 // ======================================================= InterfaceDefNode ======================================================
455
456 class InterfaceDefNode final : public TopLevelDefNode {
457 public:
458 // Constructors
459 using TopLevelDefNode::TopLevelDefNode;
460
461 // Visitor methods
462 8260 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitInterfaceDef(this); }
463 989 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitInterfaceDef(this); }
464
465 // Other methods
466 5905 GET_CHILDREN(attrs, qualifierLst, templateTypeLst, signatures);
467 3435 std::vector<Interface *> *getInterfaceManifestations() override { return &interfaceManifestations; }
468
469 // Public members
470 TopLevelDefAttrNode *attrs = nullptr;
471 QualifierLstNode *qualifierLst = nullptr;
472 TypeLstNode *templateTypeLst = nullptr;
473 std::vector<SignatureNode *> signatures;
474 bool hasTemplateTypes = false;
475 TypeQualifiers qualifiers = TypeQualifiers::of(TY_INTERFACE);
476 std::string interfaceName;
477 uint64_t typeId;
478 SymbolTableEntry *entry = nullptr;
479 std::vector<Interface *> interfaceManifestations;
480 Scope *interfaceScope = nullptr;
481 };
482
483 // ========================================================== UnionDefNode =======================================================
484
485 class UnionDefNode final : public TopLevelDefNode {
486 public:
487 // Constructors
488 using TopLevelDefNode::TopLevelDefNode;
489
490 // Visitor methods
491 540 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitUnionDef(this); }
492 62 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitUnionDef(this); }
493
494 // Other methods
495 540 GET_CHILDREN(attrs, qualifierLst, templateTypeLst, fields);
496 6 std::vector<Union *> *getUnionManifestations() override { return &unionManifestations; }
497 ✗ [[nodiscard]] bool isUnionDef() const override { return true; }
498
499 // Public members
500 TopLevelDefAttrNode *attrs = nullptr;
501 QualifierLstNode *qualifierLst = nullptr;
502 TypeLstNode *templateTypeLst = nullptr;
503 std::vector<FieldNode *> fields;
504 bool hasTemplateTypes = false;
505 TypeQualifiers qualifiers = TypeQualifiers::of(TY_UNION);
506 std::string unionName;
507 uint64_t typeId;
508 SymbolTableEntry *entry = nullptr;
509 std::vector<Union *> unionManifestations;
510 Scope *unionScope = nullptr;
511 };
512
513 // ========================================================== EnumDefNode ========================================================
514
515 class EnumDefNode final : public TopLevelDefNode {
516 public:
517 // Constructors
518 using TopLevelDefNode::TopLevelDefNode;
519
520 // Visitor methods
521 17818 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEnumDef(this); }
522 1934 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEnumDef(this); }
523
524 // Other methods
525 12139 GET_CHILDREN(qualifierLst, itemLst);
526
527 // Public members
528 QualifierLstNode *qualifierLst = nullptr;
529 EnumItemLstNode *itemLst = nullptr;
530 TypeQualifiers qualifiers = TypeQualifiers::of(TY_ENUM);
531 std::string enumName;
532 uint64_t typeId;
533 SymbolTableEntry *entry = nullptr;
534 Scope *enumScope;
535 };
536
537 // ====================================================== GenericTypeDefNode =====================================================
538
539 class GenericTypeDefNode final : public TopLevelDefNode {
540 public:
541 // Constructors
542 using TopLevelDefNode::TopLevelDefNode;
543
544 // Visitor methods
545 42246 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitGenericTypeDef(this); }
546 4965 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitGenericTypeDef(this); }
547
548 // Other methods
549 26019 GET_CHILDREN(typeAltsLst);
550
551 // Public members
552 TypeAltsLstNode *typeAltsLst = nullptr;
553 std::string typeName;
554 SymbolTableEntry *entry = nullptr;
555 };
556
557 // ========================================================= AliasDefNode ========================================================
558
559 class AliasDefNode final : public TopLevelDefNode {
560 public:
561 // Constructors
562 using TopLevelDefNode::TopLevelDefNode;
563
564 // Visitor methods
565 9824 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAliasDef(this); }
566 1183 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAliasDef(this); }
567
568 // Other methods
569 6443 GET_CHILDREN(qualifierLst, dataType);
570
571 // Public members
572 QualifierLstNode *qualifierLst = nullptr;
573 DataTypeNode *dataType = nullptr;
574 TypeQualifiers qualifiers = TypeQualifiers::of(TY_ALIAS);
575 std::string aliasName;
576 std::string dataTypeString;
577 uint64_t typeId;
578 SymbolTableEntry *entry = nullptr;
579 SymbolTableEntry *aliasedTypeContainerEntry = nullptr;
580 };
581
582 // ======================================================= GlobalVarDefNode ======================================================
583
584 class GlobalVarDefNode final : public TopLevelDefNode {
585 public:
586 // Constructors
587 using TopLevelDefNode::TopLevelDefNode;
588
589 // Visitor methods
590 76969 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitGlobalVarDef(this); }
591 10159 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitGlobalVarDef(this); }
592
593 // Other methods
594 ✗ [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override { return true; }
595 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
596
597 // Other methods
598 51096 GET_CHILDREN(dataType, constant);
599
600 // Public members
601 DataTypeNode *dataType = nullptr;
602 ConstantNode *constant = nullptr;
603 bool hasValue = false;
604 std::string varName;
605 SymbolTableEntry *entry = nullptr;
606 };
607
608 // ========================================================== ExtDeclNode ========================================================
609
610 class ExtDeclNode final : public TopLevelDefNode {
611 public:
612 // Constructors
613 using TopLevelDefNode::TopLevelDefNode;
614
615 // Visitor methods
616 108203 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitExtDecl(this); }
617 12165 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitExtDecl(this); }
618
619 // Other methods
620 69619 GET_CHILDREN(attrs, returnType, argTypeLst);
621 1614 std::vector<Function *> *getFctManifestations(const std::string &) override { return &extFunctionManifestations; }
622 24726 [[nodiscard]] std::string getScopeId() const {
623
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 24726 times.
24726 const char *prefix = hasReturnType ? "func:" : "proc:";
624
2/4
✓ Branch 5 → 6 taken 24726 times.
✗ Branch 5 → 13 not taken.
✓ Branch 6 → 7 taken 24726 times.
✗ Branch 6 → 11 not taken.
49452 return prefix + codeLoc.toString();
625 }
626
627 // Public members
628 TopLevelDefAttrNode *attrs = nullptr;
629 DataTypeNode *returnType = nullptr;
630 TypeLstWithEllipsisNode *argTypeLst = nullptr;
631 bool hasArgs = false;
632 bool hasReturnType = false;
633 std::string extFunctionName;
634 SymbolTableEntry *entry = nullptr;
635 Function *extFunction = nullptr;
636 std::vector<Function *> extFunctionManifestations;
637 };
638
639 // ======================================================== ImportDefNode ========================================================
640
641 class ImportDefNode final : public TopLevelDefNode {
642 public:
643 // Constructors
644 using TopLevelDefNode::TopLevelDefNode;
645
646 // Visitor methods
647 88452 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitImportDef(this); }
648 9377 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitImportDef(this); }
649
650 // Other methods
651 70452 GET_CHILDREN();
652
653 // Public members
654 std::string importPath;
655 std::string importName;
656 SymbolTableEntry *entry = nullptr;
657 };
658
659 // ======================================================== UnsafeBlockNode ======================================================
660
661 class UnsafeBlockNode final : public StmtNode {
662 public:
663 // Constructors
664 using StmtNode::StmtNode;
665
666 // Visitor methods
667 127883 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitUnsafeBlock(this); }
668 26928 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitUnsafeBlockDef(this); }
669
670 // Other methods
671 167474 GET_CHILDREN(body);
672
2/4
✓ Branch 2 → 3 taken 74014 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 74014 times.
✗ Branch 3 → 8 not taken.
148028 [[nodiscard]] std::string getScopeId() const { return "unsafe:" + codeLoc.toString(); }
673
674 // Public members
675 StmtLstNode *body = nullptr;
676 Scope *bodyScope = nullptr;
677 };
678
679 // ========================================================== ForLoopNode ========================================================
680
681 class ForLoopNode final : public StmtNode {
682 public:
683 // Constructors
684 using StmtNode::StmtNode;
685
686 // Visitor methods
687 45477 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitForLoop(this); }
688 10021 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitForLoop(this); }
689
690 // Other methods
691 52077 GET_CHILDREN(initDecl, condAssign, incAssign, body);
692
2/4
✓ Branch 2 → 3 taken 27514 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 27514 times.
✗ Branch 3 → 8 not taken.
55028 [[nodiscard]] std::string getScopeId() const { return "for:" + codeLoc.toString(); }
693 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
694
695 // Public members
696 DeclStmtNode *initDecl = nullptr;
697 ExprNode *condAssign = nullptr;
698 ExprNode *incAssign = nullptr;
699 StmtLstNode *body = nullptr;
700 Scope *bodyScope = nullptr;
701 };
702
703 // ======================================================== ForeachLoopNode ======================================================
704
705 class ForeachLoopNode final : public StmtNode {
706 public:
707 // Constructors
708 using StmtNode::StmtNode;
709
710 // Visitor methods
711 8993 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitForeachLoop(this); }
712 1830 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitForeachLoop(this); }
713
714 // Other methods
715 11478 GET_CHILDREN(idxVarDecl, itemVarDecl, iteratorAssign, body);
716
2/4
✓ Branch 2 → 3 taken 5183 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 5183 times.
✗ Branch 3 → 8 not taken.
10366 [[nodiscard]] std::string getScopeId() const { return "foreach:" + codeLoc.toString(); }
717
718 // Public members
719 DeclStmtNode *idxVarDecl = nullptr;
720 DeclStmtNode *itemVarDecl = nullptr;
721 ExprNode *iteratorAssign = nullptr;
722 StmtLstNode *body = nullptr;
723 Scope *bodyScope = nullptr;
724 Function *getIteratorFct = nullptr;
725 Function *getFct = nullptr;
726 Function *getIdxFct = nullptr;
727 Function *isValidFct = nullptr;
728 Function *nextFct = nullptr;
729 Function *calledItemCopyCtor = nullptr;
730 };
731
732 // ========================================================= WhileLoopNode =======================================================
733
734 class WhileLoopNode final : public StmtNode {
735 public:
736 // Constructors
737 using StmtNode::StmtNode;
738
739 // Visitor methods
740 19538 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitWhileLoop(this); }
741 3539 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitWhileLoop(this); }
742
743 // Other methods
744 25195 GET_CHILDREN(condition, body);
745
2/4
✓ Branch 2 → 3 taken 10817 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 10817 times.
✗ Branch 3 → 8 not taken.
21634 [[nodiscard]] std::string getScopeId() const { return "while:" + codeLoc.toString(); }
746 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
747
748 // Public members
749 ExprNode *condition = nullptr;
750 StmtLstNode *body = nullptr;
751 Scope *bodyScope = nullptr;
752 };
753
754 // ======================================================== DoWhileLoopNode ======================================================
755
756 class DoWhileLoopNode final : public StmtNode {
757 public:
758 // Constructors
759 using StmtNode::StmtNode;
760
761 // Visitor methods
762 177 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitDoWhileLoop(this); }
763 49 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitDoWhileLoop(this); }
764
765 // Other methods
766 209 GET_CHILDREN(body, condition);
767
2/4
✓ Branch 2 → 3 taken 135 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 135 times.
✗ Branch 3 → 8 not taken.
270 [[nodiscard]] std::string getScopeId() const { return "dowhile:" + codeLoc.toString(); }
768 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
769
770 // Public members
771 StmtLstNode *body = nullptr;
772 ExprNode *condition = nullptr;
773 Scope *bodyScope = nullptr;
774 };
775
776 // ========================================================== IfStmtNode =========================================================
777
778 class IfStmtNode final : public StmtNode {
779 public:
780 // Constructors
781 using StmtNode::StmtNode;
782
783 // Visitor methods
784 293399 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitIfStmt(this); }
785 58928 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitIfStmt(this); }
786
787 // Other methods
788 352642 GET_CHILDREN(condition, thenBody, elseStmt);
789
2/4
✓ Branch 2 → 3 taken 164311 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 164311 times.
✗ Branch 3 → 8 not taken.
328622 [[nodiscard]] std::string getScopeId() const { return "if:" + codeLoc.toString(); }
790 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
791 156210 void customItemsInitialization(const size_t manifestationCount) override {
792 156210 compileThenBranch.resize(manifestationCount, true);
793 156210 compileElseBranch.resize(manifestationCount, true);
794 156210 }
795
4/4
✓ Branch 3 → 4 taken 154559 times.
✓ Branch 3 → 6 taken 46180 times.
✓ Branch 5 → 6 taken 153065 times.
✓ Branch 5 → 7 taken 1494 times.
200739 [[nodiscard]] bool doCompileThenBranch(size_t manIdx) const { return compileThenBranch.empty() || compileThenBranch[manIdx]; }
796
4/4
✓ Branch 3 → 4 taken 96200 times.
✓ Branch 3 → 6 taken 46180 times.
✓ Branch 5 → 6 taken 95631 times.
✓ Branch 5 → 7 taken 569 times.
142380 [[nodiscard]] bool doCompileElseBranch(size_t manIdx) const { return compileElseBranch.empty() || compileElseBranch[manIdx]; }
797
798 // Public members
799 std::vector<bool> compileThenBranch;
800 std::vector<bool> compileElseBranch;
801 ExprNode *condition = nullptr;
802 StmtLstNode *thenBody = nullptr;
803 ElseStmtNode *elseStmt = nullptr;
804 Scope *thenBodyScope = nullptr;
805 };
806
807 // ========================================================= ElseStmtNode ========================================================
808
809 class ElseStmtNode final : public StmtNode {
810 public:
811 // Constructors
812 using StmtNode::StmtNode;
813
814 // Visitor methods
815 22870 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitElseStmt(this); }
816 4343 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitElseStmt(this); }
817
818 // Other methods
819 28176 GET_CHILDREN(ifStmt, body);
820
2/4
✓ Branch 2 → 3 taken 7056 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 7056 times.
✗ Branch 3 → 8 not taken.
14112 [[nodiscard]] std::string getScopeId() const { return "if:" + codeLoc.toString(); }
821 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
822
823 // Public members
824 bool isElseIf = false;
825 IfStmtNode *ifStmt = nullptr;
826 StmtLstNode *body = nullptr;
827 Scope *elseBodyScope = nullptr;
828 };
829
830 // ======================================================== SwitchStmtNode =======================================================
831
832 class SwitchStmtNode final : public StmtNode {
833 public:
834 // Constructors
835 using StmtNode::StmtNode;
836
837 // Visitor methods
838 2615 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitSwitchStmt(this); }
839 333 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitSwitchStmt(this); }
840
841 // Other methods
842 3717 GET_CHILDREN(assignExpr, caseBranches, defaultBranch);
843 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
844
845 // Public members
846 ExprNode *assignExpr = nullptr;
847 std::vector<CaseBranchNode *> caseBranches;
848 DefaultBranchNode *defaultBranch = nullptr;
849 bool hasDefaultBranch = false;
850 };
851
852 // ======================================================== CaseBranchNode =======================================================
853
854 class CaseBranchNode final : public ASTNode {
855 public:
856 // Constructors
857 using ASTNode::ASTNode;
858
859 // Visitor methods
860 23651 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitCaseBranch(this); }
861 3247 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitCaseBranch(this); }
862
863 // Other methods
864 27335 GET_CHILDREN(caseConstants, body);
865
2/4
✓ Branch 2 → 3 taken 9757 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 9757 times.
✗ Branch 3 → 8 not taken.
19514 [[nodiscard]] std::string getScopeId() const { return "case:" + codeLoc.toString(); }
866 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
867
868 // Public members
869 std::vector<CaseConstantNode *> caseConstants;
870 StmtLstNode *body = nullptr;
871 Scope *bodyScope = nullptr;
872 };
873
874 // ======================================================= DefaultBranchNode =====================================================
875
876 class DefaultBranchNode final : public ASTNode {
877 public:
878 // Constructors
879 using ASTNode::ASTNode;
880
881 // Visitor methods
882 2299 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitDefaultBranch(this); }
883 285 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitDefaultBranch(this); }
884
885 // Other methods
886 2597 GET_CHILDREN(body);
887
2/4
✓ Branch 2 → 3 taken 863 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 863 times.
✗ Branch 3 → 8 not taken.
1726 [[nodiscard]] std::string getScopeId() const { return "default:" + codeLoc.toString(); }
888 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
889
890 // Public members
891 StmtLstNode *body = nullptr;
892 Scope *bodyScope = nullptr;
893 };
894
895 // ==================================================== AnonymousBlockStmtNode ===================================================
896
897 class AnonymousBlockStmtNode final : public StmtNode {
898 public:
899 // Constructors
900 using StmtNode::StmtNode;
901
902 // Visitor methods
903 451 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAnonymousBlockStmt(this); }
904 141 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAnonymousBlockStmt(this); }
905
906 // Other methods
907 616 GET_CHILDREN(body);
908
2/4
✓ Branch 2 → 3 taken 423 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 423 times.
✗ Branch 3 → 8 not taken.
846 [[nodiscard]] std::string getScopeId() const { return "anon:" + codeLoc.toString(); }
909
910 // Public members
911 StmtLstNode *body = nullptr;
912 Scope *bodyScope = nullptr;
913 };
914
915 // ========================================================= StmtLstNode =========================================================
916
917 class StmtLstNode final : public ASTNode {
918 public:
919 // Structs
920 struct ResourcesForManifestationToCleanup {
921 std::vector<std::pair<SymbolTableEntry *, Function *>> dtorFunctionsToCall;
922 std::vector<SymbolTableEntry *> heapVarsToFree;
923 };
924
925 // Constructors
926 using ASTNode::ASTNode;
927
928 // Visitor methods
929 1221032 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitStmtLst(this); }
930 227903 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitStmtLst(this); }
931
932 // Other methods
933 1624423 GET_CHILDREN(statements);
934 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
935 606837 void customItemsInitialization(const size_t manifestationCount) override { resourcesToCleanup.resize(manifestationCount); }
936 208428 [[nodiscard]] bool isStmtLst() const override { return true; }
937
938 // Public members
939 std::vector<StmtNode *> statements;
940 size_t complexity = 0;
941 std::vector<ResourcesForManifestationToCleanup> resourcesToCleanup;
942 CodeLoc closingBraceCodeLoc = CodeLoc(1, 0);
943 };
944
945 // ========================================================= TypeLstNode =========================================================
946
947 class TypeLstNode final : public ASTNode {
948 public:
949 // Constructors
950 using ASTNode::ASTNode;
951
952 // Visitor methods
953 301174 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTypeLst(this); }
954 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTypeLst(this); }
955
956 // Other methods
957 482276 GET_CHILDREN(dataTypes);
958
959 // Public members
960 std::vector<DataTypeNode *> dataTypes;
961 };
962
963 // =================================================== TypeLstWithEllipsisNode ===================================================
964
965 class TypeLstWithEllipsisNode final : public ASTNode {
966 public:
967 // Constructors
968 using ASTNode::ASTNode;
969
970 // Visitor methods
971 53748 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTypeLstWithEllipsis(this); }
972 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTypeLstWithEllipsis(this); }
973
974 // Other methods
975 65349 GET_CHILDREN(typeLst);
976
977 // Public members
978 TypeLstNode *typeLst;
979 bool hasEllipsis = false;
980 };
981
982 // ======================================================= TypeAltsLstNode =======================================================
983
984 class TypeAltsLstNode final : public ASTNode {
985 public:
986 // Constructors
987 using ASTNode::ASTNode;
988
989 // Visitor methods
990 20882 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTypeAltsLst(this); }
991 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTypeAltsLst(this); }
992
993 // Other methods
994 26019 GET_CHILDREN(dataTypes);
995
996 // Public members
997 std::vector<DataTypeNode *> dataTypes;
998 };
999
1000 // ======================================================== ParamLstNode =========================================================
1001
1002 class ParamLstNode final : public ASTNode {
1003 public:
1004 // Constructors
1005 using ASTNode::ASTNode;
1006
1007 // Visitor methods
1008 532391 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitParamLst(this); }
1009 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitParamLst(this); }
1010
1011 // Other methods
1012 603717 GET_CHILDREN(params);
1013
1014 // Public members
1015 std::vector<DeclStmtNode *> params;
1016 };
1017
1018 // ========================================================== ArgLstNode =========================================================
1019
1020 class ArgLstNode final : public ASTNode {
1021 public:
1022 // Structs
1023 struct ArgInfo {
1024 Function *copyCtor = nullptr;
1025 };
1026
1027 // Constructors
1028 using ASTNode::ASTNode;
1029
1030 // Visitor methods
1031 676660 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitArgLst(this); }
1032 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitArgLst(this); }
1033
1034 // Other methods
1035 1107296 GET_CHILDREN(args);
1036
1037 // Public members
1038 std::vector<ExprNode *> args;
1039 std::vector<ArgInfo> argInfos;
1040 };
1041
1042 // ======================================================== EnumItemLstNode ======================================================
1043
1044 class EnumItemLstNode final : public ASTNode {
1045 public:
1046 // Constructors
1047 using ASTNode::ASTNode;
1048
1049 // Visitor methods
1050 12143 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEnumItemLst(this); }
1051 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEnumItemLst(this); }
1052
1053 // Other methods
1054 14107 GET_CHILDREN(items);
1055
1056 // Public members
1057 std::vector<EnumItemNode *> items;
1058 };
1059
1060 // ========================================================= EnumItemNode ========================================================
1061
1062 class EnumItemNode final : public ASTNode {
1063 public:
1064 // Constructors
1065 using ASTNode::ASTNode;
1066
1067 // Visitor methods
1068 116294 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEnumItem(this); }
1069 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEnumItem(this); }
1070
1071 // Other methods
1072 116282 GET_CHILDREN();
1073 3336 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override {
1074 3336 return {.intValue = static_cast<int32_t>(itemValue)};
1075 }
1076
1077 // Public members
1078 bool hasValue = false;
1079 uint32_t itemValue;
1080 std::string itemName;
1081 SymbolTableEntry *entry = nullptr;
1082 EnumDefNode *enumDef = nullptr;
1083 };
1084
1085 // ========================================================== FieldNode ==========================================================
1086
1087 class FieldNode final : public ASTNode {
1088 public:
1089 // Constructors
1090 using ASTNode::ASTNode;
1091
1092 // Visitor methods
1093 187940 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitField(this); }
1094 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitField(this); }
1095
1096 // Other methods
1097 215177 GET_CHILDREN(dataType, defaultValue);
1098
1099 // Public members
1100 DataTypeNode *dataType = nullptr;
1101 ExprNode *defaultValue = nullptr;
1102 std::string fieldName;
1103 };
1104
1105 // ======================================================== SignatureNode ========================================================
1106
1107 class SignatureNode final : public ASTNode {
1108 public:
1109 // Enums
1110 enum class SignatureType : uint8_t {
1111 TYPE_NONE,
1112 TYPE_FUNCTION,
1113 TYPE_PROCEDURE,
1114 };
1115
1116 // Constructors
1117 using ASTNode::ASTNode;
1118
1119 // Visitor methods
1120 57172 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitSignature(this); }
1121 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitSignature(this); }
1122
1123 // Other methods
1124 49647 GET_CHILDREN(qualifierLst, returnType, templateTypeLst, paramTypeLst);
1125 12 std::vector<Function *> *getFctManifestations(const std::string &) override { return &signatureManifestations; }
1126
1127 // Public members
1128 QualifierLstNode *qualifierLst = nullptr;
1129 DataTypeNode *returnType = nullptr;
1130 TypeLstNode *templateTypeLst = nullptr;
1131 TypeLstNode *paramTypeLst = nullptr;
1132 bool hasReturnType = false;
1133 bool hasTemplateTypes = false;
1134 bool hasParams = false;
1135 SignatureType signatureType = SignatureType::TYPE_NONE;
1136 TypeQualifiers signatureQualifiers;
1137 std::string methodName;
1138 SymbolTableEntry *entry = nullptr;
1139 std::vector<Function *> signatureManifestations;
1140 };
1141
1142 // ========================================================= DeclStmtNode ========================================================
1143
1144 class DeclStmtNode final : public StmtNode {
1145 public:
1146 // Constructors
1147 using StmtNode::StmtNode;
1148
1149 // Visitor methods
1150 1200636 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitDeclStmt(this); }
1151 90258 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitDeclStmt(this); }
1152
1153 // Other methods
1154 1322228 GET_CHILDREN(dataType, assignExpr);
1155 538291 void customItemsInitialization(const size_t manifestationCount) override { entries.resize(manifestationCount); }
1156 6015 [[nodiscard]] bool isParam() const override { return isFctParam; }
1157
1158 // Public members
1159 DataTypeNode *dataType = nullptr;
1160 ExprNode *assignExpr = nullptr;
1161 bool hasAssignment = false;
1162 bool isFctParam = false;
1163 bool isForEachItem = false;
1164 bool isCtorCallRequired = false; // For struct, in case there are reference fields, we need to call a user-defined ctor
1165 std::string varName;
1166 std::vector<SymbolTableEntry *> entries;
1167 Function *calledInitCtor = nullptr;
1168 Function *calledCopyCtor = nullptr;
1169 };
1170
1171 // ========================================================= ExprStmtNode ========================================================
1172
1173 class ExprStmtNode final : public StmtNode {
1174 public:
1175 // Constructors
1176 using StmtNode::StmtNode;
1177
1178 // Visitor methods
1179 771891 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitExprStmt(this); }
1180 152130 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitExprStmt(this); }
1181
1182 // Other methods
1183 1431840 GET_CHILDREN(expr);
1184 11098 [[nodiscard]] bool isExprStmt() const override { return true; }
1185
1186 // Public members
1187 ExprNode *expr = nullptr;
1188 };
1189
1190 // ======================================================= QualifierLstNode ======================================================
1191
1192 class QualifierLstNode final : public ASTNode {
1193 public:
1194 // Constructors
1195 using ASTNode::ASTNode;
1196
1197 // Visitor methods
1198 1302167 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitQualifierLst(this); }
1199 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitQualifierLst(this); }
1200
1201 // Other methods
1202 2106660 GET_CHILDREN(qualifiers);
1203
1204 // Public members
1205 std::vector<QualifierNode *> qualifiers;
1206 };
1207
1208 // ========================================================= QualifierNode =======================================================
1209
1210 class QualifierNode final : public ASTNode {
1211 public:
1212 // Enums
1213 enum class QualifierType : uint8_t {
1214 TY_NONE,
1215 TY_CONST,
1216 TY_SIGNED,
1217 TY_UNSIGNED,
1218 TY_INLINE,
1219 TY_PUBLIC,
1220 TY_HEAP,
1221 TY_COMPOSITION,
1222 };
1223
1224 // Constructors
1225 using ASTNode::ASTNode;
1226
1227 // Visitor methods
1228 1521204 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitQualifier(this); }
1229 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitQualifier(this); }
1230
1231 // Other methods
1232 2460019 GET_CHILDREN();
1233
1234 // Public members
1235 QualifierType type = QualifierType::TY_NONE;
1236 };
1237
1238 // ========================================================== ModAttrNode ========================================================
1239
1240 class ModAttrNode final : public ASTNode {
1241 public:
1242 // Constructors
1243 using ASTNode::ASTNode;
1244
1245 // Visitor methods
1246 23351 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitModAttr(this); }
1247 2218 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitModAttr(this); }
1248
1249 // Other methods
1250 23347 GET_CHILDREN(attrLst);
1251
1252 // Public members
1253 AttrLstNode *attrLst = nullptr;
1254 };
1255
1256 // ====================================================== TopLevelDefAttrNode ====================================================
1257
1258 class TopLevelDefAttrNode final : public ASTNode {
1259 public:
1260 // Constructors
1261 using ASTNode::ASTNode;
1262
1263 // Visitor methods
1264 14400 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTopLevelDefinitionAttr(this); }
1265 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTopLevelDefinitionAttr(this); }
1266
1267 // Other methods
1268 21774 GET_CHILDREN(attrLst);
1269
1270 // Public members
1271 AttrLstNode *attrLst = nullptr;
1272 };
1273
1274 // ========================================================= LambdaAttrNode ======================================================
1275
1276 class LambdaAttrNode final : public ASTNode {
1277 public:
1278 // Constructors
1279 using ASTNode::ASTNode;
1280
1281 // Visitor methods
1282 16 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLambdaAttr(this); }
1283 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLambdaAttr(this); }
1284
1285 // Other methods
1286 54 GET_CHILDREN(attrLst);
1287
1288 // Public members
1289 AttrLstNode *attrLst = nullptr;
1290 };
1291
1292 // ========================================================== AttrLstNode ========================================================
1293
1294 class AttrLstNode final : public ASTNode {
1295 public:
1296 // Constructors
1297 using ASTNode::ASTNode;
1298
1299 // Visitor methods
1300 35431 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAttrLst(this); }
1301 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAttrLst(this); }
1302
1303 // Other methods
1304 45175 GET_CHILDREN(attributes);
1305 [[nodiscard]] std::vector<const CompileTimeValue *> getAttrValuesByName(const std::string &key) const;
1306 [[nodiscard]] const CompileTimeValue *getAttrValueByName(const std::string &key) const;
1307 [[nodiscard]] bool hasAttr(const std::string &key) const;
1308
1309 // Public members
1310 std::vector<AttrNode *> attributes;
1311 };
1312
1313 // ============================================================ AttrNode =========================================================
1314
1315 class AttrNode final : public ASTNode {
1316 public:
1317 // Enums
1318 enum AttrTarget : uint8_t {
1319 TARGET_INVALID = 0,
1320 TARGET_MODULE = 1 << 0,
1321 TARGET_STRUCT = 1 << 1,
1322 TARGET_INTERFACE = 1 << 2,
1323 TARGET_FCT_PROC = 1 << 3,
1324 TARGET_EXT_DECL = 1 << 4,
1325 TARGET_LAMBDA = 1 << 5,
1326 TARGET_UNION = 1 << 6,
1327 };
1328
1329 enum class AttrType : uint8_t {
1330 ATTR_TYPE_INVALID,
1331 TYPE_STRING,
1332 TYPE_BOOL,
1333 TYPE_INT,
1334 };
1335
1336 // Constructors
1337 using ASTNode::ASTNode;
1338
1339 // Visitor methods
1340 75377 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAttr(this); }
1341 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAttr(this); }
1342
1343 // Other methods
1344 80561 GET_CHILDREN(value);
1345 [[nodiscard]] const CompileTimeValue *getValue() const;
1346
1347 // Public members
1348 ConstantNode *value = nullptr;
1349 AttrType type = AttrType::ATTR_TYPE_INVALID;
1350 AttrTarget target = TARGET_INVALID;
1351 std::string key;
1352 };
1353
1354 // ======================================================== CaseConstantNode =====================================================
1355
1356 class CaseConstantNode final : public ExprNode {
1357 public:
1358 // Constructors
1359 using ExprNode::ExprNode;
1360
1361 // Visitor methods
1362 31659 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitCaseConstant(this); }
1363 4055 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitCaseConstant(this); }
1364
1365 // Other methods
1366 36211 GET_CHILDREN(constant);
1367
1368 // Public members
1369 ConstantNode *constant = nullptr;
1370 std::vector<std::string> identifierFragments;
1371 std::string fqIdentifier;
1372 const SymbolTableEntry *entry = nullptr;
1373 };
1374
1375 // ======================================================== ReturnStmtNode =======================================================
1376
1377 class ReturnStmtNode final : public StmtNode {
1378 public:
1379 // Constructors
1380 using StmtNode::StmtNode;
1381
1382 // Visitor methods
1383 584856 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitReturnStmt(this); }
1384 104629 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitReturnStmt(this); }
1385
1386 // Other methods
1387 784703 GET_CHILDREN(assignExpr);
1388 86041 [[nodiscard]] bool returnsOnAllControlPaths(bool *, size_t) const override { return true; }
1389
1390 // Public members
1391 ExprNode *assignExpr = nullptr;
1392 QualType returnType;
1393 Function *calledCopyCtor = nullptr;
1394 bool hasReturnValue = false;
1395 };
1396
1397 // ======================================================== BreakStmtNode ========================================================
1398
1399 class BreakStmtNode final : public StmtNode {
1400 public:
1401 // Constructors
1402 using StmtNode::StmtNode;
1403
1404 // Visitor methods
1405 7155 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBreakStmt(this); }
1406 1328 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBreakStmt(this); }
1407
1408 // Other methods
1409 10142 GET_CHILDREN();
1410
1411 // Public members
1412 int breakTimes = 1;
1413 };
1414
1415 // ======================================================= ContinueStmtNode ======================================================
1416
1417 class ContinueStmtNode final : public StmtNode {
1418 public:
1419 // Constructors
1420 using StmtNode::StmtNode;
1421
1422 // Visitor methods
1423 8032 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitContinueStmt(this); }
1424 2110 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitContinueStmt(this); }
1425
1426 // Other methods
1427 10158 GET_CHILDREN();
1428
1429 // Public members
1430 int continueTimes = 1;
1431 };
1432
1433 // ====================================================== FallthroughStmtNode ====================================================
1434
1435 class FallthroughStmtNode final : public StmtNode {
1436 public:
1437 // Constructors
1438 using StmtNode::StmtNode;
1439
1440 // Visitor methods
1441 32 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFallthroughStmt(this); }
1442 8 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFallthroughStmt(this); }
1443
1444 // Other methods
1445 50 GET_CHILDREN();
1446 };
1447
1448 // ======================================================== AssertStmtNode =======================================================
1449
1450 class AssertStmtNode final : public StmtNode {
1451 public:
1452 // Constructors
1453 using StmtNode::StmtNode;
1454
1455 // Visitor methods
1456 73211 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAssertStmt(this); }
1457 17771 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAssertStmt(this); }
1458
1459 // Other methods
1460 106760 GET_CHILDREN(assignExpr);
1461
1462 // Public members
1463 ExprNode *assignExpr = nullptr;
1464 std::string expressionString;
1465 };
1466
1467 // ======================================================= AssignExprNode ========================================================
1468
1469 class AssignExprNode final : public ExprNode {
1470 public:
1471 // Enums
1472 enum class AssignOp : uint8_t {
1473 OP_NONE,
1474 OP_ASSIGN,
1475 OP_PLUS_EQUAL,
1476 OP_MINUS_EQUAL,
1477 OP_MUL_EQUAL,
1478 OP_DIV_EQUAL,
1479 OP_REM_EQUAL,
1480 OP_SHL_EQUAL,
1481 OP_SHR_EQUAL,
1482 OP_AND_EQUAL,
1483 OP_OR_EQUAL,
1484 OP_XOR_EQUAL
1485 };
1486
1487 // Constructors
1488 using ExprNode::ExprNode;
1489
1490 // Visitor methods
1491 391471 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAssignExpr(this); }
1492 76009 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAssignExpr(this); }
1493
1494 // Other methods
1495 526134 GET_CHILDREN(lhs, rhs, ternaryExpr);
1496 [[nodiscard]] bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable, size_t manIdx) const override;
1497 9168 [[nodiscard]] bool isAssignExpr() const override { return true; }
1498 9260 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1499 146592 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1500 202274 void customItemsInitialization(const size_t manifestationCount) override {
1501
2/4
✓ Branch 4 → 5 taken 202274 times.
✗ Branch 4 → 12 not taken.
✓ Branch 5 → 6 taken 202274 times.
✗ Branch 5 → 10 not taken.
404548 opFct.resize(manifestationCount, {nullptr});
1502
1/2
✓ Branch 8 → 9 taken 202274 times.
✗ Branch 8 → 17 not taken.
202274 lhsDtorFct.resize(manifestationCount, nullptr);
1503 202274 }
1504 AtomicExprNode *getLhsAtomicNode() const;
1505
1506 // Public members
1507 ExprNode *lhs = nullptr;
1508 ExprNode *rhs = nullptr;
1509 ExprNode *ternaryExpr = nullptr;
1510 AssignOp op = AssignOp::OP_NONE;
1511 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1512 // Dtor of the left-hand side to call before a copy-assignment overwrites an already initialized value.
1513 // Only set for non-declaration copy-assignments of non-trivially-destructible structs (one entry per manifestation).
1514 std::vector<const Function *> lhsDtorFct;
1515 };
1516
1517 // ======================================================= TernaryExprNode =======================================================
1518
1519 class TernaryExprNode final : public ExprNode {
1520 public:
1521 // Constructors
1522 using ExprNode::ExprNode;
1523
1524 // Visitor methods
1525 29194 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitTernaryExpr(this); }
1526 4777 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitTernaryExpr(this); }
1527
1528 // Other methods
1529 36686 GET_CHILDREN(condition, trueExpr, falseExpr);
1530 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1531 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1532
1533 // Public members
1534 ExprNode *condition = nullptr;
1535 ExprNode *trueExpr = nullptr;
1536 ExprNode *falseExpr = nullptr;
1537 Function *calledCopyCtor = nullptr;
1538 bool trueSideCallsCopyCtor = false;
1539 bool falseSideCallsCopyCtor = false;
1540 bool isShortened = false;
1541 };
1542
1543 // ===================================================== LogicalOrExprNode =======================================================
1544
1545 class LogicalOrExprNode final : public ExprNode {
1546 public:
1547 // Constructors
1548 using ExprNode::ExprNode;
1549
1550 // Visitor methods
1551 40546 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLogicalOrExpr(this); }
1552 6046 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLogicalOrExpr(this); }
1553
1554 // Other methods
1555 55823 GET_CHILDREN(operands);
1556
1557 // Public members
1558 std::vector<ExprNode *> operands;
1559 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1560 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1561 };
1562
1563 // ===================================================== LogicalAndExprNode ======================================================
1564
1565 class LogicalAndExprNode final : public ExprNode {
1566 public:
1567 // Constructors
1568 using ExprNode::ExprNode;
1569
1570 // Visitor methods
1571 32015 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLogicalAndExpr(this); }
1572 5302 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLogicalAndExpr(this); }
1573
1574 // Other methods
1575 39207 GET_CHILDREN(operands);
1576
1577 // Public members
1578 std::vector<ExprNode *> operands;
1579 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1580 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1581 };
1582
1583 // ===================================================== BitwiseOrExprNode =======================================================
1584
1585 class BitwiseOrExprNode final : public ExprNode {
1586 public:
1587 // Constructors
1588 using ExprNode::ExprNode;
1589
1590 // Visitor methods
1591 7832 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBitwiseOrExpr(this); }
1592 1090 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBitwiseOrExpr(this); }
1593
1594 // Other methods
1595 10008 GET_CHILDREN(operands);
1596 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1597 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1598 16 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1599 2352 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1600
2/4
✓ Branch 4 → 5 taken 3276 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 3276 times.
✗ Branch 5 → 9 not taken.
9828 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1601
1602 // Public members
1603 std::vector<ExprNode *> operands;
1604 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1605 };
1606
1607 // ==================================================== BitwiseXorExprNode =======================================================
1608
1609 class BitwiseXorExprNode final : public ExprNode {
1610 public:
1611 // Constructors
1612 using ExprNode::ExprNode;
1613
1614 // Visitor methods
1615 820 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBitwiseXorExpr(this); }
1616 167 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBitwiseXorExpr(this); }
1617
1618 // Other methods
1619 1164 GET_CHILDREN(operands);
1620 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1621 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1622 12 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1623 344 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1624
2/4
✓ Branch 4 → 5 taken 473 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 473 times.
✗ Branch 5 → 9 not taken.
1419 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1625
1626 // Public members
1627 std::vector<ExprNode *> operands;
1628 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1629 };
1630
1631 // ==================================================== BitwiseAndExprNode =======================================================
1632
1633 class BitwiseAndExprNode final : public ExprNode {
1634 public:
1635 // Constructors
1636 using ExprNode::ExprNode;
1637
1638 // Visitor methods
1639 3242 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBitwiseAndExpr(this); }
1640 924 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBitwiseAndExpr(this); }
1641
1642 // Other methods
1643 4264 GET_CHILDREN(operands);
1644 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1645 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1646 16 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1647 1860 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1648
2/4
✓ Branch 4 → 5 taken 1942 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 1942 times.
✗ Branch 5 → 9 not taken.
5826 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1649
1650 // Public members
1651 std::vector<ExprNode *> operands;
1652 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1653 };
1654
1655 // ===================================================== EqualityExprNode ========================================================
1656
1657 class EqualityExprNode final : public ExprNode {
1658 public:
1659 // Enums
1660 enum class EqualityOp : uint8_t {
1661 OP_NONE,
1662 OP_EQUAL,
1663 OP_NOT_EQUAL,
1664 };
1665
1666 // Constructors
1667 using ExprNode::ExprNode;
1668
1669 // Visitor methods
1670 315047 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitEqualityExpr(this); }
1671 59014 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitEqualityExpr(this); }
1672
1673 // Other methods
1674 435578 GET_CHILDREN(operands);
1675 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1676 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1677 10780 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1678 123352 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1679
2/4
✓ Branch 4 → 5 taken 164950 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 164950 times.
✗ Branch 5 → 9 not taken.
494850 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1680
1681 // Public members
1682 std::vector<ExprNode *> operands;
1683 EqualityOp op = EqualityOp::OP_NONE;
1684 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1685 };
1686
1687 // ==================================================== RelationalExprNode =======================================================
1688
1689 class RelationalExprNode final : public ExprNode {
1690 public:
1691 // Enums
1692 enum class RelationalOp : uint8_t {
1693 OP_NONE,
1694 OP_LESS,
1695 OP_GREATER,
1696 OP_LESS_EQUAL,
1697 OP_GREATER_EQUAL,
1698 };
1699
1700 // Constructors
1701 using ExprNode::ExprNode;
1702
1703 // Visitor methods
1704 161593 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitRelationalExpr(this); }
1705 34536 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitRelationalExpr(this); }
1706
1707 // Other methods
1708 216418 GET_CHILDREN(operands);
1709 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1710 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1711
1712 // Public members
1713 std::vector<ExprNode *> operands;
1714 RelationalOp op = RelationalOp::OP_NONE;
1715 };
1716
1717 // ====================================================== ShiftExprNode ==========================================================
1718
1719 class ShiftExprNode final : public ExprNode {
1720 public:
1721 // Enums
1722 enum class ShiftOp : uint8_t {
1723 OP_NONE,
1724 OP_SHIFT_LEFT,
1725 OP_SHIFT_RIGHT,
1726 };
1727
1728 // Typedefs
1729 using OpQueue = std::queue<std::pair<ShiftOp, QualType>>;
1730
1731 // Constructors
1732 using ExprNode::ExprNode;
1733
1734 // Visitor methods
1735 23818 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitShiftExpr(this); }
1736 5666 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitShiftExpr(this); }
1737
1738 // Other methods
1739 29558 GET_CHILDREN(operands);
1740 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1741 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1742 13020 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1743 22054 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1744
2/4
✓ Branch 4 → 5 taken 10040 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 10040 times.
✗ Branch 5 → 9 not taken.
30120 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1745
1746 // Public members
1747 std::vector<ExprNode *> operands;
1748 OpQueue opQueue;
1749 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1750 };
1751
1752 // ==================================================== AdditiveExprNode =========================================================
1753
1754 class AdditiveExprNode final : public ExprNode {
1755 public:
1756 // Enums
1757 enum class AdditiveOp : uint8_t {
1758 OP_PLUS,
1759 OP_MINUS,
1760 };
1761
1762 // Typedefs
1763 using OpQueue = std::queue<std::pair<AdditiveOp, QualType>>;
1764
1765 // Constructors
1766 using ExprNode::ExprNode;
1767
1768 // Visitor methods
1769 148985 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAdditiveExpr(this); }
1770 27627 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAdditiveExpr(this); }
1771
1772 // Other methods
1773 208516 GET_CHILDREN(operands);
1774 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1775 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1776 5228 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1777 65202 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1778
2/4
✓ Branch 4 → 5 taken 85325 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 85325 times.
✗ Branch 5 → 9 not taken.
255975 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1779
1780 // Public members
1781 std::vector<ExprNode *> operands;
1782 OpQueue opQueue;
1783 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1784 };
1785
1786 // ================================================== MultiplicativeExprNode =====================================================
1787
1788 class MultiplicativeExprNode final : public ExprNode {
1789 public:
1790 // Enums
1791 enum class MultiplicativeOp : uint8_t {
1792 OP_MUL,
1793 OP_DIV,
1794 OP_REM,
1795 };
1796
1797 // Typedefs
1798 using OpQueue = std::queue<std::pair<MultiplicativeOp, QualType>>;
1799
1800 // Constructors
1801 using ExprNode::ExprNode;
1802
1803 // Visitor methods
1804 34242 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitMultiplicativeExpr(this); }
1805 8067 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitMultiplicativeExpr(this); }
1806
1807 // Other methods
1808 46326 GET_CHILDREN(operands);
1809 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1810 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1811 96 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1812 16418 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1813
2/4
✓ Branch 4 → 5 taken 19705 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 19705 times.
✗ Branch 5 → 9 not taken.
59115 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1814
1815 // Public members
1816 std::vector<ExprNode *> operands;
1817 OpQueue opQueue;
1818 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1819 };
1820
1821 // ======================================================= CastExprNode ==========================================================
1822
1823 class CastExprNode final : public ExprNode {
1824 public:
1825 // Constructors
1826 using ExprNode::ExprNode;
1827
1828 // Visitor methods
1829 144751 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitCastExpr(this); }
1830 29781 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitCastExpr(this); }
1831
1832 // Other methods
1833 196965 GET_CHILDREN(prefixUnaryExpr, dataType, assignExpr);
1834 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1835 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1836
1837 // Public members
1838 ExprNode *prefixUnaryExpr = nullptr;
1839 DataTypeNode *dataType = nullptr;
1840 ExprNode *assignExpr = nullptr;
1841 bool isCast = false;
1842 };
1843
1844 // ==================================================== PrefixUnaryExprNode ======================================================
1845
1846 class PrefixUnaryExprNode final : public ExprNode {
1847 public:
1848 // Enums
1849 enum class PrefixUnaryOp : uint8_t {
1850 OP_NONE,
1851 OP_MINUS,
1852 OP_PLUS_PLUS,
1853 OP_MINUS_MINUS,
1854 OP_NOT,
1855 OP_BITWISE_NOT,
1856 OP_DEREFERENCE,
1857 OP_ADDRESS_OF,
1858 };
1859
1860 // Constructors
1861 using ExprNode::ExprNode;
1862
1863 // Visitor methods
1864 117456 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitPrefixUnaryExpr(this); }
1865 23767 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitPrefixUnaryExpr(this); }
1866
1867 // Other methods
1868 154144 GET_CHILDREN(prefixUnaryExpr, postfixUnaryExpr);
1869 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1870 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1871 8 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1872 124 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1873
2/4
✓ Branch 4 → 5 taken 52067 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 52067 times.
✗ Branch 5 → 9 not taken.
156201 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1874
1875 // Public members
1876 ExprNode *prefixUnaryExpr = nullptr;
1877 ExprNode *postfixUnaryExpr = nullptr;
1878 PrefixUnaryOp op = PrefixUnaryOp::OP_NONE;
1879 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1880 };
1881
1882 // =================================================== PostfixUnaryExprNode ======================================================
1883
1884 class PostfixUnaryExprNode final : public ExprNode {
1885 public:
1886 // Enums
1887 enum class PostfixUnaryOp : uint8_t {
1888 OP_NONE,
1889 OP_SUBSCRIPT,
1890 OP_MEMBER_ACCESS,
1891 OP_PLUS_PLUS,
1892 OP_MINUS_MINUS,
1893 OP_ERR_PROPAGATION,
1894 };
1895
1896 // Constructors
1897 using ExprNode::ExprNode;
1898
1899 // Visitor methods
1900 1286750 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitPostfixUnaryExpr(this); }
1901 249279 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitPostfixUnaryExpr(this); }
1902
1903 // Other methods
1904 1750909 GET_CHILDREN(atomicExpr, postfixUnaryExpr, subscriptIndexExpr);
1905 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1906 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1907 2428 [[nodiscard]] std::vector<std::vector<const Function *>> *getOpFctPointers() override { return &opFct; }
1908 120162 [[nodiscard]] const std::vector<std::vector<const Function *>> *getOpFctPointers() const override { return &opFct; }
1909
2/4
✓ Branch 4 → 5 taken 665381 times.
✗ Branch 4 → 11 not taken.
✓ Branch 5 → 6 taken 665381 times.
✗ Branch 5 → 9 not taken.
1996143 void customItemsInitialization(const size_t manifestationCount) override { opFct.resize(manifestationCount, {nullptr}); }
1910
1911 // Public members
1912 ExprNode *atomicExpr = nullptr;
1913 ExprNode *postfixUnaryExpr = nullptr;
1914 ExprNode *subscriptIndexExpr = nullptr;
1915 PostfixUnaryOp op = PostfixUnaryOp::OP_NONE;
1916 std::vector<std::vector<const Function *>> opFct; // Operator overloading functions
1917 std::string identifier; // Only set when operator is member access
1918
1919 // Only set when operator is error propagation ('!')
1920 const Function *errPropIsErrFct = nullptr; // Result<T>.isErr()
1921 const Function *errPropUnwrapFct = nullptr; // Result<T>.unwrap()
1922 const Function *errPropGetErrFct = nullptr; // Result<T>.getErr()
1923 const Function *errPropCtorFct = nullptr; // err<U>(const Error&), where Result<U> is the enclosing function's return type
1924 };
1925
1926 // ====================================================== AtomicExprNode =========================================================
1927
1928 class AtomicExprNode final : public ExprNode {
1929 public:
1930 // Structs
1931 struct VarAccessData {
1932 SymbolTableEntry *entry = nullptr;
1933 Scope *accessScope = nullptr;
1934 Capture *capture = nullptr;
1935 };
1936
1937 // Constructors
1938 using ExprNode::ExprNode;
1939
1940 // Visitor methods
1941 5048522 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitAtomicExpr(this); }
1942 975582 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitAtomicExpr(this); }
1943
1944 // Other methods
1945 7281736 GET_CHILDREN(constant, value, assignExpr);
1946 2573368 void customItemsInitialization(const size_t manifestationCount) override { data.resize(manifestationCount); }
1947
1948 // Public members
1949 ConstantNode *constant = nullptr;
1950 ValueNode *value = nullptr;
1951 ExprNode *assignExpr = nullptr;
1952 std::vector<std::string> identifierFragments;
1953 std::string fqIdentifier;
1954 std::vector<VarAccessData> data; // Only set if identifier is set as well
1955 };
1956
1957 // ======================================================== ValueNode ============================================================
1958
1959 class ValueNode final : public ExprNode {
1960 public:
1961 // Constructors
1962 using ExprNode::ExprNode;
1963
1964 // Visitor methods
1965 1294280 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitValue(this); }
1966 245298 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitValue(this); }
1967
1968 // Other methods
1969 2047373 GET_CHILDREN(fctCall, arrayInitialization, structInstantiation, lambdaFunc, lambdaProc, lambdaExpr, nilType);
1970 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
1971 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
1972
1973 // Public members
1974 FctCallNode *fctCall = nullptr;
1975 ArrayInitializationNode *arrayInitialization = nullptr;
1976 StructInstantiationNode *structInstantiation = nullptr;
1977 LambdaFuncNode *lambdaFunc = nullptr;
1978 LambdaProcNode *lambdaProc = nullptr;
1979 LambdaExprNode *lambdaExpr = nullptr;
1980 DataTypeNode *nilType = nullptr;
1981 bool isNil = false;
1982 };
1983
1984 // ====================================================== ConstantNode ===========================================================
1985
1986 class ConstantNode final : public ExprNode {
1987 public:
1988 // Enum
1989 enum class PrimitiveValueType : uint8_t {
1990 TYPE_NONE,
1991 TYPE_DOUBLE,
1992 TYPE_INT,
1993 TYPE_SHORT,
1994 TYPE_LONG,
1995 TYPE_CHAR,
1996 TYPE_STRING,
1997 TYPE_BOOL
1998 };
1999
2000 // Constructors
2001 using ExprNode::ExprNode;
2002
2003 // Visitor methods
2004 949350 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitConstant(this); }
2005 176934 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitConstant(this); }
2006
2007 // Other methods
2008 1185358 GET_CHILDREN();
2009 189017 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override { return compileTimeValue; }
2010 11324 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override { return true; }
2011
2012 // Public members
2013 PrimitiveValueType type = PrimitiveValueType::TYPE_NONE;
2014 CompileTimeValue compileTimeValue;
2015 };
2016
2017 // ====================================================== FctCallNode ============================================================
2018
2019 class FctCallNode final : public ExprNode {
2020 public:
2021 // Enums
2022 enum class FctCallType : uint8_t {
2023 TYPE_ORDINARY,
2024 TYPE_METHOD,
2025 TYPE_CTOR,
2026 TYPE_FCT_PTR,
2027 };
2028
2029 // Structs
2030 struct FctCallData {
2031 // Members
2032 FctCallType callType = FctCallType::TYPE_ORDINARY;
2033 bool isImported = false;
2034 QualTypeList templateTypes;
2035 QualType thisType = QualType(TY_DYN); // Is filled if method or ctor call
2036 ArgList args;
2037 const Function *callee = nullptr; // Stays nullptr if function pointer call
2038 Scope *calleeParentScope = nullptr;
2039 CompileTimeValue compileTimeValue;
2040 bool compileTimeValueSet = false;
2041
2042 // Methods
2043 189272 [[nodiscard]] bool isOrdinaryCall() const { return callType == FctCallType::TYPE_ORDINARY; }
2044 691192 [[nodiscard]] bool isMethodCall() const { return callType == FctCallType::TYPE_METHOD; }
2045
4/4
✓ Branch 3 → 4 taken 124761 times.
✓ Branch 3 → 7 taken 108818 times.
✓ Branch 5 → 6 taken 13938 times.
✓ Branch 5 → 7 taken 110823 times.
233579 [[nodiscard]] bool isVirtualMethodCall() const { return isMethodCall() && thisType.isBase(TY_INTERFACE); }
2046 876563 [[nodiscard]] bool isCtorCall() const { return callType == FctCallType::TYPE_CTOR; }
2047 2176913 [[nodiscard]] bool isFctPtrCall() const { return callType == FctCallType::TYPE_FCT_PTR; }
2048
2049 6438 void setCompileTimeValue(const CompileTimeValue &value) {
2050 6438 compileTimeValue = value;
2051 6438 compileTimeValueSet = true;
2052 6438 }
2053
2054 [[nodiscard]] bool hasCompileTimeValue() const { return compileTimeValueSet; }
2055 };
2056
2057 // Constructors
2058 using ExprNode::ExprNode;
2059
2060 // Visitor methods
2061 1109484 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFctCall(this); }
2062 211494 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFctCall(this); }
2063
2064 // Other methods
2065 1456306 GET_CHILDREN(templateTypeLst, argLst);
2066 [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override;
2067 [[nodiscard]] CompileTimeValue getCompileTimeValue(size_t manIdx) const override;
2068 void setCompileTimeValue(const CompileTimeValue &value, size_t manIdx);
2069 [[nodiscard]] bool returnsOnAllControlPaths(bool *overrideUnreachable, size_t manIdx) const override;
2070 559153 void customItemsInitialization(const size_t manifestationCount) override { data.resize(manifestationCount); }
2071 [[nodiscard]] bool hasReturnValueReceiver() const;
2072
2073 // Public members
2074 TypeLstNode *templateTypeLst = nullptr;
2075 ArgLstNode *argLst = nullptr;
2076 bool hasArgs = false;
2077 bool hasTemplateTypes = false;
2078 std::string fqFunctionName;
2079 std::vector<std::string> functionNameFragments;
2080 std::vector<FctCallData> data;
2081 bool isErrorTraceOrigin = false; // Set if this is a direct call to err<T>(...), and error return tracing is enabled
2082 };
2083
2084 // ================================================= ArrayInitializationNode =====================================================
2085
2086 class ArrayInitializationNode final : public ExprNode {
2087 public:
2088 // Constructors
2089 using ExprNode::ExprNode;
2090
2091 // Visitor methods
2092 6296 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitArrayInitialization(this); }
2093 1028 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitArrayInitialization(this); }
2094
2095 // Other methods
2096 8116 GET_CHILDREN(itemLst);
2097
2098 // Public members
2099 ArgLstNode *itemLst = nullptr;
2100 size_t actualSize = 0z;
2101 };
2102
2103 // ================================================= StructInstantiationNode =====================================================
2104
2105 class StructInstantiationNode final : public ExprNode {
2106 public:
2107 // Constructors
2108 using ExprNode::ExprNode;
2109
2110 // Visitor methods
2111 31278 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitStructInstantiation(this); }
2112 5856 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitStructInstantiation(this); }
2113
2114 // Other methods
2115 41566 GET_CHILDREN(templateTypeLst, fieldLst);
2116 12884 void customItemsInitialization(const size_t manifestationCount) override {
2117 12884 instantiatedStructs.resize(manifestationCount);
2118 12884 fieldCopyCtors.resize(manifestationCount);
2119 12884 }
2120
2121 // Public members
2122 TypeLstNode *templateTypeLst = nullptr;
2123 ArgLstNode *fieldLst = nullptr;
2124 bool hasTemplateTypes = false;
2125 std::string fqStructName;
2126 std::vector<std::string> structNameFragments;
2127 std::vector<Struct *> instantiatedStructs;
2128 // Per-manifestation (the struct itself may be/depend on a generic type, e.g. inside a generic function), per-field
2129 // copy ctor to call for a field value that needs to be deep-copied instead of raw-stored. Kept here rather than on
2130 // the (manifestation-unaware) shared fieldLst->argInfos, since a struct literal inside a generic function is
2131 // re-type-checked once per manifestation and each needs its own copy-ctor set.
2132 std::vector<std::vector<Function *>> fieldCopyCtors;
2133 };
2134
2135 // ====================================================== LambdaBaseNode =========================================================
2136
2137 class LambdaBaseNode : public ExprNode {
2138 public:
2139 // Constructors
2140 using ExprNode::ExprNode;
2141
2142 // Other methods
2143
2/4
✓ Branch 2 → 3 taken 1029 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 1029 times.
✗ Branch 3 → 8 not taken.
2058 [[nodiscard]] std::string getScopeId() const { return "lambda:" + codeLoc.toString(); }
2144 ✗ [[nodiscard]] bool hasCompileTimeValue(size_t manIdx) const override { return false; }
2145 1088 void customItemsInitialization(size_t manifestationCount) override { manifestations.resize(manifestationCount); }
2146
2147 // Public members
2148 ParamLstNode *paramLst = nullptr;
2149 bool hasParams = false;
2150 Scope *bodyScope = nullptr;
2151 std::vector<Function> manifestations;
2152 };
2153
2154 // ====================================================== LambdaFuncNode =========================================================
2155
2156 class LambdaFuncNode final : public LambdaBaseNode {
2157 public:
2158 // Constructors
2159 using LambdaBaseNode::LambdaBaseNode;
2160
2161 // Visit methods
2162 315 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLambdaFunc(this); }
2163 97 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLambdaFunc(this); }
2164
2165 // Other methods
2166 333 GET_CHILDREN(returnType, paramLst, body, lambdaAttr);
2167 [[nodiscard]] bool returnsOnAllControlPaths(bool *overrideUnreachable, size_t manIdx) const override;
2168
2169 // Public members
2170 DataTypeNode *returnType = nullptr;
2171 StmtLstNode *body = nullptr;
2172 LambdaAttrNode *lambdaAttr = nullptr;
2173 };
2174
2175 // ====================================================== LambdaProcNode =========================================================
2176
2177 class LambdaProcNode final : public LambdaBaseNode {
2178 public:
2179 // Constructors
2180 using LambdaBaseNode::LambdaBaseNode;
2181
2182 // Visit methods
2183 1474 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLambdaProc(this); }
2184 208 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLambdaProc(this); }
2185
2186 // Other methods
2187 1820 GET_CHILDREN(paramLst, body, lambdaAttr);
2188 bool returnsOnAllControlPaths(bool *overrideUnreachable, size_t manIdx) const override;
2189
2190 // Public members
2191 StmtLstNode *body = nullptr;
2192 LambdaAttrNode *lambdaAttr = nullptr;
2193 };
2194
2195 // ====================================================== LambdaExprNode =========================================================
2196
2197 class LambdaExprNode final : public LambdaBaseNode {
2198 public:
2199 // Constructors
2200 using LambdaBaseNode::LambdaBaseNode;
2201
2202 // Visit methods
2203 6 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitLambdaExpr(this); }
2204 2 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitLambdaExpr(this); }
2205
2206 // Other methods
2207 6 GET_CHILDREN(paramLst, lambdaExpr);
2208
2209 // Public members
2210 ExprNode *lambdaExpr = nullptr;
2211 };
2212
2213 // ======================================================= DataTypeNode ==========================================================
2214
2215 class DataTypeNode final : public ExprNode {
2216 public:
2217 // Enums
2218 enum class TypeModifierType : uint8_t {
2219 TYPE_PTR,
2220 TYPE_REF,
2221 TYPE_ARRAY,
2222 };
2223
2224 // Structs
2225 struct TypeModifier {
2226 TypeModifierType modifierType = TypeModifierType::TYPE_PTR;
2227 bool hasSize = false;
2228 unsigned int hardcodedSize = 0;
2229 std::string sizeVarName;
2230 };
2231
2232 // Constructors
2233 using ExprNode::ExprNode;
2234
2235 // Visitor methods
2236 2588112 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitDataType(this); }
2237 36772 std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitDataType(this); }
2238
2239 // Other methods
2240 3201502 GET_CHILDREN(qualifierLst, baseDataType);
2241 void setFieldTypeRecursive();
2242
2243 // Public members
2244 QualifierLstNode *qualifierLst = nullptr;
2245 BaseDataTypeNode *baseDataType = nullptr;
2246 bool isParamType = false;
2247 bool isGlobalType = false;
2248 bool isFieldType = false;
2249 bool isReturnType = false;
2250 std::queue<TypeModifier> tmQueue;
2251 };
2252
2253 // ==================================================== BaseDataTypeNode =========================================================
2254
2255 class BaseDataTypeNode final : public ExprNode {
2256 public:
2257 // Enums
2258 enum class Type : uint8_t {
2259 TYPE_NONE,
2260 TYPE_DOUBLE,
2261 TYPE_INT,
2262 TYPE_SHORT,
2263 TYPE_LONG,
2264 TYPE_BYTE,
2265 TYPE_CHAR,
2266 TYPE_STRING,
2267 TYPE_BOOL,
2268 TYPE_DYN,
2269 TYPE_CUSTOM,
2270 TYPE_FUNCTION
2271 };
2272
2273 // Constructors
2274 using ExprNode::ExprNode;
2275
2276 // Visitor methods
2277 2588112 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitBaseDataType(this); }
2278 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitBaseDataType(this); }
2279
2280 // Other methods
2281 3201280 GET_CHILDREN(customDataType, functionDataType);
2282
2283 // Public members
2284 CustomDataTypeNode *customDataType = nullptr;
2285 FunctionDataTypeNode *functionDataType = nullptr;
2286 Type type = Type::TYPE_NONE;
2287 };
2288
2289 // ==================================================== CustomDataTypeNode =======================================================
2290
2291 class CustomDataTypeNode final : public ExprNode {
2292 public:
2293 // Constructors
2294 using ExprNode::ExprNode;
2295
2296 // Visitor methods
2297 1297688 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitCustomDataType(this); }
2298 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitCustomDataType(this); }
2299
2300 // Other methods
2301 1600399 GET_CHILDREN(templateTypeLst);
2302 619285 void customItemsInitialization(const size_t manifestationCount) override { customTypes.resize(manifestationCount); }
2303
2304 // Public members
2305 TypeLstNode *templateTypeLst = nullptr;
2306 std::string fqTypeName;
2307 std::vector<std::string> typeNameFragments;
2308 std::vector<SymbolTableEntry *> customTypes;
2309 };
2310
2311 // =================================================== FunctionDataTypeNode ======================================================
2312
2313 class FunctionDataTypeNode final : public ExprNode {
2314 public:
2315 // Constructors
2316 using ExprNode::ExprNode;
2317
2318 // Visitor methods
2319 5985 std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFunctionDataType(this); }
2320 ✗ std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFunctionDataType(this); }
2321
2322 // Other methods
2323 7528 GET_CHILDREN(returnType, paramTypeLst);
2324 3095 void customItemsInitialization(const size_t manifestationCount) override { customTypes.resize(manifestationCount); }
2325
2326 // Public members
2327 DataTypeNode *returnType = nullptr;
2328 TypeLstNode *paramTypeLst = nullptr;
2329 bool isFunction = false; // Function or procedure
2330 std::vector<SymbolTableEntry *> customTypes;
2331 };
2332
2333 } // namespace spice::compiler
2334