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>
This commit is contained in:
Ben Clayton 2021-07-13 12:18:13 +00:00
parent 51cfe26bb7
commit af6fc5f5d9
2 changed files with 8 additions and 46 deletions

View File

@ -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<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 @@ bool Resolver::Function(ast::Function* func) {
// 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 @@ 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 <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);

View File

@ -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 <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.