GCC Code Coverage Report


Directory: ../
File: src/ast/ASTNodes.h
Date: 2024-12-24 01:17:15
Exec Total Coverage
Lines: 256 284 90.1%
Functions: 229 255 89.8%
Branches: 71 128 55.5%

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