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:
parent
51cfe26bb7
commit
af6fc5f5d9
|
@ -1643,9 +1643,13 @@ bool Resolver::Function(ast::Function* func) {
|
||||||
auto* constructor = var->declaration->constructor();
|
auto* constructor = var->declaration->constructor();
|
||||||
if (constructor) {
|
if (constructor) {
|
||||||
// Resolve the constructor expression to use as the default value.
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
value = val.Elements()[0].i32;
|
||||||
} else {
|
} else {
|
||||||
// No constructor means this value must be overriden by the user.
|
// No constructor means this value must be overriden by the user.
|
||||||
info->workgroup_size[i].value = 0;
|
info->workgroup_size[i].value = 0;
|
||||||
|
@ -1656,7 +1660,8 @@ bool Resolver::Function(ast::Function* func) {
|
||||||
// We have a literal.
|
// We have a literal.
|
||||||
Mark(scalar->literal());
|
Mark(scalar->literal());
|
||||||
|
|
||||||
if (!scalar->literal()->Is<ast::IntLiteral>()) {
|
auto* i32_literal = scalar->literal()->As<ast::IntLiteral>();
|
||||||
|
if (!i32_literal) {
|
||||||
AddError(
|
AddError(
|
||||||
"workgroup_size parameter must be a literal i32 or an i32 "
|
"workgroup_size parameter must be a literal i32 or an i32 "
|
||||||
"module-scope constant",
|
"module-scope constant",
|
||||||
|
@ -1664,9 +1669,7 @@ bool Resolver::Function(ast::Function* func) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetScalarConstExprValue(scalar, &value)) {
|
value = i32_literal->value_as_i32();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate and set the default value for this dimension.
|
// Validate and set the default value for this dimension.
|
||||||
|
@ -4028,40 +4031,6 @@ bool Resolver::ApplyStorageClassUsageToType(ast::StorageClass sc,
|
||||||
return true;
|
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>
|
template <typename F>
|
||||||
bool Resolver::BlockScope(const ast::BlockStatement* block, F&& callback) {
|
bool Resolver::BlockScope(const ast::BlockStatement* block, F&& callback) {
|
||||||
auto* sem_block = builder_->Sem().Get<sem::BlockStatement>(block);
|
auto* sem_block = builder_->Sem().Get<sem::BlockStatement>(block);
|
||||||
|
|
|
@ -394,13 +394,6 @@ class Resolver {
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
std::string type_name = "");
|
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
|
/// Constructs a new semantic BlockStatement with the given type and with
|
||||||
/// #current_block_ as its parent, assigns this to #current_block_, and then
|
/// #current_block_ as its parent, assigns this to #current_block_, and then
|
||||||
/// calls `callback`. The original #current_block_ is restored on exit.
|
/// calls `callback`. The original #current_block_ is restored on exit.
|
||||||
|
|
Loading…
Reference in New Issue