GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 93.0% 361 / 10 / 398
Functions: 93.0% 307 / 5 / 335
Branches: 58.4% 132 / 0 / 226

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