src/typechecker/TypeCheckerBuiltinFunctions.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (c) 2021-2026 ChilliBits. All rights reserved. | ||
| 2 | |||
| 3 | #include "TypeChecker.h" | ||
| 4 | |||
| 5 | #include <SourceFile.h> | ||
| 6 | #include <ast/ASTNodes.h> | ||
| 7 | #include <driver/Driver.h> | ||
| 8 | #include <global/GlobalResourceManager.h> | ||
| 9 | #include <global/TypeRegistry.h> | ||
| 10 | #include <typechecker/Builtins.h> | ||
| 11 | #include <typechecker/MacroDefs.h> | ||
| 12 | |||
| 13 | namespace spice::compiler { | ||
| 14 | |||
| 15 | 1889 | std::any TypeChecker::visitBuiltinCall(FctCallNode *node) const { | |
| 16 |
2/4✓ Branch 3 → 4 taken 1889 times.
✗ Branch 3 → 68 not taken.
✓ Branch 4 → 5 taken 1889 times.
✗ Branch 4 → 6 not taken.
|
1889 | assert(BUILTIN_FUNCTIONS_MAP.contains(node->fqFunctionName) && "Builtin function not implemented!"); |
| 17 |
1/2✓ Branch 8 → 9 taken 1889 times.
✗ Branch 8 → 69 not taken.
|
1889 | const auto &info = BUILTIN_FUNCTIONS_MAP.find(node->fqFunctionName)->second; |
| 18 | |||
| 19 | 18 | const auto buildErrorMessage = [](unsigned int min, unsigned int max, unsigned int actual, const char *suffix) { | |
| 20 | 18 | std::string expectedStr; | |
| 21 |
2/2✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 15 taken 9 times.
|
18 | if (min == max) |
| 22 |
5/8✓ Branch 4 → 5 taken 3 times.
✓ Branch 4 → 8 taken 6 times.
✓ Branch 7 → 9 taken 3 times.
✗ Branch 7 → 46 not taken.
✓ Branch 11 → 12 taken 3 times.
✓ Branch 11 → 14 taken 6 times.
✗ Branch 46 → 47 not taken.
✗ Branch 46 → 49 not taken.
|
15 | expectedStr = min == 0 ? "no" : std::to_string(min); |
| 23 | else | ||
| 24 |
5/10✓ Branch 17 → 18 taken 9 times.
✗ Branch 17 → 60 not taken.
✓ Branch 18 → 19 taken 9 times.
✗ Branch 18 → 58 not taken.
✓ Branch 19 → 20 taken 9 times.
✗ Branch 19 → 56 not taken.
✓ Branch 20 → 21 taken 9 times.
✗ Branch 20 → 54 not taken.
✓ Branch 21 → 22 taken 9 times.
✗ Branch 21 → 52 not taken.
|
9 | expectedStr = "between " + std::to_string(min) + " and " + std::to_string(max) + " " + suffix; |
| 25 |
5/10✓ Branch 32 → 33 taken 18 times.
✗ Branch 32 → 79 not taken.
✓ Branch 33 → 34 taken 18 times.
✗ Branch 33 → 77 not taken.
✓ Branch 34 → 35 taken 18 times.
✗ Branch 34 → 75 not taken.
✓ Branch 35 → 36 taken 18 times.
✗ Branch 35 → 73 not taken.
✓ Branch 36 → 37 taken 18 times.
✗ Branch 36 → 71 not taken.
|
36 | return "This builtin expects " + expectedStr + " " + suffix + ", but got " + std::to_string(actual); |
| 26 | 18 | }; | |
| 27 | |||
| 28 | // Do basic checks of template types and args, based on the builtin function info | ||
| 29 |
2/2✓ Branch 10 → 11 taken 179 times.
✓ Branch 10 → 12 taken 1710 times.
|
1889 | const size_t numTemplateTypes = node->hasTemplateTypes ? node->templateTypeLst->dataTypes.size() : 0; |
| 30 |
4/4✓ Branch 13 → 14 taken 1886 times.
✓ Branch 13 → 15 taken 3 times.
✓ Branch 14 → 15 taken 6 times.
✓ Branch 14 → 22 taken 1880 times.
|
1889 | if (numTemplateTypes < info.minTemplateTypes || numTemplateTypes > info.maxTemplateTypes) { |
| 31 |
1/2✓ Branch 15 → 16 taken 9 times.
✗ Branch 15 → 74 not taken.
|
9 | const auto msg = buildErrorMessage(info.minTemplateTypes, info.maxTemplateTypes, numTemplateTypes, "template type(s)"); |
| 32 |
3/6✓ Branch 16 → 17 taken 9 times.
✗ Branch 16 → 72 not taken.
✓ Branch 17 → 18 taken 9 times.
✗ Branch 17 → 71 not taken.
✓ Branch 18 → 19 taken 9 times.
✗ Branch 18 → 71 not taken.
|
9 | SOFT_ERROR_ER(node, BUILTIN_TEMPLATE_TYPE_COUNT_MISMATCH, msg); |
| 33 | 9 | } | |
| 34 | |||
| 35 |
2/2✓ Branch 22 → 23 taken 1730 times.
✓ Branch 22 → 24 taken 150 times.
|
1880 | const size_t numArgs = node->hasArgs ? node->argLst->args.size() : 0; |
| 36 |
4/4✓ Branch 25 → 26 taken 1878 times.
✓ Branch 25 → 27 taken 2 times.
✓ Branch 26 → 27 taken 7 times.
✓ Branch 26 → 34 taken 1871 times.
|
1880 | if (numArgs < info.minArgTypes || numArgs > info.maxArgTypes) { |
| 37 |
1/2✓ Branch 27 → 28 taken 9 times.
✗ Branch 27 → 78 not taken.
|
9 | const auto msg = buildErrorMessage(info.minArgTypes, info.maxArgTypes, numArgs, "argument(s)"); |
| 38 |
3/6✓ Branch 28 → 29 taken 9 times.
✗ Branch 28 → 76 not taken.
✓ Branch 29 → 30 taken 9 times.
✗ Branch 29 → 75 not taken.
✓ Branch 30 → 31 taken 9 times.
✗ Branch 30 → 75 not taken.
|
9 | SOFT_ERROR_ER(node, BUILTIN_ARG_COUNT_MISMATCH, msg); |
| 39 | 9 | } | |
| 40 | |||
| 41 |
2/2✓ Branch 34 → 35 taken 180 times.
✓ Branch 34 → 59 taken 1691 times.
|
1871 | if (info.allTemplateTypesOrAllArgTypes) { |
| 42 |
4/4✓ Branch 35 → 36 taken 141 times.
✓ Branch 35 → 47 taken 39 times.
✓ Branch 36 → 37 taken 3 times.
✓ Branch 36 → 47 taken 138 times.
|
180 | if (numTemplateTypes > 0 && numArgs > 0) |
| 43 |
4/8✓ Branch 39 → 40 taken 3 times.
✗ Branch 39 → 81 not taken.
✓ Branch 40 → 41 taken 3 times.
✗ Branch 40 → 79 not taken.
✓ Branch 43 → 44 taken 3 times.
✗ Branch 43 → 85 not taken.
✓ Branch 44 → 45 taken 3 times.
✗ Branch 44 → 85 not taken.
|
9 | SOFT_ERROR_ER(node, BUILTIN_SIGNATURE_MISMATCH, "This builtin expects either template types or arguments, but got both"); |
| 44 |
4/4✓ Branch 47 → 48 taken 39 times.
✓ Branch 47 → 59 taken 138 times.
✓ Branch 48 → 49 taken 3 times.
✓ Branch 48 → 59 taken 36 times.
|
177 | if (numTemplateTypes == 0 && numArgs == 0) |
| 45 |
4/8✓ Branch 51 → 52 taken 3 times.
✗ Branch 51 → 88 not taken.
✓ Branch 52 → 53 taken 3 times.
✗ Branch 52 → 86 not taken.
✓ Branch 55 → 56 taken 3 times.
✗ Branch 55 → 92 not taken.
✓ Branch 56 → 57 taken 3 times.
✗ Branch 56 → 92 not taken.
|
9 | SOFT_ERROR_ER(node, BUILTIN_SIGNATURE_MISMATCH, "This builtin expects either template types or arguments, but got none"); |
| 46 | } | ||
| 47 | |||
| 48 | // If specified, call to TypeChecker delegate to execute further checks | ||
| 49 |
3/8✓ Branch 59 → 60 taken 1865 times.
✗ Branch 59 → 64 not taken.
✗ Branch 60 → 61 not taken.
✓ Branch 60 → 62 taken 1865 times.
✓ Branch 63 → 65 taken 1865 times.
✗ Branch 63 → 93 not taken.
✗ Branch 64 → 65 not taken.
✗ Branch 64 → 93 not taken.
|
1865 | return info.typeCheckerVisitMethod != nullptr ? (this->*info.typeCheckerVisitMethod)(node) : nullptr; |
| 50 | } | ||
| 51 | |||
| 52 | 856 | std::any TypeChecker::visitBuiltinPrintfCall(FctCallNode *node) const { | |
| 53 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 856 times.
|
856 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_PRINTF); |
| 54 | |||
| 55 | // Retrieve templated string | ||
| 56 |
1/2✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 856 times.
|
856 | assert(node->hasArgs); |
| 57 | 856 | const ExprNode *firstArg = node->argLst->args.front(); | |
| 58 |
5/10✓ Branch 9 → 10 taken 856 times.
✗ Branch 9 → 223 not taken.
✓ Branch 10 → 11 taken 856 times.
✗ Branch 10 → 223 not taken.
✓ Branch 11 → 12 taken 856 times.
✗ Branch 11 → 15 not taken.
✓ Branch 12 → 13 taken 856 times.
✗ Branch 12 → 223 not taken.
✓ Branch 13 → 14 taken 856 times.
✗ Branch 13 → 15 not taken.
|
856 | assert(firstArg->getEvaluatedSymbolType(manIdx).is(TY_STRING) && firstArg->hasCompileTimeValue(manIdx)); |
| 59 |
1/2✓ Branch 16 → 17 taken 856 times.
✗ Branch 16 → 223 not taken.
|
856 | const size_t stringOffset = firstArg->getCompileTimeValue(manIdx).stringValueOffset; |
| 60 |
2/4✓ Branch 17 → 18 taken 856 times.
✗ Branch 17 → 223 not taken.
✓ Branch 18 → 19 taken 856 times.
✗ Branch 18 → 223 not taken.
|
856 | const std::string templatedString = resourceManager.compileTimeStringValues.at(stringOffset); |
| 61 | |||
| 62 | // Check if assignment types match placeholder types | ||
| 63 | 856 | size_t placeholderCount = 0; | |
| 64 | 856 | size_t index = templatedString.find_first_of('%'); | |
| 65 |
5/6✓ Branch 133 → 134 taken 703 times.
✓ Branch 133 → 137 taken 848 times.
✓ Branch 135 → 136 taken 703 times.
✗ Branch 135 → 137 not taken.
✓ Branch 138 → 20 taken 703 times.
✓ Branch 138 → 139 taken 848 times.
|
1551 | while (index != std::string::npos && index != templatedString.size() - 1) { |
| 66 | // Check if there is another assignExpr | ||
| 67 |
2/2✓ Branch 21 → 22 taken 1 time.
✓ Branch 21 → 32 taken 702 times.
|
703 | if (node->argLst->args.size() - 1 <= placeholderCount) |
| 68 |
4/8✓ Branch 24 → 25 taken 1 time.
✗ Branch 24 → 161 not taken.
✓ Branch 25 → 26 taken 1 time.
✗ Branch 25 → 159 not taken.
✓ Branch 28 → 29 taken 1 time.
✗ Branch 28 → 165 not taken.
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 165 not taken.
|
3 | SOFT_ERROR_ER(node, PRINTF_ARG_COUNT_ERROR, "The placeholder string contains more placeholders than arguments") |
| 69 | |||
| 70 | // Get next assignment | ||
| 71 |
1/2✓ Branch 32 → 33 taken 702 times.
✗ Branch 32 → 211 not taken.
|
702 | const ExprNode *assignment = node->argLst->args.at(placeholderCount + 1); |
| 72 | // Visit assignment | ||
| 73 |
1/2✓ Branch 33 → 34 taken 702 times.
✗ Branch 33 → 211 not taken.
|
702 | QualType argType = assignment->getEvaluatedSymbolType(manIdx); |
| 74 |
2/8✓ Branch 34 → 35 taken 702 times.
✗ Branch 34 → 211 not taken.
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 40 taken 702 times.
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 166 not taken.
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 166 not taken.
|
702 | HANDLE_UNRESOLVED_TYPE_ER(argType) |
| 75 |
1/2✓ Branch 40 → 41 taken 702 times.
✗ Branch 40 → 167 not taken.
|
702 | argType = argType.removeReferenceWrapper(); |
| 76 | |||
| 77 |
7/8✓ Branch 41 → 42 taken 702 times.
✗ Branch 41 → 211 not taken.
✓ Branch 42 → 43 taken 29 times.
✓ Branch 42 → 55 taken 351 times.
✓ Branch 42 → 67 taken 53 times.
✓ Branch 42 → 79 taken 263 times.
✓ Branch 42 → 100 taken 5 times.
✓ Branch 42 → 119 taken 1 time.
|
702 | switch (templatedString.at(index + 1)) { |
| 78 | 29 | case 'c': { | |
| 79 |
3/4✓ Branch 43 → 44 taken 29 times.
✗ Branch 43 → 211 not taken.
✓ Branch 44 → 45 taken 1 time.
✓ Branch 44 → 54 taken 28 times.
|
29 | if (!argType.is(TY_CHAR)) |
| 80 |
5/10✓ Branch 45 → 46 taken 1 time.
✗ Branch 45 → 172 not taken.
✓ Branch 46 → 47 taken 1 time.
✗ Branch 46 → 170 not taken.
✓ Branch 47 → 48 taken 1 time.
✗ Branch 47 → 168 not taken.
✓ Branch 50 → 51 taken 1 time.
✗ Branch 50 → 174 not taken.
✓ Branch 51 → 52 taken 1 time.
✗ Branch 51 → 174 not taken.
|
1 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, "The placeholder string expects char, but got " + argType.getName(false)) |
| 81 | 28 | placeholderCount++; | |
| 82 | 28 | break; | |
| 83 | } | ||
| 84 | 351 | case 'd': | |
| 85 | case 'i': | ||
| 86 | case 'l': | ||
| 87 | case 'o': | ||
| 88 | case 'u': | ||
| 89 | case 'x': | ||
| 90 | case 'X': { | ||
| 91 |
3/4✓ Branch 55 → 56 taken 351 times.
✗ Branch 55 → 175 not taken.
✓ Branch 56 → 57 taken 2 times.
✓ Branch 56 → 66 taken 349 times.
|
351 | if (!argType.isOneOf({TY_INT, TY_SHORT, TY_LONG, TY_BYTE, TY_BOOL})) |
| 92 |
5/10✓ Branch 57 → 58 taken 2 times.
✗ Branch 57 → 180 not taken.
✓ Branch 58 → 59 taken 2 times.
✗ Branch 58 → 178 not taken.
✓ Branch 59 → 60 taken 2 times.
✗ Branch 59 → 176 not taken.
✓ Branch 62 → 63 taken 2 times.
✗ Branch 62 → 182 not taken.
✓ Branch 63 → 64 taken 2 times.
✗ Branch 63 → 182 not taken.
|
2 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, |
| 93 | "The placeholder string expects int, short, long, byte or bool, but got " + argType.getName(false)) | ||
| 94 | 349 | placeholderCount++; | |
| 95 | 349 | break; | |
| 96 | } | ||
| 97 | 53 | case 'a': | |
| 98 | case 'A': | ||
| 99 | case 'f': | ||
| 100 | case 'F': | ||
| 101 | case 'e': | ||
| 102 | case 'E': | ||
| 103 | case 'g': | ||
| 104 | case 'G': { | ||
| 105 |
3/4✓ Branch 67 → 68 taken 53 times.
✗ Branch 67 → 211 not taken.
✓ Branch 68 → 69 taken 1 time.
✓ Branch 68 → 78 taken 52 times.
|
53 | if (!argType.is(TY_DOUBLE)) |
| 106 |
5/10✓ Branch 69 → 70 taken 1 time.
✗ Branch 69 → 187 not taken.
✓ Branch 70 → 71 taken 1 time.
✗ Branch 70 → 185 not taken.
✓ Branch 71 → 72 taken 1 time.
✗ Branch 71 → 183 not taken.
✓ Branch 74 → 75 taken 1 time.
✗ Branch 74 → 189 not taken.
✓ Branch 75 → 76 taken 1 time.
✗ Branch 75 → 189 not taken.
|
1 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, "The placeholder string expects double, but got " + argType.getName(false)) |
| 107 | 52 | placeholderCount++; | |
| 108 | 52 | break; | |
| 109 | } | ||
| 110 | 263 | case 's': { | |
| 111 |
13/18✓ Branch 79 → 80 taken 263 times.
✗ Branch 79 → 211 not taken.
✓ Branch 80 → 81 taken 63 times.
✓ Branch 80 → 88 taken 200 times.
✓ Branch 81 → 82 taken 63 times.
✗ Branch 81 → 211 not taken.
✓ Branch 82 → 83 taken 2 times.
✓ Branch 82 → 88 taken 61 times.
✓ Branch 83 → 84 taken 2 times.
✗ Branch 83 → 211 not taken.
✓ Branch 84 → 85 taken 1 time.
✓ Branch 84 → 88 taken 1 time.
✓ Branch 85 → 86 taken 1 time.
✗ Branch 85 → 211 not taken.
✓ Branch 86 → 87 taken 1 time.
✗ Branch 86 → 88 not taken.
✓ Branch 89 → 90 taken 1 time.
✓ Branch 89 → 99 taken 262 times.
|
263 | if (!argType.is(TY_STRING) && !argType.isStringObj() && !argType.isPtrTo(TY_CHAR) && !argType.isArrayOf(TY_CHAR)) |
| 112 |
5/10✓ Branch 90 → 91 taken 1 time.
✗ Branch 90 → 194 not taken.
✓ Branch 91 → 92 taken 1 time.
✗ Branch 91 → 192 not taken.
✓ Branch 92 → 93 taken 1 time.
✗ Branch 92 → 190 not taken.
✓ Branch 95 → 96 taken 1 time.
✗ Branch 95 → 196 not taken.
✓ Branch 96 → 97 taken 1 time.
✗ Branch 96 → 196 not taken.
|
1 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, |
| 113 | "The placeholder string expects string, String, char* or char[], but got " + argType.getName(false)) | ||
| 114 | 262 | placeholderCount++; | |
| 115 | 262 | break; | |
| 116 | } | ||
| 117 | 5 | case 'p': { | |
| 118 |
9/14✓ Branch 100 → 101 taken 5 times.
✗ Branch 100 → 211 not taken.
✓ Branch 101 → 102 taken 1 time.
✓ Branch 101 → 107 taken 4 times.
✓ Branch 102 → 103 taken 1 time.
✗ Branch 102 → 211 not taken.
✓ Branch 103 → 104 taken 1 time.
✗ Branch 103 → 107 not taken.
✓ Branch 104 → 105 taken 1 time.
✗ Branch 104 → 211 not taken.
✓ Branch 105 → 106 taken 1 time.
✗ Branch 105 → 107 not taken.
✓ Branch 108 → 109 taken 1 time.
✓ Branch 108 → 118 taken 4 times.
|
5 | if (!argType.isPtr() && !argType.isArray() && !argType.is(TY_STRING)) |
| 119 |
5/10✓ Branch 109 → 110 taken 1 time.
✗ Branch 109 → 201 not taken.
✓ Branch 110 → 111 taken 1 time.
✗ Branch 110 → 199 not taken.
✓ Branch 111 → 112 taken 1 time.
✗ Branch 111 → 197 not taken.
✓ Branch 114 → 115 taken 1 time.
✗ Branch 114 → 203 not taken.
✓ Branch 115 → 116 taken 1 time.
✗ Branch 115 → 203 not taken.
|
1 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, |
| 120 | "The placeholder string expects pointer, array or string, but got " + argType.getName(false)) | ||
| 121 | 4 | placeholderCount++; | |
| 122 | 4 | break; | |
| 123 | } | ||
| 124 | 1 | default: | |
| 125 |
4/8✓ Branch 121 → 122 taken 1 time.
✗ Branch 121 → 206 not taken.
✓ Branch 122 → 123 taken 1 time.
✗ Branch 122 → 204 not taken.
✓ Branch 125 → 126 taken 1 time.
✗ Branch 125 → 210 not taken.
✓ Branch 126 → 127 taken 1 time.
✗ Branch 126 → 210 not taken.
|
3 | SOFT_ERROR_ER(node, PRINTF_TYPE_ERROR, "The placeholder string contains an invalid placeholder") |
| 126 | } | ||
| 127 | 695 | index = templatedString.find_first_of('%', index + 2); // We can also skip the following char | |
| 128 | } | ||
| 129 | |||
| 130 | // Check if the number of placeholders matches the number of args | ||
| 131 |
2/2✓ Branch 140 → 141 taken 1 time.
✓ Branch 140 → 151 taken 847 times.
|
848 | if (placeholderCount < node->argLst->args.size() - 1) |
| 132 |
4/8✓ Branch 143 → 144 taken 1 time.
✗ Branch 143 → 214 not taken.
✓ Branch 144 → 145 taken 1 time.
✗ Branch 144 → 212 not taken.
✓ Branch 147 → 148 taken 1 time.
✗ Branch 147 → 218 not taken.
✓ Branch 148 → 149 taken 1 time.
✗ Branch 148 → 218 not taken.
|
3 | SOFT_ERROR_ER(node, PRINTF_ARG_COUNT_ERROR, "The placeholder string contains less placeholders than arguments") |
| 133 | |||
| 134 |
3/6✓ Branch 151 → 152 taken 847 times.
✗ Branch 151 → 219 not taken.
✓ Branch 152 → 153 taken 847 times.
✗ Branch 152 → 219 not taken.
✓ Branch 153 → 154 taken 847 times.
✗ Branch 153 → 219 not taken.
|
847 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_INT), manIdx)}; |
| 135 | 856 | } | |
| 136 | |||
| 137 | 153 | std::any TypeChecker::visitBuiltinSizeOfCall(FctCallNode *node) const { | |
| 138 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 153 times.
|
153 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_SIZEOF); |
| 139 | |||
| 140 | // Directly set compile time value here, so that compile time ifs can be evaluated. | ||
| 141 | 153 | QualType qualType; | |
| 142 |
2/2✓ Branch 6 → 7 taken 129 times.
✓ Branch 6 → 10 taken 24 times.
|
153 | if (node->hasTemplateTypes) { // Align of type |
| 143 |
1/2✓ Branch 8 → 9 taken 129 times.
✗ Branch 8 → 54 not taken.
|
129 | qualType = node->templateTypeLst->dataTypes.front()->getEvaluatedSymbolType(manIdx); |
| 144 | } else { // Align of value | ||
| 145 |
1/2✓ Branch 11 → 12 taken 24 times.
✗ Branch 11 → 54 not taken.
|
24 | qualType = node->argLst->args.front()->getEvaluatedSymbolType(manIdx); |
| 146 | } | ||
| 147 | |||
| 148 |
3/4✓ Branch 13 → 14 taken 153 times.
✗ Branch 13 → 40 not taken.
✓ Branch 14 → 15 taken 2 times.
✓ Branch 14 → 25 taken 151 times.
|
153 | if (qualType.isOneOf({TY_UNRESOLVED, TY_DYN})) |
| 149 |
4/8✓ Branch 17 → 18 taken 2 times.
✗ Branch 17 → 43 not taken.
✓ Branch 18 → 19 taken 2 times.
✗ Branch 18 → 41 not taken.
✓ Branch 21 → 22 taken 2 times.
✗ Branch 21 → 47 not taken.
✓ Branch 22 → 23 taken 2 times.
✗ Branch 22 → 47 not taken.
|
6 | SOFT_ERROR_ER(node, UNEXPECTED_DYN_TYPE, "Cannot use sizeof on a dyn or unresolved type"); |
| 150 | |||
| 151 |
1/2✓ Branch 25 → 26 taken 151 times.
✗ Branch 25 → 54 not taken.
|
151 | llvm::Type *type = qualType.toLLVMType(sourceFile); |
| 152 |
3/6✓ Branch 27 → 28 taken 151 times.
✗ Branch 27 → 50 not taken.
✓ Branch 28 → 29 taken 151 times.
✗ Branch 28 → 48 not taken.
✓ Branch 29 → 30 taken 151 times.
✗ Branch 29 → 48 not taken.
|
151 | const int64_t typeSize = sourceFile->targetMachine->createDataLayout().getTypeAllocSize(type); |
| 153 |
1/2✓ Branch 31 → 32 taken 151 times.
✗ Branch 31 → 54 not taken.
|
151 | node->data.at(manIdx).setCompileTimeValue({.longValue = typeSize}); |
| 154 | |||
| 155 |
3/6✓ Branch 33 → 34 taken 151 times.
✗ Branch 33 → 52 not taken.
✓ Branch 34 → 35 taken 151 times.
✗ Branch 34 → 52 not taken.
✓ Branch 35 → 36 taken 151 times.
✗ Branch 35 → 52 not taken.
|
151 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)}; |
| 156 | } | ||
| 157 | |||
| 158 | 13 | std::any TypeChecker::visitBuiltinAlignOfCall(FctCallNode *node) const { | |
| 159 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 13 times.
|
13 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_ALIGNOF); |
| 160 | |||
| 161 | // Directly set compile time value here, so that compile time ifs can be evaluated. | ||
| 162 | 13 | QualType qualType; | |
| 163 |
2/2✓ Branch 6 → 7 taken 2 times.
✓ Branch 6 → 10 taken 11 times.
|
13 | if (node->hasTemplateTypes) { // Align of type |
| 164 |
1/2✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 54 not taken.
|
2 | qualType = node->templateTypeLst->dataTypes.front()->getEvaluatedSymbolType(manIdx); |
| 165 | } else { // Align of value | ||
| 166 |
1/2✓ Branch 11 → 12 taken 11 times.
✗ Branch 11 → 54 not taken.
|
11 | qualType = node->argLst->args.front()->getEvaluatedSymbolType(manIdx); |
| 167 | } | ||
| 168 | |||
| 169 |
3/4✓ Branch 13 → 14 taken 13 times.
✗ Branch 13 → 40 not taken.
✓ Branch 14 → 15 taken 2 times.
✓ Branch 14 → 25 taken 11 times.
|
13 | if (qualType.isOneOf({TY_UNRESOLVED, TY_DYN})) |
| 170 |
4/8✓ Branch 17 → 18 taken 2 times.
✗ Branch 17 → 43 not taken.
✓ Branch 18 → 19 taken 2 times.
✗ Branch 18 → 41 not taken.
✓ Branch 21 → 22 taken 2 times.
✗ Branch 21 → 47 not taken.
✓ Branch 22 → 23 taken 2 times.
✗ Branch 22 → 47 not taken.
|
6 | SOFT_ERROR_ER(node, UNEXPECTED_DYN_TYPE, "Cannot use alignof on a dyn or unresolved type"); |
| 171 | |||
| 172 |
1/2✓ Branch 25 → 26 taken 11 times.
✗ Branch 25 → 54 not taken.
|
11 | llvm::Type *type = qualType.toLLVMType(sourceFile); |
| 173 |
2/4✓ Branch 27 → 28 taken 11 times.
✗ Branch 27 → 50 not taken.
✓ Branch 28 → 29 taken 11 times.
✗ Branch 28 → 48 not taken.
|
11 | const int64_t typeAlignment = sourceFile->targetMachine->createDataLayout().getABITypeAlign(type).value(); |
| 174 |
1/2✓ Branch 31 → 32 taken 11 times.
✗ Branch 31 → 54 not taken.
|
11 | node->data.at(manIdx).setCompileTimeValue({.longValue = typeAlignment}); |
| 175 | |||
| 176 |
3/6✓ Branch 33 → 34 taken 11 times.
✗ Branch 33 → 52 not taken.
✓ Branch 34 → 35 taken 11 times.
✗ Branch 34 → 52 not taken.
✓ Branch 35 → 36 taken 11 times.
✗ Branch 35 → 52 not taken.
|
11 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)}; |
| 177 | } | ||
| 178 | |||
| 179 | 8 | std::any TypeChecker::visitBuiltinTypeIdCall(FctCallNode *node) const { | |
| 180 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 8 times.
|
8 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_TYPEID); |
| 181 | |||
| 182 | // Directly set compile time value here, so that compile time ifs can be evaluated. | ||
| 183 | 8 | QualType qualType; | |
| 184 |
2/2✓ Branch 6 → 7 taken 7 times.
✓ Branch 6 → 10 taken 1 time.
|
8 | if (node->hasTemplateTypes) { // typeid of type |
| 185 |
1/2✓ Branch 8 → 9 taken 7 times.
✗ Branch 8 → 26 not taken.
|
7 | qualType = node->templateTypeLst->dataTypes.front()->getEvaluatedSymbolType(manIdx); |
| 186 | } else { // typeid of value | ||
| 187 |
1/2✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 26 not taken.
|
1 | qualType = node->argLst->args.front()->getEvaluatedSymbolType(manIdx); |
| 188 | } | ||
| 189 |
1/2✓ Branch 14 → 15 taken 8 times.
✗ Branch 14 → 26 not taken.
|
8 | const uint64_t typeId = TypeRegistry::getTypeHash(*qualType.getType()); |
| 190 |
1/2✓ Branch 15 → 16 taken 8 times.
✗ Branch 15 → 26 not taken.
|
8 | node->data.at(manIdx).setCompileTimeValue({.longValue = std::bit_cast<int64_t>(typeId)}); |
| 191 | |||
| 192 |
3/6✓ Branch 18 → 19 taken 8 times.
✗ Branch 18 → 24 not taken.
✓ Branch 19 → 20 taken 8 times.
✗ Branch 19 → 24 not taken.
✓ Branch 20 → 21 taken 8 times.
✗ Branch 20 → 24 not taken.
|
8 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)}; |
| 193 | } | ||
| 194 | |||
| 195 | 60 | std::any TypeChecker::visitBuiltinLenCall(FctCallNode *node) const { | |
| 196 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 60 times.
|
60 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_LEN); |
| 197 | |||
| 198 | // Directly set compile time value here, so that compile time ifs can be evaluated. | ||
| 199 |
1/2✓ Branch 7 → 8 taken 60 times.
✗ Branch 7 → 56 not taken.
|
60 | QualType argType = node->argLst->args.front()->getEvaluatedSymbolType(manIdx); |
| 200 |
1/2✓ Branch 8 → 9 taken 60 times.
✗ Branch 8 → 45 not taken.
|
60 | argType = argType.removeReferenceWrapper(); |
| 201 | |||
| 202 | // Check if arg is of type array | ||
| 203 |
8/10✓ Branch 9 → 10 taken 60 times.
✗ Branch 9 → 56 not taken.
✓ Branch 10 → 11 taken 36 times.
✓ Branch 10 → 14 taken 24 times.
✓ Branch 11 → 12 taken 36 times.
✗ Branch 11 → 56 not taken.
✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 14 taken 35 times.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 27 taken 59 times.
|
60 | if (!argType.isArray() && !argType.is(TY_STRING)) |
| 204 |
4/8✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 48 not taken.
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 46 not taken.
✓ Branch 23 → 24 taken 1 time.
✗ Branch 23 → 52 not taken.
✓ Branch 24 → 25 taken 1 time.
✗ Branch 24 → 52 not taken.
|
3 | SOFT_ERROR_ER(node->argLst->args.front(), EXPECTED_ARRAY_TYPE, "The len builtin can only work on arrays or strings") |
| 205 | |||
| 206 |
3/4✓ Branch 27 → 28 taken 59 times.
✗ Branch 27 → 56 not taken.
✓ Branch 28 → 29 taken 24 times.
✓ Branch 28 → 33 taken 35 times.
|
59 | if (argType.is(TY_ARRAY)) { |
| 207 |
2/4✓ Branch 29 → 30 taken 24 times.
✗ Branch 29 → 56 not taken.
✓ Branch 30 → 31 taken 24 times.
✗ Branch 30 → 53 not taken.
|
24 | node->data.at(manIdx).setCompileTimeValue({.longValue = argType.getArraySize()}); |
| 208 | } else { | ||
| 209 | // If we want to use the len builtin on a string, we need to import the string runtime module | ||
| 210 |
3/4✓ Branch 33 → 34 taken 35 times.
✗ Branch 33 → 56 not taken.
✓ Branch 36 → 37 taken 34 times.
✓ Branch 36 → 38 taken 1 time.
|
70 | if (!sourceFile->isStringRT()) |
| 211 |
1/2✓ Branch 37 → 38 taken 34 times.
✗ Branch 37 → 56 not taken.
|
34 | sourceFile->requestRuntimeModule(STRING_RT); |
| 212 | } | ||
| 213 | |||
| 214 |
3/6✓ Branch 38 → 39 taken 59 times.
✗ Branch 38 → 54 not taken.
✓ Branch 39 → 40 taken 59 times.
✗ Branch 39 → 54 not taken.
✓ Branch 40 → 41 taken 59 times.
✗ Branch 40 → 54 not taken.
|
59 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)}; |
| 215 | } | ||
| 216 | |||
| 217 | 745 | std::any TypeChecker::visitBuiltinPanicCall(FctCallNode *node) const { | |
| 218 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 745 times.
|
745 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_PANIC); |
| 219 | |||
| 220 |
1/2✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 745 times.
|
745 | assert(node->hasArgs); |
| 221 | 745 | const ExprNode *assignExpr = node->argLst->args.front(); | |
| 222 |
1/2✓ Branch 9 → 10 taken 745 times.
✗ Branch 9 → 47 not taken.
|
745 | QualType argType = assignExpr->getEvaluatedSymbolType(manIdx); |
| 223 |
2/8✓ Branch 10 → 11 taken 745 times.
✗ Branch 10 → 47 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 16 taken 745 times.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 36 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 36 not taken.
|
745 | HANDLE_UNRESOLVED_TYPE_ER(argType) |
| 224 |
1/2✓ Branch 16 → 17 taken 745 times.
✗ Branch 16 → 37 not taken.
|
745 | argType = argType.removeReferenceWrapper(); |
| 225 | |||
| 226 | // Check if arg is of type array | ||
| 227 |
3/4✓ Branch 17 → 18 taken 745 times.
✗ Branch 17 → 47 not taken.
✓ Branch 18 → 19 taken 1 time.
✓ Branch 18 → 29 taken 744 times.
|
745 | if (!argType.isErrorObj()) |
| 228 |
4/8✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 40 not taken.
✓ Branch 22 → 23 taken 1 time.
✗ Branch 22 → 38 not taken.
✓ Branch 25 → 26 taken 1 time.
✗ Branch 25 → 44 not taken.
✓ Branch 26 → 27 taken 1 time.
✗ Branch 26 → 44 not taken.
|
3 | SOFT_ERROR_ER(assignExpr, EXPECTED_ERROR_TYPE, "The panic builtin can only work with errors") |
| 229 | |||
| 230 |
3/6✓ Branch 29 → 30 taken 744 times.
✗ Branch 29 → 45 not taken.
✓ Branch 30 → 31 taken 744 times.
✗ Branch 30 → 45 not taken.
✓ Branch 31 → 32 taken 744 times.
✗ Branch 31 → 45 not taken.
|
744 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_DYN), manIdx)}; |
| 231 | } | ||
| 232 | |||
| 233 | 4 | std::any TypeChecker::visitBuiltinSyscallCall(FctCallNode *node) const { | |
| 234 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 4 times.
|
4 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_SYSCALL); |
| 235 | |||
| 236 | // Check if the syscall number if of type short | ||
| 237 | 4 | const ExprNode *sysCallNumberExpr = node->argLst->args.front(); | |
| 238 |
1/2✓ Branch 7 → 8 taken 4 times.
✗ Branch 7 → 57 not taken.
|
4 | const QualType sysCallNumberType = sysCallNumberExpr->getEvaluatedSymbolType(manIdx); |
| 239 |
3/4✓ Branch 8 → 9 taken 4 times.
✗ Branch 8 → 57 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 20 taken 3 times.
|
4 | if (!sysCallNumberType.is(TY_SHORT)) |
| 240 |
4/8✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 43 not taken.
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 41 not taken.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 47 not taken.
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 47 not taken.
|
3 | SOFT_ERROR_ER(sysCallNumberExpr, INVALID_SYSCALL_NUMBER_TYPE, "Syscall number must be of type short") |
| 241 | |||
| 242 | // Check if the syscall number is out of range | ||
| 243 | // According to https://www.chromium.org/chromium-os/developer-library/reference/linux-constants/syscalls/ | ||
| 244 |
2/4✓ Branch 20 → 21 taken 3 times.
✗ Branch 20 → 57 not taken.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 34 taken 3 times.
|
3 | if (node->hasCompileTimeValue(manIdx)) { |
| 245 | ✗ | const unsigned short sysCallNumber = node->getCompileTimeValue(manIdx).shortValue; | |
| 246 | ✗ | if (sysCallNumber < 0 || sysCallNumber > 439) | |
| 247 | ✗ | SOFT_ERROR_ER(node, SYSCALL_NUMBER_OUT_OF_RANGE, "Only syscall numbers between 0 and 439 are supported") | |
| 248 | } | ||
| 249 | |||
| 250 |
3/6✓ Branch 34 → 35 taken 3 times.
✗ Branch 34 → 55 not taken.
✓ Branch 35 → 36 taken 3 times.
✗ Branch 35 → 55 not taken.
✓ Branch 36 → 37 taken 3 times.
✗ Branch 36 → 55 not taken.
|
3 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)}; |
| 251 | } | ||
| 252 | |||
| 253 | 6 | std::any TypeChecker::visitBuiltinIsSameCall(FctCallNode *node) const { | |
| 254 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 6 times.
|
6 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_IS_SAME); |
| 255 | |||
| 256 | // Directly set compile time value here, so that compile time ifs can be evaluated. | ||
| 257 |
1/2✓ Branch 6 → 7 taken 6 times.
✗ Branch 6 → 25 not taken.
|
6 | node->setCompileTimeValue({.boolValue = true}, manIdx); |
| 258 | 6 | const std::vector<DataTypeNode *> &dataTypeNodes = node->templateTypeLst->dataTypes; | |
| 259 |
1/2✓ Branch 8 → 9 taken 6 times.
✗ Branch 8 → 30 not taken.
|
6 | const QualType firstType = dataTypeNodes.front()->getEvaluatedSymbolType(manIdx); |
| 260 |
2/2✓ Branch 18 → 10 taken 6 times.
✓ Branch 18 → 19 taken 2 times.
|
8 | for (size_t i = 1; i < dataTypeNodes.size(); i++) { |
| 261 |
2/4✓ Branch 10 → 11 taken 6 times.
✗ Branch 10 → 27 not taken.
✓ Branch 11 → 12 taken 6 times.
✗ Branch 11 → 27 not taken.
|
6 | const QualType qualType = dataTypeNodes.at(i)->getEvaluatedSymbolType(manIdx); |
| 262 |
3/4✓ Branch 12 → 13 taken 6 times.
✗ Branch 12 → 27 not taken.
✓ Branch 13 → 14 taken 4 times.
✓ Branch 13 → 16 taken 2 times.
|
6 | if (!qualType.matches(firstType, false, true, false)) { |
| 263 |
1/2✓ Branch 14 → 15 taken 4 times.
✗ Branch 14 → 26 not taken.
|
4 | node->setCompileTimeValue({.boolValue = false}, manIdx); |
| 264 | 4 | break; | |
| 265 | } | ||
| 266 | } | ||
| 267 | |||
| 268 |
3/6✓ Branch 19 → 20 taken 6 times.
✗ Branch 19 → 28 not taken.
✓ Branch 20 → 21 taken 6 times.
✗ Branch 20 → 28 not taken.
✓ Branch 21 → 22 taken 6 times.
✗ Branch 21 → 28 not taken.
|
6 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_BOOL), manIdx)}; |
| 269 | } | ||
| 270 | |||
| 271 | 1 | std::any TypeChecker::visitBuiltinImplementsInterfaceCall(FctCallNode *node) const { | |
| 272 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 1 time.
|
1 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_IMPLEMENTS_INTERFACE); |
| 273 | |||
| 274 |
1/2✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 28 not taken.
|
1 | const QualType interfaceType = node->templateTypeLst->dataTypes.front()->getEvaluatedSymbolType(manIdx); |
| 275 |
1/2✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 28 not taken.
|
1 | const QualType structType = node->templateTypeLst->dataTypes.back()->getEvaluatedSymbolType(manIdx); |
| 276 |
6/12✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 28 not taken.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 17 not taken.
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 28 not taken.
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 17 not taken.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 28 not taken.
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 17 not taken.
|
1 | const bool value = interfaceType.is(TY_INTERFACE) && structType.is(TY_STRUCT) && structType.doesImplement(interfaceType, node); |
| 277 |
1/2✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 25 not taken.
|
1 | node->setCompileTimeValue({.boolValue = value}, manIdx); |
| 278 | |||
| 279 |
3/6✓ Branch 19 → 20 taken 1 time.
✗ Branch 19 → 26 not taken.
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 26 not taken.
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 26 not taken.
|
1 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_BOOL), manIdx)}; |
| 280 | } | ||
| 281 | |||
| 282 | 19 | std::any TypeChecker::visitBuiltinGetBuildVarCall(FctCallNode *node) const { | |
| 283 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 19 times.
|
19 | assert(node->fqFunctionName == BUILTIN_FCT_NAME_GET_BUILD_VAR); |
| 284 | |||
| 285 | 19 | const DataTypeNode *requestedTypeNode = node->templateTypeLst->dataTypes.front(); | |
| 286 |
1/2✓ Branch 7 → 8 taken 19 times.
✗ Branch 7 → 210 not taken.
|
19 | const QualType requestedType = requestedTypeNode->getEvaluatedSymbolType(manIdx); |
| 287 |
3/4✓ Branch 8 → 9 taken 19 times.
✗ Branch 8 → 120 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 20 taken 18 times.
|
19 | if (!requestedType.isOneOf({TY_STRING, TY_INT, TY_BOOL})) |
| 288 |
4/8✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 123 not taken.
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 121 not taken.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 127 not taken.
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 127 not taken.
|
3 | SOFT_ERROR_ER(requestedTypeNode, BUILTIN_SIGNATURE_MISMATCH, "Build var type must be string, int or bool") |
| 289 | |||
| 290 |
1/2✓ Branch 20 → 21 taken 18 times.
✗ Branch 20 → 210 not taken.
|
18 | const ExprNode *varNameNode = node->argLst->args.at(0); |
| 291 |
1/2✓ Branch 21 → 22 taken 18 times.
✗ Branch 21 → 210 not taken.
|
18 | const QualType varNameType = varNameNode->getEvaluatedSymbolType(manIdx); |
| 292 |
3/4✓ Branch 22 → 23 taken 18 times.
✗ Branch 22 → 210 not taken.
✓ Branch 23 → 24 taken 1 time.
✓ Branch 23 → 34 taken 17 times.
|
18 | if (!varNameType.is(TY_STRING)) |
| 293 |
4/8✓ Branch 26 → 27 taken 1 time.
✗ Branch 26 → 130 not taken.
✓ Branch 27 → 28 taken 1 time.
✗ Branch 27 → 128 not taken.
✓ Branch 30 → 31 taken 1 time.
✗ Branch 30 → 134 not taken.
✓ Branch 31 → 32 taken 1 time.
✗ Branch 31 → 134 not taken.
|
3 | SOFT_ERROR_ER(varNameNode, BUILTIN_ARG_TYPE_MISMATCH, "Build var name must be a string") |
| 294 |
3/4✓ Branch 34 → 35 taken 17 times.
✗ Branch 34 → 210 not taken.
✓ Branch 35 → 36 taken 1 time.
✓ Branch 35 → 46 taken 16 times.
|
17 | if (!varNameNode->hasCompileTimeValue(manIdx)) |
| 295 |
4/8✓ Branch 38 → 39 taken 1 time.
✗ Branch 38 → 137 not taken.
✓ Branch 39 → 40 taken 1 time.
✗ Branch 39 → 135 not taken.
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 141 not taken.
✓ Branch 43 → 44 taken 1 time.
✗ Branch 43 → 141 not taken.
|
3 | SOFT_ERROR_ER(varNameNode, EXPECTED_COMPILE_TIME_VALUE, "Var name must be known at compile time") |
| 296 | |||
| 297 | 16 | const bool hasDefaultValue = node->argLst->args.size() == 2; | |
| 298 | 16 | CompileTimeValue defaultValue; | |
| 299 |
2/2✓ Branch 47 → 48 taken 10 times.
✓ Branch 47 → 77 taken 6 times.
|
16 | if (hasDefaultValue) { |
| 300 |
1/2✓ Branch 48 → 49 taken 10 times.
✗ Branch 48 → 156 not taken.
|
10 | const ExprNode *defaultValueNode = node->argLst->args.at(1); |
| 301 |
1/2✓ Branch 49 → 50 taken 10 times.
✗ Branch 49 → 156 not taken.
|
10 | const QualType defaultValueType = defaultValueNode->getEvaluatedSymbolType(manIdx); |
| 302 |
3/4✓ Branch 50 → 51 taken 10 times.
✗ Branch 50 → 156 not taken.
✓ Branch 51 → 52 taken 1 time.
✓ Branch 51 → 62 taken 9 times.
|
10 | if (!defaultValueType.matches(requestedType, false, true, true)) |
| 303 |
4/8✓ Branch 54 → 55 taken 1 time.
✗ Branch 54 → 144 not taken.
✓ Branch 55 → 56 taken 1 time.
✗ Branch 55 → 142 not taken.
✓ Branch 58 → 59 taken 1 time.
✗ Branch 58 → 148 not taken.
✓ Branch 59 → 60 taken 1 time.
✗ Branch 59 → 148 not taken.
|
3 | SOFT_ERROR_ER(defaultValueNode, BUILTIN_ARG_TYPE_MISMATCH, "Default value type must be the same as the requested type") |
| 304 |
3/4✓ Branch 62 → 63 taken 9 times.
✗ Branch 62 → 156 not taken.
✓ Branch 63 → 64 taken 1 time.
✓ Branch 63 → 74 taken 8 times.
|
9 | if (!defaultValueNode->hasCompileTimeValue(manIdx)) |
| 305 |
4/8✓ Branch 66 → 67 taken 1 time.
✗ Branch 66 → 151 not taken.
✓ Branch 67 → 68 taken 1 time.
✗ Branch 67 → 149 not taken.
✓ Branch 70 → 71 taken 1 time.
✗ Branch 70 → 155 not taken.
✓ Branch 71 → 72 taken 1 time.
✗ Branch 71 → 155 not taken.
|
3 | SOFT_ERROR_ER(defaultValueNode, EXPECTED_COMPILE_TIME_VALUE, "Default value must be known at compile time") |
| 306 |
1/2✓ Branch 74 → 75 taken 8 times.
✗ Branch 74 → 156 not taken.
|
8 | defaultValue = defaultValueNode->getCompileTimeValue(manIdx); |
| 307 | } | ||
| 308 | |||
| 309 |
1/2✓ Branch 77 → 78 taken 14 times.
✗ Branch 77 → 210 not taken.
|
14 | const size_t stringValueOffset = varNameNode->getCompileTimeValue(manIdx).stringValueOffset; |
| 310 |
1/2✓ Branch 78 → 79 taken 14 times.
✗ Branch 78 → 210 not taken.
|
14 | const std::string &varName = resourceManager.compileTimeStringValues.at(stringValueOffset); |
| 311 |
1/2✓ Branch 79 → 80 taken 14 times.
✗ Branch 79 → 210 not taken.
|
14 | const auto it = cliOptions.buildVars.find(varName); |
| 312 |
2/2✓ Branch 82 → 83 taken 12 times.
✓ Branch 82 → 102 taken 2 times.
|
14 | if (it != cliOptions.buildVars.end()) { |
| 313 | try { | ||
| 314 |
3/4✓ Branch 83 → 84 taken 12 times.
✗ Branch 83 → 160 not taken.
✓ Branch 84 → 85 taken 8 times.
✓ Branch 84 → 90 taken 4 times.
|
12 | if (requestedType.is(TY_STRING)) { |
| 315 | 8 | const size_t value = resourceManager.compileTimeStringValues.size(); | |
| 316 |
1/2✓ Branch 87 → 88 taken 8 times.
✗ Branch 87 → 160 not taken.
|
8 | resourceManager.compileTimeStringValues.push_back(it->second); |
| 317 |
1/2✓ Branch 88 → 89 taken 8 times.
✗ Branch 88 → 157 not taken.
|
8 | node->setCompileTimeValue({.stringValueOffset = value}, manIdx); |
| 318 |
3/4✓ Branch 90 → 91 taken 4 times.
✗ Branch 90 → 160 not taken.
✓ Branch 91 → 92 taken 3 times.
✓ Branch 91 → 96 taken 1 time.
|
4 | } else if (requestedType.is(TY_INT)) { |
| 319 |
2/2✓ Branch 93 → 94 taken 1 time.
✓ Branch 93 → 160 taken 2 times.
|
3 | const int value = std::stoi(it->second); |
| 320 |
1/2✓ Branch 94 → 95 taken 1 time.
✗ Branch 94 → 158 not taken.
|
1 | node->setCompileTimeValue({.intValue = value}, manIdx); |
| 321 |
2/4✓ Branch 96 → 97 taken 1 time.
✗ Branch 96 → 160 not taken.
✓ Branch 97 → 98 taken 1 time.
✗ Branch 97 → 114 not taken.
|
1 | } else if (requestedType.is(TY_BOOL)) { |
| 322 |
1/2✓ Branch 99 → 100 taken 1 time.
✗ Branch 99 → 160 not taken.
|
1 | const bool value = it->second == "true"; |
| 323 |
1/2✓ Branch 100 → 101 taken 1 time.
✗ Branch 100 → 159 not taken.
|
1 | node->setCompileTimeValue({.boolValue = value}, manIdx); |
| 324 | } | ||
| 325 |
1/3✗ Branch 160 → 161 not taken.
✓ Branch 160 → 162 taken 2 times.
✗ Branch 160 → 173 not taken.
|
2 | } catch (const std::invalid_argument &) { |
| 326 |
4/8✓ Branch 165 → 166 taken 2 times.
✗ Branch 165 → 186 not taken.
✓ Branch 166 → 167 taken 2 times.
✗ Branch 166 → 184 not taken.
✓ Branch 169 → 170 taken 2 times.
✗ Branch 169 → 190 not taken.
✓ Branch 170 → 171 taken 2 times.
✗ Branch 170 → 190 not taken.
|
6 | SOFT_ERROR_ER(node, BUILTIN_ARG_TYPE_MISMATCH, "Error while parsing the provided value to the requested type") |
| 327 | 2 | } catch (const std::out_of_range &) { | |
| 328 | ✗ | SOFT_ERROR_ER(node, BUILTIN_ARG_TYPE_MISMATCH, "Error while parsing the provided value to the requested type") | |
| 329 | ✗ | } | |
| 330 | } else { | ||
| 331 |
2/2✓ Branch 102 → 103 taken 1 time.
✓ Branch 102 → 113 taken 1 time.
|
2 | if (!hasDefaultValue) |
| 332 |
4/8✓ Branch 105 → 106 taken 1 time.
✗ Branch 105 → 204 not taken.
✓ Branch 106 → 107 taken 1 time.
✗ Branch 106 → 202 not taken.
✓ Branch 109 → 110 taken 1 time.
✗ Branch 109 → 208 not taken.
✓ Branch 110 → 111 taken 1 time.
✗ Branch 110 → 208 not taken.
|
3 | SOFT_ERROR_ER(varNameNode, BUILTIN_ARG_TYPE_MISMATCH, "Build var with this name was not provided"); |
| 333 |
1/2✓ Branch 113 → 114 taken 1 time.
✗ Branch 113 → 210 not taken.
|
1 | node->setCompileTimeValue(defaultValue, manIdx); |
| 334 | } | ||
| 335 | |||
| 336 |
2/4✓ Branch 114 → 115 taken 11 times.
✗ Branch 114 → 209 not taken.
✓ Branch 115 → 116 taken 11 times.
✗ Branch 115 → 209 not taken.
|
11 | return ExprResult{node->setEvaluatedSymbolType(requestedType, manIdx)}; |
| 337 | } | ||
| 338 | |||
| 339 | } // namespace spice::compiler | ||
| 340 |