GCC Code Coverage Report


Directory: ../
File: src/model/Function.cpp
Date: 2024-12-24 01:17:15
Exec Total Coverage
Lines: 68 70 97.1%
Functions: 12 12 100.0%
Branches: 89 142 62.7%

Line Branch Exec Source
1 // Copyright (c) 2021-2024 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
9 namespace spice::compiler {
10
11 /**
12 * Retrieve the parameter types of the current function
13 *
14 * @return Vector of parameter types
15 */
16 24909 QualTypeList Function::getParamTypes() const {
17 24909 QualTypeList newParamTypes;
18
2/2
✓ Branch 5 taken 33852 times.
✓ Branch 6 taken 24909 times.
58761 for (const auto &[qualType, isOptional] : paramList)
19
1/2
✓ Branch 1 taken 33852 times.
✗ Branch 2 not taken.
33852 newParamTypes.push_back(qualType);
20 24909 return newParamTypes;
21 }
22
23 /**
24 * Get a string representation of the current function.
25 *
26 * Example:
27 * string Vector<double>.setData<double>(double)
28 *
29 * @param withThisType Include 'this' type in signature
30 * @param ignorePublic Not include public modifiers in signature
31 * @return String representation as function signature
32 */
33 29444 std::string Function::getSignature(bool withThisType /*=true*/, bool ignorePublic /*=false*/) const {
34 29444 QualTypeList concreteTemplateTypes;
35
1/2
✓ Branch 2 taken 29444 times.
✗ Branch 3 not taken.
29444 concreteTemplateTypes.reserve(templateTypes.size());
36
2/2
✓ Branch 5 taken 15551 times.
✓ Branch 6 taken 29444 times.
44995 for (const GenericType &genericType : templateTypes) {
37
6/8
✓ Branch 1 taken 15551 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15551 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 7172 times.
✓ Branch 7 taken 8379 times.
✓ Branch 8 taken 7172 times.
✓ Branch 9 taken 8379 times.
15551 if (genericType.is(TY_GENERIC) && !typeMapping.empty()) {
38
3/6
✓ Branch 1 taken 7172 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7172 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 7172 times.
7172 assert(typeMapping.contains(genericType.getSubType()));
39
3/6
✓ Branch 1 taken 7172 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7172 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7172 times.
✗ Branch 8 not taken.
7172 concreteTemplateTypes.push_back(typeMapping.at(genericType.getSubType()));
40 } else {
41
1/2
✓ Branch 1 taken 8379 times.
✗ Branch 2 not taken.
8379 concreteTemplateTypes.push_back(genericType);
42 }
43 }
44
45
1/2
✓ Branch 1 taken 29444 times.
✗ Branch 2 not taken.
58888 return Function::getSignature(name, thisType, returnType, paramList, concreteTemplateTypes, withThisType, ignorePublic);
46 29444 }
47
48 /**
49 * Get a string representation of the current function.
50 *
51 * @param name Function name
52 * @param thisType This symbol type
53 * @param returnType Return symbol type
54 * @param paramList Param symbol types
55 * @param concreteTemplateTypes Concrete template symbol types
56 * @param withReturnType Include return type in signature
57 * @param withThisType Include 'this' type in signature
58 * @param ignorePublic Not include public modifiers in signature
59 * @return Function signature
60 */
61 29456 std::string Function::getSignature(const std::string &name, const QualType &thisType, const QualType &returnType,
62 const ParamList &paramList, const QualTypeList &concreteTemplateTypes,
63 bool withReturnType /*=true*/, bool withThisType /*=true*/, bool ignorePublic /*=false*/) {
64
1/2
✓ Branch 1 taken 29456 times.
✗ Branch 2 not taken.
29456 std::stringstream signature;
65
66 // Build return type string
67
2/2
✓ Branch 0 taken 11823 times.
✓ Branch 1 taken 17633 times.
29456 if (withReturnType) {
68
3/4
✓ Branch 1 taken 11823 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4864 times.
✓ Branch 4 taken 6959 times.
11823 if (returnType.is(TY_DYN)) {
69
1/2
✓ Branch 1 taken 4864 times.
✗ Branch 2 not taken.
4864 signature << "p ";
70 } else {
71
1/2
✓ Branch 1 taken 6959 times.
✗ Branch 2 not taken.
6959 signature << "f<";
72
1/2
✓ Branch 1 taken 6959 times.
✗ Branch 2 not taken.
6959 returnType.getName(signature, false, ignorePublic);
73
1/2
✓ Branch 1 taken 6959 times.
✗ Branch 2 not taken.
6959 signature << "> ";
74 }
75 }
76
77 // Build this type string
78
6/8
✓ Branch 0 taken 29456 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 29456 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20596 times.
✓ Branch 6 taken 8860 times.
✓ Branch 7 taken 20596 times.
✓ Branch 8 taken 8860 times.
29456 if (withThisType && !thisType.is(TY_DYN)) {
79
3/6
✓ Branch 1 taken 20596 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20596 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20596 times.
✗ Branch 8 not taken.
20596 signature << thisType.getBase().getSubType();
80
1/2
✓ Branch 1 taken 20596 times.
✗ Branch 2 not taken.
20596 const QualTypeList &thisTemplateTypes = thisType.getTemplateTypes();
81
2/2
✓ Branch 1 taken 8805 times.
✓ Branch 2 taken 11791 times.
20596 if (!thisTemplateTypes.empty()) {
82
1/2
✓ Branch 1 taken 8805 times.
✗ Branch 2 not taken.
8805 signature << "<";
83
2/2
✓ Branch 1 taken 10967 times.
✓ Branch 2 taken 8805 times.
19772 for (size_t i = 0; i < thisTemplateTypes.size(); i++) {
84
2/2
✓ Branch 0 taken 2162 times.
✓ Branch 1 taken 8805 times.
10967 if (i > 0)
85
1/2
✓ Branch 1 taken 2162 times.
✗ Branch 2 not taken.
2162 signature << ",";
86
3/6
✓ Branch 1 taken 10967 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10967 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10967 times.
✗ Branch 8 not taken.
10967 signature << thisTemplateTypes.at(i).getName(false, ignorePublic);
87 }
88
1/2
✓ Branch 1 taken 8805 times.
✗ Branch 2 not taken.
8805 signature << ">";
89 }
90
1/2
✓ Branch 1 taken 20596 times.
✗ Branch 2 not taken.
20596 signature << MEMBER_ACCESS_TOKEN;
91 }
92
93 // Name
94
1/2
✓ Branch 1 taken 29456 times.
✗ Branch 2 not taken.
29456 signature << name;
95
96 // Build template type string
97
2/2
✓ Branch 1 taken 12839 times.
✓ Branch 2 taken 16617 times.
29456 if (!concreteTemplateTypes.empty()) {
98
1/2
✓ Branch 1 taken 12839 times.
✗ Branch 2 not taken.
12839 signature << "<";
99
2/2
✓ Branch 1 taken 15551 times.
✓ Branch 2 taken 12839 times.
28390 for (size_t i = 0; i < concreteTemplateTypes.size(); i++) {
100
2/2
✓ Branch 0 taken 2712 times.
✓ Branch 1 taken 12839 times.
15551 if (i > 0)
101
1/2
✓ Branch 1 taken 2712 times.
✗ Branch 2 not taken.
2712 signature << ",";
102
3/6
✓ Branch 1 taken 15551 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15551 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 15551 times.
✗ Branch 8 not taken.
15551 signature << concreteTemplateTypes.at(i).getName(false, ignorePublic);
103 }
104
1/2
✓ Branch 1 taken 12839 times.
✗ Branch 2 not taken.
12839 signature << ">";
105 }
106
107 // Parameter type string
108
1/2
✓ Branch 1 taken 29456 times.
✗ Branch 2 not taken.
29456 signature << "(";
109
2/2
✓ Branch 1 taken 30264 times.
✓ Branch 2 taken 29456 times.
59720 for (size_t i = 0; i < paramList.size(); i++) {
110
1/2
✓ Branch 1 taken 30264 times.
✗ Branch 2 not taken.
30264 const auto &[qualType, isOptional] = paramList.at(i);
111
2/2
✓ Branch 0 taken 10156 times.
✓ Branch 1 taken 20108 times.
30264 if (i > 0)
112
1/2
✓ Branch 1 taken 10156 times.
✗ Branch 2 not taken.
10156 signature << ",";
113
2/4
✓ Branch 1 taken 30264 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30264 times.
✗ Branch 5 not taken.
30264 signature << qualType.getName(false, ignorePublic);
114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30264 times.
30264 if (isOptional)
115 signature << "?";
116 }
117
1/2
✓ Branch 1 taken 29456 times.
✗ Branch 2 not taken.
29456 signature << ")";
118
119
1/2
✓ Branch 1 taken 29456 times.
✗ Branch 2 not taken.
58912 return signature.str();
120 29456 }
121
122 17763 std::string Function::getMangledName() const {
123 // Use predefined mangled name if available
124
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 17762 times.
17763 if (!predefinedMangledName.empty())
125 1 return predefinedMangledName;
126 // Use function name if mangling is disabled
127
2/2
✓ Branch 0 taken 2114 times.
✓ Branch 1 taken 15648 times.
17762 if (!mangleFunctionName)
128 2114 return name;
129 // Use normal name mangling
130 15648 return NameMangling::mangleFunction(*this);
131 }
132
133 14152 std::string Function::getSymbolTableEntryName(const std::string &functionName, const CodeLoc &codeLoc) {
134
3/6
✓ Branch 1 taken 14152 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14152 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14152 times.
✗ Branch 8 not taken.
14152 return functionName + ":" + codeLoc.toString();
135 }
136
137 /**
138 * Checks if a function contains optional parameters.
139 * This would imply that the function is not substantiated by its optional parameters yet.
140 *
141 * @return Substantiated params or not
142 */
143 602245 bool Function::hasSubstantiatedParams() const {
144 1348874 return std::ranges::none_of(paramList, [](const Param &param) { return param.isOptional; });
145 }
146
147 /**
148 * Checks if a function contains template types.
149 * This would imply that the function is not substantiated by its generic types yet.
150 *
151 * @return Substantiated generics or not
152 */
153 169878 bool Function::hasSubstantiatedGenerics() const {
154 89284 const auto predicate = [this](const GenericType &genericType) { return typeMapping.contains(genericType.getSubType()); };
155
1/2
✓ Branch 1 taken 169878 times.
✗ Branch 2 not taken.
339756 return std::ranges::all_of(templateTypes, predicate);
156 }
157
158 /**
159 * Checks if a function contains optional parameters or has generic types present.
160 * This would imply that the function is not fully substantiated yet.
161 *
162 * @return Fully substantiated or not
163 */
164
3/4
✓ Branch 1 taken 169878 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 116599 times.
✓ Branch 5 taken 53279 times.
169878 bool Function::isFullySubstantiated() const { return hasSubstantiatedParams() && hasSubstantiatedGenerics(); }
165
166 /**
167 * Returns, if this function is a substantiation of a generic one.
168 *
169 * @return Generic substantiation or not
170 */
171 321965 bool Function::isGenericSubstantiation() const { return genericPreset != nullptr; }
172
173 /**
174 * Retrieve the declaration code location of this function
175 *
176 * @return Declaration code location
177 */
178 2864 const CodeLoc &Function::getDeclCodeLoc() const { return declNode->codeLoc; }
179
180 } // namespace spice::compiler
181