Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
2 | |||
3 | #include "TypeChecker.h" | ||
4 | |||
5 | #include <SourceFile.h> | ||
6 | #include <ast/ASTNodes.h> | ||
7 | #include <ast/Attributes.h> | ||
8 | #include <global/GlobalResourceManager.h> | ||
9 | #include <symboltablebuilder/ScopeHandle.h> | ||
10 | #include <symboltablebuilder/SymbolTableBuilder.h> | ||
11 | #include <typechecker/MacroDefs.h> | ||
12 | #include <typechecker/TypeMatcher.h> | ||
13 | |||
14 | namespace spice::compiler { | ||
15 | |||
16 | 15097 | std::any TypeChecker::visitValue(ValueNode *node) { | |
17 | // Function call | ||
18 |
2/2✓ Branch 0 (2→3) taken 13511 times.
✓ Branch 1 (2→4) taken 1586 times.
|
15097 | if (node->fctCall) |
19 | 13511 | return visit(node->fctCall); | |
20 | |||
21 | // Array initialization | ||
22 |
2/2✓ Branch 0 (4→5) taken 74 times.
✓ Branch 1 (4→6) taken 1512 times.
|
1586 | if (node->arrayInitialization) |
23 | 74 | return visit(node->arrayInitialization); | |
24 | |||
25 | // Struct instantiation | ||
26 |
2/2✓ Branch 0 (6→7) taken 284 times.
✓ Branch 1 (6→8) taken 1228 times.
|
1512 | if (node->structInstantiation) |
27 | 284 | return visit(node->structInstantiation); | |
28 | |||
29 | // Lambda function | ||
30 |
2/2✓ Branch 0 (8→9) taken 12 times.
✓ Branch 1 (8→10) taken 1216 times.
|
1228 | if (node->lambdaFunc) |
31 | 12 | return visit(node->lambdaFunc); | |
32 | |||
33 | // Lambda procedure | ||
34 |
2/2✓ Branch 0 (10→11) taken 28 times.
✓ Branch 1 (10→12) taken 1188 times.
|
1216 | if (node->lambdaProc) |
35 | 28 | return visit(node->lambdaProc); | |
36 | |||
37 | // Lambda expression | ||
38 |
2/2✓ Branch 0 (12→13) taken 1 times.
✓ Branch 1 (12→14) taken 1187 times.
|
1188 | if (node->lambdaExpr) |
39 | 1 | return visit(node->lambdaExpr); | |
40 | |||
41 | // Typed nil | ||
42 |
1/2✓ Branch 0 (14→15) taken 1187 times.
✗ Branch 1 (14→41) not taken.
|
1187 | if (node->isNil) { |
43 |
2/4✓ Branch 0 (15→16) taken 1187 times.
✗ Branch 1 (15→52) not taken.
✓ Branch 2 (16→17) taken 1187 times.
✗ Branch 3 (16→50) not taken.
|
1187 | const auto nilType = std::any_cast<QualType>(visit(node->nilType)); |
44 |
2/8✓ Branch 0 (18→19) taken 1187 times.
✗ Branch 1 (18→62) not taken.
✗ Branch 2 (19→20) not taken.
✓ Branch 3 (19→24) taken 1187 times.
✗ Branch 4 (20→21) not taken.
✗ Branch 5 (20→53) not taken.
✗ Branch 6 (21→22) not taken.
✗ Branch 7 (21→53) not taken.
|
1187 | HANDLE_UNRESOLVED_TYPE_ER(nilType) |
45 |
2/4✓ Branch 0 (24→25) taken 1187 times.
✗ Branch 1 (24→62) not taken.
✗ Branch 2 (25→26) not taken.
✓ Branch 3 (25→36) taken 1187 times.
|
1187 | if (nilType.is(TY_DYN)) |
46 | ✗ | SOFT_ERROR_ER(node->nilType, UNEXPECTED_DYN_TYPE, "Nil must have an explicit type") | |
47 |
2/4✓ Branch 0 (36→37) taken 1187 times.
✗ Branch 1 (36→61) not taken.
✓ Branch 2 (37→38) taken 1187 times.
✗ Branch 3 (37→61) not taken.
|
1187 | return ExprResult{node->setEvaluatedSymbolType(nilType, manIdx)}; |
48 | } | ||
49 | |||
50 | − | throw CompilerError(UNHANDLED_BRANCH, "Value fall-through"); // GCOV_EXCL_LINE | |
51 | } | ||
52 | |||
53 | 18205 | std::any TypeChecker::visitConstant(ConstantNode *node) { | |
54 | SuperType superType; | ||
55 |
7/9✓ Branch 0 (2→3) taken 309 times.
✓ Branch 1 (2→4) taken 3142 times.
✓ Branch 2 (2→5) taken 540 times.
✓ Branch 3 (2→6) taken 6713 times.
✗ Branch 4 (2→7) not taken.
✓ Branch 5 (2→8) taken 2165 times.
✓ Branch 6 (2→9) taken 3096 times.
✓ Branch 7 (2→10) taken 2240 times.
✗ Branch 8 (2→11) not taken.
|
18205 | switch (node->type) { |
56 | 309 | case ConstantNode::PrimitiveValueType::TYPE_DOUBLE: | |
57 | 309 | superType = TY_DOUBLE; | |
58 | 309 | break; | |
59 | 3142 | case ConstantNode::PrimitiveValueType::TYPE_INT: | |
60 | 3142 | superType = TY_INT; | |
61 | 3142 | break; | |
62 | 540 | case ConstantNode::PrimitiveValueType::TYPE_SHORT: | |
63 | 540 | superType = TY_SHORT; | |
64 | 540 | break; | |
65 | 6713 | case ConstantNode::PrimitiveValueType::TYPE_LONG: | |
66 | 6713 | superType = TY_LONG; | |
67 | 6713 | break; | |
68 | ✗ | case ConstantNode::PrimitiveValueType::TYPE_BYTE: | |
69 | ✗ | superType = TY_BYTE; | |
70 | ✗ | break; | |
71 | 2165 | case ConstantNode::PrimitiveValueType::TYPE_CHAR: | |
72 | 2165 | superType = TY_CHAR; | |
73 | 2165 | break; | |
74 | 3096 | case ConstantNode::PrimitiveValueType::TYPE_STRING: | |
75 | 3096 | superType = TY_STRING; | |
76 | 3096 | break; | |
77 | 2240 | case ConstantNode::PrimitiveValueType::TYPE_BOOL: | |
78 | 2240 | superType = TY_BOOL; | |
79 | 2240 | break; | |
80 | − | default: // GCOV_EXCL_LINE | |
81 | − | throw CompilerError(UNHANDLED_BRANCH, "Constant fall-through"); // GCOV_EXCL_LINE | |
82 | } | ||
83 |
3/6✓ Branch 0 (19→20) taken 18205 times.
✗ Branch 1 (19→34) not taken.
✓ Branch 2 (20→21) taken 18205 times.
✗ Branch 3 (20→34) not taken.
✓ Branch 4 (21→22) taken 18205 times.
✗ Branch 5 (21→34) not taken.
|
18205 | return ExprResult{node->setEvaluatedSymbolType(QualType(superType), manIdx)}; |
84 | } | ||
85 | |||
86 | 13511 | std::any TypeChecker::visitFctCall(FctCallNode *node) { | |
87 |
1/2✓ Branch 0 (2→3) taken 13511 times.
✗ Branch 1 (2→501) not taken.
|
13511 | FctCallNode::FctCallData &data = node->data.at(manIdx); |
88 | 13511 | auto &[callType, isImported, templateTypes, thisType, args, callee, calleeParentScope] = data; | |
89 | |||
90 | // Retrieve arg types | ||
91 | 13511 | args.clear(); | |
92 |
2/2✓ Branch 0 (4→5) taken 10477 times.
✓ Branch 1 (4→28) taken 3034 times.
|
13511 | if (node->hasArgs) { |
93 |
1/2✓ Branch 0 (6→7) taken 10477 times.
✗ Branch 1 (6→501) not taken.
|
10477 | args.reserve(node->argLst->args.size()); |
94 |
2/2✓ Branch 0 (26→9) taken 16079 times.
✓ Branch 1 (26→27) taken 10477 times.
|
26556 | for (AssignExprNode *arg : node->argLst->args) { |
95 | // Visit argument | ||
96 |
2/4✓ Branch 0 (10→11) taken 16079 times.
✗ Branch 1 (10→386) not taken.
✓ Branch 2 (11→12) taken 16079 times.
✗ Branch 3 (11→384) not taken.
|
16079 | const auto argResult = std::any_cast<ExprResult>(visit(arg)); |
97 |
2/8✓ Branch 0 (13→14) taken 16079 times.
✗ Branch 1 (13→389) not taken.
✗ Branch 2 (14→15) not taken.
✓ Branch 3 (14→19) taken 16079 times.
✗ Branch 4 (15→16) not taken.
✗ Branch 5 (15→387) not taken.
✗ Branch 6 (16→17) not taken.
✗ Branch 7 (16→387) not taken.
|
16079 | HANDLE_UNRESOLVED_TYPE_ER(argResult.type) |
98 |
2/4✓ Branch 0 (19→20) taken 16079 times.
✗ Branch 1 (19→389) not taken.
✗ Branch 2 (20→21) not taken.
✓ Branch 3 (20→22) taken 16079 times.
|
16079 | assert(!argResult.type.hasAnyGenericParts()); |
99 | // Save arg type to arg types list | ||
100 |
1/2✓ Branch 0 (23→24) taken 16079 times.
✗ Branch 1 (23→388) not taken.
|
16079 | args.emplace_back(argResult.type, argResult.isTemporary()); |
101 | } | ||
102 | } | ||
103 | |||
104 | // Retrieve entry of the first fragment | ||
105 | 13511 | const std::string &firstFrag = node->functionNameFragments.front(); | |
106 |
1/2✓ Branch 0 (29→30) taken 13511 times.
✗ Branch 1 (29→501) not taken.
|
13511 | SymbolTableEntry *firstFragEntry = currentScope->lookup(firstFrag); |
107 |
2/2✓ Branch 0 (32→33) taken 8381 times.
✓ Branch 1 (32→70) taken 5130 times.
|
13511 | if (firstFragEntry) { |
108 | // Check if we have seen a 'this.' prefix, because the generator needs that | ||
109 |
6/8✓ Branch 0 (33→34) taken 1 times.
✓ Branch 1 (33→37) taken 8380 times.
✓ Branch 2 (34→35) taken 1 times.
✗ Branch 3 (34→401) not taken.
✓ Branch 4 (35→36) taken 1 times.
✗ Branch 5 (35→37) not taken.
✓ Branch 6 (38→39) taken 1 times.
✓ Branch 7 (38→48) taken 8380 times.
|
8381 | if (firstFragEntry->scope->type == ScopeType::STRUCT && firstFrag != THIS_VARIABLE_NAME) |
110 |
5/10✓ Branch 0 (39→40) taken 1 times.
✗ Branch 1 (39→395) not taken.
✓ Branch 2 (40→41) taken 1 times.
✗ Branch 3 (40→393) not taken.
✓ Branch 4 (41→42) taken 1 times.
✗ Branch 5 (41→391) not taken.
✓ Branch 6 (44→45) taken 1 times.
✗ Branch 7 (44→397) not taken.
✓ Branch 8 (45→46) taken 1 times.
✗ Branch 9 (45→397) not taken.
|
1 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, |
111 | "The symbol '" + firstFrag + "' could not be found. Missing 'this.' prefix?") | ||
112 | |||
113 | 8380 | firstFragEntry->used = true; | |
114 | // Decide of which type the function call is | ||
115 |
2/4✓ Branch 0 (48→49) taken 8380 times.
✗ Branch 1 (48→401) not taken.
✓ Branch 2 (49→50) taken 8380 times.
✗ Branch 3 (49→401) not taken.
|
8380 | const QualType &baseType = firstFragEntry->getQualType().getBase(); |
116 |
5/8✓ Branch 0 (50→51) taken 8380 times.
✗ Branch 1 (50→401) not taken.
✓ Branch 2 (51→52) taken 4 times.
✓ Branch 3 (51→56) taken 8376 times.
✓ Branch 4 (52→53) taken 4 times.
✗ Branch 5 (52→398) not taken.
✓ Branch 6 (53→54) taken 4 times.
✗ Branch 7 (53→398) not taken.
|
8380 | HANDLE_UNRESOLVED_TYPE_ER(baseType) |
117 |
3/4✓ Branch 0 (56→57) taken 8376 times.
✗ Branch 1 (56→399) not taken.
✓ Branch 2 (57→58) taken 6355 times.
✓ Branch 3 (57→61) taken 2021 times.
|
8376 | if (baseType.isOneOf({TY_STRUCT, TY_INTERFACE})) { |
118 |
2/2✓ Branch 0 (58→59) taken 949 times.
✓ Branch 1 (58→60) taken 5406 times.
|
6355 | if (firstFragEntry->scope->type == ScopeType::GLOBAL) |
119 | 949 | callType = FctCallNode::FctCallType::TYPE_CTOR; | |
120 | else | ||
121 | 5406 | callType = FctCallNode::FctCallType::TYPE_METHOD; | |
122 |
7/8✓ Branch 0 (61→62) taken 2021 times.
✗ Branch 1 (61→400) not taken.
✓ Branch 2 (62→63) taken 1945 times.
✓ Branch 3 (62→65) taken 76 times.
✓ Branch 4 (63→64) taken 48 times.
✓ Branch 5 (63→65) taken 1897 times.
✓ Branch 6 (66→67) taken 48 times.
✓ Branch 7 (66→68) taken 1973 times.
|
2021 | } else if (baseType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && firstFragEntry->scope->type != ScopeType::GLOBAL) { |
123 | 48 | callType = FctCallNode::FctCallType::TYPE_FCT_PTR; | |
124 | } | ||
125 | } | ||
126 | |||
127 | // Get struct name. Retrieve it from alias if required | ||
128 |
1/2✓ Branch 0 (70→71) taken 13506 times.
✗ Branch 1 (70→501) not taken.
|
13506 | const auto &[structEntry, isAlias] = rootScope->symbolTable.lookupWithAliasResolution(node->fqFunctionName); |
129 |
4/6✓ Branch 0 (73→74) taken 1 times.
✓ Branch 1 (73→77) taken 13505 times.
✓ Branch 2 (74→75) taken 1 times.
✗ Branch 3 (74→501) not taken.
✓ Branch 4 (75→76) taken 1 times.
✗ Branch 5 (75→501) not taken.
|
13506 | const std::string &fqFunctionName = isAlias ? structEntry->getQualType().getSubType() : node->fqFunctionName; |
130 | |||
131 | // Get the concrete template types | ||
132 | 13506 | templateTypes.clear(); | |
133 |
2/2✓ Branch 0 (79→80) taken 1 times.
✓ Branch 1 (79→99) taken 13505 times.
|
13506 | if (isAlias) { |
134 | // Retrieve concrete template types from type alias | ||
135 |
3/6✓ Branch 0 (80→81) taken 1 times.
✗ Branch 1 (80→501) not taken.
✓ Branch 2 (81→82) taken 1 times.
✗ Branch 3 (81→501) not taken.
✓ Branch 4 (82→83) taken 1 times.
✗ Branch 5 (82→501) not taken.
|
1 | templateTypes = structEntry->getQualType().getTemplateTypes(); |
136 | // Check if the aliased type specified template types and the struct instantiation does | ||
137 |
3/6✓ Branch 0 (84→85) taken 1 times.
✗ Branch 1 (84→87) not taken.
✗ Branch 2 (85→86) not taken.
✓ Branch 3 (85→87) taken 1 times.
✗ Branch 4 (88→89) not taken.
✓ Branch 5 (88→99) taken 1 times.
|
1 | if (!templateTypes.empty() && node->hasTemplateTypes) |
138 | ✗ | SOFT_ERROR_ER(node->templateTypeLst, ALIAS_WITH_TEMPLATE_LIST, "The aliased type already has a template list") | |
139 | } | ||
140 | |||
141 | // Get concrete template types | ||
142 |
2/2✓ Branch 0 (99→100) taken 508 times.
✓ Branch 1 (99→135) taken 12998 times.
|
13506 | if (node->hasTemplateTypes) { |
143 |
2/2✓ Branch 0 (133→102) taken 600 times.
✓ Branch 1 (133→134) taken 508 times.
|
1108 | for (DataTypeNode *templateTypeNode : node->templateTypeLst->dataTypes) { |
144 |
2/4✓ Branch 0 (103→104) taken 600 times.
✗ Branch 1 (103→411) not taken.
✓ Branch 2 (104→105) taken 600 times.
✗ Branch 3 (104→409) not taken.
|
600 | auto templateType = std::any_cast<QualType>(visit(templateTypeNode)); |
145 |
2/4✓ Branch 0 (106→107) taken 600 times.
✗ Branch 1 (106→412) not taken.
✗ Branch 2 (107→108) not taken.
✓ Branch 3 (107→109) taken 600 times.
|
600 | assert(!templateType.isOneOf({TY_DYN, TY_INVALID})); |
146 | |||
147 | // Abort if the type is unresolved | ||
148 |
2/4✓ Branch 0 (109→110) taken 600 times.
✗ Branch 1 (109→422) not taken.
✗ Branch 2 (110→111) not taken.
✓ Branch 3 (110→117) taken 600 times.
|
600 | if (templateType.is(TY_UNRESOLVED)) |
149 | ✗ | HANDLE_UNRESOLVED_TYPE_ER(templateType) | |
150 | |||
151 | // Check if the given type is generic | ||
152 |
2/4✓ Branch 0 (117→118) taken 600 times.
✗ Branch 1 (117→422) not taken.
✗ Branch 2 (118→119) not taken.
✓ Branch 3 (118→129) taken 600 times.
|
600 | if (templateType.is(TY_GENERIC)) |
153 | ✗ | SOFT_ERROR_ER(templateTypeNode, EXPECTED_NON_GENERIC_TYPE, "You must specify a concrete type here") | |
154 | |||
155 |
1/2✓ Branch 0 (129→130) taken 600 times.
✗ Branch 1 (129→422) not taken.
|
600 | templateTypes.push_back(templateType); |
156 | } | ||
157 | } | ||
158 | |||
159 | // Check if this is a method call or a normal function call | ||
160 |
2/2✓ Branch 0 (136→137) taken 5406 times.
✓ Branch 1 (136→151) taken 8100 times.
|
13506 | if (data.isMethodCall()) { |
161 | // This is a method call | ||
162 |
1/2✓ Branch 0 (137→138) taken 5406 times.
✗ Branch 1 (137→501) not taken.
|
5406 | thisType = firstFragEntry->getQualType(); |
163 |
2/4✓ Branch 0 (138→139) taken 5406 times.
✗ Branch 1 (138→424) not taken.
✓ Branch 2 (139→140) taken 5406 times.
✗ Branch 3 (139→424) not taken.
|
5406 | Scope *structBodyScope = thisType.getBase().getBodyScope(); |
164 |
1/2✗ Branch 0 (140→141) not taken.
✓ Branch 1 (140→142) taken 5406 times.
|
5406 | assert(structBodyScope != nullptr); |
165 |
3/4✓ Branch 0 (142→143) taken 5406 times.
✗ Branch 1 (142→501) not taken.
✓ Branch 2 (143→144) taken 2 times.
✓ Branch 3 (143→149) taken 5404 times.
|
5406 | if (!visitMethodCall(node, structBodyScope)) // Check if soft errors occurred |
166 |
3/6✓ Branch 0 (144→145) taken 2 times.
✗ Branch 1 (144→425) not taken.
✓ Branch 2 (145→146) taken 2 times.
✗ Branch 3 (145→425) not taken.
✓ Branch 4 (146→147) taken 2 times.
✗ Branch 5 (146→425) not taken.
|
2 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_UNRESOLVED), manIdx)}; |
167 |
1/2✗ Branch 0 (149→150) not taken.
✓ Branch 1 (149→187) taken 5404 times.
|
5404 | assert(calleeParentScope != nullptr); |
168 |
2/2✓ Branch 0 (152→153) taken 48 times.
✓ Branch 1 (152→166) taken 8052 times.
|
8100 | } else if (data.isFctPtrCall()) { |
169 | // This is a function pointer call | ||
170 |
2/4✓ Branch 0 (153→154) taken 48 times.
✗ Branch 1 (153→430) not taken.
✓ Branch 2 (154→155) taken 48 times.
✗ Branch 3 (154→430) not taken.
|
48 | const QualType &functionType = firstFragEntry->getQualType().getBase(); |
171 |
2/4✓ Branch 0 (155→156) taken 48 times.
✗ Branch 1 (155→427) not taken.
✗ Branch 2 (156→157) not taken.
✓ Branch 3 (156→158) taken 48 times.
|
48 | assert(functionType.isOneOf({TY_FUNCTION, TY_PROCEDURE})); |
172 |
2/4✓ Branch 0 (158→159) taken 48 times.
✗ Branch 1 (158→430) not taken.
✗ Branch 2 (159→160) not taken.
✓ Branch 3 (159→165) taken 48 times.
|
48 | if (!visitFctPtrCall(node, functionType)) // Check if soft errors occurred |
173 | ✗ | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_UNRESOLVED), manIdx)}; | |
174 | } else { | ||
175 | // This is an ordinary function call | ||
176 |
3/4✓ Branch 0 (167→168) taken 954 times.
✓ Branch 1 (167→171) taken 7098 times.
✗ Branch 2 (169→170) not taken.
✓ Branch 3 (169→171) taken 954 times.
|
8052 | assert(data.isOrdinaryCall() || data.isCtorCall()); |
177 |
5/6✓ Branch 0 (171→172) taken 8052 times.
✗ Branch 1 (171→433) not taken.
✓ Branch 2 (172→173) taken 8050 times.
✓ Branch 3 (172→431) taken 2 times.
✓ Branch 4 (174→175) taken 4 times.
✓ Branch 5 (174→180) taken 8046 times.
|
8054 | if (!visitOrdinaryFctCall(node, fqFunctionName)) // Check if soft errors occurred |
178 |
3/6✓ Branch 0 (175→176) taken 4 times.
✗ Branch 1 (175→434) not taken.
✓ Branch 2 (176→177) taken 4 times.
✗ Branch 3 (176→434) not taken.
✓ Branch 4 (177→178) taken 4 times.
✗ Branch 5 (177→434) not taken.
|
4 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_UNRESOLVED), manIdx)}; |
179 |
1/2✗ Branch 0 (180→181) not taken.
✓ Branch 1 (180→182) taken 8046 times.
|
8046 | assert(calleeParentScope != nullptr); |
180 | |||
181 | // If the call is no ordinary call, it must be a constructor, which takes a struct as this type. | ||
182 |
4/6✓ Branch 0 (183→184) taken 2027 times.
✓ Branch 1 (183→187) taken 6019 times.
✓ Branch 2 (184→185) taken 2027 times.
✗ Branch 3 (184→501) not taken.
✗ Branch 4 (185→186) not taken.
✓ Branch 5 (185→187) taken 2027 times.
|
8046 | assert(data.isOrdinaryCall() || data.thisType.is(TY_STRUCT)); |
183 | } | ||
184 | |||
185 |
2/2✓ Branch 0 (188→189) taken 13450 times.
✓ Branch 1 (188→260) taken 48 times.
|
13498 | if (!data.isFctPtrCall()) { |
186 | // Check if we were able to find a function | ||
187 |
2/2✓ Branch 0 (189→190) taken 12 times.
✓ Branch 1 (189→227) taken 13438 times.
|
13450 | if (!callee) { |
188 | // Build error message | ||
189 |
6/10✓ Branch 0 (191→192) taken 2 times.
✓ Branch 1 (191→195) taken 10 times.
✓ Branch 2 (194→197) taken 2 times.
✗ Branch 3 (194→436) not taken.
✓ Branch 4 (196→197) taken 10 times.
✗ Branch 5 (196→436) not taken.
✓ Branch 6 (197→198) taken 2 times.
✓ Branch 7 (197→200) taken 10 times.
✗ Branch 8 (436→437) not taken.
✗ Branch 9 (436→439) not taken.
|
14 | const std::string functionName = data.isCtorCall() ? CTOR_FUNCTION_NAME : node->functionNameFragments.back(); |
190 | 12 | ParamList errArgTypes; | |
191 |
1/2✓ Branch 0 (201→202) taken 12 times.
✗ Branch 1 (201→456) not taken.
|
12 | errArgTypes.reserve(args.size()); |
192 |
5/8✓ Branch 0 (202→203) taken 12 times.
✗ Branch 1 (202→442) not taken.
✓ Branch 2 (203→204) taken 12 times.
✗ Branch 3 (203→442) not taken.
✓ Branch 4 (204→205) taken 12 times.
✗ Branch 5 (204→442) not taken.
✓ Branch 6 (210→206) taken 7 times.
✓ Branch 7 (210→211) taken 12 times.
|
19 | for (const auto &type : args | std::views::keys) |
193 |
1/2✓ Branch 0 (207→208) taken 7 times.
✗ Branch 1 (207→441) not taken.
|
7 | errArgTypes.push_back({type, false}); |
194 |
2/4✓ Branch 0 (212→213) taken 12 times.
✗ Branch 1 (212→443) not taken.
✓ Branch 2 (213→214) taken 12 times.
✗ Branch 3 (213→443) not taken.
|
12 | const std::string signature = Function::getSignature(functionName, thisType, QualType(TY_DYN), errArgTypes, {}, false); |
195 | // Throw error | ||
196 |
5/10✓ Branch 0 (215→216) taken 12 times.
✗ Branch 1 (215→451) not taken.
✓ Branch 2 (216→217) taken 12 times.
✗ Branch 3 (216→449) not taken.
✓ Branch 4 (217→218) taken 12 times.
✗ Branch 5 (217→447) not taken.
✓ Branch 6 (220→221) taken 12 times.
✗ Branch 7 (220→453) not taken.
✓ Branch 8 (221→222) taken 12 times.
✗ Branch 9 (221→453) not taken.
|
12 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_FUNCTION, "Function/procedure '" + signature + "' could not be found") |
197 | 12 | } | |
198 | |||
199 | // Check if we need to request a re-visit, because the function body was not type-checked yet | ||
200 |
1/2✓ Branch 0 (227→228) taken 13438 times.
✗ Branch 1 (227→501) not taken.
|
13438 | requestRevisitIfRequired(callee); |
201 | |||
202 | // Get function entry from function object | ||
203 | 13438 | SymbolTableEntry *functionEntry = callee->entry; | |
204 | |||
205 | // Check if the called function has sufficient visibility | ||
206 |
1/2✓ Branch 0 (228→229) taken 13438 times.
✗ Branch 1 (228→501) not taken.
|
13438 | isImported = calleeParentScope->isImportedBy(rootScope); |
207 |
8/10✓ Branch 0 (229→230) taken 3796 times.
✓ Branch 1 (229→234) taken 9642 times.
✓ Branch 2 (230→231) taken 3796 times.
✗ Branch 3 (230→501) not taken.
✓ Branch 4 (231→232) taken 3796 times.
✗ Branch 5 (231→501) not taken.
✓ Branch 6 (232→233) taken 1 times.
✓ Branch 7 (232→234) taken 3795 times.
✓ Branch 8 (235→236) taken 1 times.
✓ Branch 9 (235→260) taken 13437 times.
|
13438 | if (isImported && !functionEntry->getQualType().isPublic()) { |
208 |
1/2✓ Branch 0 (236→237) taken 1 times.
✗ Branch 1 (236→477) not taken.
|
1 | const QualType functionEntryType = functionEntry->getQualType(); |
209 |
1/2✓ Branch 0 (237→238) taken 1 times.
✗ Branch 1 (237→477) not taken.
|
1 | const std::string signature = callee->getSignature(); |
210 |
2/4✓ Branch 0 (238→239) taken 1 times.
✗ Branch 1 (238→475) not taken.
✓ Branch 2 (239→240) taken 1 times.
✗ Branch 3 (239→249) not taken.
|
1 | if (functionEntryType.is(TY_FUNCTION)) |
211 |
5/10✓ Branch 0 (240→241) taken 1 times.
✗ Branch 1 (240→465) not taken.
✓ Branch 2 (241→242) taken 1 times.
✗ Branch 3 (241→463) not taken.
✓ Branch 4 (242→243) taken 1 times.
✗ Branch 5 (242→461) not taken.
✓ Branch 6 (245→246) taken 1 times.
✗ Branch 7 (245→467) not taken.
✓ Branch 8 (246→247) taken 1 times.
✗ Branch 9 (246→467) not taken.
|
1 | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Function '" + signature + "' has insufficient visibility") |
212 | else | ||
213 | ✗ | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Procedure '" + signature + "' has insufficient visibility") | |
214 | 1 | } | |
215 | } | ||
216 | |||
217 | // Generate arg infos | ||
218 |
2/2✓ Branch 0 (260→261) taken 10465 times.
✓ Branch 1 (260→302) taken 3020 times.
|
13485 | if (node->hasArgs) { |
219 | 10465 | QualTypeList paramTypes; | |
220 |
2/2✓ Branch 0 (262→263) taken 25 times.
✓ Branch 1 (262→269) taken 10440 times.
|
10465 | if (data.isFctPtrCall()) { |
221 |
2/4✓ Branch 0 (263→264) taken 25 times.
✗ Branch 1 (263→479) not taken.
✓ Branch 2 (264→265) taken 25 times.
✗ Branch 3 (264→479) not taken.
|
25 | const QualType &functionType = firstFragEntry->getQualType().getBase(); |
222 |
1/2✓ Branch 0 (265→266) taken 25 times.
✗ Branch 1 (265→478) not taken.
|
25 | paramTypes = functionType.getFunctionParamTypes(); |
223 | } else { | ||
224 |
1/2✗ Branch 0 (269→270) not taken.
✓ Branch 1 (269→271) taken 10440 times.
|
10440 | assert(callee != nullptr); |
225 |
1/2✓ Branch 0 (271→272) taken 10440 times.
✗ Branch 1 (271→480) not taken.
|
10440 | paramTypes = callee->getParamTypes(); |
226 | } | ||
227 | |||
228 | 10465 | node->argLst->argInfos.clear(); | |
229 |
2/2✓ Branch 0 (295→277) taken 16064 times.
✓ Branch 1 (295→296) taken 10465 times.
|
26529 | for (size_t argIdx = 0; argIdx < args.size(); argIdx++) { |
230 |
1/2✓ Branch 0 (277→278) taken 16064 times.
✗ Branch 1 (277→482) not taken.
|
16064 | const QualType &expectedType = paramTypes.at(argIdx); |
231 |
1/2✓ Branch 0 (278→279) taken 16064 times.
✗ Branch 1 (278→482) not taken.
|
16064 | const auto &[actualType, _] = args.at(argIdx); |
232 | |||
233 | 16064 | Function *copyCtor = nullptr; | |
234 |
10/14✓ Branch 0 (281→282) taken 16064 times.
✗ Branch 1 (281→482) not taken.
✓ Branch 2 (282→283) taken 32 times.
✓ Branch 3 (282→288) taken 16032 times.
✓ Branch 4 (283→284) taken 32 times.
✗ Branch 5 (283→482) not taken.
✓ Branch 6 (284→285) taken 32 times.
✗ Branch 7 (284→288) not taken.
✓ Branch 8 (285→286) taken 32 times.
✗ Branch 9 (285→482) not taken.
✓ Branch 10 (286→287) taken 14 times.
✓ Branch 11 (286→288) taken 18 times.
✓ Branch 12 (289→290) taken 14 times.
✓ Branch 13 (289→292) taken 16050 times.
|
16064 | if (expectedType.is(TY_STRUCT) && actualType.is(TY_STRUCT) && !actualType.isTriviallyCopyable(node)) { |
235 |
1/2✓ Branch 0 (290→291) taken 14 times.
✗ Branch 1 (290→482) not taken.
|
14 | copyCtor = matchCopyCtor(actualType, node); |
236 | // Insert anonymous symbol to track the dtor call of the copy | ||
237 |
1/2✓ Branch 0 (291→292) taken 14 times.
✗ Branch 1 (291→482) not taken.
|
14 | currentScope->symbolTable.insertAnonymous(actualType, node, argIdx + 1); // +1 because 0 is reserved for return value |
238 | } | ||
239 | |||
240 |
1/2✓ Branch 0 (292→293) taken 16064 times.
✗ Branch 1 (292→481) not taken.
|
16064 | node->argLst->argInfos.push_back(ArgLstNode::ArgInfo{copyCtor}); |
241 | } | ||
242 |
1/2✗ Branch 0 (298→299) not taken.
✓ Branch 1 (298→300) taken 10465 times.
|
10465 | assert(node->argLst->argInfos.size() == node->argLst->args.size()); |
243 | 10465 | } | |
244 | |||
245 | // Retrieve return type | ||
246 |
6/10✓ Branch 0 (303→304) taken 48 times.
✓ Branch 1 (303→308) taken 13437 times.
✓ Branch 2 (304→305) taken 48 times.
✗ Branch 3 (304→485) not taken.
✓ Branch 4 (305→306) taken 48 times.
✗ Branch 5 (305→485) not taken.
✓ Branch 6 (306→307) taken 48 times.
✗ Branch 7 (306→485) not taken.
✓ Branch 8 (308→309) taken 13437 times.
✗ Branch 9 (308→485) not taken.
|
26922 | const bool isFct = data.isFctPtrCall() ? firstFragEntry->getQualType().getBase().is(TY_FUNCTION) : callee->isFunction(); |
247 | 13485 | QualType returnType; | |
248 |
2/2✓ Branch 0 (313→314) taken 48 times.
✓ Branch 1 (313→321) taken 13437 times.
|
13485 | if (data.isFctPtrCall()) { |
249 |
6/10✓ Branch 0 (314→315) taken 20 times.
✓ Branch 1 (314→319) taken 28 times.
✓ Branch 2 (315→316) taken 20 times.
✗ Branch 3 (315→486) not taken.
✓ Branch 4 (316→317) taken 20 times.
✗ Branch 5 (316→486) not taken.
✓ Branch 6 (317→318) taken 20 times.
✗ Branch 7 (317→486) not taken.
✓ Branch 8 (319→320) taken 28 times.
✗ Branch 9 (319→486) not taken.
|
48 | returnType = isFct ? firstFragEntry->getQualType().getBase().getFunctionReturnType() : QualType(TY_BOOL); |
250 |
2/2✓ Branch 0 (322→323) taken 2025 times.
✓ Branch 1 (322→324) taken 11412 times.
|
13437 | } else if (data.isCtorCall()) { |
251 | 2025 | returnType = thisType; | |
252 |
3/4✓ Branch 0 (324→325) taken 11412 times.
✗ Branch 1 (324→501) not taken.
✓ Branch 2 (327→328) taken 2660 times.
✓ Branch 3 (327→330) taken 8752 times.
|
22824 | } else if (callee->isProcedure()) { |
253 |
1/2✓ Branch 0 (328→329) taken 2660 times.
✗ Branch 1 (328→488) not taken.
|
2660 | returnType = QualType(TY_DYN); |
254 | } else { | ||
255 | 8752 | returnType = callee->returnType; | |
256 | } | ||
257 |
1/2✓ Branch 0 (331→332) taken 13485 times.
✗ Branch 1 (331→501) not taken.
|
13485 | const QualType returnBaseType = returnType.getBase(); |
258 | |||
259 | // Make sure this source file knows about the return type | ||
260 |
3/4✓ Branch 0 (332→333) taken 13485 times.
✗ Branch 1 (332→501) not taken.
✓ Branch 2 (333→334) taken 3157 times.
✓ Branch 3 (333→337) taken 10328 times.
|
13485 | if (returnBaseType.is(TY_STRUCT)) |
261 |
2/4✓ Branch 0 (334→335) taken 3157 times.
✗ Branch 1 (334→489) not taken.
✓ Branch 2 (335→336) taken 3157 times.
✗ Branch 3 (335→489) not taken.
|
3157 | returnType = mapImportedScopeTypeToLocalType(returnBaseType.getBodyScope(), returnType); |
262 | |||
263 | // Add anonymous symbol to keep track of dtor call, if non-trivially destructible | ||
264 | 13485 | SymbolTableEntry *anonymousSymbol = nullptr; | |
265 |
8/10✓ Branch 0 (337→338) taken 13485 times.
✗ Branch 1 (337→501) not taken.
✓ Branch 2 (338→339) taken 2783 times.
✓ Branch 3 (338→342) taken 10702 times.
✓ Branch 4 (339→340) taken 2783 times.
✗ Branch 5 (339→501) not taken.
✓ Branch 6 (340→341) taken 1849 times.
✓ Branch 7 (340→342) taken 934 times.
✓ Branch 8 (343→344) taken 1849 times.
✓ Branch 9 (343→346) taken 11636 times.
|
13485 | if (returnType.is(TY_STRUCT) && !returnType.isTriviallyDestructible(node)) |
266 |
1/2✓ Branch 0 (344→345) taken 1849 times.
✗ Branch 1 (344→501) not taken.
|
1849 | anonymousSymbol = currentScope->symbolTable.insertAnonymous(returnType, node); |
267 | |||
268 | // Remove public qualifier to not have public local variables | ||
269 | 13485 | returnType.getQualifiers().isPublic = false; | |
270 | |||
271 | // Check if the return value gets discarded | ||
272 |
7/8✓ Branch 0 (347→348) taken 8772 times.
✓ Branch 1 (347→351) taken 4713 times.
✓ Branch 2 (348→349) taken 8772 times.
✗ Branch 3 (348→501) not taken.
✓ Branch 4 (349→350) taken 148 times.
✓ Branch 5 (349→351) taken 8624 times.
✓ Branch 6 (352→353) taken 148 times.
✓ Branch 7 (352→378) taken 13337 times.
|
13485 | if (isFct && !node->hasReturnValueReceiver()) { |
273 | // Check if we want to ignore the discarded return value | ||
274 | 148 | bool ignoreUnusedReturnValue = false; | |
275 |
2/2✓ Branch 0 (354→355) taken 145 times.
✓ Branch 1 (354→375) taken 3 times.
|
148 | if (!data.isFctPtrCall()) { |
276 |
1/2✗ Branch 0 (355→356) not taken.
✓ Branch 1 (355→357) taken 145 times.
|
145 | assert(callee != nullptr); |
277 |
1/2✓ Branch 0 (357→358) taken 145 times.
✗ Branch 1 (357→359) not taken.
|
145 | auto fctDef = dynamic_cast<const FctDefNode *>(callee->declNode); |
278 |
12/18✓ Branch 0 (360→361) taken 95 times.
✓ Branch 1 (360→368) taken 50 times.
✓ Branch 2 (361→362) taken 24 times.
✓ Branch 3 (361→368) taken 71 times.
✓ Branch 4 (364→365) taken 24 times.
✗ Branch 5 (364→490) not taken.
✓ Branch 6 (365→366) taken 24 times.
✗ Branch 7 (365→490) not taken.
✓ Branch 8 (366→367) taken 23 times.
✓ Branch 9 (366→368) taken 1 times.
✓ Branch 10 (369→370) taken 24 times.
✓ Branch 11 (369→371) taken 121 times.
✓ Branch 12 (371→372) taken 24 times.
✓ Branch 13 (371→374) taken 121 times.
✗ Branch 14 (490→491) not taken.
✗ Branch 15 (490→492) not taken.
✗ Branch 16 (494→495) not taken.
✗ Branch 17 (494→497) not taken.
|
193 | ignoreUnusedReturnValue = fctDef && fctDef->attrs && fctDef->attrs->attrLst->hasAttr(ATTR_IGNORE_UNUSED_RETURN_VALUE); |
279 | } | ||
280 | |||
281 |
2/2✓ Branch 0 (375→376) taken 125 times.
✓ Branch 1 (375→378) taken 23 times.
|
148 | if (!ignoreUnusedReturnValue) |
282 |
1/2✓ Branch 0 (376→377) taken 125 times.
✗ Branch 1 (376→499) not taken.
|
125 | warnings.emplace_back(node->codeLoc, UNUSED_RETURN_VALUE, "The return value of the function call is unused"); |
283 | } | ||
284 | |||
285 |
2/4✓ Branch 0 (378→379) taken 13485 times.
✗ Branch 1 (378→500) not taken.
✓ Branch 2 (379→380) taken 13485 times.
✗ Branch 3 (379→500) not taken.
|
13485 | return ExprResult{node->setEvaluatedSymbolType(returnType, manIdx), anonymousSymbol}; |
286 | } | ||
287 | |||
288 | 8052 | bool TypeChecker::visitOrdinaryFctCall(FctCallNode *node, std::string fqFunctionName) { | |
289 |
1/2✓ Branch 0 (2→3) taken 8052 times.
✗ Branch 1 (2→106) not taken.
|
8052 | FctCallNode::FctCallData &data = node->data.at(manIdx); |
290 | 8052 | auto &[callType, isImported, templateTypes, thisType, args, callee, calleeParentScope] = data; | |
291 | |||
292 | // Check if this is a well-known ctor/fct call | ||
293 |
2/2✓ Branch 0 (4→5) taken 7982 times.
✓ Branch 1 (4→7) taken 70 times.
|
8052 | if (node->functionNameFragments.size() == 1) { |
294 |
1/2✓ Branch 0 (5→6) taken 7982 times.
✗ Branch 1 (5→106) not taken.
|
7982 | ensureLoadedRuntimeForTypeName(fqFunctionName); |
295 |
1/2✓ Branch 0 (6→7) taken 7982 times.
✗ Branch 1 (6→106) not taken.
|
7982 | ensureLoadedRuntimeForFunctionName(fqFunctionName); |
296 | } | ||
297 | |||
298 | // Check if the type is generic (possible in case of ctor call) | ||
299 |
1/2✓ Branch 0 (7→8) taken 8052 times.
✗ Branch 1 (7→106) not taken.
|
8052 | const QualType *genericType = rootScope->lookupGenericTypeStrict(fqFunctionName); |
300 |
6/8✓ Branch 0 (8→9) taken 1 times.
✓ Branch 1 (8→12) taken 8051 times.
✓ Branch 2 (9→10) taken 1 times.
✗ Branch 3 (9→106) not taken.
✓ Branch 4 (10→11) taken 1 times.
✗ Branch 5 (10→12) not taken.
✓ Branch 6 (13→14) taken 1 times.
✓ Branch 7 (13→19) taken 8051 times.
|
8052 | if (genericType && typeMapping.contains(fqFunctionName)) { |
301 |
1/2✓ Branch 0 (14→15) taken 1 times.
✗ Branch 1 (14→106) not taken.
|
1 | const QualType &replacementType = typeMapping.at(fqFunctionName); |
302 |
2/4✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→106) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→19) not taken.
|
1 | if (replacementType.is(TY_STRUCT)) |
303 |
2/4✓ Branch 0 (17→18) taken 1 times.
✗ Branch 1 (17→106) not taken.
✓ Branch 2 (18→19) taken 1 times.
✗ Branch 3 (18→106) not taken.
|
1 | fqFunctionName = replacementType.getSubType(); |
304 | } | ||
305 | |||
306 | // Check if the exported name registry contains that function name | ||
307 |
1/2✓ Branch 0 (19→20) taken 8052 times.
✗ Branch 1 (19→106) not taken.
|
8052 | const NameRegistryEntry *functionRegistryEntry = sourceFile->getNameRegistryEntry(fqFunctionName); |
308 |
2/2✓ Branch 0 (20→21) taken 3 times.
✓ Branch 1 (20→29) taken 8049 times.
|
8052 | if (!functionRegistryEntry) { |
309 |
2/4✓ Branch 0 (22→23) taken 3 times.
✗ Branch 1 (22→86) not taken.
✓ Branch 2 (23→24) taken 3 times.
✗ Branch 3 (23→84) not taken.
|
3 | const std::string msg = "Function/procedure/struct '" + node->functionNameFragments.back() + "' could not be found"; |
310 |
1/2✓ Branch 0 (25→26) taken 3 times.
✗ Branch 1 (25→87) not taken.
|
3 | SOFT_ERROR_BOOL(node, REFERENCED_UNDEFINED_FUNCTION, msg) |
311 | 3 | } | |
312 | 8049 | const SymbolTableEntry *functionEntry = functionRegistryEntry->targetEntry; | |
313 | 8049 | calleeParentScope = functionRegistryEntry->targetScope; | |
314 | |||
315 | // Check if the target symbol is a struct -> this must be a constructor call | ||
316 |
1/2✓ Branch 0 (30→31) taken 8049 times.
✗ Branch 1 (30→106) not taken.
|
8049 | std::string functionName = node->functionNameFragments.back(); |
317 |
7/10✓ Branch 0 (31→32) taken 8049 times.
✗ Branch 1 (31→36) not taken.
✓ Branch 2 (32→33) taken 8049 times.
✗ Branch 3 (32→104) not taken.
✓ Branch 4 (33→34) taken 8049 times.
✗ Branch 5 (33→104) not taken.
✓ Branch 6 (34→35) taken 2028 times.
✓ Branch 7 (34→36) taken 6021 times.
✓ Branch 8 (37→38) taken 2028 times.
✓ Branch 9 (37→54) taken 6021 times.
|
8049 | if (functionEntry != nullptr && functionEntry->getQualType().is(TY_STRUCT)) { |
318 | 2028 | callType = FctCallNode::FctCallType::TYPE_CTOR; | |
319 |
1/2✓ Branch 0 (38→39) taken 2028 times.
✗ Branch 1 (38→104) not taken.
|
2028 | functionName = CTOR_FUNCTION_NAME; |
320 | |||
321 | 2028 | const NameRegistryEntry *structRegistryEntry = functionRegistryEntry; | |
322 | 2028 | const SymbolTableEntry *structEntry = functionEntry; | |
323 | |||
324 | // Substantiate potentially generic this struct | ||
325 |
2/4✓ Branch 0 (39→40) taken 2028 times.
✗ Branch 1 (39→104) not taken.
✓ Branch 2 (40→41) taken 2028 times.
✗ Branch 3 (40→104) not taken.
|
2028 | const Struct *thisStruct = structEntry->getQualType().getStruct(node, templateTypes); |
326 |
2/2✓ Branch 0 (41→42) taken 1 times.
✓ Branch 1 (41→51) taken 2027 times.
|
2028 | if (!thisStruct) { |
327 |
1/2✓ Branch 0 (42→43) taken 1 times.
✗ Branch 1 (42→97) not taken.
|
1 | const std::string signature = Struct::getSignature(structRegistryEntry->targetEntry->name, templateTypes); |
328 |
2/4✓ Branch 0 (43→44) taken 1 times.
✗ Branch 1 (43→92) not taken.
✓ Branch 2 (44→45) taken 1 times.
✗ Branch 3 (44→90) not taken.
|
1 | const std::string errorMsg = "Could not find struct candidate for struct '" + signature + "'. Do the template types match?"; |
329 |
1/2✓ Branch 0 (46→47) taken 1 times.
✗ Branch 1 (46→93) not taken.
|
1 | SOFT_ERROR_BOOL(node, UNKNOWN_DATATYPE, errorMsg) |
330 | 1 | } | |
331 | |||
332 | // Set the 'this' type of the function to the struct type | ||
333 |
2/4✓ Branch 0 (51→52) taken 2027 times.
✗ Branch 1 (51→98) not taken.
✓ Branch 2 (52→53) taken 2027 times.
✗ Branch 3 (52→98) not taken.
|
2027 | thisType = structEntry->getQualType().getWithBodyScope(thisStruct->scope); |
334 | 2027 | calleeParentScope = thisStruct->scope; | |
335 | } | ||
336 | |||
337 | // Attach the concrete template types to the 'this' type | ||
338 |
7/8✓ Branch 0 (54→55) taken 8048 times.
✗ Branch 1 (54→104) not taken.
✓ Branch 2 (55→56) taken 2027 times.
✓ Branch 3 (55→59) taken 6021 times.
✓ Branch 4 (57→58) taken 314 times.
✓ Branch 5 (57→59) taken 1713 times.
✓ Branch 6 (60→61) taken 314 times.
✓ Branch 7 (60→63) taken 7734 times.
|
8048 | if (!thisType.is(TY_DYN) && !templateTypes.empty()) |
339 |
1/2✓ Branch 0 (61→62) taken 314 times.
✗ Branch 1 (61→99) not taken.
|
314 | thisType = thisType.getWithTemplateTypes(templateTypes); |
340 | |||
341 | // Map local arg types to imported types | ||
342 |
5/8✓ Branch 0 (63→64) taken 8048 times.
✗ Branch 1 (63→101) not taken.
✓ Branch 2 (64→65) taken 8048 times.
✗ Branch 3 (64→101) not taken.
✓ Branch 4 (65→66) taken 8048 times.
✗ Branch 5 (65→101) not taken.
✓ Branch 6 (71→67) taken 12079 times.
✓ Branch 7 (71→72) taken 8048 times.
|
20127 | for (QualType &argType : args | std::views::keys) |
343 |
1/2✓ Branch 0 (68→69) taken 12079 times.
✗ Branch 1 (68→100) not taken.
|
12079 | argType = mapLocalTypeToImportedScopeType(calleeParentScope, argType); |
344 | |||
345 | // Map local template types to imported types | ||
346 |
2/2✓ Branch 0 (78→74) taken 601 times.
✓ Branch 1 (78→79) taken 8048 times.
|
8649 | for (QualType &templateType : templateTypes) |
347 |
1/2✓ Branch 0 (75→76) taken 601 times.
✗ Branch 1 (75→102) not taken.
|
601 | templateType = mapLocalTypeToImportedScopeType(calleeParentScope, templateType); |
348 | |||
349 | // Retrieve function object | ||
350 | 8048 | Scope *matchScope = calleeParentScope; | |
351 |
2/2✓ Branch 0 (79→80) taken 8046 times.
✓ Branch 1 (79→104) taken 2 times.
|
8048 | callee = FunctionManager::match(this, matchScope, functionName, data.thisType, data.args, templateTypes, false, node); |
352 | |||
353 | 8046 | return true; | |
354 | 8049 | } | |
355 | |||
356 | 48 | bool TypeChecker::visitFctPtrCall(const FctCallNode *node, const QualType &functionType) const { | |
357 |
1/2✓ Branch 0 (2→3) taken 48 times.
✗ Branch 1 (2→75) not taken.
|
48 | const FctCallNode::FctCallData &data = node->data.at(manIdx); |
358 | 48 | const auto &[callType, isImported, templateTypes, thisType, args, callee, calleeParentScope] = data; | |
359 | |||
360 | // Check if the given argument types match the type | ||
361 |
1/2✓ Branch 0 (3→4) taken 48 times.
✗ Branch 1 (3→75) not taken.
|
48 | const QualTypeList expectedArgTypes = functionType.getFunctionParamTypes(); |
362 |
1/2✗ Branch 0 (6→7) not taken.
✓ Branch 1 (6→14) taken 48 times.
|
48 | if (args.size() != expectedArgTypes.size()) |
363 | ✗ | SOFT_ERROR_BOOL(node, REFERENCED_UNDEFINED_FUNCTION, "Expected and actual number of arguments do not match") | |
364 | |||
365 | // Create resolver function, that always returns a nullptr | ||
366 | 48 | TypeMatcher::ResolverFct resolverFct = [](const std::string &) { return nullptr; }; | |
367 | |||
368 |
2/2✓ Branch 0 (41→16) taken 31 times.
✓ Branch 1 (41→42) taken 48 times.
|
79 | for (size_t i = 0; i < args.size(); i++) { |
369 |
1/2✓ Branch 0 (16→17) taken 31 times.
✗ Branch 1 (16→71) not taken.
|
31 | const QualType &actualType = args.at(i).first; |
370 |
1/2✓ Branch 0 (17→18) taken 31 times.
✗ Branch 1 (17→71) not taken.
|
31 | const QualType &expectedType = expectedArgTypes.at(i); |
371 |
2/4✓ Branch 0 (19→20) taken 31 times.
✗ Branch 1 (19→68) not taken.
✗ Branch 2 (20→21) not taken.
✓ Branch 3 (20→34) taken 31 times.
|
31 | if (TypeMapping tm; !TypeMatcher::matchRequestedToCandidateType(expectedType, actualType, tm, resolverFct, false)) |
372 |
1/16✗ Branch 0 (21→22) not taken.
✗ Branch 1 (21→66) not taken.
✗ Branch 2 (22→23) not taken.
✗ Branch 3 (22→61) not taken.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→59) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→57) not taken.
✗ Branch 8 (25→26) not taken.
✗ Branch 9 (25→55) not taken.
✗ Branch 10 (26→27) not taken.
✗ Branch 11 (26→53) not taken.
✗ Branch 12 (27→28) not taken.
✗ Branch 13 (27→53) not taken.
✓ Branch 14 (36→37) taken 31 times.
✗ Branch 15 (36→39) not taken.
|
31 | SOFT_ERROR_BOOL(node->argLst->args.at(i), REFERENCED_UNDEFINED_FUNCTION, |
373 | "Expected " + expectedType.getName(false) + " but got " + actualType.getName(false)) | ||
374 | } | ||
375 | 48 | return true; | |
376 | 48 | } | |
377 | |||
378 | 5406 | bool TypeChecker::visitMethodCall(FctCallNode *node, Scope *structScope) { | |
379 | 5406 | FctCallNode::FctCallData &data = node->data.at(manIdx); | |
380 | 5406 | auto &[callType, isImported, templateTypes, thisType, args, callee, calleeParentScope] = data; | |
381 | |||
382 | // Traverse through structs - the first fragment is already looked up and the last one is the method name | ||
383 |
2/2✓ Branch 0 (41→4) taken 688 times.
✓ Branch 1 (41→42) taken 5404 times.
|
6092 | for (size_t i = 1; i < node->functionNameFragments.size() - 1; i++) { |
384 | 688 | const std::string &identifier = node->functionNameFragments.at(i); | |
385 | |||
386 | // Retrieve field entry | ||
387 | 688 | SymbolTableEntry *fieldEntry = structScope->lookupStrict(identifier); | |
388 |
2/2✓ Branch 0 (8→9) taken 1 times.
✓ Branch 1 (8→24) taken 687 times.
|
688 | if (!fieldEntry) { |
389 |
1/2✓ Branch 0 (9→10) taken 1 times.
✗ Branch 1 (9→82) not taken.
|
1 | std::stringstream errorMsg; |
390 |
1/2✓ Branch 0 (10→11) taken 1 times.
✗ Branch 1 (10→80) not taken.
|
1 | errorMsg << "The type '"; |
391 |
3/6✓ Branch 0 (11→12) taken 1 times.
✗ Branch 1 (11→75) not taken.
✓ Branch 2 (12→13) taken 1 times.
✗ Branch 3 (12→75) not taken.
✓ Branch 4 (13→14) taken 1 times.
✗ Branch 5 (13→73) not taken.
|
1 | errorMsg << thisType.getBase().getName(false, true); |
392 |
3/6✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→80) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→80) not taken.
✓ Branch 4 (17→18) taken 1 times.
✗ Branch 5 (17→80) not taken.
|
1 | errorMsg << "' does not have a member with the name '" << identifier << "'"; |
393 |
2/4✓ Branch 0 (18→19) taken 1 times.
✗ Branch 1 (18→79) not taken.
✓ Branch 2 (19→20) taken 1 times.
✗ Branch 3 (19→77) not taken.
|
1 | SOFT_ERROR_BOOL(node, ACCESS_TO_NON_EXISTING_MEMBER, errorMsg.str()) |
394 | 1 | } | |
395 |
5/8✓ Branch 0 (24→25) taken 687 times.
✗ Branch 1 (24→84) not taken.
✓ Branch 2 (25→26) taken 687 times.
✗ Branch 3 (25→84) not taken.
✓ Branch 4 (26→27) taken 687 times.
✗ Branch 5 (26→83) not taken.
✓ Branch 6 (27→28) taken 1 times.
✓ Branch 7 (27→34) taken 686 times.
|
687 | if (!fieldEntry->getQualType().getBase().isOneOf({TY_STRUCT, TY_INTERFACE})) |
396 |
3/6✓ Branch 0 (28→29) taken 1 times.
✗ Branch 1 (28→89) not taken.
✓ Branch 2 (29→30) taken 1 times.
✗ Branch 3 (29→87) not taken.
✓ Branch 4 (30→31) taken 1 times.
✗ Branch 5 (30→85) not taken.
|
1 | SOFT_ERROR_BOOL(node, INVALID_MEMBER_ACCESS, |
397 | "Cannot call a method on '" + identifier + "', since it is no struct or interface") | ||
398 | 686 | fieldEntry->used = true; | |
399 | |||
400 | // Get struct type and scope | ||
401 | 686 | thisType = fieldEntry->getQualType(); | |
402 |
2/4✓ Branch 0 (35→36) taken 686 times.
✗ Branch 1 (35→91) not taken.
✓ Branch 2 (36→37) taken 686 times.
✗ Branch 3 (36→91) not taken.
|
686 | structScope = thisType.getBase().getBodyScope(); |
403 |
1/2✗ Branch 0 (37→38) not taken.
✓ Branch 1 (37→39) taken 686 times.
|
686 | assert(structScope != nullptr); |
404 | } | ||
405 | |||
406 |
1/2✗ Branch 0 (43→44) not taken.
✓ Branch 1 (43→51) taken 5404 times.
|
5404 | if (thisType.is(TY_INTERFACE)) |
407 | ✗ | SOFT_ERROR_BOOL(node, INVALID_MEMBER_ACCESS, "Cannot call a method on an interface") | |
408 | |||
409 | // Map local arg types to imported types | ||
410 | 5404 | Scope *matchScope = calleeParentScope = structScope; | |
411 |
5/8✓ Branch 0 (51→52) taken 5404 times.
✗ Branch 1 (51→99) not taken.
✓ Branch 2 (52→53) taken 5404 times.
✗ Branch 3 (52→99) not taken.
✓ Branch 4 (53→54) taken 5404 times.
✗ Branch 5 (53→99) not taken.
✓ Branch 6 (59→55) taken 3963 times.
✓ Branch 7 (59→60) taken 5404 times.
|
9367 | for (QualType &argType : args | std::views::keys) |
412 |
1/2✓ Branch 0 (56→57) taken 3963 times.
✗ Branch 1 (56→98) not taken.
|
3963 | argType = mapLocalTypeToImportedScopeType(calleeParentScope, argType); |
413 | |||
414 | // Map local template types to imported types | ||
415 |
1/2✗ Branch 0 (66→62) not taken.
✓ Branch 1 (66→67) taken 5404 times.
|
5404 | for (QualType &templateType : templateTypes) |
416 | ✗ | templateType = mapLocalTypeToImportedScopeType(calleeParentScope, templateType); | |
417 | |||
418 | // 'this' type | ||
419 |
1/2✓ Branch 0 (67→68) taken 5404 times.
✗ Branch 1 (67→102) not taken.
|
5404 | thisType = thisType.autoDeReference(); |
420 |
1/2✓ Branch 0 (68→69) taken 5404 times.
✗ Branch 1 (68→103) not taken.
|
5404 | thisType = mapLocalTypeToImportedScopeType(calleeParentScope, thisType); |
421 | |||
422 | // Retrieve function object | ||
423 | 5404 | const std::string &functionName = node->functionNameFragments.back(); | |
424 | 5404 | callee = FunctionManager::match(this, matchScope, functionName, thisType, args, templateTypes, false, node); | |
425 | |||
426 | 5404 | return true; | |
427 | } | ||
428 | |||
429 | 74 | std::any TypeChecker::visitArrayInitialization(ArrayInitializationNode *node) { | |
430 |
5/6✓ Branch 0 (2→3) taken 73 times.
✓ Branch 1 (2→5) taken 1 times.
✗ Branch 2 (4→5) not taken.
✓ Branch 3 (4→6) taken 73 times.
✓ Branch 4 (7→8) taken 1 times.
✓ Branch 5 (7→18) taken 73 times.
|
74 | if (!node->itemLst || node->itemLst->args.empty()) |
431 |
4/8✓ Branch 0 (10→11) taken 1 times.
✗ Branch 1 (10→68) not taken.
✓ Branch 2 (11→12) taken 1 times.
✗ Branch 3 (11→66) not taken.
✓ Branch 4 (14→15) taken 1 times.
✗ Branch 5 (14→72) not taken.
✓ Branch 6 (15→16) taken 1 times.
✗ Branch 7 (15→72) not taken.
|
3 | SOFT_ERROR_ER(node, ARRAY_SIZE_INVALID, "Array initializers must at least contain one value"); |
432 | 73 | node->actualSize = node->itemLst->args.size(); | |
433 | |||
434 |
1/2✓ Branch 0 (19→20) taken 73 times.
✗ Branch 1 (19→97) not taken.
|
73 | QualType actualItemType(TY_DYN); |
435 | // Check if all values have the same type | ||
436 |
2/2✓ Branch 0 (55→22) taken 491 times.
✓ Branch 1 (55→56) taken 72 times.
|
563 | for (AssignExprNode *arg : node->itemLst->args) { |
437 |
2/4✓ Branch 0 (23→24) taken 491 times.
✗ Branch 1 (23→75) not taken.
✓ Branch 2 (24→25) taken 491 times.
✗ Branch 3 (24→73) not taken.
|
491 | const QualType itemType = std::any_cast<ExprResult>(visit(arg)).type; |
438 |
2/8✓ Branch 0 (26→27) taken 491 times.
✗ Branch 1 (26→94) not taken.
✗ Branch 2 (27→28) not taken.
✓ Branch 3 (27→32) taken 491 times.
✗ Branch 4 (28→29) not taken.
✗ Branch 5 (28→77) not taken.
✗ Branch 6 (29→30) not taken.
✗ Branch 7 (29→77) not taken.
|
491 | HANDLE_UNRESOLVED_TYPE_ER(itemType) |
439 |
3/4✓ Branch 0 (32→33) taken 491 times.
✗ Branch 1 (32→94) not taken.
✓ Branch 2 (33→34) taken 73 times.
✓ Branch 3 (33→35) taken 418 times.
|
491 | if (actualItemType.is(TY_DYN)) // Perform type inference |
440 | 73 | actualItemType = itemType; | |
441 |
3/4✓ Branch 0 (35→36) taken 418 times.
✗ Branch 1 (35→94) not taken.
✓ Branch 2 (36→37) taken 1 times.
✓ Branch 3 (36→52) taken 417 times.
|
418 | else if (itemType != actualItemType) // Check if types are matching |
442 |
8/16✓ Branch 0 (37→38) taken 1 times.
✗ Branch 1 (37→91) not taken.
✓ Branch 2 (38→39) taken 1 times.
✗ Branch 3 (38→86) not taken.
✓ Branch 4 (39→40) taken 1 times.
✗ Branch 5 (39→84) not taken.
✓ Branch 6 (40→41) taken 1 times.
✗ Branch 7 (40→82) not taken.
✓ Branch 8 (41→42) taken 1 times.
✗ Branch 9 (41→80) not taken.
✓ Branch 10 (42→43) taken 1 times.
✗ Branch 11 (42→78) not taken.
✓ Branch 12 (48→49) taken 1 times.
✗ Branch 13 (48→93) not taken.
✓ Branch 14 (49→50) taken 1 times.
✗ Branch 15 (49→93) not taken.
|
1 | SOFT_ERROR_ER(arg, ARRAY_ITEM_TYPE_NOT_MATCHING, |
443 | "All provided values have to be of the same data type. You provided " + actualItemType.getName(false) + | ||
444 | " and " + itemType.getName(false)) | ||
445 | } | ||
446 |
2/4✓ Branch 0 (56→57) taken 72 times.
✗ Branch 1 (56→97) not taken.
✗ Branch 2 (57→58) not taken.
✓ Branch 3 (57→59) taken 72 times.
|
72 | assert(!actualItemType.is(TY_DYN)); |
447 | |||
448 |
1/2✓ Branch 0 (59→60) taken 72 times.
✗ Branch 1 (59→97) not taken.
|
72 | const QualType arrayType = actualItemType.toArr(node, node->actualSize, true); |
449 |
2/4✓ Branch 0 (60→61) taken 72 times.
✗ Branch 1 (60→96) not taken.
✓ Branch 2 (61→62) taken 72 times.
✗ Branch 3 (61→96) not taken.
|
72 | return ExprResult{node->setEvaluatedSymbolType(arrayType, manIdx)}; |
450 | } | ||
451 | |||
452 | 284 | std::any TypeChecker::visitStructInstantiation(StructInstantiationNode *node) { | |
453 | // Retrieve struct name | ||
454 |
1/2✓ Branch 0 (2→3) taken 284 times.
✗ Branch 1 (2→264) not taken.
|
284 | const auto [aliasedEntry, isAlias] = rootScope->symbolTable.lookupWithAliasResolution(node->fqStructName); |
455 |
4/6✓ Branch 0 (5→6) taken 1 times.
✓ Branch 1 (5→9) taken 283 times.
✓ Branch 2 (6→7) taken 1 times.
✗ Branch 3 (6→264) not taken.
✓ Branch 4 (7→8) taken 1 times.
✗ Branch 5 (7→264) not taken.
|
284 | const std::string &structName = isAlias ? aliasedEntry->getQualType().getSubType() : node->fqStructName; |
456 | |||
457 | // Retrieve struct | ||
458 |
1/2✓ Branch 0 (10→11) taken 284 times.
✗ Branch 1 (10→264) not taken.
|
284 | const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(structName); |
459 |
2/2✓ Branch 0 (11→12) taken 1 times.
✓ Branch 1 (11→21) taken 283 times.
|
284 | if (!registryEntry) |
460 |
5/10✓ Branch 0 (12→13) taken 1 times.
✗ Branch 1 (12→195) not taken.
✓ Branch 2 (13→14) taken 1 times.
✗ Branch 3 (13→193) not taken.
✓ Branch 4 (14→15) taken 1 times.
✗ Branch 5 (14→191) not taken.
✓ Branch 6 (17→18) taken 1 times.
✗ Branch 7 (17→197) not taken.
✓ Branch 8 (18→19) taken 1 times.
✗ Branch 9 (18→197) not taken.
|
1 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_STRUCT, "Cannot find struct '" + structName + "'") |
461 |
2/4✓ Branch 0 (21→22) taken 283 times.
✗ Branch 1 (21→24) not taken.
✓ Branch 2 (22→23) taken 283 times.
✗ Branch 3 (22→24) not taken.
|
283 | assert(registryEntry->targetEntry != nullptr && registryEntry->targetScope != nullptr); |
462 | 283 | SymbolTableEntry *structEntry = registryEntry->targetEntry; | |
463 | |||
464 | // Check visibility | ||
465 |
9/12✓ Branch 0 (25→26) taken 283 times.
✗ Branch 1 (25→264) not taken.
✓ Branch 2 (26→27) taken 283 times.
✗ Branch 3 (26→264) not taken.
✓ Branch 4 (27→28) taken 58 times.
✓ Branch 5 (27→31) taken 225 times.
✓ Branch 6 (28→29) taken 58 times.
✗ Branch 7 (28→264) not taken.
✓ Branch 8 (29→30) taken 1 times.
✓ Branch 9 (29→31) taken 57 times.
✓ Branch 10 (32→33) taken 1 times.
✓ Branch 11 (32→42) taken 282 times.
|
283 | if (!structEntry->getQualType().isPublic() && structEntry->scope->isImportedBy(currentScope)) |
466 |
5/10✓ Branch 0 (33→34) taken 1 times.
✗ Branch 1 (33→202) not taken.
✓ Branch 2 (34→35) taken 1 times.
✗ Branch 3 (34→200) not taken.
✓ Branch 4 (35→36) taken 1 times.
✗ Branch 5 (35→198) not taken.
✓ Branch 6 (38→39) taken 1 times.
✗ Branch 7 (38→204) not taken.
✓ Branch 8 (39→40) taken 1 times.
✗ Branch 9 (39→204) not taken.
|
1 | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Struct '" + structName + "' has insufficient visibility") |
467 | |||
468 | // Get struct type | ||
469 |
1/2✓ Branch 0 (42→43) taken 282 times.
✗ Branch 1 (42→264) not taken.
|
282 | QualType structType = structEntry->getQualType(); |
470 | |||
471 | // Get the concrete template types | ||
472 | 282 | QualTypeList concreteTemplateTypes; | |
473 |
2/2✓ Branch 0 (43→44) taken 1 times.
✓ Branch 1 (43→63) taken 281 times.
|
282 | if (isAlias) { |
474 | // Retrieve concrete template types from type alias | ||
475 |
3/6✓ Branch 0 (44→45) taken 1 times.
✗ Branch 1 (44→262) not taken.
✓ Branch 2 (45→46) taken 1 times.
✗ Branch 3 (45→262) not taken.
✓ Branch 4 (46→47) taken 1 times.
✗ Branch 5 (46→262) not taken.
|
1 | concreteTemplateTypes = aliasedEntry->getQualType().getTemplateTypes(); |
476 | // Check if the aliased type specified template types and the struct instantiation does | ||
477 |
3/6✓ Branch 0 (48→49) taken 1 times.
✗ Branch 1 (48→51) not taken.
✗ Branch 2 (49→50) not taken.
✓ Branch 3 (49→51) taken 1 times.
✗ Branch 4 (52→53) not taken.
✓ Branch 5 (52→63) taken 1 times.
|
1 | if (!concreteTemplateTypes.empty() && node->templateTypeLst) |
478 | ✗ | SOFT_ERROR_ER(node->templateTypeLst, ALIAS_WITH_TEMPLATE_LIST, "The aliased type already has a template list") | |
479 | } | ||
480 | |||
481 |
2/2✓ Branch 0 (63→64) taken 15 times.
✓ Branch 1 (63→96) taken 267 times.
|
282 | if (node->templateTypeLst) { |
482 |
1/2✓ Branch 0 (65→66) taken 15 times.
✗ Branch 1 (65→262) not taken.
|
15 | concreteTemplateTypes.reserve(node->templateTypeLst->dataTypes.size()); |
483 |
2/2✓ Branch 0 (94→68) taken 23 times.
✓ Branch 1 (94→95) taken 15 times.
|
38 | for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) { |
484 |
2/4✓ Branch 0 (69→70) taken 23 times.
✗ Branch 1 (69→214) not taken.
✓ Branch 2 (70→71) taken 23 times.
✗ Branch 3 (70→212) not taken.
|
23 | auto concreteType = std::any_cast<QualType>(visit(dataType)); |
485 |
2/8✓ Branch 0 (72→73) taken 23 times.
✗ Branch 1 (72→223) not taken.
✗ Branch 2 (73→74) not taken.
✓ Branch 3 (73→78) taken 23 times.
✗ Branch 4 (74→75) not taken.
✗ Branch 5 (74→215) not taken.
✗ Branch 6 (75→76) not taken.
✗ Branch 7 (75→215) not taken.
|
23 | HANDLE_UNRESOLVED_TYPE_ER(concreteType) |
486 | // Check if generic type | ||
487 |
2/4✓ Branch 0 (78→79) taken 23 times.
✗ Branch 1 (78→223) not taken.
✗ Branch 2 (79→80) not taken.
✓ Branch 3 (79→90) taken 23 times.
|
23 | if (concreteType.is(TY_GENERIC)) |
488 | ✗ | SOFT_ERROR_ER(dataType, EXPECTED_NON_GENERIC_TYPE, "Struct instantiations may only take concrete template types") | |
489 |
1/2✓ Branch 0 (90→91) taken 23 times.
✗ Branch 1 (90→223) not taken.
|
23 | concreteTemplateTypes.push_back(concreteType); |
490 | } | ||
491 | } | ||
492 | |||
493 | // Get the struct instance | ||
494 |
2/4✓ Branch 0 (96→97) taken 282 times.
✗ Branch 1 (96→262) not taken.
✓ Branch 2 (97→98) taken 282 times.
✗ Branch 3 (97→262) not taken.
|
282 | Struct *spiceStruct = node->instantiatedStructs.at(manIdx) = structType.getStructAndAdjustType(node, concreteTemplateTypes); |
495 |
1/2✗ Branch 0 (98→99) not taken.
✓ Branch 1 (98→110) taken 282 times.
|
282 | if (!spiceStruct) |
496 | ✗ | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_STRUCT, "Struct '" + spiceStruct->getSignature() + "' could not be found") | |
497 | |||
498 | // Struct instantiation for an inheriting struct is forbidden, because the vtable needs to be initialized and this is done in | ||
499 | // the ctor of the struct, which is never called in case of struct instantiation | ||
500 |
2/2✓ Branch 0 (111→112) taken 1 times.
✓ Branch 1 (111→122) taken 281 times.
|
282 | if (!spiceStruct->interfaceTypes.empty()) |
501 |
4/8✓ Branch 0 (114→115) taken 1 times.
✗ Branch 1 (114→237) not taken.
✓ Branch 2 (115→116) taken 1 times.
✗ Branch 3 (115→235) not taken.
✓ Branch 4 (118→119) taken 1 times.
✗ Branch 5 (118→241) not taken.
✓ Branch 6 (119→120) taken 1 times.
✗ Branch 7 (119→241) not taken.
|
3 | SOFT_ERROR_ER(node, INVALID_STRUCT_INSTANTIATION, "Struct instantiations for inheriting structs are forbidden") |
502 | |||
503 | // Check if the number of fields matches | ||
504 |
2/2✓ Branch 0 (122→123) taken 267 times.
✓ Branch 1 (122→166) taken 14 times.
|
281 | if (node->fieldLst) { // Check if any fields are passed. Empty braces are also allowed |
505 |
2/2✓ Branch 0 (125→126) taken 1 times.
✓ Branch 1 (125→136) taken 266 times.
|
267 | if (spiceStruct->fieldTypes.size() != node->fieldLst->args.size()) |
506 |
4/8✓ Branch 0 (128→129) taken 1 times.
✗ Branch 1 (128→244) not taken.
✓ Branch 2 (129→130) taken 1 times.
✗ Branch 3 (129→242) not taken.
✓ Branch 4 (132→133) taken 1 times.
✗ Branch 5 (132→248) not taken.
✓ Branch 6 (133→134) taken 1 times.
✗ Branch 7 (133→248) not taken.
|
3 | SOFT_ERROR_ER(node->fieldLst, NUMBER_OF_FIELDS_NOT_MATCHING, |
507 | "You've passed too less/many field values. Pass either none or all of them") | ||
508 | |||
509 | // Check if the field types are matching | ||
510 | 266 | const size_t fieldCount = spiceStruct->fieldTypes.size(); | |
511 |
1/2✓ Branch 0 (137→138) taken 266 times.
✗ Branch 1 (137→262) not taken.
|
266 | const size_t explicitFieldsStartIdx = spiceStruct->scope->getFieldCount() - fieldCount; |
512 |
2/2✓ Branch 0 (165→139) taken 387 times.
✓ Branch 1 (165→178) taken 265 times.
|
652 | for (size_t i = 0; i < node->fieldLst->args.size(); i++) { |
513 | // Get actual type | ||
514 |
1/2✓ Branch 0 (139→140) taken 387 times.
✗ Branch 1 (139→253) not taken.
|
387 | AssignExprNode *assignExpr = node->fieldLst->args.at(i); |
515 |
2/4✓ Branch 0 (140→141) taken 387 times.
✗ Branch 1 (140→251) not taken.
✓ Branch 2 (141→142) taken 387 times.
✗ Branch 3 (141→249) not taken.
|
387 | auto fieldResult = std::any_cast<ExprResult>(visit(assignExpr)); |
516 |
2/8✓ Branch 0 (143→144) taken 387 times.
✗ Branch 1 (143→253) not taken.
✗ Branch 2 (144→145) not taken.
✓ Branch 3 (144→149) taken 387 times.
✗ Branch 4 (145→146) not taken.
✗ Branch 5 (145→252) not taken.
✗ Branch 6 (146→147) not taken.
✗ Branch 7 (146→252) not taken.
|
387 | HANDLE_UNRESOLVED_TYPE_ER(fieldResult.type) |
517 | // Get expected type | ||
518 |
1/2✗ Branch 0 (149→150) not taken.
✓ Branch 1 (149→151) taken 387 times.
|
387 | SymbolTableEntry *expectedField = spiceStruct->scope->lookupField(explicitFieldsStartIdx + i); |
519 |
1/2✗ Branch 0 (154→155) not taken.
✓ Branch 1 (154→156) taken 387 times.
|
387 | assert(expectedField != nullptr); |
520 |
1/2✓ Branch 0 (156→157) taken 387 times.
✗ Branch 1 (156→253) not taken.
|
387 | const ExprResult expected = {expectedField->getQualType(), expectedField}; |
521 |
1/2✓ Branch 0 (157→158) taken 387 times.
✗ Branch 1 (157→253) not taken.
|
387 | const bool rhsIsImmediate = assignExpr->hasCompileTimeValue(); |
522 | |||
523 | // Check if actual type matches expected type | ||
524 |
2/2✓ Branch 0 (158→159) taken 386 times.
✓ Branch 1 (158→253) taken 1 times.
|
387 | (void)opRuleManager.getFieldAssignResultType(assignExpr, expected, fieldResult, rhsIsImmediate, true); |
525 | |||
526 | // If there is an anonymous entry attached (e.g. for struct instantiation), delete it | ||
527 |
4/4✓ Branch 0 (159→160) taken 99 times.
✓ Branch 1 (159→163) taken 287 times.
✓ Branch 2 (160→161) taken 3 times.
✓ Branch 3 (160→163) taken 96 times.
|
386 | if (fieldResult.entry != nullptr && fieldResult.entry->anonymous) { |
528 |
1/2✓ Branch 0 (161→162) taken 3 times.
✗ Branch 1 (161→253) not taken.
|
3 | currentScope->symbolTable.deleteAnonymous(fieldResult.entry->name); |
529 | 3 | fieldResult.entry = nullptr; | |
530 | } | ||
531 | } | ||
532 | } else { | ||
533 |
2/4✓ Branch 0 (166→167) taken 14 times.
✗ Branch 1 (166→262) not taken.
✗ Branch 2 (167→168) not taken.
✓ Branch 3 (167→178) taken 14 times.
|
57 | if (std::ranges::any_of(spiceStruct->fieldTypes, [](const QualType &fieldType) { return fieldType.isRef(); })) |
534 | ✗ | SOFT_ERROR_ER(node, REFERENCE_WITHOUT_INITIALIZER, | |
535 | "The struct takes at least one reference field. You need to instantiate it with all fields.") | ||
536 | } | ||
537 | |||
538 | // Update type of struct entry | ||
539 |
1/2✓ Branch 0 (178→179) taken 279 times.
✗ Branch 1 (178→262) not taken.
|
279 | structEntry->updateType(structType, true); |
540 | |||
541 | // Add anonymous symbol to keep track of dtor call, if non-trivially destructible | ||
542 | 279 | SymbolTableEntry *anonymousEntry = nullptr; | |
543 |
3/4✓ Branch 0 (179→180) taken 279 times.
✗ Branch 1 (179→262) not taken.
✓ Branch 2 (180→181) taken 21 times.
✓ Branch 3 (180→183) taken 258 times.
|
279 | if (!structType.isTriviallyDestructible(node)) |
544 |
1/2✓ Branch 0 (181→182) taken 21 times.
✗ Branch 1 (181→262) not taken.
|
21 | anonymousEntry = currentScope->symbolTable.insertAnonymous(structType, node); |
545 | |||
546 | // Remove public qualifier to not have public local variables | ||
547 | 279 | structType.getQualifiers().isPublic = false; | |
548 | |||
549 |
2/4✓ Branch 0 (184→185) taken 279 times.
✗ Branch 1 (184→261) not taken.
✓ Branch 2 (185→186) taken 279 times.
✗ Branch 3 (185→261) not taken.
|
279 | return ExprResult{node->setEvaluatedSymbolType(structType, manIdx), anonymousEntry}; |
550 | 282 | } | |
551 | |||
552 | 12 | std::any TypeChecker::visitLambdaFunc(LambdaFuncNode *node) { | |
553 | // Check if all control paths in the lambda body return | ||
554 | 12 | bool returnsOnAllControlPaths = true; | |
555 |
3/4✓ Branch 0 (2→3) taken 12 times.
✗ Branch 1 (2→186) not taken.
✓ Branch 2 (3→4) taken 1 times.
✓ Branch 3 (3→14) taken 11 times.
|
12 | if (!node->returnsOnAllControlPaths(&returnsOnAllControlPaths)) |
556 |
4/8✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→112) not taken.
✓ Branch 2 (7→8) taken 1 times.
✗ Branch 3 (7→110) not taken.
✓ Branch 4 (10→11) taken 1 times.
✗ Branch 5 (10→116) not taken.
✓ Branch 6 (11→12) taken 1 times.
✗ Branch 7 (11→116) not taken.
|
3 | SOFT_ERROR_ER(node, MISSING_RETURN_STMT, "Not all control paths of this lambda function have a return statement") |
557 | |||
558 | // Change to function scope | ||
559 |
2/4✓ Branch 0 (14→15) taken 11 times.
✗ Branch 1 (14→119) not taken.
✓ Branch 2 (15→16) taken 11 times.
✗ Branch 3 (15→117) not taken.
|
11 | Scope *bodyScope = currentScope->getChildScope(node->getScopeId()); |
560 |
1/2✓ Branch 0 (17→18) taken 11 times.
✗ Branch 1 (17→120) not taken.
|
11 | ScopeHandle scopeHandle(this, bodyScope, ScopeType::LAMBDA_BODY); |
561 | |||
562 | // Visit return type | ||
563 |
2/4✓ Branch 0 (18→19) taken 11 times.
✗ Branch 1 (18→123) not taken.
✓ Branch 2 (19→20) taken 11 times.
✗ Branch 3 (19→121) not taken.
|
11 | const auto returnType = std::any_cast<QualType>(visit(node->returnType)); |
564 |
2/8✓ Branch 0 (21→22) taken 11 times.
✗ Branch 1 (21→184) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 11 times.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→124) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→124) not taken.
|
11 | HANDLE_UNRESOLVED_TYPE_ER(returnType) |
565 |
3/4✓ Branch 0 (27→28) taken 11 times.
✗ Branch 1 (27→184) not taken.
✓ Branch 2 (28→29) taken 1 times.
✓ Branch 3 (28→39) taken 10 times.
|
11 | if (returnType.is(TY_DYN)) |
566 |
4/8✓ Branch 0 (31→32) taken 1 times.
✗ Branch 1 (31→127) not taken.
✓ Branch 2 (32→33) taken 1 times.
✗ Branch 3 (32→125) not taken.
✓ Branch 4 (35→36) taken 1 times.
✗ Branch 5 (35→131) not taken.
✓ Branch 6 (36→37) taken 1 times.
✗ Branch 7 (36→131) not taken.
|
3 | SOFT_ERROR_ER(node, UNEXPECTED_DYN_TYPE, "Dyn return types are not allowed") |
567 | |||
568 | // Set the type of the result variable | ||
569 |
1/2✓ Branch 0 (41→42) taken 10 times.
✗ Branch 1 (41→134) not taken.
|
30 | SymbolTableEntry *resultVarEntry = currentScope->lookupStrict(RETURN_VARIABLE_NAME); |
570 |
1/2✗ Branch 0 (47→48) not taken.
✓ Branch 1 (47→49) taken 10 times.
|
10 | assert(resultVarEntry != nullptr); |
571 |
1/2✓ Branch 0 (49→50) taken 10 times.
✗ Branch 1 (49→184) not taken.
|
10 | resultVarEntry->updateType(returnType, true); |
572 | 10 | resultVarEntry->used = true; | |
573 | |||
574 | // Visit parameters | ||
575 | 10 | QualTypeList paramTypes; | |
576 | 10 | ParamList paramList; | |
577 |
2/2✓ Branch 0 (50→51) taken 6 times.
✓ Branch 1 (50→72) taken 4 times.
|
10 | if (node->hasParams) { |
578 | // Visit param list to retrieve the param names | ||
579 |
2/4✓ Branch 0 (51→52) taken 6 times.
✗ Branch 1 (51→140) not taken.
✓ Branch 2 (52→53) taken 6 times.
✗ Branch 3 (52→138) not taken.
|
6 | auto namedParamList = std::any_cast<NamedParamList>(visit(node->paramLst)); |
580 |
2/2✓ Branch 0 (69→56) taken 10 times.
✓ Branch 1 (69→70) taken 6 times.
|
16 | for (const auto &[name, qualType, isOptional] : namedParamList) { |
581 |
1/2✗ Branch 0 (57→58) not taken.
✓ Branch 1 (57→65) taken 10 times.
|
10 | if (isOptional) |
582 | ✗ | softError(node, LAMBDA_WITH_OPTIONAL_PARAMS, "Lambdas cannot have optional parameters"); | |
583 | |||
584 |
1/2✓ Branch 0 (65→66) taken 10 times.
✗ Branch 1 (65→148) not taken.
|
10 | paramTypes.push_back(qualType); |
585 |
1/2✓ Branch 0 (66→67) taken 10 times.
✗ Branch 1 (66→147) not taken.
|
10 | paramList.push_back({qualType, isOptional}); |
586 | } | ||
587 | 6 | } | |
588 | |||
589 | // Visit lambda body | ||
590 |
2/2✓ Branch 0 (72→73) taken 9 times.
✓ Branch 1 (72→152) taken 1 times.
|
10 | visit(node->body); |
591 | |||
592 | // Leave function body scope | ||
593 |
1/2✓ Branch 0 (74→75) taken 9 times.
✗ Branch 1 (74→180) not taken.
|
9 | scopeHandle.leaveScopeEarly(); |
594 | |||
595 | // Prepare type of function | ||
596 |
1/2✓ Branch 0 (75→76) taken 9 times.
✗ Branch 1 (75→153) not taken.
|
9 | const QualType functionType = QualType(TY_FUNCTION) |
597 |
1/2✓ Branch 0 (76→77) taken 9 times.
✗ Branch 1 (76→153) not taken.
|
9 | .getWithFunctionParamAndReturnTypes(returnType, paramTypes) |
598 |
1/2✓ Branch 0 (78→79) taken 9 times.
✗ Branch 1 (78→153) not taken.
|
9 | .getWithLambdaCaptures(!bodyScope->symbolTable.captures.empty()); |
599 | |||
600 | // Create function object | ||
601 |
2/4✓ Branch 0 (79→80) taken 9 times.
✗ Branch 1 (79→157) not taken.
✓ Branch 2 (80→81) taken 9 times.
✗ Branch 3 (80→155) not taken.
|
9 | const std::string fctName = "lambda." + node->codeLoc.toPrettyLineAndColumn(); |
602 |
4/8✓ Branch 0 (83→84) taken 9 times.
✗ Branch 1 (83→166) not taken.
✓ Branch 2 (84→85) taken 9 times.
✗ Branch 3 (84→163) not taken.
✓ Branch 4 (85→86) taken 9 times.
✗ Branch 5 (85→162) not taken.
✓ Branch 6 (87→88) taken 9 times.
✗ Branch 7 (87→158) not taken.
|
9 | node->manifestations.at(manIdx) = Function(fctName, nullptr, QualType(TY_DYN), returnType, paramList, {}, node); |
603 |
1/2✓ Branch 0 (93→94) taken 9 times.
✗ Branch 1 (93→178) not taken.
|
9 | node->manifestations.at(manIdx).bodyScope = bodyScope; |
604 |
3/6✓ Branch 0 (94→95) taken 9 times.
✗ Branch 1 (94→175) not taken.
✓ Branch 2 (95→96) taken 9 times.
✗ Branch 3 (95→173) not taken.
✓ Branch 4 (96→97) taken 9 times.
✗ Branch 5 (96→171) not taken.
|
9 | node->manifestations.at(manIdx).mangleSuffix = "." + std::to_string(manIdx); |
605 | |||
606 | // Check special requirements if this is an async lambda | ||
607 |
1/2✓ Branch 0 (100→101) taken 9 times.
✗ Branch 1 (100→178) not taken.
|
9 | (void)checkAsyncLambdaCaptureRules(node, node->lambdaAttr); |
608 | |||
609 |
2/4✓ Branch 0 (101→102) taken 9 times.
✗ Branch 1 (101→177) not taken.
✓ Branch 2 (102→103) taken 9 times.
✗ Branch 3 (102→177) not taken.
|
9 | return ExprResult{node->setEvaluatedSymbolType(functionType, manIdx)}; |
610 | 13 | } | |
611 | |||
612 | 28 | std::any TypeChecker::visitLambdaProc(LambdaProcNode *node) { | |
613 | // Mark unreachable statements | ||
614 | 28 | bool doSetPredecessorsUnreachable = true; | |
615 |
1/2✓ Branch 0 (2→3) taken 28 times.
✗ Branch 1 (2→123) not taken.
|
28 | node->returnsOnAllControlPaths(&doSetPredecessorsUnreachable); |
616 | |||
617 | // Change to function scope | ||
618 |
2/4✓ Branch 0 (3→4) taken 28 times.
✗ Branch 1 (3→71) not taken.
✓ Branch 2 (4→5) taken 28 times.
✗ Branch 3 (4→69) not taken.
|
28 | Scope *bodyScope = currentScope->getChildScope(node->getScopeId()); |
619 |
1/2✓ Branch 0 (6→7) taken 28 times.
✗ Branch 1 (6→72) not taken.
|
28 | ScopeHandle scopeHandle(this, bodyScope, ScopeType::LAMBDA_BODY); |
620 | |||
621 | // Visit parameters | ||
622 | 28 | QualTypeList paramTypes; | |
623 | 28 | ParamList paramList; | |
624 |
2/2✓ Branch 0 (7→8) taken 7 times.
✓ Branch 1 (7→29) taken 21 times.
|
28 | if (node->hasParams) { |
625 | // Visit param list to retrieve the param names | ||
626 |
2/4✓ Branch 0 (8→9) taken 7 times.
✗ Branch 1 (8→75) not taken.
✓ Branch 2 (9→10) taken 7 times.
✗ Branch 3 (9→73) not taken.
|
7 | auto namedParamList = std::any_cast<NamedParamList>(visit(node->paramLst)); |
627 |
2/2✓ Branch 0 (26→13) taken 11 times.
✓ Branch 1 (26→27) taken 7 times.
|
18 | for (const auto &[_, qualType, isOptional] : namedParamList) { |
628 |
2/2✓ Branch 0 (14→15) taken 1 times.
✓ Branch 1 (14→22) taken 10 times.
|
11 | if (isOptional) |
629 |
2/4✓ Branch 0 (17→18) taken 1 times.
✗ Branch 1 (17→78) not taken.
✓ Branch 2 (18→19) taken 1 times.
✗ Branch 3 (18→76) not taken.
|
2 | softError(node, LAMBDA_WITH_OPTIONAL_PARAMS, "Lambdas cannot have optional parameters"); |
630 | |||
631 |
1/2✓ Branch 0 (22→23) taken 11 times.
✗ Branch 1 (22→83) not taken.
|
11 | paramTypes.push_back(qualType); |
632 |
1/2✓ Branch 0 (23→24) taken 11 times.
✗ Branch 1 (23→82) not taken.
|
11 | paramList.push_back({qualType, isOptional}); |
633 | } | ||
634 | 7 | } | |
635 | |||
636 | // Visit lambda body | ||
637 |
1/2✓ Branch 0 (29→30) taken 28 times.
✗ Branch 1 (29→87) not taken.
|
28 | visit(node->body); |
638 | |||
639 | // Leave function body scope | ||
640 |
1/2✓ Branch 0 (31→32) taken 28 times.
✗ Branch 1 (31→117) not taken.
|
28 | scopeHandle.leaveScopeEarly(); |
641 | |||
642 | // Prepare type of function | ||
643 |
1/2✓ Branch 0 (32→33) taken 28 times.
✗ Branch 1 (32→89) not taken.
|
28 | const QualType functionType = QualType(TY_PROCEDURE) |
644 |
2/4✓ Branch 0 (33→34) taken 28 times.
✗ Branch 1 (33→88) not taken.
✓ Branch 2 (34→35) taken 28 times.
✗ Branch 3 (34→88) not taken.
|
28 | .getWithFunctionParamAndReturnTypes(QualType(TY_DYN), paramTypes) |
645 |
1/2✓ Branch 0 (36→37) taken 28 times.
✗ Branch 1 (36→88) not taken.
|
28 | .getWithLambdaCaptures(!bodyScope->symbolTable.captures.empty()); |
646 | |||
647 | // Create function object | ||
648 |
2/4✓ Branch 0 (37→38) taken 28 times.
✗ Branch 1 (37→93) not taken.
✓ Branch 2 (38→39) taken 28 times.
✗ Branch 3 (38→91) not taken.
|
28 | const std::string fctName = "lambda." + node->codeLoc.toPrettyLineAndColumn(); |
649 |
5/10✓ Branch 0 (41→42) taken 28 times.
✗ Branch 1 (41→103) not taken.
✓ Branch 2 (42→43) taken 28 times.
✗ Branch 3 (42→100) not taken.
✓ Branch 4 (43→44) taken 28 times.
✗ Branch 5 (43→99) not taken.
✓ Branch 6 (44→45) taken 28 times.
✗ Branch 7 (44→98) not taken.
✓ Branch 8 (46→47) taken 28 times.
✗ Branch 9 (46→94) not taken.
|
28 | node->manifestations.at(manIdx) = Function(fctName, nullptr, QualType(TY_DYN), QualType(TY_DYN), paramList, {}, node); |
650 |
1/2✓ Branch 0 (52→53) taken 28 times.
✗ Branch 1 (52→115) not taken.
|
28 | node->manifestations.at(manIdx).bodyScope = bodyScope; |
651 |
3/6✓ Branch 0 (53→54) taken 28 times.
✗ Branch 1 (53→112) not taken.
✓ Branch 2 (54→55) taken 28 times.
✗ Branch 3 (54→110) not taken.
✓ Branch 4 (55→56) taken 28 times.
✗ Branch 5 (55→108) not taken.
|
28 | node->manifestations.at(manIdx).mangleSuffix = "." + std::to_string(manIdx); |
652 | |||
653 | // Check special requirements if this is an async lambda | ||
654 |
1/2✓ Branch 0 (59→60) taken 28 times.
✗ Branch 1 (59→115) not taken.
|
28 | (void)checkAsyncLambdaCaptureRules(node, node->lambdaAttr); |
655 | |||
656 |
2/4✓ Branch 0 (60→61) taken 28 times.
✗ Branch 1 (60→114) not taken.
✓ Branch 2 (61→62) taken 28 times.
✗ Branch 3 (61→114) not taken.
|
56 | return ExprResult{node->setEvaluatedSymbolType(functionType, manIdx)}; |
657 | 28 | } | |
658 | |||
659 | 1 | std::any TypeChecker::visitLambdaExpr(LambdaExprNode *node) { | |
660 | // Change to function scope | ||
661 |
2/4✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→90) not taken.
✓ Branch 2 (3→4) taken 1 times.
✗ Branch 3 (3→88) not taken.
|
1 | Scope *bodyScope = currentScope->getChildScope(node->getScopeId()); |
662 |
1/2✓ Branch 0 (5→6) taken 1 times.
✗ Branch 1 (5→91) not taken.
|
1 | ScopeHandle scopeHandle(this, bodyScope, ScopeType::LAMBDA_BODY); |
663 | |||
664 | // Visit parameters | ||
665 | 1 | QualTypeList paramTypes; | |
666 | 1 | ParamList paramList; | |
667 |
1/2✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→28) not taken.
|
1 | if (node->hasParams) { |
668 | // Visit param list to retrieve the param names | ||
669 |
2/4✓ Branch 0 (7→8) taken 1 times.
✗ Branch 1 (7→94) not taken.
✓ Branch 2 (8→9) taken 1 times.
✗ Branch 3 (8→92) not taken.
|
1 | auto namedParamList = std::any_cast<NamedParamList>(visit(node->paramLst)); |
670 |
2/2✓ Branch 0 (25→12) taken 2 times.
✓ Branch 1 (25→26) taken 1 times.
|
3 | for (const NamedParam ¶m : namedParamList) { |
671 |
1/2✗ Branch 0 (13→14) not taken.
✓ Branch 1 (13→21) taken 2 times.
|
2 | if (param.isOptional) |
672 | ✗ | softError(node, LAMBDA_WITH_OPTIONAL_PARAMS, "Lambdas cannot have optional parameters"); | |
673 | |||
674 |
1/2✓ Branch 0 (21→22) taken 2 times.
✗ Branch 1 (21→102) not taken.
|
2 | paramTypes.push_back(param.qualType); |
675 |
1/2✓ Branch 0 (22→23) taken 2 times.
✗ Branch 1 (22→101) not taken.
|
2 | paramList.push_back({param.qualType, param.isOptional}); |
676 | } | ||
677 | 1 | } | |
678 | |||
679 | // Visit lambda expression | ||
680 |
2/4✓ Branch 0 (28→29) taken 1 times.
✗ Branch 1 (28→108) not taken.
✓ Branch 2 (29→30) taken 1 times.
✗ Branch 3 (29→106) not taken.
|
1 | const QualType returnType = std::any_cast<ExprResult>(visit(node->lambdaExpr)).type; |
681 |
2/8✓ Branch 0 (31→32) taken 1 times.
✗ Branch 1 (31→145) not taken.
✗ Branch 2 (32→33) not taken.
✓ Branch 3 (32→37) taken 1 times.
✗ Branch 4 (33→34) not taken.
✗ Branch 5 (33→110) not taken.
✗ Branch 6 (34→35) not taken.
✗ Branch 7 (34→110) not taken.
|
1 | HANDLE_UNRESOLVED_TYPE_ER(returnType) |
682 |
2/4✓ Branch 0 (37→38) taken 1 times.
✗ Branch 1 (37→145) not taken.
✗ Branch 2 (38→39) not taken.
✓ Branch 3 (38→49) taken 1 times.
|
1 | if (returnType.is(TY_DYN)) |
683 | ✗ | SOFT_ERROR_ER(node, UNEXPECTED_DYN_TYPE, "Dyn return types are not allowed") | |
684 | |||
685 | // Leave function body scope | ||
686 |
1/2✓ Branch 0 (49→50) taken 1 times.
✗ Branch 1 (49→145) not taken.
|
1 | scopeHandle.leaveScopeEarly(); |
687 | |||
688 | // Prepare type of function | ||
689 |
2/4✓ Branch 0 (50→51) taken 1 times.
✗ Branch 1 (50→145) not taken.
✗ Branch 2 (51→52) not taken.
✓ Branch 3 (51→53) taken 1 times.
|
1 | const SuperType superType = returnType.is(TY_DYN) ? TY_PROCEDURE : TY_FUNCTION; |
690 |
1/2✓ Branch 0 (54→55) taken 1 times.
✗ Branch 1 (54→118) not taken.
|
1 | const QualType functionType = QualType(superType) |
691 |
1/2✓ Branch 0 (55→56) taken 1 times.
✗ Branch 1 (55→118) not taken.
|
1 | .getWithFunctionParamAndReturnTypes(returnType, paramTypes) |
692 |
1/2✓ Branch 0 (57→58) taken 1 times.
✗ Branch 1 (57→118) not taken.
|
1 | .getWithLambdaCaptures(!bodyScope->symbolTable.captures.empty()); |
693 | |||
694 | // Create function object | ||
695 |
2/4✓ Branch 0 (58→59) taken 1 times.
✗ Branch 1 (58→122) not taken.
✓ Branch 2 (59→60) taken 1 times.
✗ Branch 3 (59→120) not taken.
|
1 | const std::string fctName = "lambda." + node->codeLoc.toPrettyLineAndColumn(); |
696 |
4/8✓ Branch 0 (62→63) taken 1 times.
✗ Branch 1 (62→131) not taken.
✓ Branch 2 (63→64) taken 1 times.
✗ Branch 3 (63→128) not taken.
✓ Branch 4 (64→65) taken 1 times.
✗ Branch 5 (64→127) not taken.
✓ Branch 6 (66→67) taken 1 times.
✗ Branch 7 (66→123) not taken.
|
1 | node->manifestations.at(manIdx) = Function(fctName, nullptr, QualType(TY_DYN), returnType, paramList, {}, node); |
697 |
1/2✓ Branch 0 (72→73) taken 1 times.
✗ Branch 1 (72→143) not taken.
|
1 | node->manifestations.at(manIdx).bodyScope = bodyScope; |
698 |
3/6✓ Branch 0 (73→74) taken 1 times.
✗ Branch 1 (73→140) not taken.
✓ Branch 2 (74→75) taken 1 times.
✗ Branch 3 (74→138) not taken.
✓ Branch 4 (75→76) taken 1 times.
✗ Branch 5 (75→136) not taken.
|
1 | node->manifestations.at(manIdx).mangleSuffix = "." + std::to_string(manIdx); |
699 | |||
700 |
2/4✓ Branch 0 (79→80) taken 1 times.
✗ Branch 1 (79→142) not taken.
✓ Branch 2 (80→81) taken 1 times.
✗ Branch 3 (80→142) not taken.
|
1 | return ExprResult{node->setEvaluatedSymbolType(functionType, manIdx)}; |
701 | 1 | } | |
702 | |||
703 | } // namespace spice::compiler | ||
704 |