GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 97.6% 80 / 0 / 82
Functions: 100.0% 17 / 0 / 17
Branches: 62.1% 108 / 0 / 174

src/model/Function.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "Function.h"
4
5 #include <ast/ASTBuilder.h>
6 #include <ast/ASTNodes.h>
7 #include <irgenerator/NameMangling.h>
8 #include <symboltablebuilder/SymbolTableBuilder.h>
9
10 namespace spice::compiler {
11
12 15606 Function::Function(std::string name, SymbolTableEntry *entry, const QualType &thisType, const QualType &returnType,
13 15606 ParamList paramList, std::vector<GenericType> templateTypes, ASTNode *declNode)
14 15606 : name(std::move(name)), thisType(thisType), returnType(returnType), paramList(std::move(paramList)),
15 15606 templateTypes(std::move(templateTypes)), entry(entry), declNode(declNode) {}
16
17 /**
18 * Retrieve the parameter types of the current function
19 *
20 * @return Vector of parameter types
21 */
22 66942 QualTypeList Function::getParamTypes() const {
23 66942 QualTypeList newParamTypes;
24
2/2
✓ Branch 8 → 4 taken 114970 times.
✓ Branch 8 → 9 taken 66942 times.
181912 for (const auto &[qualType, isOptional] : paramList)
25
1/2
✓ Branch 5 → 6 taken 114970 times.
✗ Branch 5 → 11 not taken.
114970 newParamTypes.push_back(qualType);
26 66942 return newParamTypes;
27 }
28
29 /**
30 * Get a string representation of the current function.
31 *
32 * Example:
33 * string Vector<double>.setData<double>(double)
34 *
35 * @param withThisType Include 'this' type in signature
36 * @param withTemplateTypes Include concrete template types in the signature
37 * @param withTypeAliases Print type aliases as is and not decompose them
38 * @return String representation as function signature
39 */
40 58473 std::string Function::getSignature(bool withThisType /*=true*/, bool withTemplateTypes /*=true*/,
41 bool withTypeAliases /*=true*/) const {
42 58473 QualTypeList concreteTemplateTypes;
43
2/2
✓ Branch 2 → 3 taken 58471 times.
✓ Branch 2 → 27 taken 2 times.
58473 if (withTemplateTypes) {
44
1/2
✓ Branch 4 → 5 taken 58471 times.
✗ Branch 4 → 33 not taken.
58471 concreteTemplateTypes.reserve(templateTypes.size());
45
2/2
✓ Branch 25 → 7 taken 35475 times.
✓ Branch 25 → 26 taken 58471 times.
93946 for (const GenericType &genericType : templateTypes) {
46
7/8
✓ Branch 8 → 9 taken 35475 times.
✗ Branch 8 → 32 not taken.
✓ Branch 9 → 10 taken 35463 times.
✓ Branch 9 → 13 taken 12 times.
✓ Branch 11 → 12 taken 19009 times.
✓ Branch 11 → 13 taken 16454 times.
✓ Branch 14 → 15 taken 19009 times.
✓ Branch 14 → 22 taken 16466 times.
35475 if (genericType.is(TY_GENERIC) && !typeMapping.empty()) {
47
3/6
✓ Branch 15 → 16 taken 19009 times.
✗ Branch 15 → 32 not taken.
✓ Branch 16 → 17 taken 19009 times.
✗ Branch 16 → 32 not taken.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 19009 times.
19009 assert(typeMapping.contains(genericType.getSubType()));
48
3/6
✓ Branch 19 → 20 taken 19009 times.
✗ Branch 19 → 32 not taken.
✓ Branch 20 → 21 taken 19009 times.
✗ Branch 20 → 32 not taken.
✓ Branch 21 → 23 taken 19009 times.
✗ Branch 21 → 32 not taken.
19009 concreteTemplateTypes.push_back(typeMapping.at(genericType.getSubType()));
49 } else {
50
1/2
✓ Branch 22 → 23 taken 16466 times.
✗ Branch 22 → 32 not taken.
16466 concreteTemplateTypes.push_back(genericType);
51 }
52 }
53 }
54
55
1/2
✓ Branch 27 → 28 taken 58473 times.
✗ Branch 27 → 33 not taken.
116946 return getSignature(name, thisType, returnType, paramList, concreteTemplateTypes, true, withThisType, true, withTypeAliases);
56 58473 }
57
58 /**
59 * Get a string representation of the current function.
60 *
61 * @param name Function name
62 * @param thisType This symbol type
63 * @param returnType Return symbol type
64 * @param paramList Param symbol types
65 * @param concreteTemplateTypes Concrete template symbol types
66 * @param withReturnType Include return type in signature
67 * @param withThisType Include 'this' type in signature
68 * @param ignorePublic Not include public modifiers in signature
69 * @param withTypeAliases Print type aliases as is and not decompose them
70 * @return Function signature
71 */
72 58485 std::string Function::getSignature(const std::string &name, const QualType &thisType, const QualType &returnType,
73 const ParamList &paramList, const QualTypeList &concreteTemplateTypes,
74 bool withReturnType /*=true*/, bool withThisType /*=true*/, bool ignorePublic /*=false*/,
75 bool withTypeAliases /*=true*/) {
76
1/2
✓ Branch 2 → 3 taken 58485 times.
✗ Branch 2 → 81 not taken.
58485 std::stringstream signature;
77
78 // Build return type string
79
2/2
✓ Branch 3 → 4 taken 58473 times.
✓ Branch 3 → 10 taken 12 times.
58485 if (withReturnType) {
80
3/4
✓ Branch 4 → 5 taken 58473 times.
✗ Branch 4 → 79 not taken.
✓ Branch 5 → 6 taken 23937 times.
✓ Branch 5 → 7 taken 34536 times.
58473 if (returnType.is(TY_DYN)) {
81
1/2
✓ Branch 6 → 10 taken 23937 times.
✗ Branch 6 → 79 not taken.
23937 signature << "p ";
82 } else {
83
1/2
✓ Branch 7 → 8 taken 34536 times.
✗ Branch 7 → 79 not taken.
34536 signature << "f<";
84
1/2
✓ Branch 8 → 9 taken 34536 times.
✗ Branch 8 → 79 not taken.
34536 returnType.getName(signature, false, ignorePublic, withTypeAliases);
85
1/2
✓ Branch 9 → 10 taken 34536 times.
✗ Branch 9 → 79 not taken.
34536 signature << "> ";
86 }
87 }
88
89 // Build this type string
90
7/8
✓ Branch 10 → 11 taken 23357 times.
✓ Branch 10 → 14 taken 35128 times.
✓ Branch 11 → 12 taken 23357 times.
✗ Branch 11 → 79 not taken.
✓ Branch 12 → 13 taken 13038 times.
✓ Branch 12 → 14 taken 10319 times.
✓ Branch 15 → 16 taken 13038 times.
✓ Branch 15 → 35 taken 45447 times.
58485 if (withThisType && !thisType.is(TY_DYN)) {
91
3/6
✓ Branch 16 → 17 taken 13038 times.
✗ Branch 16 → 69 not taken.
✓ Branch 17 → 18 taken 13038 times.
✗ Branch 17 → 69 not taken.
✓ Branch 18 → 19 taken 13038 times.
✗ Branch 18 → 69 not taken.
13038 signature << thisType.getBase().getSubType();
92
1/2
✓ Branch 19 → 20 taken 13038 times.
✗ Branch 19 → 79 not taken.
13038 const QualTypeList &thisTemplateTypes = thisType.getTemplateTypes();
93
2/2
✓ Branch 21 → 22 taken 6276 times.
✓ Branch 21 → 34 taken 6762 times.
13038 if (!thisTemplateTypes.empty()) {
94
1/2
✓ Branch 22 → 23 taken 6276 times.
✗ Branch 22 → 79 not taken.
6276 signature << "<";
95
2/2
✓ Branch 32 → 24 taken 8032 times.
✓ Branch 32 → 33 taken 6276 times.
14308 for (size_t i = 0; i < thisTemplateTypes.size(); i++) {
96
2/2
✓ Branch 24 → 25 taken 1756 times.
✓ Branch 24 → 26 taken 6276 times.
8032 if (i > 0)
97
1/2
✓ Branch 25 → 26 taken 1756 times.
✗ Branch 25 → 79 not taken.
1756 signature << ",";
98
3/6
✓ Branch 26 → 27 taken 8032 times.
✗ Branch 26 → 72 not taken.
✓ Branch 27 → 28 taken 8032 times.
✗ Branch 27 → 72 not taken.
✓ Branch 28 → 29 taken 8032 times.
✗ Branch 28 → 70 not taken.
8032 signature << thisTemplateTypes.at(i).getName(false, ignorePublic, withTypeAliases);
99 }
100
1/2
✓ Branch 33 → 34 taken 6276 times.
✗ Branch 33 → 79 not taken.
6276 signature << ">";
101 }
102
1/2
✓ Branch 34 → 35 taken 13038 times.
✗ Branch 34 → 79 not taken.
13038 signature << MEMBER_ACCESS_TOKEN;
103 }
104
105 // Name
106
1/2
✓ Branch 35 → 36 taken 58485 times.
✗ Branch 35 → 79 not taken.
58485 signature << name;
107
108 // Build template type string
109
2/2
✓ Branch 37 → 38 taken 26185 times.
✓ Branch 37 → 50 taken 32300 times.
58485 if (!concreteTemplateTypes.empty()) {
110
1/2
✓ Branch 38 → 39 taken 26185 times.
✗ Branch 38 → 79 not taken.
26185 signature << "<";
111
2/2
✓ Branch 48 → 40 taken 35475 times.
✓ Branch 48 → 49 taken 26185 times.
61660 for (size_t i = 0; i < concreteTemplateTypes.size(); i++) {
112
2/2
✓ Branch 40 → 41 taken 9290 times.
✓ Branch 40 → 42 taken 26185 times.
35475 if (i > 0)
113
1/2
✓ Branch 41 → 42 taken 9290 times.
✗ Branch 41 → 79 not taken.
9290 signature << ",";
114
3/6
✓ Branch 42 → 43 taken 35475 times.
✗ Branch 42 → 75 not taken.
✓ Branch 43 → 44 taken 35475 times.
✗ Branch 43 → 75 not taken.
✓ Branch 44 → 45 taken 35475 times.
✗ Branch 44 → 73 not taken.
35475 signature << concreteTemplateTypes.at(i).getName(false, ignorePublic, withTypeAliases);
115 }
116
1/2
✓ Branch 49 → 50 taken 26185 times.
✗ Branch 49 → 79 not taken.
26185 signature << ">";
117 }
118
119 // Parameter type string
120
1/2
✓ Branch 50 → 51 taken 58485 times.
✗ Branch 50 → 79 not taken.
58485 signature << "(";
121
2/2
✓ Branch 62 → 52 taken 74363 times.
✓ Branch 62 → 63 taken 58485 times.
132848 for (size_t i = 0; i < paramList.size(); i++) {
122
1/2
✓ Branch 52 → 53 taken 74363 times.
✗ Branch 52 → 79 not taken.
74363 const auto &[qualType, isOptional] = paramList.at(i);
123
2/2
✓ Branch 53 → 54 taken 30631 times.
✓ Branch 53 → 55 taken 43732 times.
74363 if (i > 0)
124
1/2
✓ Branch 54 → 55 taken 30631 times.
✗ Branch 54 → 79 not taken.
30631 signature << ",";
125
2/4
✓ Branch 55 → 56 taken 74363 times.
✗ Branch 55 → 78 not taken.
✓ Branch 56 → 57 taken 74363 times.
✗ Branch 56 → 76 not taken.
74363 signature << qualType.getName(false, ignorePublic, withTypeAliases);
126
1/2
✗ Branch 58 → 59 not taken.
✓ Branch 58 → 60 taken 74363 times.
74363 if (isOptional)
127 signature << "?";
128 }
129
1/2
✓ Branch 63 → 64 taken 58485 times.
✗ Branch 63 → 79 not taken.
58485 signature << ")";
130
131
1/2
✓ Branch 64 → 65 taken 58485 times.
✗ Branch 64 → 79 not taken.
116970 return signature.str();
132 58485 }
133
134 35128 std::string Function::getScopeName() const { return getSignature(false, true, false); }
135
136 37121 std::string Function::getMangledName() const {
137 // Use predefined mangled name if available
138
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 37120 times.
37121 if (!predefinedMangledName.empty())
139 1 return predefinedMangledName;
140 // Use function name if mangling is disabled
141
2/2
✓ Branch 5 → 6 taken 3839 times.
✓ Branch 5 → 7 taken 33281 times.
37120 if (!mangleFunctionName)
142 3839 return name;
143 // Use normal name mangling
144 33281 return NameMangling::mangleFunction(*this);
145 }
146
147 26905 std::string Function::getSymbolTableEntryName(const std::string &functionName, const CodeLoc &codeLoc) {
148
3/6
✓ Branch 2 → 3 taken 26905 times.
✗ Branch 2 → 15 not taken.
✓ Branch 3 → 4 taken 26905 times.
✗ Branch 3 → 12 not taken.
✓ Branch 4 → 5 taken 26905 times.
✗ Branch 4 → 10 not taken.
26905 return functionName + ":" + codeLoc.toString();
149 }
150
151 69 std::string Function::getSymbolTableEntryNameDefaultCtor(const CodeLoc &structCodeLoc) {
152
5/10
✓ Branch 2 → 3 taken 69 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 69 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 69 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 69 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 69 times.
✗ Branch 8 → 17 not taken.
207 return "default_" + std::string(CTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString();
153 }
154
155 224 std::string Function::getSymbolTableEntryNameDefaultCopyCtor(const CodeLoc &structCodeLoc) {
156
5/10
✓ Branch 2 → 3 taken 224 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 224 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 224 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 224 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 224 times.
✗ Branch 8 → 17 not taken.
672 return "default_copy" + std::string(CTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString();
157 }
158
159 118 std::string Function::getSymbolTableEntryNameDefaultDtor(const CodeLoc &structCodeLoc) {
160
5/10
✓ Branch 2 → 3 taken 118 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 118 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 118 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 118 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 118 times.
✗ Branch 8 → 17 not taken.
354 return "default_" + std::string(DTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString();
161 }
162
163 /**
164 * Checks if a function contains optional parameters.
165 * This would imply that the function is not substantiated by its optional parameters yet.
166 *
167 * @return Substantiated params or not
168 */
169 1221008 bool Function::hasSubstantiatedParams() const {
170 3080303 return std::ranges::none_of(paramList, [](const Param &param) { return param.isOptional; });
171 }
172
173 /**
174 * Checks if a function contains template types.
175 * This would imply that the function is not substantiated by its generic types yet.
176 *
177 * @return Substantiated generics or not
178 */
179 121613 bool Function::hasSubstantiatedGenerics() const {
180 71170 const auto predicate = [this](const GenericType &genericType) { return typeMapping.contains(genericType.getSubType()); };
181
1/2
✓ Branch 2 → 3 taken 121613 times.
✗ Branch 2 → 6 not taken.
243226 return std::ranges::all_of(templateTypes, predicate);
182 }
183
184 /**
185 * Checks if a function contains optional parameters or has generic types present.
186 * This would imply that the function is not fully substantiated yet.
187 *
188 * @return Fully substantiated or not
189 */
190
3/4
✓ Branch 3 → 4 taken 121613 times.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 78026 times.
✓ Branch 5 → 7 taken 43587 times.
121613 bool Function::isFullySubstantiated() const { return hasSubstantiatedParams() && hasSubstantiatedGenerics(); }
191
192 /**
193 * Returns, if this function is a substantiation of a generic one.
194 *
195 * @return Generic substantiation or not
196 */
197 1013137 bool Function::isGenericSubstantiation() const { return genericPreset != nullptr; }
198
199 /**
200 * Retrieve the declaration code location of this function
201 *
202 * @return Declaration code location
203 */
204 5053 const CodeLoc &Function::getDeclCodeLoc() const { return declNode->codeLoc; }
205
206 } // namespace spice::compiler
207