GCC Code Coverage Report


src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
137 / 148
92.6%
Branches:
67 / 73, 12 excl
91.8%
Functions:
11 / 12
91.7%

symboltablebuilder/type-chain.spice
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 // Std imports
4 import "std/data/vector";
5 import "std/text/stringstream";
6 import "std/type/type-conversion";
7
8 // Own imports
9 import "@/symboltablebuilder/super-type";
10 import "@/symboltablebuilder/qual-type";
11 import "@/symboltablebuilder/scope";
12 import "@/global/type-name-disambiguator";
13
14 // Constants
15 public const unsigned long ARRAY_SIZE_UNKNOWN = 0ul;
16
17 14306594 public type TypeChainElementData struct {
18 14306594 public unsigned int arraySize = 0 // TY_ARRAY
19 14306594 public Scope* bodyScope = nil<Scope*> // TY_STRUCT, TY_INTERFACE, TY_ENUM
20 14306594 public bool hasCaptures = false // TY_FUNCTION, TY_PROCEDURE (lambdas)
21 }
22
23 14289039 public type TypeChainElement struct {
24 14301512 public SuperType superType = SuperType::TY_INVALID
25 public String subType
26 14301512 public unsigned long typeId = cast<unsigned long>(SuperType::TY_INVALID)
27 public TypeChainElementData data
28 public QualTypeList templateTypes
29 public QualTypeList paramTypes // First type is the return type
30 }
31
32 4331782 public p TypeChainElement.ctor(SuperType superType) {
33 4331782 this.superType = superType;
34 4331782 this.typeId = cast<unsigned long>(superType);
35 4331782 }
36
37 6445 public p TypeChainElement.ctor(SuperType superType, const String& subType) {
38 6445 this.ctor(superType);
39 6445 this.subType = subType;
40 6445 }
41
42 1031 public p TypeChainElement.ctor(SuperType superType, const TypeChainElementData& data) {
43 1031 this.ctor(superType);
44 1031 this.data = data;
45 1031 }
46
47 5079 public p TypeChainElement.ctor(SuperType superType, const String& subType, unsigned long typeId, const TypeChainElementData& data, const QualTypeList& templateTypes) {
48 5079 this.superType = superType;
49 5079 this.subType = subType;
50 5079 this.typeId = typeId;
51 5079 this.data = data;
52 5079 this.templateTypes = templateTypes;
53 5079 }
54
55 // Explicit copy ctor: a user-defined ctor suppresses the auto-generated copy ctor, but elements are copied
56 // when type chains are duplicated (e.g. in Type.toPtr) and stored in vectors, so a deep copy is required.
57 9957175 public p TypeChainElement.ctor(const TypeChainElement& other) {
58 9957175 this.superType = other.superType;
59 9957175 this.subType = other.subType;
60 9957175 this.typeId = other.typeId;
61 9957175 this.data = other.data;
62 9957175 this.templateTypes = other.templateTypes;
63 9957175 this.paramTypes = other.paramTypes;
64 9957175 }
65
66 /**
67 * Compare two lists of qualified types element-wise. The equality operator of Vector compares the raw memory, which also
68 * compares the (uninitialized) padding bytes of the QualType elements.
69 *
70 * @param lhs Left list
71 * @param rhs Right list
72 * @return Equal or not
73 */
74 1595840 f<bool> areQualTypeListsEqual(const QualTypeList& lhs, const QualTypeList& rhs) {
75
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1595840 times.
1595840 if lhs.getSize() != rhs.getSize() {
76 ✗ return false;
77 }
78
2/2
✓ Branch 0 taken 781932 times.
✓ Branch 1 taken 1595780 times.
2377712 for unsigned long i = 0ul; i < lhs.getSize(); i++ {
79
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 781872 times.
781932 if lhs[i] != rhs[i] {
80 60 return false;
81 }
82 781872 }
83 1595780 return true;
84 }
85
86 7119570 public f<bool> operator==(const TypeChainElement& lhs, const TypeChainElement& rhs) {
87 // Check super type
88
2/2
✓ Branch 0 taken 87449 times.
✓ Branch 1 taken 7032121 times.
7119570 if lhs.superType != rhs.superType { return false; }
89
90 // Check the super-type-specific data payload
91
8/8
✓ Branch 0 taken 1464 times.
✓ Branch 1 taken 7893 times.
✓ Branch 2 taken 5152241 times.
✓ Branch 3 taken 81723 times.
✓ Branch 4 taken 1624506 times.
✓ Branch 5 taken 108 times.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 164185 times.
7032121 switch lhs.superType {
92 case SuperType::TY_ARRAY: {
93 1464 return lhs.data.arraySize == rhs.data.arraySize;
94 }
95 case SuperType::TY_STRUCT: {
96 1624506 assert lhs.data.bodyScope != nil<Scope*> && rhs.data.bodyScope != nil<Scope*>;
97
2/2
✓ Branch 0 taken 28774 times.
✓ Branch 1 taken 1595732 times.
1624506 return lhs.typeId == rhs.typeId && areQualTypeListsEqual(lhs.templateTypes, rhs.templateTypes);
98 }
99 case SuperType::TY_INTERFACE: {
100 7893 return lhs.typeId == rhs.typeId;
101 }
102 case SuperType::TY_UNION: {
103 108 assert lhs.data.bodyScope != nil<Scope*> && rhs.data.bodyScope != nil<Scope*>;
104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 return lhs.typeId == rhs.typeId && areQualTypeListsEqual(lhs.templateTypes, rhs.templateTypes);
105 }
106 case SuperType::TY_ENUM: {
107 1 assert lhs.data.bodyScope != nil<Scope*> && rhs.data.bodyScope != nil<Scope*>;
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 return lhs.typeId == rhs.typeId && lhs.data.bodyScope == rhs.data.bodyScope;
109 }
110 case SuperType::TY_FUNCTION, SuperType::TY_PROCEDURE: {
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 81723 times.
81723 if lhs.paramTypes.getSize() != rhs.paramTypes.getSize() {
112 ✗ return false;
113 }
114
2/2
✓ Branch 0 taken 51470 times.
✓ Branch 1 taken 81712 times.
133182 for unsigned long i = 0ul; i < lhs.paramTypes.getSize(); i++ {
115
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 51459 times.
51470 if lhs.paramTypes[i] != rhs.paramTypes[i] {
116 11 return false;
117 }
118 51459 }
119 81712 return true;
120 }
121 case SuperType::TY_GENERIC: {
122 164185 return lhs.subType == rhs.subType;
123 }
124 default: {
125 5152241 return true;
126 }
127 }
128 ✗ }
129
130 7119570 public f<bool> operator!=(const TypeChainElement& lhs, const TypeChainElement& rhs) {
131 7119570 return !(lhs == rhs);
132 }
133
134 1949865 public p TypeChainElement.getName(StringStream& name, bool withSize, bool ignorePublic, bool withAliases) {
135
19/21
✓ Branch 0 taken 190466 times.
✓ Branch 1 taken 222758 times.
✓ Branch 2 taken 2168 times.
✓ Branch 3 taken 10727 times.
✓ Branch 4 taken 167079 times.
✓ Branch 5 taken 12415 times.
✓ Branch 6 taken 155137 times.
✓ Branch 7 taken 81114 times.
✓ Branch 8 taken 76005 times.
✓ Branch 9 taken 116487 times.
✓ Branch 10 taken 103992 times.
✓ Branch 11 taken 879 times.
✓ Branch 12 taken 760 times.
✓ Branch 13 taken 78317 times.
✓ Branch 14 taken 59311 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 373697 times.
✓ Branch 18 taken 254982 times.
✓ Branch 19 taken 4141 times.
✓ Branch 20 taken 39430 times.
1949865 switch this.superType {
136 case SuperType::TY_PTR: {
137 190466 name << "*";
138 190466 }
139 case SuperType::TY_REF: {
140 222758 name << "&";
141 222758 }
142 case SuperType::TY_ARRAY: {
143 2168 name << "[";
144
4/4
✓ Branch 0 taken 657 times.
✓ Branch 1 taken 1511 times.
✓ Branch 2 taken 1355 times.
✓ Branch 3 taken 813 times.
2168 if withSize && this.data.arraySize != ARRAY_SIZE_UNKNOWN {
145 813 name << toString(this.data.arraySize);
146 813 }
147 2168 name << "]";
148 2168 }
149 case SuperType::TY_DOUBLE: {
150 10727 name << "double";
151 10727 }
152 case SuperType::TY_INT: {
153 167079 name << "int";
154 167079 }
155 case SuperType::TY_SHORT: {
156 12415 name << "short";
157 12415 }
158 case SuperType::TY_LONG: {
159 155137 name << "long";
160 155137 }
161 case SuperType::TY_BYTE: {
162 81114 name << "byte";
163 81114 }
164 case SuperType::TY_CHAR: {
165 76005 name << "char";
166 76005 }
167 case SuperType::TY_STRING: {
168 116487 name << (withAliases ? "string" : "const char*");
169 116487 }
170 case SuperType::TY_BOOL: {
171 103992 name << "bool";
172 103992 }
173 case SuperType::TY_STRUCT, SuperType::TY_INTERFACE, SuperType::TY_UNION: {
174 373697 name << this.subType << getDisambiguationSuffix(this.subType, this.typeId);
175
2/2
✓ Branch 0 taken 167437 times.
✓ Branch 1 taken 206260 times.
373697 if !this.templateTypes.isEmpty() {
176 167437 name << "<";
177
2/2
✓ Branch 0 taken 209472 times.
✓ Branch 1 taken 167437 times.
376909 foreach unsigned long i, const QualType& templateType : this.templateTypes {
178
2/2
✓ Branch 0 taken 167437 times.
✓ Branch 1 taken 42035 times.
209472 if i > 0 { name << ","; }
179 209472 templateType.getName(name, withSize, ignorePublic);
180 209472 }
181 167437 name << ">";
182 167437 }
183 373697 }
184 case SuperType::TY_ENUM: {
185 879 name << "enum(" << this.subType << ")";
186 879 }
187 case SuperType::TY_GENERIC, SuperType::TY_ALIAS: {
188 254982 name << this.subType;
189 254982 }
190 case SuperType::TY_DYN: {
191 760 name << "dyn";
192 760 }
193 case SuperType::TY_FUNCTION: {
194 78317 name << "f";
195
2/2
✓ Branch 0 taken 78262 times.
✓ Branch 1 taken 55 times.
78317 if this.data.hasCaptures { name << "[]"; }
196
2/2
✓ Branch 0 taken 760 times.
✓ Branch 1 taken 77557 times.
78317 if !this.paramTypes.isEmpty() {
197 77557 const QualType& returnType = this.paramTypes.front();
198 77557 name << "<";
199 77557 returnType.getName(name, true, ignorePublic);
200 77557 name << ">";
201 77557 }
202 78317 name << "(";
203
2/2
✓ Branch 0 taken 85345 times.
✓ Branch 1 taken 78317 times.
163662 for unsigned long i = 1ul; i < this.paramTypes.getSize(); i++ {
204
2/2
✓ Branch 0 taken 50831 times.
✓ Branch 1 taken 34514 times.
85345 if i > 1ul { name << ","; }
205 85345 const QualType& paramType = this.paramTypes.get(i);
206 85345 paramType.getName(name, true, ignorePublic);
207 85345 }
208 78317 name << ")";
209 78317 }
210 case SuperType::TY_PROCEDURE: {
211 59311 name << "p";
212
2/2
✓ Branch 0 taken 59026 times.
✓ Branch 1 taken 285 times.
59311 if this.data.hasCaptures { name << "[]"; }
213 59311 name << "(";
214
2/2
✓ Branch 0 taken 59963 times.
✓ Branch 1 taken 59311 times.
119274 for unsigned long i = 1ul; i < this.paramTypes.getSize(); i++ {
215
2/2
✓ Branch 0 taken 41829 times.
✓ Branch 1 taken 18134 times.
59963 if i > 1ul { name << ","; }
216 59963 const QualType& paramType = this.paramTypes.get(i);
217 59963 paramType.getName(name, true, ignorePublic);
218 59963 }
219 59311 name << ")";
220 59311 }
221 case SuperType::TY_IMPORT: {
222 4141 name << "import";
223 4141 }
224 case SuperType::TY_UNRESOLVED: {
225 ✗ name << "unresolved";
226 ✗ }
227 case SuperType::TY_INVALID: {
228 39430 name << "invalid";
229 39430 }
230 default: {
231 ✗ panic(Error("Could not get name of this type chain element"));
232 }
233 }
234 1949865 }
235
236 /**
237 * Return the type name as string
238 *
239 * @param withSize Also encode array sizes
240 * @param ignorePublic Ignore public qualifier
241 * @param withAliases Print aliases as is and not decompose them
242 * @return Name as string
243 */
244 ✗ public const f<String> TypeChainElement.getName(bool withSize, bool ignorePublic, bool withAliases) {
245 ✗ StringStream name;
246 ✗ this.getName(name, withSize, ignorePublic, withAliases);
247 ✗ return name.str();
248 ✗ }
249
250 public type TypeChain alias Vector<TypeChainElement>;
251