GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 93.0% 373 / 14 / 415
Functions: 92.9% 314 / 7 / 345
Branches: 57.9% 132 / 0 / 228

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