Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
2 | |||
3 | #include "Type.h" | ||
4 | |||
5 | #include <utility> | ||
6 | |||
7 | #include <SourceFile.h> | ||
8 | #include <ast/Attributes.h> | ||
9 | #include <exception/CompilerError.h> | ||
10 | #include <exception/SemanticError.h> | ||
11 | #include <global/TypeRegistry.h> | ||
12 | #include <irgenerator/NameMangling.h> | ||
13 | #include <model/Struct.h> | ||
14 | #include <symboltablebuilder/Scope.h> | ||
15 | #include <symboltablebuilder/SymbolTableEntry.h> | ||
16 | |||
17 | #include <llvm/IR/Module.h> | ||
18 | #include <llvm/IR/Type.h> | ||
19 | |||
20 | namespace spice::compiler { | ||
21 | |||
22 |
3/10✓ Branch 0 (5→6) taken 3752991 times.
✗ Branch 1 (5→11) not taken.
✓ Branch 2 (7→8) taken 3752991 times.
✓ Branch 3 (7→9) taken 3752991 times.
✗ Branch 4 (12→13) not taken.
✗ Branch 5 (12→14) not taken.
✗ Branch 6 (15→16) not taken.
✗ Branch 7 (15→19) not taken.
✗ Branch 8 (17→18) not taken.
✗ Branch 9 (17→19) not taken.
|
11258973 | Type::Type(SuperType superType) : typeChain({TypeChainElement{superType}}) {} |
23 | |||
24 |
4/12✓ Branch 0 (4→5) taken 1397 times.
✗ Branch 1 (4→19) not taken.
✓ Branch 2 (6→7) taken 1397 times.
✗ Branch 3 (6→13) not taken.
✓ Branch 4 (8→9) taken 1397 times.
✓ Branch 5 (8→10) taken 1397 times.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→16) not taken.
✗ Branch 8 (20→21) not taken.
✗ Branch 9 (20→24) not taken.
✗ Branch 10 (22→23) not taken.
✗ Branch 11 (22→24) not taken.
|
4191 | Type::Type(SuperType superType, const std::string &subType) : typeChain({TypeChainElement{superType, subType}}) {} |
25 | |||
26 | 944 | Type::Type(SuperType superType, const std::string &subType, uint64_t typeId, const TypeChainElementData &data, | |
27 | 944 | const QualTypeList &templateTypes) | |
28 |
5/14✓ Branch 0 (4→5) taken 944 times.
✗ Branch 1 (4→24) not taken.
✓ Branch 2 (5→6) taken 944 times.
✗ Branch 3 (5→21) not taken.
✓ Branch 4 (7→8) taken 944 times.
✗ Branch 5 (7→15) not taken.
✓ Branch 6 (9→10) taken 944 times.
✓ Branch 7 (9→11) taken 944 times.
✗ Branch 8 (16→17) not taken.
✗ Branch 9 (16→18) not taken.
✗ Branch 10 (25→26) not taken.
✗ Branch 11 (25→29) not taken.
✗ Branch 12 (27→28) not taken.
✗ Branch 13 (27→29) not taken.
|
2832 | : typeChain({TypeChainElement(superType, subType, typeId, data, templateTypes)}) {} |
29 | |||
30 | 1047468 | Type::Type(TypeChain typeChain) : typeChain(std::move(typeChain)) {} | |
31 | |||
32 | /** | ||
33 | * Get the super type of the current type | ||
34 | * | ||
35 | * @return Super type | ||
36 | */ | ||
37 | 7069307 | SuperType Type::getSuperType() const { | |
38 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 7069307 times.
|
7069307 | assert(!typeChain.empty()); |
39 | 7069307 | return typeChain.back().superType; | |
40 | } | ||
41 | |||
42 | /** | ||
43 | * Get the sub type of the current type | ||
44 | * | ||
45 | * @return Sub type | ||
46 | */ | ||
47 | 169170 | const std::string &Type::getSubType() const { | |
48 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 169170 times.
|
169170 | assert(!typeChain.empty()); |
49 |
2/4✓ Branch 0 (5→6) taken 169170 times.
✗ Branch 1 (5→11) not taken.
✗ Branch 2 (6→7) not taken.
✓ Branch 3 (6→8) taken 169170 times.
|
169170 | assert(isOneOf({TY_STRUCT, TY_INTERFACE, TY_ENUM, TY_GENERIC})); |
50 | 169170 | return typeChain.back().subType; | |
51 | } | ||
52 | |||
53 | /** | ||
54 | * Get the array size of the current type | ||
55 | * | ||
56 | * @return Array size | ||
57 | */ | ||
58 | 518 | unsigned int Type::getArraySize() const { | |
59 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 518 times.
|
518 | assert(isArray()); |
60 | 518 | return typeChain.back().data.arraySize; | |
61 | } | ||
62 | |||
63 | /** | ||
64 | * Get the body scope of the current type | ||
65 | * | ||
66 | * @return Body scope | ||
67 | */ | ||
68 | 124384 | Scope *Type::getBodyScope() const { | |
69 |
2/4✓ Branch 0 (2→3) taken 124384 times.
✗ Branch 1 (2→8) not taken.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 124384 times.
|
124384 | assert(isOneOf({TY_STRUCT, TY_INTERFACE})); |
70 | 124384 | return typeChain.back().data.bodyScope; | |
71 | } | ||
72 | |||
73 | /** | ||
74 | * Get the pointer type of the current type as a new type | ||
75 | * | ||
76 | * @param node AST node for error messages | ||
77 | * @return Pointer type of the current type | ||
78 | */ | ||
79 | 12270 | const Type *Type::toPtr(const ASTNode *node) const { | |
80 | // Do not allow pointers of dyn | ||
81 |
2/2✓ Branch 0 (3→4) taken 2 times.
✓ Branch 1 (3→12) taken 12268 times.
|
12270 | if (is(TY_DYN)) |
82 |
2/4✓ Branch 0 (7→8) taken 2 times.
✗ Branch 1 (7→32) not taken.
✓ Branch 2 (8→9) taken 2 times.
✗ Branch 3 (8→29) not taken.
|
6 | throw SemanticError(node, DYN_POINTERS_NOT_ALLOWED, "Just use the dyn type without '*' instead"); |
83 |
1/2✗ Branch 0 (13→14) not taken.
✓ Branch 1 (13→22) taken 12268 times.
|
12268 | if (isRef()) |
84 | ✗ | throw SemanticError(node, REF_POINTERS_ARE_NOT_ALLOWED, "Pointers to references are not allowed. Use pointer instead"); | |
85 | |||
86 | // Create new type chain | ||
87 |
1/2✓ Branch 0 (22→23) taken 12268 times.
✗ Branch 1 (22→50) not taken.
|
12268 | TypeChain newTypeChain = typeChain; |
88 |
1/2✓ Branch 0 (23→24) taken 12268 times.
✗ Branch 1 (23→47) not taken.
|
12268 | newTypeChain.emplace_back(TY_PTR); |
89 | |||
90 | // Register new type or return if already registered | ||
91 |
1/2✓ Branch 0 (24→25) taken 12268 times.
✗ Branch 1 (24→48) not taken.
|
24536 | return TypeRegistry::getOrInsert(newTypeChain); |
92 | 12268 | } | |
93 | |||
94 | /** | ||
95 | * Get the reference type of the current type as a new type | ||
96 | * | ||
97 | * @param node AST node for error messages | ||
98 | * @return Reference type of the current type | ||
99 | */ | ||
100 | 10310 | const Type *Type::toRef(const ASTNode *node) const { | |
101 | // Do not allow references of dyn | ||
102 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→12) taken 10310 times.
|
10310 | if (is(TY_DYN)) |
103 | ✗ | throw SemanticError(node, DYN_REFERENCES_NOT_ALLOWED, "Just use the dyn type without '&' instead"); | |
104 | // Do not allow references of references | ||
105 |
1/2✗ Branch 0 (13→14) not taken.
✓ Branch 1 (13→22) taken 10310 times.
|
10310 | if (isRef()) |
106 | ✗ | throw SemanticError(node, MULTI_REF_NOT_ALLOWED, "References to references are not allowed"); | |
107 | |||
108 | // Create new type chain | ||
109 |
1/2✓ Branch 0 (22→23) taken 10310 times.
✗ Branch 1 (22→50) not taken.
|
10310 | TypeChain newTypeChain = typeChain; |
110 |
1/2✓ Branch 0 (23→24) taken 10310 times.
✗ Branch 1 (23→47) not taken.
|
10310 | newTypeChain.emplace_back(TY_REF); |
111 | |||
112 | // Register new type or return if already registered | ||
113 |
1/2✓ Branch 0 (24→25) taken 10310 times.
✗ Branch 1 (24→48) not taken.
|
20620 | return TypeRegistry::getOrInsert(newTypeChain); |
114 | 10310 | } | |
115 | |||
116 | /** | ||
117 | * Get the array type of the current type as a new type | ||
118 | * | ||
119 | * @param node AST node for error messages | ||
120 | * @param size Size of the array | ||
121 | * @param skipDynCheck Skip check if array base type is dyn | ||
122 | * @return Array type of the current type | ||
123 | */ | ||
124 | 199 | const Type *Type::toArr(const ASTNode *node, unsigned int size, bool skipDynCheck) const { | |
125 | // Do not allow arrays of dyn | ||
126 |
6/6✓ Branch 0 (2→3) taken 135 times.
✓ Branch 1 (2→6) taken 64 times.
✓ Branch 2 (4→5) taken 1 times.
✓ Branch 3 (4→6) taken 134 times.
✓ Branch 4 (7→8) taken 1 times.
✓ Branch 5 (7→16) taken 198 times.
|
199 | if (!skipDynCheck && typeChain.back().superType == TY_DYN) |
127 |
2/4✓ Branch 0 (11→12) taken 1 times.
✗ Branch 1 (11→26) not taken.
✓ Branch 2 (12→13) taken 1 times.
✗ Branch 3 (12→23) not taken.
|
3 | throw SemanticError(node, DYN_ARRAYS_NOT_ALLOWED, "Just use the dyn type without '[]' instead"); |
128 | |||
129 | // Create new type chain | ||
130 |
1/2✓ Branch 0 (16→17) taken 198 times.
✗ Branch 1 (16→36) not taken.
|
198 | TypeChain newTypeChain = typeChain; |
131 |
1/2✓ Branch 0 (17→18) taken 198 times.
✗ Branch 1 (17→32) not taken.
|
198 | newTypeChain.emplace_back(TY_ARRAY, TypeChainElementData{.arraySize = size}); |
132 | |||
133 | // Register new type or return if already registered | ||
134 |
1/2✓ Branch 0 (18→19) taken 198 times.
✗ Branch 1 (18→34) not taken.
|
396 | return TypeRegistry::getOrInsert(newTypeChain); |
135 | 198 | } | |
136 | |||
137 | /** | ||
138 | * Retrieve the base type of an array or a pointer | ||
139 | * | ||
140 | * @return Base type | ||
141 | */ | ||
142 | 90340 | const Type *Type::getContained() const { | |
143 |
2/2✓ Branch 0 (3→4) taken 1290 times.
✓ Branch 1 (3→6) taken 89050 times.
|
90340 | if (is(TY_STRING)) |
144 |
1/2✓ Branch 0 (4→5) taken 1290 times.
✗ Branch 1 (4→18) not taken.
|
1290 | return TypeRegistry::getOrInsert(TY_CHAR); |
145 | |||
146 | // Create new type chain | ||
147 |
1/2✓ Branch 0 (6→7) taken 89050 times.
✗ Branch 1 (6→18) not taken.
|
89050 | TypeChain newTypeChain = typeChain; |
148 |
1/2✗ Branch 0 (8→9) not taken.
✓ Branch 1 (8→10) taken 89050 times.
|
89050 | assert(newTypeChain.size() > 1); |
149 | 89050 | newTypeChain.pop_back(); | |
150 | |||
151 | // Register new type or return if already registered | ||
152 |
1/2✓ Branch 0 (11→12) taken 89050 times.
✗ Branch 1 (11→16) not taken.
|
89050 | return TypeRegistry::getOrInsert(newTypeChain); |
153 | 89050 | } | |
154 | |||
155 | /** | ||
156 | * Replace the base type with another one | ||
157 | * | ||
158 | * @param newBaseType New base type | ||
159 | * @return The new type | ||
160 | */ | ||
161 | 11312 | const Type *Type::replaceBase(const Type *newBaseType) const { | |
162 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 11312 times.
|
11312 | assert(!typeChain.empty()); |
163 | |||
164 | // Create new type | ||
165 |
1/2✓ Branch 0 (5→6) taken 11312 times.
✗ Branch 1 (5→27) not taken.
|
11312 | TypeChain newTypeChain = newBaseType->typeChain; |
166 |
4/4✓ Branch 0 (7→8) taken 434 times.
✓ Branch 1 (7→11) taken 10878 times.
✓ Branch 2 (9→10) taken 14 times.
✓ Branch 3 (9→11) taken 420 times.
|
11312 | const bool doubleRef = newTypeChain.back().superType == TY_REF && typeChain.back().superType == TY_REF; |
167 |
2/2✓ Branch 0 (19→13) taken 1752 times.
✓ Branch 1 (19→20) taken 11312 times.
|
13064 | for (size_t i = 1; i < typeChain.size(); i++) |
168 |
3/4✓ Branch 0 (13→14) taken 14 times.
✓ Branch 1 (13→15) taken 1738 times.
✗ Branch 2 (14→15) not taken.
✓ Branch 3 (14→17) taken 14 times.
|
1752 | if (!doubleRef || i > 1) |
169 |
2/4✓ Branch 0 (15→16) taken 1738 times.
✗ Branch 1 (15→25) not taken.
✓ Branch 2 (16→17) taken 1738 times.
✗ Branch 3 (16→25) not taken.
|
1738 | newTypeChain.push_back(typeChain.at(i)); |
170 | |||
171 | // Register new type or return if already registered | ||
172 |
1/2✓ Branch 0 (20→21) taken 11312 times.
✗ Branch 1 (20→25) not taken.
|
22624 | return TypeRegistry::getOrInsert(newTypeChain); |
173 | 11312 | } | |
174 | |||
175 | /** | ||
176 | * Remove reference wrapper from the current type | ||
177 | * | ||
178 | * @return Type without reference wrapper | ||
179 | */ | ||
180 |
1/2✓ Branch 0 (3→4) taken 29996 times.
✗ Branch 1 (3→6) not taken.
|
29996 | const Type *Type::removeReferenceWrapper() const { return isRef() ? getContained() : this; } |
181 | |||
182 | /** | ||
183 | * Return the LLVM type for this symbol type | ||
184 | * | ||
185 | * @param sourceFile Referenced source file | ||
186 | * @return Corresponding LLVM type | ||
187 | */ | ||
188 | 5866 | llvm::Type *Type::toLLVMType(SourceFile *sourceFile) const { // NOLINT(misc-no-recursion) | |
189 |
2/4✓ Branch 0 (3→4) taken 5866 times.
✗ Branch 1 (3→7) not taken.
✓ Branch 2 (5→6) taken 5866 times.
✗ Branch 3 (5→7) not taken.
|
5866 | assert(!typeChain.empty() && !is(TY_INVALID)); |
190 | 5866 | llvm::LLVMContext &context = sourceFile->llvmModule->getContext(); | |
191 | |||
192 |
2/2✓ Branch 0 (11→12) taken 65 times.
✓ Branch 1 (11→14) taken 5801 times.
|
5866 | if (is(TY_DOUBLE)) |
193 | 65 | return llvm::Type::getDoubleTy(context); | |
194 | |||
195 |
3/4✓ Branch 0 (14→15) taken 5801 times.
✗ Branch 1 (14→160) not taken.
✓ Branch 2 (15→16) taken 521 times.
✓ Branch 3 (15→18) taken 5280 times.
|
5801 | if (isOneOf({TY_INT, TY_ENUM})) |
196 | 521 | return llvm::Type::getInt32Ty(context); | |
197 | |||
198 |
2/2✓ Branch 0 (19→20) taken 62 times.
✓ Branch 1 (19→22) taken 5218 times.
|
5280 | if (is(TY_SHORT)) |
199 | 62 | return llvm::Type::getInt16Ty(context); | |
200 | |||
201 |
2/2✓ Branch 0 (23→24) taken 338 times.
✓ Branch 1 (23→26) taken 4880 times.
|
5218 | if (is(TY_LONG)) |
202 | 338 | return llvm::Type::getInt64Ty(context); | |
203 | |||
204 |
3/4✓ Branch 0 (26→27) taken 4880 times.
✗ Branch 1 (26→161) not taken.
✓ Branch 2 (27→28) taken 241 times.
✓ Branch 3 (27→30) taken 4639 times.
|
4880 | if (isOneOf({TY_CHAR, TY_BYTE})) |
205 | 241 | return llvm::Type::getInt8Ty(context); | |
206 | |||
207 |
2/2✓ Branch 0 (31→32) taken 393 times.
✓ Branch 1 (31→34) taken 4246 times.
|
4639 | if (is(TY_BOOL)) |
208 | 393 | return llvm::Type::getInt1Ty(context); | |
209 | |||
210 |
3/4✓ Branch 0 (34→35) taken 4246 times.
✗ Branch 1 (34→162) not taken.
✓ Branch 2 (35→36) taken 1516 times.
✓ Branch 3 (35→124) taken 2730 times.
|
4246 | if (isOneOf({TY_STRUCT, TY_INTERFACE})) { |
211 |
1/2✓ Branch 0 (36→37) taken 1516 times.
✗ Branch 1 (36→194) not taken.
|
1516 | const Scope *structBodyScope = getBodyScope(); |
212 |
2/4✓ Branch 0 (38→39) taken 1516 times.
✗ Branch 1 (38→194) not taken.
✓ Branch 2 (39→40) taken 1516 times.
✗ Branch 3 (39→194) not taken.
|
1516 | const std::string structSignature = Struct::getSignature(getSubType(), getTemplateTypes()); |
213 |
1/2✓ Branch 0 (40→41) taken 1516 times.
✗ Branch 1 (40→192) not taken.
|
1516 | const SymbolTableEntry *structSymbol = structBodyScope->parent->lookupStrict(structSignature); |
214 |
1/2✗ Branch 0 (43→44) not taken.
✓ Branch 1 (43→45) taken 1516 times.
|
1516 | assert(structSymbol != nullptr); |
215 | |||
216 | // Collect concrete field types | ||
217 | llvm::StructType *structType; | ||
218 | 1516 | std::vector<llvm::Type *> fieldTypes; | |
219 | 1516 | bool isPacked = false; | |
220 |
2/2✓ Branch 0 (46→47) taken 1362 times.
✓ Branch 1 (46→108) taken 154 times.
|
1516 | if (is(TY_STRUCT)) { // Struct |
221 |
2/4✓ Branch 0 (47→48) taken 1362 times.
✗ Branch 1 (47→183) not taken.
✓ Branch 2 (48→49) taken 1362 times.
✗ Branch 3 (48→183) not taken.
|
1362 | const Struct *spiceStruct = structSymbol->getQualType().getStruct(structSymbol->declNode); |
222 |
1/2✗ Branch 0 (49→50) not taken.
✓ Branch 1 (49→51) taken 1362 times.
|
1362 | assert(spiceStruct != nullptr); |
223 |
1/2✓ Branch 0 (51→52) taken 1362 times.
✗ Branch 1 (51→183) not taken.
|
1362 | const std::string mangledName = NameMangling::mangleStruct(*spiceStruct); |
224 |
1/2✓ Branch 0 (53→54) taken 1362 times.
✗ Branch 1 (53→163) not taken.
|
1362 | structType = llvm::StructType::create(context, mangledName); |
225 | |||
226 |
1/2✓ Branch 0 (54→55) taken 1362 times.
✗ Branch 1 (54→181) not taken.
|
1362 | const size_t totalFieldCount = spiceStruct->scope->getFieldCount(); |
227 |
1/2✓ Branch 0 (55→56) taken 1362 times.
✗ Branch 1 (55→181) not taken.
|
1362 | fieldTypes.reserve(totalFieldCount); |
228 | |||
229 | // If the struct has no interface types, but a vtable was requested, add another ptr field type | ||
230 |
2/4✓ Branch 0 (56→57) taken 1362 times.
✗ Branch 1 (56→181) not taken.
✗ Branch 2 (57→58) not taken.
✓ Branch 3 (57→59) taken 1362 times.
|
1362 | assert(structSymbol->declNode->isStructDef()); |
231 |
1/2✓ Branch 0 (59→60) taken 1362 times.
✗ Branch 1 (59→61) not taken.
|
1362 | const auto structDeclNode = spice_pointer_cast<StructDefNode *>(structSymbol->declNode); |
232 |
4/4✓ Branch 0 (66→67) taken 1102 times.
✓ Branch 1 (66→71) taken 260 times.
✓ Branch 2 (67→68) taken 38 times.
✓ Branch 3 (67→71) taken 1064 times.
|
1362 | if (!structDeclNode->hasInterfaces && structDeclNode->emitVTable) |
233 |
2/4✓ Branch 0 (68→69) taken 38 times.
✗ Branch 1 (68→164) not taken.
✓ Branch 2 (69→70) taken 38 times.
✗ Branch 3 (69→164) not taken.
|
38 | fieldTypes.push_back(llvm::PointerType::get(context, 0)); |
234 | |||
235 | // Collect all field types | ||
236 |
2/2✓ Branch 0 (84→72) taken 3543 times.
✓ Branch 1 (84→85) taken 1362 times.
|
4905 | for (size_t i = 0; i < totalFieldCount; i++) { |
237 |
1/2✗ Branch 0 (72→73) not taken.
✓ Branch 1 (72→74) taken 3543 times.
|
3543 | const SymbolTableEntry *fieldSymbol = spiceStruct->scope->lookupField(i); |
238 |
1/2✗ Branch 0 (77→78) not taken.
✓ Branch 1 (77→79) taken 3543 times.
|
3543 | assert(fieldSymbol != nullptr); |
239 |
3/6✓ Branch 0 (79→80) taken 3543 times.
✗ Branch 1 (79→165) not taken.
✓ Branch 2 (81→82) taken 3543 times.
✗ Branch 3 (81→165) not taken.
✓ Branch 4 (82→83) taken 3543 times.
✗ Branch 5 (82→165) not taken.
|
3543 | fieldTypes.push_back(sourceFile->getLLVMType(fieldSymbol->getQualType().getType())); |
240 | } | ||
241 | |||
242 | // Check if the struct is declared as packed | ||
243 |
12/18✓ Branch 0 (85→86) taken 39 times.
✓ Branch 1 (85→92) taken 1323 times.
✓ Branch 2 (88→89) taken 39 times.
✗ Branch 3 (88→166) not taken.
✓ Branch 4 (89→90) taken 39 times.
✗ Branch 5 (89→166) not taken.
✓ Branch 6 (90→91) taken 1 times.
✓ Branch 7 (90→92) taken 38 times.
✓ Branch 8 (93→94) taken 39 times.
✓ Branch 9 (93→95) taken 1323 times.
✓ Branch 10 (95→96) taken 39 times.
✓ Branch 11 (95→98) taken 1323 times.
✓ Branch 12 (98→99) taken 1 times.
✓ Branch 13 (98→106) taken 1361 times.
✗ Branch 14 (166→167) not taken.
✗ Branch 15 (166→168) not taken.
✗ Branch 16 (170→171) not taken.
✗ Branch 17 (170→173) not taken.
|
1440 | if (structDeclNode->attrs && structDeclNode->attrs->attrLst->hasAttr(ATTR_CORE_COMPILER_PACKED)) |
244 |
2/4✓ Branch 0 (101→102) taken 1 times.
✗ Branch 1 (101→177) not taken.
✓ Branch 2 (102→103) taken 1 times.
✗ Branch 3 (102→175) not taken.
|
3 | isPacked = structDeclNode->attrs->attrLst->getAttrValueByName(ATTR_CORE_COMPILER_PACKED)->boolValue; |
245 | 1362 | } else { // Interface | |
246 |
2/4✓ Branch 0 (108→109) taken 154 times.
✗ Branch 1 (108→188) not taken.
✓ Branch 2 (109→110) taken 154 times.
✗ Branch 3 (109→188) not taken.
|
154 | const Interface *spiceInterface = structSymbol->getQualType().getInterface(structSymbol->declNode); |
247 |
1/2✗ Branch 0 (110→111) not taken.
✓ Branch 1 (110→112) taken 154 times.
|
154 | assert(spiceInterface != nullptr); |
248 |
1/2✓ Branch 0 (112→113) taken 154 times.
✗ Branch 1 (112→188) not taken.
|
154 | const std::string mangledName = NameMangling::mangleInterface(*spiceInterface); |
249 |
1/2✓ Branch 0 (114→115) taken 154 times.
✗ Branch 1 (114→184) not taken.
|
154 | structType = llvm::StructType::create(context, mangledName); |
250 | |||
251 |
2/4✓ Branch 0 (115→116) taken 154 times.
✗ Branch 1 (115→185) not taken.
✓ Branch 2 (116→117) taken 154 times.
✗ Branch 3 (116→185) not taken.
|
154 | fieldTypes.push_back(llvm::PointerType::get(context, 0)); |
252 | 154 | } | |
253 | |||
254 | // Set field types to struct type | ||
255 |
1/2✓ Branch 0 (120→121) taken 1516 times.
✗ Branch 1 (120→189) not taken.
|
1516 | structType->setBody(fieldTypes, isPacked); |
256 | |||
257 | 1516 | return structType; | |
258 | 1516 | } | |
259 | |||
260 |
10/12✓ Branch 0 (124→125) taken 2730 times.
✗ Branch 1 (124→195) not taken.
✓ Branch 2 (125→126) taken 127 times.
✓ Branch 3 (125→130) taken 2603 times.
✓ Branch 4 (127→128) taken 54 times.
✓ Branch 5 (127→131) taken 73 times.
✓ Branch 6 (128→129) taken 54 times.
✗ Branch 7 (128→195) not taken.
✓ Branch 8 (129→130) taken 20 times.
✓ Branch 9 (129→131) taken 34 times.
✓ Branch 10 (132→133) taken 2623 times.
✓ Branch 11 (132→135) taken 107 times.
|
2730 | if (isOneOf({TY_PTR, TY_REF, TY_STRING}) || (isArray() && getArraySize() == 0)) |
261 | 2623 | return llvm::PointerType::get(context, 0); | |
262 | |||
263 |
3/4✓ Branch 0 (135→136) taken 107 times.
✗ Branch 1 (135→196) not taken.
✓ Branch 2 (136→137) taken 73 times.
✓ Branch 3 (136→142) taken 34 times.
|
107 | if (isOneOf({TY_FUNCTION, TY_PROCEDURE})) { |
264 | 73 | llvm::PointerType *ptrTy = llvm::PointerType::get(context, 0); | |
265 |
1/2✓ Branch 0 (139→140) taken 73 times.
✗ Branch 1 (139→197) not taken.
|
73 | return llvm::StructType::get(context, {ptrTy, ptrTy}); |
266 | } | ||
267 | |||
268 |
1/2✓ Branch 0 (143→144) taken 34 times.
✗ Branch 1 (143→152) not taken.
|
34 | if (isArray()) { |
269 |
1/2✗ Branch 0 (145→146) not taken.
✓ Branch 1 (145→147) taken 34 times.
|
34 | assert(getArraySize() > 0); |
270 | 34 | llvm::Type *containedType = sourceFile->getLLVMType(getContained()); | |
271 | 34 | return llvm::ArrayType::get(containedType, getArraySize()); | |
272 | } | ||
273 | |||
274 | − | throw CompilerError(UNHANDLED_BRANCH, "Cannot determine LLVM type of " + getName(true)); // GCOVR_EXCL_LINE | |
275 | } | ||
276 | |||
277 | /** | ||
278 | * Check if the base type of the current type chain is of a certain super type | ||
279 | * | ||
280 | * @param superType Super type to check for | ||
281 | * @return Applicable or not | ||
282 | */ | ||
283 | 550958 | bool Type::isBase(SuperType superType) const { | |
284 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 550958 times.
|
550958 | assert(!typeChain.empty()); |
285 | 550958 | return typeChain.front().superType == superType; | |
286 | } | ||
287 | |||
288 | /** | ||
289 | * Check if the current type is a primitive type | ||
290 | * | ||
291 | * @return Primitive type or not | ||
292 | */ | ||
293 |
1/2✓ Branch 0 (2→3) taken 102925 times.
✗ Branch 1 (2→6) not taken.
|
102925 | bool Type::isPrimitive() const { return isOneOf({TY_DOUBLE, TY_INT, TY_SHORT, TY_LONG, TY_BYTE, TY_CHAR, TY_STRING, TY_BOOL}); } |
294 | |||
295 | /** | ||
296 | * Check if the type is an extended primitive type | ||
297 | * The definition of extended primitive types contains all primitive types plus the following: | ||
298 | * - structs | ||
299 | * - interfaces | ||
300 | * - functions/procedures | ||
301 | * | ||
302 | * @return Extended primitive or not | ||
303 | */ | ||
304 | 70027 | bool Type::isExtendedPrimitive() const { | |
305 |
6/8✓ Branch 0 (2→3) taken 70027 times.
✗ Branch 1 (2→11) not taken.
✓ Branch 2 (3→4) taken 21390 times.
✓ Branch 3 (3→6) taken 48637 times.
✓ Branch 4 (4→5) taken 21390 times.
✗ Branch 5 (4→11) not taken.
✓ Branch 6 (5→6) taken 19096 times.
✓ Branch 7 (5→7) taken 2294 times.
|
70027 | return isPrimitive() || isOneOf({TY_STRUCT, TY_INTERFACE, TY_FUNCTION, TY_PROCEDURE}); |
306 | } | ||
307 | |||
308 | /** | ||
309 | * Check if the current type is a pointer type | ||
310 | * | ||
311 | * @return Pointer type or not | ||
312 | */ | ||
313 | 252608 | bool Type::isPtr() const { return getSuperType() == TY_PTR; } | |
314 | |||
315 | /** | ||
316 | * Check if the current type is a reference type | ||
317 | * | ||
318 | * @return Reference type or not | ||
319 | */ | ||
320 | 755935 | bool Type::isRef() const { return getSuperType() == TY_REF; } | |
321 | |||
322 | /** | ||
323 | * Check if the current type is an array type | ||
324 | * | ||
325 | * @return Array type or not | ||
326 | */ | ||
327 | 94679 | bool Type::isArray() const { return getSuperType() == TY_ARRAY; } | |
328 | |||
329 | /** | ||
330 | * Check if the current type is of the same container type like the other type. | ||
331 | * Only TY_PTR, TY_REF and TY_ARRAY are considered as container types. | ||
332 | * | ||
333 | * @param other Other symbol type | ||
334 | * @return Same container type or not | ||
335 | */ | ||
336 | 71992 | bool Type::isSameContainerTypeAs(const Type *other) const { | |
337 |
4/4✓ Branch 0 (3→4) taken 1675 times.
✓ Branch 1 (3→7) taken 70317 times.
✓ Branch 2 (5→6) taken 1525 times.
✓ Branch 3 (5→7) taken 150 times.
|
71992 | const bool bothPtr = isPtr() && other->isPtr(); |
338 |
4/4✓ Branch 0 (9→10) taken 3274 times.
✓ Branch 1 (9→13) taken 68718 times.
✓ Branch 2 (11→12) taken 3171 times.
✓ Branch 3 (11→13) taken 103 times.
|
71992 | const bool bothRef = isRef() && other->isRef(); |
339 |
3/4✓ Branch 0 (15→16) taken 50 times.
✓ Branch 1 (15→19) taken 71942 times.
✓ Branch 2 (17→18) taken 50 times.
✗ Branch 3 (17→19) not taken.
|
71992 | const bool bothArray = isArray() && other->isArray(); |
340 |
6/6✓ Branch 0 (20→21) taken 70467 times.
✓ Branch 1 (20→23) taken 1525 times.
✓ Branch 2 (21→22) taken 67296 times.
✓ Branch 3 (21→23) taken 3171 times.
✓ Branch 4 (22→23) taken 50 times.
✓ Branch 5 (22→24) taken 67246 times.
|
71992 | return bothPtr || bothRef || bothArray; |
341 | } | ||
342 | |||
343 | /** | ||
344 | * Retrieve the base type of the current type | ||
345 | * | ||
346 | * @return Base type | ||
347 | */ | ||
348 | 884653 | const Type *Type::getBase() const { | |
349 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 884653 times.
|
884653 | assert(!typeChain.empty()); |
350 | |||
351 | // Create new type chain | ||
352 |
3/6✓ Branch 0 (9→10) taken 884653 times.
✗ Branch 1 (9→19) not taken.
✓ Branch 2 (12→13) taken 884653 times.
✓ Branch 3 (12→14) taken 884653 times.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→25) not taken.
|
2653959 | const TypeChain newTypeChain = {typeChain.front()}; |
353 | |||
354 | // Register new type or return if already registered | ||
355 |
1/2✓ Branch 0 (14→15) taken 884653 times.
✗ Branch 1 (14→32) not taken.
|
1769306 | return TypeRegistry::getOrInsert(newTypeChain); |
356 |
1/6✓ Branch 0 (6→7) taken 884653 times.
✗ Branch 1 (6→26) not taken.
✗ Branch 2 (26→27) not taken.
✗ Branch 3 (26→30) not taken.
✗ Branch 4 (28→29) not taken.
✗ Branch 5 (28→30) not taken.
|
1769306 | } |
357 | |||
358 | /** | ||
359 | * Retrieve the same type, but with lambda captures | ||
360 | * | ||
361 | * @return Type with lambda captures | ||
362 | */ | ||
363 | 45 | const Type *Type::getWithLambdaCaptures(bool enabled) const { | |
364 |
3/6✓ Branch 0 (2→3) taken 45 times.
✗ Branch 1 (2→16) not taken.
✓ Branch 2 (3→4) taken 45 times.
✗ Branch 3 (3→13) not taken.
✗ Branch 4 (4→5) not taken.
✓ Branch 5 (4→6) taken 45 times.
|
45 | assert(getBase()->isOneOf({TY_FUNCTION, TY_PROCEDURE})); |
365 | |||
366 | // Create new type chain | ||
367 |
1/2✓ Branch 0 (6→7) taken 45 times.
✗ Branch 1 (6→16) not taken.
|
45 | TypeChain newTypeChain = typeChain; |
368 | 45 | newTypeChain.front().data.hasCaptures = enabled; | |
369 | |||
370 | // Register new type or return if already registered | ||
371 |
1/2✓ Branch 0 (8→9) taken 45 times.
✗ Branch 1 (8→14) not taken.
|
90 | return TypeRegistry::getOrInsert(newTypeChain); |
372 | 45 | } | |
373 | |||
374 | /** | ||
375 | * Retrieve the same type, but with the body scope removed | ||
376 | * | ||
377 | * @return Type with body scope removed | ||
378 | */ | ||
379 | 22436 | const Type *Type::getWithBodyScope(Scope *bodyScope) const { | |
380 |
3/6✓ Branch 0 (2→3) taken 22436 times.
✗ Branch 1 (2→16) not taken.
✓ Branch 2 (3→4) taken 22436 times.
✗ Branch 3 (3→13) not taken.
✗ Branch 4 (4→5) not taken.
✓ Branch 5 (4→6) taken 22436 times.
|
22436 | assert(getBase()->isOneOf({TY_STRUCT, TY_INTERFACE})); |
381 | |||
382 | // Create new type chain | ||
383 |
1/2✓ Branch 0 (6→7) taken 22436 times.
✗ Branch 1 (6→16) not taken.
|
22436 | TypeChain newTypeChain = typeChain; |
384 | 22436 | newTypeChain.front().data.bodyScope = bodyScope; | |
385 | |||
386 | // Register new type or return if already registered | ||
387 |
1/2✓ Branch 0 (8→9) taken 22436 times.
✗ Branch 1 (8→14) not taken.
|
44872 | return TypeRegistry::getOrInsert(newTypeChain); |
388 | 22436 | } | |
389 | |||
390 | /** | ||
391 | * Retrieve the same type, but with the given template types | ||
392 | * | ||
393 | * @return Type with new template types | ||
394 | */ | ||
395 | 2974 | const Type *Type::getWithTemplateTypes(const QualTypeList &templateTypes) const { | |
396 |
2/4✓ Branch 0 (2→3) taken 2974 times.
✗ Branch 1 (2→8) not taken.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 2974 times.
|
2974 | assert(isOneOf({TY_STRUCT, TY_INTERFACE})); |
397 | 2974 | return getWithBaseTemplateTypes(templateTypes); | |
398 | } | ||
399 | |||
400 | /** | ||
401 | * Retrieve the same type, but with the given base template types | ||
402 | * | ||
403 | * @return Type with new base template types | ||
404 | */ | ||
405 | 6616 | const Type *Type::getWithBaseTemplateTypes(const QualTypeList &templateTypes) const { | |
406 |
3/6✓ Branch 0 (2→3) taken 6616 times.
✗ Branch 1 (2→17) not taken.
✓ Branch 2 (3→4) taken 6616 times.
✗ Branch 3 (3→14) not taken.
✗ Branch 4 (4→5) not taken.
✓ Branch 5 (4→6) taken 6616 times.
|
6616 | assert(getBase()->isOneOf({TY_STRUCT, TY_INTERFACE})); |
407 | |||
408 | // Create new type chain | ||
409 |
1/2✓ Branch 0 (6→7) taken 6616 times.
✗ Branch 1 (6→17) not taken.
|
6616 | TypeChain newTypeChain = typeChain; |
410 |
1/2✓ Branch 0 (8→9) taken 6616 times.
✗ Branch 1 (8→15) not taken.
|
6616 | newTypeChain.front().templateTypes = templateTypes; |
411 | |||
412 | // Register new type or return if already registered | ||
413 |
1/2✓ Branch 0 (9→10) taken 6616 times.
✗ Branch 1 (9→15) not taken.
|
13232 | return TypeRegistry::getOrInsert(newTypeChain); |
414 | 6616 | } | |
415 | |||
416 | /** | ||
417 | * Retrieve the same type, but with the param and return types removed | ||
418 | * | ||
419 | * @return Type with param and return types removed | ||
420 | */ | ||
421 | 10580 | const Type *Type::getWithFunctionParamAndReturnTypes(const QualTypeList ¶mAndReturnTypes) const { | |
422 |
3/6✓ Branch 0 (2→3) taken 10580 times.
✗ Branch 1 (2→17) not taken.
✓ Branch 2 (3→4) taken 10580 times.
✗ Branch 3 (3→14) not taken.
✗ Branch 4 (4→5) not taken.
✓ Branch 5 (4→6) taken 10580 times.
|
10580 | assert(getBase()->isOneOf({TY_FUNCTION, TY_PROCEDURE})); |
423 | |||
424 | // Create new type chain | ||
425 |
1/2✓ Branch 0 (6→7) taken 10580 times.
✗ Branch 1 (6→17) not taken.
|
10580 | TypeChain newTypeChain = typeChain; |
426 |
1/2✓ Branch 0 (8→9) taken 10580 times.
✗ Branch 1 (8→15) not taken.
|
10580 | newTypeChain.front().paramTypes = paramAndReturnTypes; |
427 | |||
428 | // Register new type or return if already registered | ||
429 |
1/2✓ Branch 0 (9→10) taken 10580 times.
✗ Branch 1 (9→15) not taken.
|
21160 | return TypeRegistry::getOrInsert(newTypeChain); |
430 | 10580 | } | |
431 | |||
432 | /** | ||
433 | * Checks if the base type is generic itself or has generic parts in its template types | ||
434 | * | ||
435 | * @return Contains generic parts or not | ||
436 | */ | ||
437 | 246419 | bool Type::hasAnyGenericParts() const { // NOLINT(misc-no-recursion) | |
438 |
1/2✓ Branch 0 (2→3) taken 246419 times.
✗ Branch 1 (2→34) not taken.
|
246419 | const Type *baseType = getBase(); |
439 | |||
440 | // Check if the type itself is generic | ||
441 |
2/2✓ Branch 0 (4→5) taken 42579 times.
✓ Branch 1 (4→6) taken 203840 times.
|
246419 | if (baseType->is(TY_GENERIC)) |
442 | 42579 | return true; | |
443 | |||
444 | // Check if the type has generic template types | ||
445 |
1/2✓ Branch 0 (7→8) taken 203840 times.
✗ Branch 1 (7→34) not taken.
|
203840 | const auto templateTypes = baseType->getTemplateTypes(); |
446 |
3/4✓ Branch 0 (8→9) taken 203840 times.
✗ Branch 1 (8→32) not taken.
✓ Branch 2 (9→10) taken 16412 times.
✓ Branch 3 (9→11) taken 187428 times.
|
244356 | if (std::ranges::any_of(templateTypes, [](const QualType &t) { return t.hasAnyGenericParts(); })) |
447 | 16412 | return true; | |
448 | |||
449 | // Check param and return types or functions/procedures | ||
450 |
3/4✓ Branch 0 (11→12) taken 187428 times.
✗ Branch 1 (11→28) not taken.
✓ Branch 2 (12→13) taken 504 times.
✓ Branch 3 (12→24) taken 186924 times.
|
187428 | if (baseType->isOneOf({TY_FUNCTION, TY_PROCEDURE})) { |
451 |
2/4✓ Branch 0 (13→14) taken 504 times.
✗ Branch 1 (13→31) not taken.
✓ Branch 2 (14→15) taken 504 times.
✗ Branch 3 (14→31) not taken.
|
504 | const auto paramTypes = baseType->getFunctionParamAndReturnTypes(); |
452 |
3/4✓ Branch 0 (15→16) taken 504 times.
✗ Branch 1 (15→29) not taken.
✓ Branch 2 (16→17) taken 144 times.
✓ Branch 3 (16→18) taken 360 times.
|
1326 | if (std::ranges::any_of(paramTypes, [](const QualType &t) { return t.hasAnyGenericParts(); })) |
453 | 144 | return true; | |
454 |
2/2✓ Branch 0 (20→21) taken 360 times.
✓ Branch 1 (20→23) taken 144 times.
|
504 | } |
455 | |||
456 | 187284 | return false; // Does not have generic parts | |
457 | 203840 | } | |
458 | |||
459 | /** | ||
460 | * Retrieve template types of the current type | ||
461 | * | ||
462 | * @return Vector of template types | ||
463 | */ | ||
464 | 291027 | const QualTypeList &Type::getTemplateTypes() const { return typeChain.back().templateTypes; } | |
465 | |||
466 | /** | ||
467 | * Check if the current type is of a certain super type | ||
468 | * | ||
469 | * @return Applicable or not | ||
470 | */ | ||
471 | 5269957 | bool Type::is(SuperType superType) const { return getSuperType() == superType; } | |
472 | |||
473 | /** | ||
474 | * Check if the current type is one of a list of super types | ||
475 | * | ||
476 | * @return Applicable or not | ||
477 | */ | ||
478 | 1114781 | bool Type::isOneOf(const std::initializer_list<SuperType> &superTypes) const { | |
479 | 3626167 | return std::ranges::any_of(superTypes, [this](SuperType superType) { return is(superType); }); | |
480 | } | ||
481 | |||
482 | /** | ||
483 | * Get the name of the symbol type as a string | ||
484 | * | ||
485 | * @param name Get name of type | ||
486 | * @param withSize Include the array size for sized types | ||
487 | * @return Symbol type name | ||
488 | */ | ||
489 | 325117 | void Type::getName(std::stringstream &name, bool withSize) const { // NOLINT(misc-no-recursion) | |
490 | // Loop through all chain elements | ||
491 |
2/2✓ Branch 0 (10→4) taken 407875 times.
✓ Branch 1 (10→11) taken 325117 times.
|
732992 | for (const TypeChainElement &chainElement : typeChain) |
492 |
2/4✓ Branch 0 (5→6) taken 407875 times.
✗ Branch 1 (5→14) not taken.
✓ Branch 2 (6→7) taken 407875 times.
✗ Branch 3 (6→12) not taken.
|
407875 | name << chainElement.getName(withSize); |
493 | 325117 | } | |
494 | |||
495 | /** | ||
496 | * Get the name of the symbol type as a string | ||
497 | * | ||
498 | * @param withSize Include the array size for sized types | ||
499 | * @return Symbol type name | ||
500 | */ | ||
501 | 11971 | std::string Type::getName(bool withSize) const { | |
502 |
1/2✓ Branch 0 (2→3) taken 11971 times.
✗ Branch 1 (2→11) not taken.
|
11971 | std::stringstream name; |
503 |
1/2✓ Branch 0 (3→4) taken 11971 times.
✗ Branch 1 (3→9) not taken.
|
11971 | getName(name, withSize); |
504 |
1/2✓ Branch 0 (4→5) taken 11971 times.
✗ Branch 1 (4→9) not taken.
|
23942 | return name.str(); |
505 | 11971 | } | |
506 | |||
507 | /** | ||
508 | * Get the return type of function type | ||
509 | * | ||
510 | * @return Function return type | ||
511 | */ | ||
512 | 39 | const QualType &Type::getFunctionReturnType() const { | |
513 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 39 times.
|
39 | assert(is(TY_FUNCTION)); |
514 |
1/2✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→9) taken 39 times.
|
39 | assert(!typeChain.back().paramTypes.empty()); |
515 | 39 | return typeChain.back().paramTypes.front(); | |
516 | } | ||
517 | |||
518 | /** | ||
519 | * Get the param types of a function or procedure type | ||
520 | * | ||
521 | * @return Function param types | ||
522 | */ | ||
523 | 140 | QualTypeList Type::getFunctionParamTypes() const { | |
524 |
2/4✓ Branch 0 (2→3) taken 140 times.
✗ Branch 1 (2→20) not taken.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 140 times.
|
140 | assert(isOneOf({TY_FUNCTION, TY_PROCEDURE})); |
525 |
1/2✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→9) taken 140 times.
|
140 | if (typeChain.back().paramTypes.empty()) |
526 | ✗ | return {}; | |
527 |
1/2✓ Branch 0 (16→17) taken 140 times.
✗ Branch 1 (16→21) not taken.
|
420 | return {typeChain.back().paramTypes.begin() + 1, typeChain.back().paramTypes.end()}; |
528 | } | ||
529 | |||
530 | /** | ||
531 | * Check if a function or procedure type has captures | ||
532 | * | ||
533 | * @return Has captures | ||
534 | */ | ||
535 | 176 | bool Type::hasLambdaCaptures() const { | |
536 |
2/4✓ Branch 0 (3→4) taken 176 times.
✗ Branch 1 (3→9) not taken.
✗ Branch 2 (4→5) not taken.
✓ Branch 3 (4→6) taken 176 times.
|
176 | assert(getBase()->isOneOf({TY_FUNCTION, TY_PROCEDURE})); |
537 | 176 | return typeChain.front().data.hasCaptures; | |
538 | } | ||
539 | |||
540 | /** | ||
541 | * Get the param and return types of a function or procedure base type | ||
542 | * | ||
543 | * @return Function param and return types (first is return type, rest are param types) | ||
544 | */ | ||
545 | 647 | const QualTypeList &Type::getFunctionParamAndReturnTypes() const { | |
546 |
2/4✓ Branch 0 (3→4) taken 647 times.
✗ Branch 1 (3→9) not taken.
✗ Branch 2 (4→5) not taken.
✓ Branch 3 (4→6) taken 647 times.
|
647 | assert(getBase()->isOneOf({TY_FUNCTION, TY_PROCEDURE})); |
547 | 647 | return typeChain.front().paramTypes; | |
548 | } | ||
549 | |||
550 | /** | ||
551 | * Check for the matching compatibility of two types. | ||
552 | * Useful for struct and function matching as well as assignment type validation and function arg matching. | ||
553 | * | ||
554 | * @param otherType Type to compare against | ||
555 | * @param ignoreArraySize Ignore array sizes | ||
556 | * @return Matching or not | ||
557 | */ | ||
558 | 92343 | bool Type::matches(const Type *otherType, bool ignoreArraySize) const { | |
559 | // If the size does not match, it is not equal | ||
560 |
2/2✓ Branch 0 (4→5) taken 11861 times.
✓ Branch 1 (4→6) taken 80482 times.
|
92343 | if (typeChain.size() != otherType->typeChain.size()) |
561 | 11861 | return false; | |
562 | |||
563 | // Compare the elements | ||
564 |
2/2✓ Branch 0 (18→7) taken 86515 times.
✓ Branch 1 (18→19) taken 52940 times.
|
139455 | for (size_t i = 0; i < typeChain.size(); i++) { |
565 | 86515 | const TypeChainElement &lhsElement = typeChain.at(i); | |
566 | 86515 | const TypeChainElement &rhsElement = otherType->typeChain.at(i); | |
567 | |||
568 | // Ignore differences in array size | ||
569 |
5/6✓ Branch 0 (9→10) taken 52595 times.
✓ Branch 1 (9→13) taken 33920 times.
✓ Branch 2 (10→11) taken 1 times.
✓ Branch 3 (10→13) taken 52594 times.
✓ Branch 4 (11→12) taken 1 times.
✗ Branch 5 (11→13) not taken.
|
86515 | if (ignoreArraySize && lhsElement.superType == TY_ARRAY && rhsElement.superType == TY_ARRAY) |
570 | 1 | continue; | |
571 | |||
572 | // Not both types are arrays -> compare them as usual | ||
573 |
2/2✓ Branch 0 (14→15) taken 27542 times.
✓ Branch 1 (14→16) taken 58972 times.
|
86514 | if (lhsElement != rhsElement) |
574 | 27542 | return false; | |
575 | } | ||
576 | |||
577 | // Ignore or compare qualifiers | ||
578 | 52940 | return true; | |
579 | } | ||
580 | |||
581 | /** | ||
582 | * Remove pointers / arrays / references if both types have them as far as possible. | ||
583 | * Furthermore, remove reference wrappers if possible. | ||
584 | * | ||
585 | * @param typeA Candidate type | ||
586 | * @param typeB Requested type | ||
587 | */ | ||
588 | 64651 | void Type::unwrapBoth(const Type *&typeA, const Type *&typeB) { | |
589 | // Remove reference wrapper of front type if required | ||
590 |
6/6✓ Branch 0 (3→4) taken 30969 times.
✓ Branch 1 (3→7) taken 33682 times.
✓ Branch 2 (5→6) taken 27798 times.
✓ Branch 3 (5→7) taken 3171 times.
✓ Branch 4 (8→9) taken 27798 times.
✓ Branch 5 (8→11) taken 36853 times.
|
64651 | if (typeA->isRef() && !typeB->isRef()) |
591 | 27798 | typeA = typeA->removeReferenceWrapper(); | |
592 | |||
593 | // Remove reference wrapper of requested type if required | ||
594 |
8/8✓ Branch 0 (12→13) taken 61480 times.
✓ Branch 1 (12→19) taken 3171 times.
✓ Branch 2 (14→15) taken 2552 times.
✓ Branch 3 (14→19) taken 58928 times.
✓ Branch 4 (17→18) taken 2198 times.
✓ Branch 5 (17→19) taken 354 times.
✓ Branch 6 (20→21) taken 2198 times.
✓ Branch 7 (20→23) taken 62453 times.
|
64651 | if (!typeA->isRef() && typeB->isRef() && !typeA->getBase()->is(TY_GENERIC)) |
595 | 2198 | typeB = typeB->removeReferenceWrapper(); | |
596 | |||
597 | // Unwrap both types as far as possible | ||
598 |
2/2✓ Branch 0 (28→24) taken 4620 times.
✓ Branch 1 (28→29) taken 64651 times.
|
69271 | while (typeA->isSameContainerTypeAs(typeB)) { |
599 | 4620 | typeB = typeB->getContained(); | |
600 | 4620 | typeA = typeA->getContained(); | |
601 | } | ||
602 | 64651 | } | |
603 | |||
604 | /** | ||
605 | * Check if two types have the same type chain depth | ||
606 | * | ||
607 | * @param typeA First type | ||
608 | * @param typeB Second type | ||
609 | * @return Same depth or not | ||
610 | */ | ||
611 | 15960 | bool Type::hasSameTypeChainDepth(const Type *typeA, const Type *typeB) { | |
612 | 15960 | return typeA->typeChain.size() == typeB->typeChain.size(); | |
613 | } | ||
614 | |||
615 | } // namespace spice::compiler | ||
616 |