GCC Code Coverage Report


Directory: ../
File: src/model/Function.cpp
Date: 2026-01-03 22:25:30
Coverage Exec Excl Total
Lines: 97.4% 76 0 78
Functions: 100.0% 16 0 16
Branches: 62.1% 108 0 174

Line Branch Exec Source
1 // Copyright (c) 2021-2026 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 61118 QualTypeList Function::getParamTypes() const {
19 61118 QualTypeList newParamTypes;
20
2/2
✓ Branch 8 → 4 taken 106013 times.
✓ Branch 8 → 9 taken 61118 times.
167131 for (const auto &[qualType, isOptional] : paramList)
21
1/2
✓ Branch 5 → 6 taken 106013 times.
✗ Branch 5 → 11 not taken.
106013 newParamTypes.push_back(qualType);
22 61118 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 * @param withTypeAliases Print type aliases as is and not decompose them
34 * @return String representation as function signature
35 */
36 53531 std::string Function::getSignature(bool withThisType /*=true*/, bool withTemplateTypes /*=true*/,
37 bool withTypeAliases /*=true*/) const {
38 53531 QualTypeList concreteTemplateTypes;
39
2/2
✓ Branch 2 → 3 taken 32146 times.
✓ Branch 2 → 27 taken 21385 times.
53531 if (withTemplateTypes) {
40
1/2
✓ Branch 4 → 5 taken 32146 times.
✗ Branch 4 → 33 not taken.
32146 concreteTemplateTypes.reserve(templateTypes.size());
41
2/2
✓ Branch 25 → 7 taken 18128 times.
✓ Branch 25 → 26 taken 32146 times.
50274 for (const GenericType &genericType : templateTypes) {
42
7/8
✓ Branch 8 → 9 taken 18128 times.
✗ Branch 8 → 32 not taken.
✓ Branch 9 → 10 taken 18125 times.
✓ Branch 9 → 13 taken 3 times.
✓ Branch 11 → 12 taken 8401 times.
✓ Branch 11 → 13 taken 9724 times.
✓ Branch 14 → 15 taken 8401 times.
✓ Branch 14 → 22 taken 9727 times.
18128 if (genericType.is(TY_GENERIC) && !typeMapping.empty()) {
43
3/6
✓ Branch 15 → 16 taken 8401 times.
✗ Branch 15 → 32 not taken.
✓ Branch 16 → 17 taken 8401 times.
✗ Branch 16 → 32 not taken.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 8401 times.
8401 assert(typeMapping.contains(genericType.getSubType()));
44
3/6
✓ Branch 19 → 20 taken 8401 times.
✗ Branch 19 → 32 not taken.
✓ Branch 20 → 21 taken 8401 times.
✗ Branch 20 → 32 not taken.
✓ Branch 21 → 23 taken 8401 times.
✗ Branch 21 → 32 not taken.
8401 concreteTemplateTypes.push_back(typeMapping.at(genericType.getSubType()));
45 } else {
46
1/2
✓ Branch 22 → 23 taken 9727 times.
✗ Branch 22 → 32 not taken.
9727 concreteTemplateTypes.push_back(genericType);
47 }
48 }
49 }
50
51
1/2
✓ Branch 27 → 28 taken 53531 times.
✗ Branch 27 → 33 not taken.
107062 return getSignature(name, thisType, returnType, paramList, concreteTemplateTypes, true, withThisType, true, withTypeAliases);
52 53531 }
53
54 /**
55 * Get a string representation of the current function.
56 *
57 * @param name Function name
58 * @param thisType This symbol type
59 * @param returnType Return symbol type
60 * @param paramList Param symbol types
61 * @param concreteTemplateTypes Concrete template symbol types
62 * @param withReturnType Include return type in signature
63 * @param withThisType Include 'this' type in signature
64 * @param ignorePublic Not include public modifiers in signature
65 * @param withTypeAliases Print type aliases as is and not decompose them
66 * @return Function signature
67 */
68 53543 std::string Function::getSignature(const std::string &name, const QualType &thisType, const QualType &returnType,
69 const ParamList &paramList, const QualTypeList &concreteTemplateTypes,
70 bool withReturnType /*=true*/, bool withThisType /*=true*/, bool ignorePublic /*=false*/,
71 bool withTypeAliases /*=true*/) {
72
1/2
✓ Branch 2 → 3 taken 53543 times.
✗ Branch 2 → 81 not taken.
53543 std::stringstream signature;
73
74 // Build return type string
75
2/2
✓ Branch 3 → 4 taken 53531 times.
✓ Branch 3 → 10 taken 12 times.
53543 if (withReturnType) {
76
3/4
✓ Branch 4 → 5 taken 53531 times.
✗ Branch 4 → 79 not taken.
✓ Branch 5 → 6 taken 21690 times.
✓ Branch 5 → 7 taken 31841 times.
53531 if (returnType.is(TY_DYN)) {
77
1/2
✓ Branch 6 → 10 taken 21690 times.
✗ Branch 6 → 79 not taken.
21690 signature << "p ";
78 } else {
79
1/2
✓ Branch 7 → 8 taken 31841 times.
✗ Branch 7 → 79 not taken.
31841 signature << "f<";
80
1/2
✓ Branch 8 → 9 taken 31841 times.
✗ Branch 8 → 79 not taken.
31841 returnType.getName(signature, false, ignorePublic, withTypeAliases);
81
1/2
✓ Branch 9 → 10 taken 31841 times.
✗ Branch 9 → 79 not taken.
31841 signature << "> ";
82 }
83 }
84
85 // Build this type string
86
7/8
✓ Branch 10 → 11 taken 21436 times.
✓ Branch 10 → 14 taken 32107 times.
✓ Branch 11 → 12 taken 21436 times.
✗ Branch 11 → 79 not taken.
✓ Branch 12 → 13 taken 11873 times.
✓ Branch 12 → 14 taken 9563 times.
✓ Branch 15 → 16 taken 11873 times.
✓ Branch 15 → 35 taken 41670 times.
53543 if (withThisType && !thisType.is(TY_DYN)) {
87
3/6
✓ Branch 16 → 17 taken 11873 times.
✗ Branch 16 → 69 not taken.
✓ Branch 17 → 18 taken 11873 times.
✗ Branch 17 → 69 not taken.
✓ Branch 18 → 19 taken 11873 times.
✗ Branch 18 → 69 not taken.
11873 signature << thisType.getBase().getSubType();
88
1/2
✓ Branch 19 → 20 taken 11873 times.
✗ Branch 19 → 79 not taken.
11873 const QualTypeList &thisTemplateTypes = thisType.getTemplateTypes();
89
2/2
✓ Branch 21 → 22 taken 5626 times.
✓ Branch 21 → 34 taken 6247 times.
11873 if (!thisTemplateTypes.empty()) {
90
1/2
✓ Branch 22 → 23 taken 5626 times.
✗ Branch 22 → 79 not taken.
5626 signature << "<";
91
2/2
✓ Branch 32 → 24 taken 7172 times.
✓ Branch 32 → 33 taken 5626 times.
12798 for (size_t i = 0; i < thisTemplateTypes.size(); i++) {
92
2/2
✓ Branch 24 → 25 taken 1546 times.
✓ Branch 24 → 26 taken 5626 times.
7172 if (i > 0)
93
1/2
✓ Branch 25 → 26 taken 1546 times.
✗ Branch 25 → 79 not taken.
1546 signature << ",";
94
3/6
✓ Branch 26 → 27 taken 7172 times.
✗ Branch 26 → 72 not taken.
✓ Branch 27 → 28 taken 7172 times.
✗ Branch 27 → 72 not taken.
✓ Branch 28 → 29 taken 7172 times.
✗ Branch 28 → 70 not taken.
7172 signature << thisTemplateTypes.at(i).getName(false, ignorePublic, withTypeAliases);
95 }
96
1/2
✓ Branch 33 → 34 taken 5626 times.
✗ Branch 33 → 79 not taken.
5626 signature << ">";
97 }
98
1/2
✓ Branch 34 → 35 taken 11873 times.
✗ Branch 34 → 79 not taken.
11873 signature << MEMBER_ACCESS_TOKEN;
99 }
100
101 // Name
102
1/2
✓ Branch 35 → 36 taken 53543 times.
✗ Branch 35 → 79 not taken.
53543 signature << name;
103
104 // Build template type string
105
2/2
✓ Branch 37 → 38 taken 13281 times.
✓ Branch 37 → 50 taken 40262 times.
53543 if (!concreteTemplateTypes.empty()) {
106
1/2
✓ Branch 38 → 39 taken 13281 times.
✗ Branch 38 → 79 not taken.
13281 signature << "<";
107
2/2
✓ Branch 48 → 40 taken 18128 times.
✓ Branch 48 → 49 taken 13281 times.
31409 for (size_t i = 0; i < concreteTemplateTypes.size(); i++) {
108
2/2
✓ Branch 40 → 41 taken 4847 times.
✓ Branch 40 → 42 taken 13281 times.
18128 if (i > 0)
109
1/2
✓ Branch 41 → 42 taken 4847 times.
✗ Branch 41 → 79 not taken.
4847 signature << ",";
110
3/6
✓ Branch 42 → 43 taken 18128 times.
✗ Branch 42 → 75 not taken.
✓ Branch 43 → 44 taken 18128 times.
✗ Branch 43 → 75 not taken.
✓ Branch 44 → 45 taken 18128 times.
✗ Branch 44 → 73 not taken.
18128 signature << concreteTemplateTypes.at(i).getName(false, ignorePublic, withTypeAliases);
111 }
112
1/2
✓ Branch 49 → 50 taken 13281 times.
✗ Branch 49 → 79 not taken.
13281 signature << ">";
113 }
114
115 // Parameter type string
116
1/2
✓ Branch 50 → 51 taken 53543 times.
✗ Branch 50 → 79 not taken.
53543 signature << "(";
117
2/2
✓ Branch 62 → 52 taken 68568 times.
✓ Branch 62 → 63 taken 53543 times.
122111 for (size_t i = 0; i < paramList.size(); i++) {
118
1/2
✓ Branch 52 → 53 taken 68568 times.
✗ Branch 52 → 79 not taken.
68568 const auto &[qualType, isOptional] = paramList.at(i);
119
2/2
✓ Branch 53 → 54 taken 28580 times.
✓ Branch 53 → 55 taken 39988 times.
68568 if (i > 0)
120
1/2
✓ Branch 54 → 55 taken 28580 times.
✗ Branch 54 → 79 not taken.
28580 signature << ",";
121
2/4
✓ Branch 55 → 56 taken 68568 times.
✗ Branch 55 → 78 not taken.
✓ Branch 56 → 57 taken 68568 times.
✗ Branch 56 → 76 not taken.
68568 signature << qualType.getName(false, ignorePublic, withTypeAliases);
122
1/2
✗ Branch 58 → 59 not taken.
✓ Branch 58 → 60 taken 68568 times.
68568 if (isOptional)
123 signature << "?";
124 }
125
1/2
✓ Branch 63 → 64 taken 53543 times.
✗ Branch 63 → 79 not taken.
53543 signature << ")";
126
127
1/2
✓ Branch 64 → 65 taken 53543 times.
✗ Branch 64 → 79 not taken.
107086 return signature.str();
128 53543 }
129
130 32107 std::string Function::getScopeName() const { return getSignature(false, true, false); }
131
132 33791 std::string Function::getMangledName() const {
133 // Use predefined mangled name if available
134
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 33790 times.
33791 if (!predefinedMangledName.empty())
135 1 return predefinedMangledName;
136 // Use function name if mangling is disabled
137
2/2
✓ Branch 5 → 6 taken 3295 times.
✓ Branch 5 → 7 taken 30495 times.
33790 if (!mangleFunctionName)
138 3295 return name;
139 // Use normal name mangling
140 30495 return NameMangling::mangleFunction(*this);
141 }
142
143 24783 std::string Function::getSymbolTableEntryName(const std::string &functionName, const CodeLoc &codeLoc) {
144
3/6
✓ Branch 2 → 3 taken 24783 times.
✗ Branch 2 → 15 not taken.
✓ Branch 3 → 4 taken 24783 times.
✗ Branch 3 → 12 not taken.
✓ Branch 4 → 5 taken 24783 times.
✗ Branch 4 → 10 not taken.
24783 return functionName + ":" + codeLoc.toString();
145 }
146
147 64 std::string Function::getSymbolTableEntryNameDefaultCtor(const CodeLoc &structCodeLoc) {
148
5/10
✓ Branch 2 → 3 taken 64 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 64 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 64 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 64 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 64 times.
✗ Branch 8 → 17 not taken.
192 return "default_" + std::string(CTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString();
149 }
150
151 210 std::string Function::getSymbolTableEntryNameDefaultCopyCtor(const CodeLoc &structCodeLoc) {
152
5/10
✓ Branch 2 → 3 taken 210 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 210 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 210 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 210 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 210 times.
✗ Branch 8 → 17 not taken.
630 return "default_copy" + std::string(CTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString();
153 }
154
155 107 std::string Function::getSymbolTableEntryNameDefaultDtor(const CodeLoc &structCodeLoc) {
156
5/10
✓ Branch 2 → 3 taken 107 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 107 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 107 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 107 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 107 times.
✗ Branch 8 → 17 not taken.
321 return "default_" + std::string(DTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString();
157 }
158
159 /**
160 * Checks if a function contains optional parameters.
161 * This would imply that the function is not substantiated by its optional parameters yet.
162 *
163 * @return Substantiated params or not
164 */
165 1151346 bool Function::hasSubstantiatedParams() const {
166 2875232 return std::ranges::none_of(paramList, [](const Param &param) { return param.isOptional; });
167 }
168
169 /**
170 * Checks if a function contains template types.
171 * This would imply that the function is not substantiated by its generic types yet.
172 *
173 * @return Substantiated generics or not
174 */
175 134595 bool Function::hasSubstantiatedGenerics() const {
176 72573 const auto predicate = [this](const GenericType &genericType) { return typeMapping.contains(genericType.getSubType()); };
177
1/2
✓ Branch 2 → 3 taken 134595 times.
✗ Branch 2 → 6 not taken.
269190 return std::ranges::all_of(templateTypes, predicate);
178 }
179
180 /**
181 * Checks if a function contains optional parameters or has generic types present.
182 * This would imply that the function is not fully substantiated yet.
183 *
184 * @return Fully substantiated or not
185 */
186
3/4
✓ Branch 3 → 4 taken 134595 times.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 87586 times.
✓ Branch 5 → 7 taken 47009 times.
134595 bool Function::isFullySubstantiated() const { return hasSubstantiatedParams() && hasSubstantiatedGenerics(); }
187
188 /**
189 * Returns, if this function is a substantiation of a generic one.
190 *
191 * @return Generic substantiation or not
192 */
193 913784 bool Function::isGenericSubstantiation() const { return genericPreset != nullptr; }
194
195 /**
196 * Retrieve the declaration code location of this function
197 *
198 * @return Declaration code location
199 */
200 4501 const CodeLoc &Function::getDeclCodeLoc() const { return declNode->codeLoc; }
201
202 } // namespace spice::compiler
203