| 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 ¶mList, 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 ¶m) { 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 |