diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc index a32466771a..8390108d30 100644 --- a/src/resolver/resolver.cc +++ b/src/resolver/resolver.cc @@ -1643,9 +1643,13 @@ bool Resolver::Function(ast::Function* func) { 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()) { + 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 @@ bool Resolver::Function(ast::Function* func) { // We have a literal. Mark(scalar->literal()); - if (!scalar->literal()->Is()) { + auto* i32_literal = scalar->literal()->As(); + if (!i32_literal) { AddError( "workgroup_size parameter must be a literal i32 or an i32 " "module-scope constant", @@ -1664,9 +1669,7 @@ bool Resolver::Function(ast::Function* func) { 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 @@ bool Resolver::ApplyStorageClassUsageToType(ast::StorageClass sc, return true; } -template -bool Resolver::GetScalarConstExprValue(ast::Expression* expr, T* result) { - if (auto* type_constructor = expr->As()) { - if (type_constructor->values().size() == 0) { - // Zero-valued constructor. - *result = static_cast(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()) { - // Cast literal to result type. - if (auto* int_lit = scalar->literal()->As()) { - *result = static_cast(int_lit->value_as_u32()); - return true; - } else if (auto* float_lit = scalar->literal()->As()) { - *result = static_cast(float_lit->value()); - return true; - } else if (auto* bool_lit = scalar->literal()->As()) { - *result = static_cast(bool_lit->IsTrue()); - return true; - } else { - TINT_ICE(Resolver, diagnostics_) << "unhandled scalar constructor"; - } - } else { - TINT_ICE(Resolver, diagnostics_) << "unhandled constant expression"; - } - - return false; -} - template bool Resolver::BlockScope(const ast::BlockStatement* block, F&& callback) { auto* sem_block = builder_->Sem().Get(block); diff --git a/src/resolver/resolver.h b/src/resolver/resolver.h index 822d6bc919..bd2bf626ae 100644 --- a/src/resolver/resolver.h +++ b/src/resolver/resolver.h @@ -394,13 +394,6 @@ class Resolver { 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 - 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.