resolver: Replace GetScalarConstExprValue with ConstantValueOf
ConstantValueOf() obtains the constant value from the logic in resolver_constants.cc. This is better tested, and is the foundation of Tint's constant folder.
Change-Id: I42036f3ff4ab684b4864cd69856de1715b38d246
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/57702
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index a324667..8390108 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -1643,9 +1643,13 @@
auto* constructor = var->declaration->constructor();
if (constructor) {
// Resolve the constructor expression to use as the default value.
- if (!GetScalarConstExprValue(constructor, &value)) {
+ auto val = ConstantValueOf(constructor);
+ if (!val.IsValid() || !val.Type()->Is<sem::I32>()) {
+ TINT_ICE(Resolver, diagnostics_)
+ << "failed to resolve workgroup_size constant value";
return false;
}
+ value = val.Elements()[0].i32;
} else {
// No constructor means this value must be overriden by the user.
info->workgroup_size[i].value = 0;
@@ -1656,7 +1660,8 @@
// We have a literal.
Mark(scalar->literal());
- if (!scalar->literal()->Is<ast::IntLiteral>()) {
+ auto* i32_literal = scalar->literal()->As<ast::IntLiteral>();
+ if (!i32_literal) {
AddError(
"workgroup_size parameter must be a literal i32 or an i32 "
"module-scope constant",
@@ -1664,9 +1669,7 @@
return false;
}
- if (!GetScalarConstExprValue(scalar, &value)) {
- return false;
- }
+ value = i32_literal->value_as_i32();
}
// Validate and set the default value for this dimension.
@@ -4028,40 +4031,6 @@
return true;
}
-template <typename T>
-bool Resolver::GetScalarConstExprValue(ast::Expression* expr, T* result) {
- if (auto* type_constructor = expr->As<ast::TypeConstructorExpression>()) {
- if (type_constructor->values().size() == 0) {
- // Zero-valued constructor.
- *result = static_cast<T>(0);
- return true;
- } else if (type_constructor->values().size() == 1) {
- // Recurse into the constructor argument expression.
- return GetScalarConstExprValue(type_constructor->values()[0], result);
- } else {
- TINT_ICE(Resolver, diagnostics_) << "malformed scalar type constructor";
- }
- } else if (auto* scalar = expr->As<ast::ScalarConstructorExpression>()) {
- // Cast literal to result type.
- if (auto* int_lit = scalar->literal()->As<ast::IntLiteral>()) {
- *result = static_cast<T>(int_lit->value_as_u32());
- return true;
- } else if (auto* float_lit = scalar->literal()->As<ast::FloatLiteral>()) {
- *result = static_cast<T>(float_lit->value());
- return true;
- } else if (auto* bool_lit = scalar->literal()->As<ast::BoolLiteral>()) {
- *result = static_cast<T>(bool_lit->IsTrue());
- return true;
- } else {
- TINT_ICE(Resolver, diagnostics_) << "unhandled scalar constructor";
- }
- } else {
- TINT_ICE(Resolver, diagnostics_) << "unhandled constant expression";
- }
-
- return false;
-}
-
template <typename F>
bool Resolver::BlockScope(const ast::BlockStatement* block, F&& callback) {
auto* sem_block = builder_->Sem().Get<sem::BlockStatement>(block);
diff --git a/src/resolver/resolver.h b/src/resolver/resolver.h
index 822d6bc..bd2bf62 100644
--- a/src/resolver/resolver.h
+++ b/src/resolver/resolver.h
@@ -394,13 +394,6 @@
const sem::Type* type,
std::string type_name = "");
- /// Resolve the value of a scalar const_expr.
- /// @param expr the expression
- /// @param result pointer to the where the result will be stored
- /// @returns true on success, false on error
- template <typename T>
- bool GetScalarConstExprValue(ast::Expression* expr, T* result);
-
/// Constructs a new semantic BlockStatement with the given type and with
/// #current_block_ as its parent, assigns this to #current_block_, and then
/// calls `callback`. The original #current_block_ is restored on exit.