Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
2 | |||
3 | #include "Function.h" | ||
4 | |||
5 | #include "symboltablebuilder/SymbolTableBuilder.h" | ||
6 | |||
7 | #include <ast/ASTBuilder.h> | ||
8 | #include <ast/ASTNodes.h> | ||
9 | #include <irgenerator/NameMangling.h> | ||
10 | |||
11 | namespace spice::compiler { | ||
12 | |||
13 | /** | ||
14 | * Retrieve the parameter types of the current function | ||
15 | * | ||
16 | * @return Vector of parameter types | ||
17 | */ | ||
18 | 50256 | QualTypeList Function::getParamTypes() const { | |
19 | 50256 | QualTypeList newParamTypes; | |
20 |
2/2✓ Branch 8 → 4 taken 74026 times.
✓ Branch 8 → 9 taken 50256 times.
|
124282 | for (const auto &[qualType, isOptional] : paramList) |
21 |
1/2✓ Branch 5 → 6 taken 74026 times.
✗ Branch 5 → 11 not taken.
|
74026 | newParamTypes.push_back(qualType); |
22 | 50256 | return newParamTypes; | |
23 | ✗ | } | |
24 | |||
25 | /** | ||
26 | * Get a string representation of the current function. | ||
27 | * | ||
28 | * Example: | ||
29 | * string Vector<double>.setData<double>(double) | ||
30 | * | ||
31 | * @param withThisType Include 'this' type in signature | ||
32 | * @param withTemplateTypes Include concrete template types in the signature | ||
33 | * @return String representation as function signature | ||
34 | */ | ||
35 | 45658 | std::string Function::getSignature(bool withThisType /*=true*/, bool withTemplateTypes /*=true*/) const { | |
36 | 45658 | QualTypeList concreteTemplateTypes; | |
37 |
2/2✓ Branch 2 → 3 taken 27549 times.
✓ Branch 2 → 27 taken 18109 times.
|
45658 | if (withTemplateTypes) { |
38 |
1/2✓ Branch 4 → 5 taken 27549 times.
✗ Branch 4 → 33 not taken.
|
27549 | concreteTemplateTypes.reserve(templateTypes.size()); |
39 |
2/2✓ Branch 25 → 7 taken 12499 times.
✓ Branch 25 → 26 taken 27549 times.
|
40048 | for (const GenericType &genericType : templateTypes) { |
40 |
6/8✓ Branch 8 → 9 taken 12499 times.
✗ Branch 8 → 32 not taken.
✓ Branch 9 → 10 taken 12499 times.
✗ Branch 9 → 13 not taken.
✓ Branch 11 → 12 taken 5057 times.
✓ Branch 11 → 13 taken 7442 times.
✓ Branch 14 → 15 taken 5057 times.
✓ Branch 14 → 22 taken 7442 times.
|
12499 | if (genericType.is(TY_GENERIC) && !typeMapping.empty()) { |
41 |
3/6✓ Branch 15 → 16 taken 5057 times.
✗ Branch 15 → 32 not taken.
✓ Branch 16 → 17 taken 5057 times.
✗ Branch 16 → 32 not taken.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 5057 times.
|
5057 | assert(typeMapping.contains(genericType.getSubType())); |
42 |
3/6✓ Branch 19 → 20 taken 5057 times.
✗ Branch 19 → 32 not taken.
✓ Branch 20 → 21 taken 5057 times.
✗ Branch 20 → 32 not taken.
✓ Branch 21 → 23 taken 5057 times.
✗ Branch 21 → 32 not taken.
|
5057 | concreteTemplateTypes.push_back(typeMapping.at(genericType.getSubType())); |
43 | } else { | ||
44 |
1/2✓ Branch 22 → 23 taken 7442 times.
✗ Branch 22 → 32 not taken.
|
7442 | concreteTemplateTypes.push_back(genericType); |
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
49 |
1/2✓ Branch 27 → 28 taken 45658 times.
✗ Branch 27 → 33 not taken.
|
91316 | return getSignature(name, thisType, returnType, paramList, concreteTemplateTypes, true, withThisType, true); |
50 | 45658 | } | |
51 | |||
52 | /** | ||
53 | * Get a string representation of the current function. | ||
54 | * | ||
55 | * @param name Function name | ||
56 | * @param thisType This symbol type | ||
57 | * @param returnType Return symbol type | ||
58 | * @param paramList Param symbol types | ||
59 | * @param concreteTemplateTypes Concrete template symbol types | ||
60 | * @param withReturnType Include return type in signature | ||
61 | * @param withThisType Include 'this' type in signature | ||
62 | * @param ignorePublic Not include public modifiers in signature | ||
63 | * @return Function signature | ||
64 | */ | ||
65 | 45670 | std::string Function::getSignature(const std::string &name, const QualType &thisType, const QualType &returnType, | |
66 | const ParamList ¶mList, const QualTypeList &concreteTemplateTypes, | ||
67 | bool withReturnType /*=true*/, bool withThisType /*=true*/, bool ignorePublic /*=false*/) { | ||
68 |
1/2✓ Branch 2 → 3 taken 45670 times.
✗ Branch 2 → 81 not taken.
|
45670 | std::stringstream signature; |
69 | |||
70 | // Build return type string | ||
71 |
2/2✓ Branch 3 → 4 taken 45658 times.
✓ Branch 3 → 10 taken 12 times.
|
45670 | if (withReturnType) { |
72 |
3/4✓ Branch 4 → 5 taken 45658 times.
✗ Branch 4 → 79 not taken.
✓ Branch 5 → 6 taken 16268 times.
✓ Branch 5 → 7 taken 29390 times.
|
45658 | if (returnType.is(TY_DYN)) { |
73 |
1/2✓ Branch 6 → 10 taken 16268 times.
✗ Branch 6 → 79 not taken.
|
16268 | signature << "p "; |
74 | } else { | ||
75 |
1/2✓ Branch 7 → 8 taken 29390 times.
✗ Branch 7 → 79 not taken.
|
29390 | signature << "f<"; |
76 |
1/2✓ Branch 8 → 9 taken 29390 times.
✗ Branch 8 → 79 not taken.
|
29390 | returnType.getName(signature, false, ignorePublic); |
77 |
1/2✓ Branch 9 → 10 taken 29390 times.
✗ Branch 9 → 79 not taken.
|
29390 | signature << "> "; |
78 | } | ||
79 | } | ||
80 | |||
81 | // Build this type string | ||
82 |
7/8✓ Branch 10 → 11 taken 18161 times.
✓ Branch 10 → 14 taken 27509 times.
✓ Branch 11 → 12 taken 18161 times.
✗ Branch 11 → 79 not taken.
✓ Branch 12 → 13 taken 10973 times.
✓ Branch 12 → 14 taken 7188 times.
✓ Branch 15 → 16 taken 10973 times.
✓ Branch 15 → 35 taken 34697 times.
|
45670 | if (withThisType && !thisType.is(TY_DYN)) { |
83 |
3/6✓ Branch 16 → 17 taken 10973 times.
✗ Branch 16 → 69 not taken.
✓ Branch 17 → 18 taken 10973 times.
✗ Branch 17 → 69 not taken.
✓ Branch 18 → 19 taken 10973 times.
✗ Branch 18 → 69 not taken.
|
10973 | signature << thisType.getBase().getSubType(); |
84 |
1/2✓ Branch 19 → 20 taken 10973 times.
✗ Branch 19 → 79 not taken.
|
10973 | const QualTypeList &thisTemplateTypes = thisType.getTemplateTypes(); |
85 |
2/2✓ Branch 21 → 22 taken 5213 times.
✓ Branch 21 → 34 taken 5760 times.
|
10973 | if (!thisTemplateTypes.empty()) { |
86 |
1/2✓ Branch 22 → 23 taken 5213 times.
✗ Branch 22 → 79 not taken.
|
5213 | signature << "<"; |
87 |
2/2✓ Branch 32 → 24 taken 6720 times.
✓ Branch 32 → 33 taken 5213 times.
|
11933 | for (size_t i = 0; i < thisTemplateTypes.size(); i++) { |
88 |
2/2✓ Branch 24 → 25 taken 1507 times.
✓ Branch 24 → 26 taken 5213 times.
|
6720 | if (i > 0) |
89 |
1/2✓ Branch 25 → 26 taken 1507 times.
✗ Branch 25 → 79 not taken.
|
1507 | signature << ","; |
90 |
3/6✓ Branch 26 → 27 taken 6720 times.
✗ Branch 26 → 72 not taken.
✓ Branch 27 → 28 taken 6720 times.
✗ Branch 27 → 72 not taken.
✓ Branch 28 → 29 taken 6720 times.
✗ Branch 28 → 70 not taken.
|
6720 | signature << thisTemplateTypes.at(i).getName(false, ignorePublic); |
91 | } | ||
92 |
1/2✓ Branch 33 → 34 taken 5213 times.
✗ Branch 33 → 79 not taken.
|
5213 | signature << ">"; |
93 | } | ||
94 |
1/2✓ Branch 34 → 35 taken 10973 times.
✗ Branch 34 → 79 not taken.
|
10973 | signature << MEMBER_ACCESS_TOKEN; |
95 | } | ||
96 | |||
97 | // Name | ||
98 |
1/2✓ Branch 35 → 36 taken 45670 times.
✗ Branch 35 → 79 not taken.
|
45670 | signature << name; |
99 | |||
100 | // Build template type string | ||
101 |
2/2✓ Branch 37 → 38 taken 10235 times.
✓ Branch 37 → 50 taken 35435 times.
|
45670 | if (!concreteTemplateTypes.empty()) { |
102 |
1/2✓ Branch 38 → 39 taken 10235 times.
✗ Branch 38 → 79 not taken.
|
10235 | signature << "<"; |
103 |
2/2✓ Branch 48 → 40 taken 12499 times.
✓ Branch 48 → 49 taken 10235 times.
|
22734 | for (size_t i = 0; i < concreteTemplateTypes.size(); i++) { |
104 |
2/2✓ Branch 40 → 41 taken 2264 times.
✓ Branch 40 → 42 taken 10235 times.
|
12499 | if (i > 0) |
105 |
1/2✓ Branch 41 → 42 taken 2264 times.
✗ Branch 41 → 79 not taken.
|
2264 | signature << ","; |
106 |
3/6✓ Branch 42 → 43 taken 12499 times.
✗ Branch 42 → 75 not taken.
✓ Branch 43 → 44 taken 12499 times.
✗ Branch 43 → 75 not taken.
✓ Branch 44 → 45 taken 12499 times.
✗ Branch 44 → 73 not taken.
|
12499 | signature << concreteTemplateTypes.at(i).getName(false, ignorePublic); |
107 | } | ||
108 |
1/2✓ Branch 49 → 50 taken 10235 times.
✗ Branch 49 → 79 not taken.
|
10235 | signature << ">"; |
109 | } | ||
110 | |||
111 | // Parameter type string | ||
112 |
1/2✓ Branch 50 → 51 taken 45670 times.
✗ Branch 50 → 79 not taken.
|
45670 | signature << "("; |
113 |
2/2✓ Branch 62 → 52 taken 49773 times.
✓ Branch 62 → 63 taken 45670 times.
|
95443 | for (size_t i = 0; i < paramList.size(); i++) { |
114 |
1/2✓ Branch 52 → 53 taken 49773 times.
✗ Branch 52 → 79 not taken.
|
49773 | const auto &[qualType, isOptional] = paramList.at(i); |
115 |
2/2✓ Branch 53 → 54 taken 16413 times.
✓ Branch 53 → 55 taken 33360 times.
|
49773 | if (i > 0) |
116 |
1/2✓ Branch 54 → 55 taken 16413 times.
✗ Branch 54 → 79 not taken.
|
16413 | signature << ","; |
117 |
2/4✓ Branch 55 → 56 taken 49773 times.
✗ Branch 55 → 78 not taken.
✓ Branch 56 → 57 taken 49773 times.
✗ Branch 56 → 76 not taken.
|
49773 | signature << qualType.getName(false, ignorePublic); |
118 |
1/2✗ Branch 58 → 59 not taken.
✓ Branch 58 → 60 taken 49773 times.
|
49773 | if (isOptional) |
119 | ✗ | signature << "?"; | |
120 | } | ||
121 |
1/2✓ Branch 63 → 64 taken 45670 times.
✗ Branch 63 → 79 not taken.
|
45670 | signature << ")"; |
122 | |||
123 |
1/2✓ Branch 64 → 65 taken 45670 times.
✗ Branch 64 → 79 not taken.
|
91340 | return signature.str(); |
124 | 45670 | } | |
125 | |||
126 | 29226 | std::string Function::getMangledName() const { | |
127 | // Use predefined mangled name if available | ||
128 |
2/2✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 29225 times.
|
29226 | if (!predefinedMangledName.empty()) |
129 | 1 | return predefinedMangledName; | |
130 | // Use function name if mangling is disabled | ||
131 |
2/2✓ Branch 5 → 6 taken 3056 times.
✓ Branch 5 → 7 taken 26169 times.
|
29225 | if (!mangleFunctionName) |
132 | 3056 | return name; | |
133 | // Use normal name mangling | ||
134 | 26169 | return NameMangling::mangleFunction(*this); | |
135 | } | ||
136 | |||
137 | 22495 | std::string Function::getSymbolTableEntryName(const std::string &functionName, const CodeLoc &codeLoc) { | |
138 |
3/6✓ Branch 2 → 3 taken 22495 times.
✗ Branch 2 → 15 not taken.
✓ Branch 3 → 4 taken 22495 times.
✗ Branch 3 → 12 not taken.
✓ Branch 4 → 5 taken 22495 times.
✗ Branch 4 → 10 not taken.
|
22495 | return functionName + ":" + codeLoc.toString(); |
139 | } | ||
140 | |||
141 | 59 | std::string Function::getSymbolTableEntryNameDefaultCtor(const CodeLoc &structCodeLoc) { | |
142 |
5/10✓ Branch 2 → 3 taken 59 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 59 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 59 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 59 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 59 times.
✗ Branch 8 → 17 not taken.
|
177 | return "default_" + std::string(CTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString(); |
143 | } | ||
144 | |||
145 | 196 | std::string Function::getSymbolTableEntryNameDefaultCopyCtor(const CodeLoc &structCodeLoc) { | |
146 |
5/10✓ Branch 2 → 3 taken 196 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 196 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 196 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 196 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 196 times.
✗ Branch 8 → 17 not taken.
|
588 | return "default_copy" + std::string(CTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString(); |
147 | } | ||
148 | |||
149 | 103 | std::string Function::getSymbolTableEntryNameDefaultDtor(const CodeLoc &structCodeLoc) { | |
150 |
5/10✓ Branch 2 → 3 taken 103 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 103 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 103 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 103 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 103 times.
✗ Branch 8 → 17 not taken.
|
309 | return "default_" + std::string(DTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString(); |
151 | } | ||
152 | |||
153 | /** | ||
154 | * Checks if a function contains optional parameters. | ||
155 | * This would imply that the function is not substantiated by its optional parameters yet. | ||
156 | * | ||
157 | * @return Substantiated params or not | ||
158 | */ | ||
159 | 967005 | bool Function::hasSubstantiatedParams() const { | |
160 | 2354465 | return std::ranges::none_of(paramList, [](const Param ¶m) { return param.isOptional; }); | |
161 | } | ||
162 | |||
163 | /** | ||
164 | * Checks if a function contains template types. | ||
165 | * This would imply that the function is not substantiated by its generic types yet. | ||
166 | * | ||
167 | * @return Substantiated generics or not | ||
168 | */ | ||
169 | 116191 | bool Function::hasSubstantiatedGenerics() const { | |
170 | 57033 | const auto predicate = [this](const GenericType &genericType) { return typeMapping.contains(genericType.getSubType()); }; | |
171 |
1/2✓ Branch 2 → 3 taken 116191 times.
✗ Branch 2 → 6 not taken.
|
232382 | return std::ranges::all_of(templateTypes, predicate); |
172 | } | ||
173 | |||
174 | /** | ||
175 | * Checks if a function contains optional parameters or has generic types present. | ||
176 | * This would imply that the function is not fully substantiated yet. | ||
177 | * | ||
178 | * @return Fully substantiated or not | ||
179 | */ | ||
180 |
3/4✓ Branch 3 → 4 taken 116191 times.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 79574 times.
✓ Branch 5 → 7 taken 36617 times.
|
116191 | bool Function::isFullySubstantiated() const { return hasSubstantiatedParams() && hasSubstantiatedGenerics(); } |
181 | |||
182 | /** | ||
183 | * Returns, if this function is a substantiation of a generic one. | ||
184 | * | ||
185 | * @return Generic substantiation or not | ||
186 | */ | ||
187 | 762380 | bool Function::isGenericSubstantiation() const { return genericPreset != nullptr; } | |
188 | |||
189 | /** | ||
190 | * Retrieve the declaration code location of this function | ||
191 | * | ||
192 | * @return Declaration code location | ||
193 | */ | ||
194 | 4128 | const CodeLoc &Function::getDeclCodeLoc() const { return declNode->codeLoc; } | |
195 | |||
196 | } // namespace spice::compiler | ||
197 |