| 62 | } |
| 63 | |
| 64 | ConstantValue eval(EvalContext& context, const Args& args, SourceRange, |
| 65 | const CallExpression::SystemCallInfo& callInfo) const final { |
| 66 | ConstantValue arr = args[0]->eval(context); |
| 67 | if (!arr) |
| 68 | return nullptr; |
| 69 | |
| 70 | auto [iterExpr, iterVar] = callInfo.getIteratorInfo(); |
| 71 | if (iterExpr) { |
| 72 | SLANG_ASSERT(iterVar); |
| 73 | if (arr.empty()) { |
| 74 | auto elemType = iterExpr->type; |
| 75 | return SVInt(elemType->getBitWidth(), 0, elemType->isSigned()); |
| 76 | } |
| 77 | |
| 78 | auto it = begin(arr); |
| 79 | auto guard = context.disableCaching(); |
| 80 | auto iterVal = context.createLocal(iterVar, *it); |
| 81 | ConstantValue cv = iterExpr->eval(context); |
| 82 | if (!cv) |
| 83 | return nullptr; |
| 84 | |
| 85 | SVInt result = cv.integer(); |
| 86 | for (++it; it != end(arr); ++it) { |
| 87 | *iterVal = *it; |
| 88 | cv = iterExpr->eval(context); |
| 89 | if (!cv) |
| 90 | return nullptr; |
| 91 | |
| 92 | op(result, cv.integer()); |
| 93 | } |
| 94 | |
| 95 | return result; |
| 96 | } |
| 97 | else { |
| 98 | if (arr.empty()) { |
| 99 | auto elemType = args[0]->type->getArrayElementType(); |
| 100 | return SVInt(elemType->getBitWidth(), 0, elemType->isSigned()); |
| 101 | } |
| 102 | |
| 103 | auto it = begin(arr); |
| 104 | SVInt result = it->integer(); |
| 105 | for (++it; it != end(arr); ++it) |
| 106 | op(result, it->integer()); |
| 107 | |
| 108 | return result; |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | private: |
| 113 | Operator op; |
nothing calls this directly
no test coverage detected