GCC Code Coverage Report


Directory: ../
File: src/model/Function.cpp
Date: 2025-12-08 21:11:42
Coverage Exec Excl Total
Lines: 97.5% 77 0 79
Functions: 100.0% 16 0 16
Branches: 61.5% 107 0 174

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 60651 QualTypeList Function::getParamTypes() const {
19 60651 QualTypeList newParamTypes;
20
2/2
✓ Branch 8 → 4 taken 105172 times.
✓ Branch 8 → 9 taken 60651 times.
165823 for (const auto &[qualType, isOptional] : paramList)
21
1/2
✓ Branch 5 → 6 taken 105172 times.
✗ Branch 5 → 11 not taken.
105172 newParamTypes.push_back(qualType);
22 60651 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 53123 std::string Function::getSignature(bool withThisType /*=true*/, bool withTemplateTypes /*=true*/,
37 bool withTypeAliases /*=true*/) const {
38 53123 QualTypeList concreteTemplateTypes;
39
2/2
✓ Branch 2 → 3 taken 31896 times.
✓ Branch 2 → 27 taken 21227 times.
53123 if (withTemplateTypes) {
40
1/2
✓ Branch 4 → 5 taken 31896 times.
✗ Branch 4 → 33 not taken.
31896 concreteTemplateTypes.reserve(templateTypes.size());
41
2/2
✓ Branch 25 → 7 taken 17972 times.
✓ Branch 25 → 26 taken 31896 times.
49868 for (const GenericType &genericType : templateTypes) {
42
6/8
✓ Branch 8 → 9 taken 17972 times.
✗ Branch 8 → 32 not taken.
✓ Branch 9 → 10 taken 17972 times.
✗ Branch 9 → 13 not taken.
✓ Branch 11 → 12 taken 8321 times.
✓ Branch 11 → 13 taken 9651 times.
✓ Branch 14 → 15 taken 8321 times.
✓ Branch 14 → 22 taken 9651 times.
17972 if (genericType.is(TY_GENERIC) && !typeMapping.empty()) {
43
3/6
✓ Branch 15 → 16 taken 8321 times.
✗ Branch 15 → 32 not taken.
✓ Branch 16 → 17 taken 8321 times.
✗ Branch 16 → 32 not taken.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 8321 times.
8321 assert(typeMapping.contains(genericType.getSubType()));
44
3/6
✓ Branch 19 → 20 taken 8321 times.
✗ Branch 19 → 32 not taken.
✓ Branch 20 → 21 taken 8321 times.
✗ Branch 20 → 32 not taken.
✓ Branch 21 → 23 taken 8321 times.
✗ Branch 21 → 32 not taken.
8321 concreteTemplateTypes.push_back(typeMapping.at(genericType.getSubType()));
45 } else {
46
1/2
✓ Branch 22 → 23 taken 9651 times.
✗ Branch 22 → 32 not taken.
9651 concreteTemplateTypes.push_back(genericType);
47 }
48 }
49 }
50
51
1/2
✓ Branch 27 → 28 taken 53123 times.
✗ Branch 27 → 33 not taken.
106246 return getSignature(name, thisType, returnType, paramList, concreteTemplateTypes, true, withThisType, true, withTypeAliases);
52 53123 }
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 53135 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 53135 times.
✗ Branch 2 → 81 not taken.
53135 std::stringstream signature;
73
74 // Build return type string
75
2/2
✓ Branch 3 → 4 taken 53123 times.
✓ Branch 3 → 10 taken 12 times.
53135 if (withReturnType) {
76
3/4
✓ Branch 4 → 5 taken 53123 times.
✗ Branch 4 → 79 not taken.
✓ Branch 5 → 6 taken 21493 times.
✓ Branch 5 → 7 taken 31630 times.
53123 if (returnType.is(TY_DYN)) {
77
1/2
✓ Branch 6 → 10 taken 21493 times.
✗ Branch 6 → 79 not taken.
21493 signature << "p ";
78 } else {
79
1/2
✓ Branch 7 → 8 taken 31630 times.
✗ Branch 7 → 79 not taken.
31630 signature << "f<";
80
1/2
✓ Branch 8 → 9 taken 31630 times.
✗ Branch 8 → 79 not taken.
31630 returnType.getName(signature, false, ignorePublic, withTypeAliases);
81
1/2
✓ Branch 9 → 10 taken 31630 times.
✗ Branch 9 → 79 not taken.
31630 signature << "> ";
82 }
83 }
84
85 // Build this type string
86
7/8
✓ Branch 10 → 11 taken 21278 times.
✓ Branch 10 → 14 taken 31857 times.
✓ Branch 11 → 12 taken 21278 times.
✗ Branch 11 → 79 not taken.
✓ Branch 12 → 13 taken 11791 times.
✓ Branch 12 → 14 taken 9487 times.
✓ Branch 15 → 16 taken 11791 times.
✓ Branch 15 → 35 taken 41344 times.
53135 if (withThisType && !thisType.is(TY_DYN)) {
87
3/6
✓ Branch 16 → 17 taken 11791 times.
✗ Branch 16 → 69 not taken.
✓ Branch 17 → 18 taken 11791 times.
✗ Branch 17 → 69 not taken.
✓ Branch 18 → 19 taken 11791 times.
✗ Branch 18 → 69 not taken.
11791 signature << thisType.getBase().getSubType();
88
1/2
✓ Branch 19 → 20 taken 11791 times.
✗ Branch 19 → 79 not taken.
11791 const QualTypeList &thisTemplateTypes = thisType.getTemplateTypes();
89
2/2
✓ Branch 21 → 22 taken 5603 times.
✓ Branch 21 → 34 taken 6188 times.
11791 if (!thisTemplateTypes.empty()) {
90
1/2
✓ Branch 22 → 23 taken 5603 times.
✗ Branch 22 → 79 not taken.
5603 signature << "<";
91
2/2
✓ Branch 32 → 24 taken 7142 times.
✓ Branch 32 → 33 taken 5603 times.
12745 for (size_t i = 0; i < thisTemplateTypes.size(); i++) {
92
2/2
✓ Branch 24 → 25 taken 1539 times.
✓ Branch 24 → 26 taken 5603 times.
7142 if (i > 0)
93
1/2
✓ Branch 25 → 26 taken 1539 times.
✗ Branch 25 → 79 not taken.
1539 signature << ",";
94
3/6
✓ Branch 26 → 27 taken 7142 times.
✗ Branch 26 → 72 not taken.
✓ Branch 27 → 28 taken 7142 times.
✗ Branch 27 → 72 not taken.
✓ Branch 28 → 29 taken 7142 times.
✗ Branch 28 → 70 not taken.
7142 signature << thisTemplateTypes.at(i).getName(false, ignorePublic, withTypeAliases);
95 }
96
1/2
✓ Branch 33 → 34 taken 5603 times.
✗ Branch 33 → 79 not taken.
5603 signature << ">";
97 }
98
1/2
✓ Branch 34 → 35 taken 11791 times.
✗ Branch 34 → 79 not taken.
11791 signature << MEMBER_ACCESS_TOKEN;
99 }
100
101 // Name
102
1/2
✓ Branch 35 → 36 taken 53135 times.
✗ Branch 35 → 79 not taken.
53135 signature << name;
103
104 // Build template type string
105
2/2
✓ Branch 37 → 38 taken 13184 times.
✓ Branch 37 → 50 taken 39951 times.
53135 if (!concreteTemplateTypes.empty()) {
106
1/2
✓ Branch 38 → 39 taken 13184 times.
✗ Branch 38 → 79 not taken.
13184 signature << "<";
107
2/2
✓ Branch 48 → 40 taken 17972 times.
✓ Branch 48 → 49 taken 13184 times.
31156 for (size_t i = 0; i < concreteTemplateTypes.size(); i++) {
108
2/2
✓ Branch 40 → 41 taken 4788 times.
✓ Branch 40 → 42 taken 13184 times.
17972 if (i > 0)
109
1/2
✓ Branch 41 → 42 taken 4788 times.
✗ Branch 41 → 79 not taken.
4788 signature << ",";
110
3/6
✓ Branch 42 → 43 taken 17972 times.
✗ Branch 42 → 75 not taken.
✓ Branch 43 → 44 taken 17972 times.
✗ Branch 43 → 75 not taken.
✓ Branch 44 → 45 taken 17972 times.
✗ Branch 44 → 73 not taken.
17972 signature << concreteTemplateTypes.at(i).getName(false, ignorePublic, withTypeAliases);
111 }
112
1/2
✓ Branch 49 → 50 taken 13184 times.
✗ Branch 49 → 79 not taken.
13184 signature << ">";
113 }
114
115 // Parameter type string
116
1/2
✓ Branch 50 → 51 taken 53135 times.
✗ Branch 50 → 79 not taken.
53135 signature << "(";
117
2/2
✓ Branch 62 → 52 taken 67975 times.
✓ Branch 62 → 63 taken 53135 times.
121110 for (size_t i = 0; i < paramList.size(); i++) {
118
1/2
✓ Branch 52 → 53 taken 67975 times.
✗ Branch 52 → 79 not taken.
67975 const auto &[qualType, isOptional] = paramList.at(i);
119
2/2
✓ Branch 53 → 54 taken 28300 times.
✓ Branch 53 → 55 taken 39675 times.
67975 if (i > 0)
120
1/2
✓ Branch 54 → 55 taken 28300 times.
✗ Branch 54 → 79 not taken.
28300 signature << ",";
121
2/4
✓ Branch 55 → 56 taken 67975 times.
✗ Branch 55 → 78 not taken.
✓ Branch 56 → 57 taken 67975 times.
✗ Branch 56 → 76 not taken.
67975 signature << qualType.getName(false, ignorePublic, withTypeAliases);
122
1/2
✗ Branch 58 → 59 not taken.
✓ Branch 58 → 60 taken 67975 times.
67975 if (isOptional)
123 signature << "?";
124 }
125
1/2
✓ Branch 63 → 64 taken 53135 times.
✗ Branch 63 → 79 not taken.
53135 signature << ")";
126
127
1/2
✓ Branch 64 → 65 taken 53135 times.
✗ Branch 64 → 79 not taken.
106270 return signature.str();
128 53135 }
129
130 31857 std::string Function::getScopeName() const {
131 31857 return getSignature(false, true, false);
132 }
133
134 33550 std::string Function::getMangledName() const {
135 // Use predefined mangled name if available
136
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 33549 times.
33550 if (!predefinedMangledName.empty())
137 1 return predefinedMangledName;
138 // Use function name if mangling is disabled
139
2/2
✓ Branch 5 → 6 taken 3277 times.
✓ Branch 5 → 7 taken 30272 times.
33549 if (!mangleFunctionName)
140 3277 return name;
141 // Use normal name mangling
142 30272 return NameMangling::mangleFunction(*this);
143 }
144
145 24605 std::string Function::getSymbolTableEntryName(const std::string &functionName, const CodeLoc &codeLoc) {
146
3/6
✓ Branch 2 → 3 taken 24605 times.
✗ Branch 2 → 15 not taken.
✓ Branch 3 → 4 taken 24605 times.
✗ Branch 3 → 12 not taken.
✓ Branch 4 → 5 taken 24605 times.
✗ Branch 4 → 10 not taken.
24605 return functionName + ":" + codeLoc.toString();
147 }
148
149 62 std::string Function::getSymbolTableEntryNameDefaultCtor(const CodeLoc &structCodeLoc) {
150
5/10
✓ Branch 2 → 3 taken 62 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 62 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 62 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 62 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 62 times.
✗ Branch 8 → 17 not taken.
186 return "default_" + std::string(CTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString();
151 }
152
153 206 std::string Function::getSymbolTableEntryNameDefaultCopyCtor(const CodeLoc &structCodeLoc) {
154
5/10
✓ Branch 2 → 3 taken 206 times.
✗ Branch 2 → 31 not taken.
✓ Branch 5 → 6 taken 206 times.
✗ Branch 5 → 23 not taken.
✓ Branch 6 → 7 taken 206 times.
✗ Branch 6 → 21 not taken.
✓ Branch 7 → 8 taken 206 times.
✗ Branch 7 → 19 not taken.
✓ Branch 8 → 9 taken 206 times.
✗ Branch 8 → 17 not taken.
618 return "default_copy" + std::string(CTOR_FUNCTION_NAME) + ":" + structCodeLoc.toString();
155 }
156
157 107 std::string Function::getSymbolTableEntryNameDefaultDtor(const CodeLoc &structCodeLoc) {
158
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();
159 }
160
161 /**
162 * Checks if a function contains optional parameters.
163 * This would imply that the function is not substantiated by its optional parameters yet.
164 *
165 * @return Substantiated params or not
166 */
167 1143582 bool Function::hasSubstantiatedParams() const {
168 2853201 return std::ranges::none_of(paramList, [](const Param &param) { return param.isOptional; });
169 }
170
171 /**
172 * Checks if a function contains template types.
173 * This would imply that the function is not substantiated by its generic types yet.
174 *
175 * @return Substantiated generics or not
176 */
177 133688 bool Function::hasSubstantiatedGenerics() const {
178 72187 const auto predicate = [this](const GenericType &genericType) { return typeMapping.contains(genericType.getSubType()); };
179
1/2
✓ Branch 2 → 3 taken 133688 times.
✗ Branch 2 → 6 not taken.
267376 return std::ranges::all_of(templateTypes, predicate);
180 }
181
182 /**
183 * Checks if a function contains optional parameters or has generic types present.
184 * This would imply that the function is not fully substantiated yet.
185 *
186 * @return Fully substantiated or not
187 */
188
3/4
✓ Branch 3 → 4 taken 133688 times.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 86874 times.
✓ Branch 5 → 7 taken 46814 times.
133688 bool Function::isFullySubstantiated() const { return hasSubstantiatedParams() && hasSubstantiatedGenerics(); }
189
190 /**
191 * Returns, if this function is a substantiation of a generic one.
192 *
193 * @return Generic substantiation or not
194 */
195 907563 bool Function::isGenericSubstantiation() const { return genericPreset != nullptr; }
196
197 /**
198 * Retrieve the declaration code location of this function
199 *
200 * @return Declaration code location
201 */
202 4453 const CodeLoc &Function::getDeclCodeLoc() const { return declNode->codeLoc; }
203
204 } // namespace spice::compiler
205