GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 91.9% 363 / 10 / 405
Functions: 91.9% 319 / 5 / 352
Branches: 57.5% 115 / 0 / 200

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