tint/sem: Rename Expression to ValueExpression
ast::IdentifierExpression may also resolve to a type or core enumerator Bug: tint:1810 Change-Id: I85e3bea67e1146215079ec47430784f2fb39043d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/118402 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
3f5ae2bc54
commit
3fb9a3fba1
|
@ -367,7 +367,6 @@ libtint_source_set("libtint_syntax_tree_src") {
|
||||||
"sem/call.h",
|
"sem/call.h",
|
||||||
"sem/call_target.h",
|
"sem/call_target.h",
|
||||||
"sem/evaluation_stage.h",
|
"sem/evaluation_stage.h",
|
||||||
"sem/expression.h",
|
|
||||||
"sem/for_loop_statement.h",
|
"sem/for_loop_statement.h",
|
||||||
"sem/function.h",
|
"sem/function.h",
|
||||||
"sem/if_statement.h",
|
"sem/if_statement.h",
|
||||||
|
@ -388,6 +387,7 @@ libtint_source_set("libtint_syntax_tree_src") {
|
||||||
"sem/type_conversion.h",
|
"sem/type_conversion.h",
|
||||||
"sem/type_initializer.h",
|
"sem/type_initializer.h",
|
||||||
"sem/type_mappings.h",
|
"sem/type_mappings.h",
|
||||||
|
"sem/value_expression.h",
|
||||||
"sem/variable.h",
|
"sem/variable.h",
|
||||||
"sem/while_statement.h",
|
"sem/while_statement.h",
|
||||||
]
|
]
|
||||||
|
@ -760,8 +760,6 @@ libtint_source_set("libtint_sem_src") {
|
||||||
"sem/call_target.cc",
|
"sem/call_target.cc",
|
||||||
"sem/call_target.h",
|
"sem/call_target.h",
|
||||||
"sem/evaluation_stage.h",
|
"sem/evaluation_stage.h",
|
||||||
"sem/expression.cc",
|
|
||||||
"sem/expression.h",
|
|
||||||
"sem/for_loop_statement.cc",
|
"sem/for_loop_statement.cc",
|
||||||
"sem/for_loop_statement.h",
|
"sem/for_loop_statement.h",
|
||||||
"sem/function.cc",
|
"sem/function.cc",
|
||||||
|
@ -799,6 +797,8 @@ libtint_source_set("libtint_sem_src") {
|
||||||
"sem/type_initializer.cc",
|
"sem/type_initializer.cc",
|
||||||
"sem/type_initializer.h",
|
"sem/type_initializer.h",
|
||||||
"sem/type_mappings.h",
|
"sem/type_mappings.h",
|
||||||
|
"sem/value_expression.cc",
|
||||||
|
"sem/value_expression.h",
|
||||||
"sem/variable.cc",
|
"sem/variable.cc",
|
||||||
"sem/variable.h",
|
"sem/variable.h",
|
||||||
"sem/while_statement.cc",
|
"sem/while_statement.cc",
|
||||||
|
@ -1484,8 +1484,8 @@ if (tint_build_unittests) {
|
||||||
sources = [
|
sources = [
|
||||||
"sem/builtin_test.cc",
|
"sem/builtin_test.cc",
|
||||||
"sem/diagnostic_severity_test.cc",
|
"sem/diagnostic_severity_test.cc",
|
||||||
"sem/expression_test.cc",
|
|
||||||
"sem/struct_test.cc",
|
"sem/struct_test.cc",
|
||||||
|
"sem/value_expression_test.cc",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -328,8 +328,6 @@ list(APPEND TINT_LIB_SRCS
|
||||||
sem/call.cc
|
sem/call.cc
|
||||||
sem/call.h
|
sem/call.h
|
||||||
sem/evaluation_stage.h
|
sem/evaluation_stage.h
|
||||||
sem/expression.cc
|
|
||||||
sem/expression.h
|
|
||||||
sem/for_loop_statement.cc
|
sem/for_loop_statement.cc
|
||||||
sem/for_loop_statement.h
|
sem/for_loop_statement.h
|
||||||
sem/function.cc
|
sem/function.cc
|
||||||
|
@ -363,6 +361,8 @@ list(APPEND TINT_LIB_SRCS
|
||||||
sem/type_conversion.h
|
sem/type_conversion.h
|
||||||
sem/type_mappings.h
|
sem/type_mappings.h
|
||||||
sem/variable.cc
|
sem/variable.cc
|
||||||
|
sem/value_expression.cc
|
||||||
|
sem/value_expression.h
|
||||||
sem/while_statement.cc
|
sem/while_statement.cc
|
||||||
sem/while_statement.h
|
sem/while_statement.h
|
||||||
symbol_table.cc
|
symbol_table.cc
|
||||||
|
@ -972,8 +972,8 @@ if(TINT_BUILD_TESTS)
|
||||||
scope_stack_test.cc
|
scope_stack_test.cc
|
||||||
sem/builtin_test.cc
|
sem/builtin_test.cc
|
||||||
sem/diagnostic_severity_test.cc
|
sem/diagnostic_severity_test.cc
|
||||||
sem/expression_test.cc
|
|
||||||
sem/struct_test.cc
|
sem/struct_test.cc
|
||||||
|
sem/value_expression_test.cc
|
||||||
source_test.cc
|
source_test.cc
|
||||||
symbol_table_test.cc
|
symbol_table_test.cc
|
||||||
symbol_test.cc
|
symbol_test.cc
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include "src/tint/ast/expression.h"
|
#include "src/tint/ast/expression.h"
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/info.h"
|
#include "src/tint/sem/info.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::Expression);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::Expression);
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
#include "src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.h"
|
#include "src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.h"
|
||||||
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.h"
|
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.h"
|
||||||
#include "src/tint/fuzzers/tint_ast_fuzzer/util.h"
|
#include "src/tint/fuzzers/tint_ast_fuzzer/util.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/sem/variable.h"
|
#include "src/tint/sem/variable.h"
|
||||||
|
|
||||||
namespace tint::fuzzers::ast_fuzzer {
|
namespace tint::fuzzers::ast_fuzzer {
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
|
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
|
||||||
#include "src/tint/fuzzers/tint_ast_fuzzer/util.h"
|
#include "src/tint/fuzzers/tint_ast_fuzzer/util.h"
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/sem/variable.h"
|
#include "src/tint/sem/variable.h"
|
||||||
|
|
||||||
namespace tint::fuzzers::ast_fuzzer {
|
namespace tint::fuzzers::ast_fuzzer {
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
#include "src/tint/fuzzers/tint_ast_fuzzer/expression_size.h"
|
#include "src/tint/fuzzers/tint_ast_fuzzer/expression_size.h"
|
||||||
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.h"
|
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.h"
|
||||||
#include "src/tint/fuzzers/tint_ast_fuzzer/util.h"
|
#include "src/tint/fuzzers/tint_ast_fuzzer/util.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
|
|
||||||
namespace tint::fuzzers::ast_fuzzer {
|
namespace tint::fuzzers::ast_fuzzer {
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ MutationList MutationFinderWrapUnaryOperators::FindMutations(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* expr_sem_node = tint::As<sem::Expression>(program.Sem().Get(expr_ast_node));
|
const auto* expr_sem_node = program.Sem().Get<sem::ValueExpression>(expr_ast_node);
|
||||||
|
|
||||||
// Transformation applies only when the semantic node for the given
|
// Transformation applies only when the semantic node for the given
|
||||||
// expression is present.
|
// expression is present.
|
||||||
|
|
|
@ -50,8 +50,7 @@ bool MutationWrapUnaryOperator::IsApplicable(const tint::Program& program,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* expression_sem_node =
|
const auto* expression_sem_node = program.Sem().Get<sem::ValueExpression>(expression_ast_node);
|
||||||
tint::As<sem::Expression>(program.Sem().Get(expression_ast_node));
|
|
||||||
|
|
||||||
if (!expression_sem_node) {
|
if (!expression_sem_node) {
|
||||||
// Semantic information for the expression ast node is not present
|
// Semantic information for the expression ast node is not present
|
||||||
|
@ -94,7 +93,7 @@ protobufs::Mutation MutationWrapUnaryOperator::ToMessage() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ast::UnaryOp> MutationWrapUnaryOperator::GetValidUnaryWrapper(
|
std::vector<ast::UnaryOp> MutationWrapUnaryOperator::GetValidUnaryWrapper(
|
||||||
const sem::Expression& expr) {
|
const sem::ValueExpression& expr) {
|
||||||
const auto* expr_type = expr.Type();
|
const auto* expr_type = expr.Type();
|
||||||
if (expr_type->is_bool_scalar_or_vector()) {
|
if (expr_type->is_bool_scalar_or_vector()) {
|
||||||
return {ast::UnaryOp::kNot};
|
return {ast::UnaryOp::kNot};
|
||||||
|
|
|
@ -68,7 +68,7 @@ class MutationWrapUnaryOperator : public Mutation {
|
||||||
/// expression.
|
/// expression.
|
||||||
/// @param expr - an `ast::Expression` instance from node id map.
|
/// @param expr - an `ast::Expression` instance from node id map.
|
||||||
/// @return a list of unary operators.
|
/// @return a list of unary operators.
|
||||||
static std::vector<ast::UnaryOp> GetValidUnaryWrapper(const sem::Expression& expr);
|
static std::vector<ast::UnaryOp> GetValidUnaryWrapper(const sem::ValueExpression& expr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
protobufs::MutationWrapUnaryOperator message_;
|
protobufs::MutationWrapUnaryOperator message_;
|
||||||
|
|
|
@ -47,9 +47,9 @@
|
||||||
#include "src/tint/ir/switch.h"
|
#include "src/tint/ir/switch.h"
|
||||||
#include "src/tint/ir/terminator.h"
|
#include "src/tint/ir/terminator.h"
|
||||||
#include "src/tint/program.h"
|
#include "src/tint/program.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/module.h"
|
#include "src/tint/sem/module.h"
|
||||||
#include "src/tint/sem/switch_statement.h"
|
#include "src/tint/sem/switch_statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/type/void.h"
|
#include "src/tint/type/void.h"
|
||||||
|
|
||||||
namespace tint::ir {
|
namespace tint::ir {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "src/tint/demangler.h"
|
#include "src/tint/demangler.h"
|
||||||
#include "src/tint/resolver/resolver.h"
|
#include "src/tint/resolver/resolver.h"
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "src/tint/ast/variable_decl_statement.h"
|
#include "src/tint/ast/variable_decl_statement.h"
|
||||||
#include "src/tint/debug.h"
|
#include "src/tint/debug.h"
|
||||||
#include "src/tint/demangler.h"
|
#include "src/tint/demangler.h"
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/sem/variable.h"
|
#include "src/tint/sem/variable.h"
|
||||||
#include "src/tint/utils/compiler_macros.h"
|
#include "src/tint/utils/compiler_macros.h"
|
||||||
|
|
||||||
|
|
|
@ -1165,7 +1165,7 @@ ConstEval::Result ConstEval::Literal(const type::Type* ty, const ast::LiteralExp
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstEval::Result ConstEval::ArrayOrStructInit(const type::Type* ty,
|
ConstEval::Result ConstEval::ArrayOrStructInit(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Expression*> args) {
|
utils::VectorRef<const sem::ValueExpression*> args) {
|
||||||
if (args.IsEmpty()) {
|
if (args.IsEmpty()) {
|
||||||
return ZeroValue(builder, ty);
|
return ZeroValue(builder, ty);
|
||||||
}
|
}
|
||||||
|
@ -1277,8 +1277,8 @@ ConstEval::Result ConstEval::MatInitV(const type::Type* ty,
|
||||||
return builder.create<constant::Composite>(ty, args);
|
return builder.create<constant::Composite>(ty, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstEval::Result ConstEval::Index(const sem::Expression* obj_expr,
|
ConstEval::Result ConstEval::Index(const sem::ValueExpression* obj_expr,
|
||||||
const sem::Expression* idx_expr) {
|
const sem::ValueExpression* idx_expr) {
|
||||||
auto idx_val = idx_expr->ConstantValue();
|
auto idx_val = idx_expr->ConstantValue();
|
||||||
if (!idx_val) {
|
if (!idx_val) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1306,7 +1306,7 @@ ConstEval::Result ConstEval::Index(const sem::Expression* obj_expr,
|
||||||
return obj_val->Index(static_cast<size_t>(idx));
|
return obj_val->Index(static_cast<size_t>(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstEval::Result ConstEval::MemberAccess(const sem::Expression* obj_expr,
|
ConstEval::Result ConstEval::MemberAccess(const sem::ValueExpression* obj_expr,
|
||||||
const type::StructMember* member) {
|
const type::StructMember* member) {
|
||||||
auto obj_val = obj_expr->ConstantValue();
|
auto obj_val = obj_expr->ConstantValue();
|
||||||
if (!obj_val) {
|
if (!obj_val) {
|
||||||
|
@ -1316,7 +1316,7 @@ ConstEval::Result ConstEval::MemberAccess(const sem::Expression* obj_expr,
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstEval::Result ConstEval::Swizzle(const type::Type* ty,
|
ConstEval::Result ConstEval::Swizzle(const type::Type* ty,
|
||||||
const sem::Expression* vec_expr,
|
const sem::ValueExpression* vec_expr,
|
||||||
utils::VectorRef<uint32_t> indices) {
|
utils::VectorRef<uint32_t> indices) {
|
||||||
auto* vec_val = vec_expr->ConstantValue();
|
auto* vec_val = vec_expr->ConstantValue();
|
||||||
if (!vec_val) {
|
if (!vec_val) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace tint::constant {
|
||||||
class Value;
|
class Value;
|
||||||
} // namespace tint::constant
|
} // namespace tint::constant
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class Expression;
|
class ValueExpression;
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
namespace tint::type {
|
namespace tint::type {
|
||||||
class StructMember;
|
class StructMember;
|
||||||
|
@ -77,7 +77,8 @@ class ConstEval {
|
||||||
/// @param ty the target type - must be an array or initializer
|
/// @param ty the target type - must be an array or initializer
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @return the constructed value, or null if the value cannot be calculated
|
/// @return the constructed value, or null if the value cannot be calculated
|
||||||
Result ArrayOrStructInit(const type::Type* ty, utils::VectorRef<const sem::Expression*> args);
|
Result ArrayOrStructInit(const type::Type* ty,
|
||||||
|
utils::VectorRef<const sem::ValueExpression*> args);
|
||||||
|
|
||||||
/// @param ty the target type
|
/// @param ty the target type
|
||||||
/// @param value the value being converted
|
/// @param value the value being converted
|
||||||
|
@ -89,7 +90,7 @@ class ConstEval {
|
||||||
/// @param obj the object being indexed
|
/// @param obj the object being indexed
|
||||||
/// @param idx the index expression
|
/// @param idx the index expression
|
||||||
/// @return the result of the index, or null if the value cannot be calculated
|
/// @return the result of the index, or null if the value cannot be calculated
|
||||||
Result Index(const sem::Expression* obj, const sem::Expression* idx);
|
Result Index(const sem::ValueExpression* obj, const sem::ValueExpression* idx);
|
||||||
|
|
||||||
/// @param ty the result type
|
/// @param ty the result type
|
||||||
/// @param lit the literal AST node
|
/// @param lit the literal AST node
|
||||||
|
@ -99,14 +100,14 @@ class ConstEval {
|
||||||
/// @param obj the object being accessed
|
/// @param obj the object being accessed
|
||||||
/// @param member the member
|
/// @param member the member
|
||||||
/// @return the result of the member access, or null if the value cannot be calculated
|
/// @return the result of the member access, or null if the value cannot be calculated
|
||||||
Result MemberAccess(const sem::Expression* obj, const type::StructMember* member);
|
Result MemberAccess(const sem::ValueExpression* obj, const type::StructMember* member);
|
||||||
|
|
||||||
/// @param ty the result type
|
/// @param ty the result type
|
||||||
/// @param vector the vector being swizzled
|
/// @param vector the vector being swizzled
|
||||||
/// @param indices the swizzle indices
|
/// @param indices the swizzle indices
|
||||||
/// @return the result of the swizzle, or null if the value cannot be calculated
|
/// @return the result of the swizzle, or null if the value cannot be calculated
|
||||||
Result Swizzle(const type::Type* ty,
|
Result Swizzle(const type::Type* ty,
|
||||||
const sem::Expression* vector,
|
const sem::ValueExpression* vector,
|
||||||
utils::VectorRef<uint32_t> indices);
|
utils::VectorRef<uint32_t> indices);
|
||||||
|
|
||||||
/// Convert the `value` to `target_type`
|
/// Convert the `value` to `target_type`
|
||||||
|
|
|
@ -76,7 +76,7 @@ class MaterializeTest : public resolver::ResolverTestWithParam<CASE> {
|
||||||
protected:
|
protected:
|
||||||
using ProgramBuilder::FriendlyName;
|
using ProgramBuilder::FriendlyName;
|
||||||
|
|
||||||
void CheckTypesAndValues(const sem::Expression* expr,
|
void CheckTypesAndValues(const sem::ValueExpression* expr,
|
||||||
const tint::type::Type* expected_sem_ty,
|
const tint::type::Type* expected_sem_ty,
|
||||||
const std::variant<AInt, AFloat>& expected_value) {
|
const std::variant<AInt, AFloat>& expected_value) {
|
||||||
std::visit([&](auto v) { CheckTypesAndValuesImpl(expr, expected_sem_ty, v); },
|
std::visit([&](auto v) { CheckTypesAndValuesImpl(expr, expected_sem_ty, v); },
|
||||||
|
@ -85,7 +85,7 @@ class MaterializeTest : public resolver::ResolverTestWithParam<CASE> {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void CheckTypesAndValuesImpl(const sem::Expression* expr,
|
void CheckTypesAndValuesImpl(const sem::ValueExpression* expr,
|
||||||
const tint::type::Type* expected_sem_ty,
|
const tint::type::Type* expected_sem_ty,
|
||||||
T expected_value) {
|
T expected_value) {
|
||||||
EXPECT_TYPE(expr->Type(), expected_sem_ty);
|
EXPECT_TYPE(expr->Type(), expected_sem_ty);
|
||||||
|
|
|
@ -453,7 +453,7 @@ sem::Variable* Resolver::Override(const ast::Override* v) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Expression* rhs = nullptr;
|
const sem::ValueExpression* rhs = nullptr;
|
||||||
|
|
||||||
// Does the variable have an initializer?
|
// Does the variable have an initializer?
|
||||||
if (v->initializer) {
|
if (v->initializer) {
|
||||||
|
@ -545,7 +545,7 @@ sem::Variable* Resolver::Const(const ast::Const* c, bool is_global) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Expression* rhs = nullptr;
|
const sem::ValueExpression* rhs = nullptr;
|
||||||
{
|
{
|
||||||
ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "const initializer"};
|
ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "const initializer"};
|
||||||
TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint);
|
TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint);
|
||||||
|
@ -603,7 +603,7 @@ sem::Variable* Resolver::Var(const ast::Var* var, bool is_global) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Expression* rhs = nullptr;
|
const sem::ValueExpression* rhs = nullptr;
|
||||||
|
|
||||||
// Does the variable have a initializer?
|
// Does the variable have a initializer?
|
||||||
if (var->initializer) {
|
if (var->initializer) {
|
||||||
|
@ -1164,7 +1164,7 @@ bool Resolver::WorkgroupSize(const ast::Function* func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto values = attr->Values();
|
auto values = attr->Values();
|
||||||
utils::Vector<const sem::Expression*, 3> args;
|
utils::Vector<const sem::ValueExpression*, 3> args;
|
||||||
utils::Vector<const type::Type*, 3> arg_tys;
|
utils::Vector<const type::Type*, 3> arg_tys;
|
||||||
|
|
||||||
constexpr const char* kErrBadExpr =
|
constexpr const char* kErrBadExpr =
|
||||||
|
@ -1515,7 +1515,7 @@ sem::WhileStatement* Resolver::WhileStatement(const ast::WhileStatement* stmt) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Expression* Resolver::Expression(const ast::Expression* root) {
|
sem::ValueExpression* Resolver::Expression(const ast::Expression* root) {
|
||||||
utils::Vector<const ast::Expression*, 64> sorted;
|
utils::Vector<const ast::Expression*, 64> sorted;
|
||||||
constexpr size_t kMaxExpressionDepth = 512U;
|
constexpr size_t kMaxExpressionDepth = 512U;
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
|
@ -1550,30 +1550,34 @@ sem::Expression* Resolver::Expression(const ast::Expression* root) {
|
||||||
for (auto* expr : utils::Reverse(sorted)) {
|
for (auto* expr : utils::Reverse(sorted)) {
|
||||||
auto* sem_expr = Switch(
|
auto* sem_expr = Switch(
|
||||||
expr,
|
expr,
|
||||||
[&](const ast::IndexAccessorExpression* array) -> sem::Expression* {
|
[&](const ast::IndexAccessorExpression* array) -> sem::ValueExpression* {
|
||||||
return IndexAccessor(array);
|
return IndexAccessor(array);
|
||||||
},
|
},
|
||||||
[&](const ast::BinaryExpression* bin_op) -> sem::Expression* { return Binary(bin_op); },
|
[&](const ast::BinaryExpression* bin_op) -> sem::ValueExpression* {
|
||||||
[&](const ast::BitcastExpression* bitcast) -> sem::Expression* {
|
return Binary(bin_op);
|
||||||
|
},
|
||||||
|
[&](const ast::BitcastExpression* bitcast) -> sem::ValueExpression* {
|
||||||
return Bitcast(bitcast);
|
return Bitcast(bitcast);
|
||||||
},
|
},
|
||||||
[&](const ast::CallExpression* call) -> sem::Expression* { return Call(call); },
|
[&](const ast::CallExpression* call) -> sem::ValueExpression* { return Call(call); },
|
||||||
[&](const ast::IdentifierExpression* ident) -> sem::Expression* {
|
[&](const ast::IdentifierExpression* ident) -> sem::ValueExpression* {
|
||||||
return Identifier(ident);
|
return Identifier(ident);
|
||||||
},
|
},
|
||||||
[&](const ast::LiteralExpression* literal) -> sem::Expression* {
|
[&](const ast::LiteralExpression* literal) -> sem::ValueExpression* {
|
||||||
return Literal(literal);
|
return Literal(literal);
|
||||||
},
|
},
|
||||||
[&](const ast::MemberAccessorExpression* member) -> sem::Expression* {
|
[&](const ast::MemberAccessorExpression* member) -> sem::ValueExpression* {
|
||||||
return MemberAccessor(member);
|
return MemberAccessor(member);
|
||||||
},
|
},
|
||||||
[&](const ast::UnaryOpExpression* unary) -> sem::Expression* { return UnaryOp(unary); },
|
[&](const ast::UnaryOpExpression* unary) -> sem::ValueExpression* {
|
||||||
[&](const ast::PhonyExpression*) -> sem::Expression* {
|
return UnaryOp(unary);
|
||||||
return builder_->create<sem::Expression>(expr, builder_->create<type::Void>(),
|
},
|
||||||
sem::EvaluationStage::kRuntime,
|
[&](const ast::PhonyExpression*) -> sem::ValueExpression* {
|
||||||
current_statement_,
|
return builder_->create<sem::ValueExpression>(expr, builder_->create<type::Void>(),
|
||||||
/* constant_value */ nullptr,
|
sem::EvaluationStage::kRuntime,
|
||||||
/* has_side_effects */ false);
|
current_statement_,
|
||||||
|
/* constant_value */ nullptr,
|
||||||
|
/* has_side_effects */ false);
|
||||||
},
|
},
|
||||||
[&](Default) {
|
[&](Default) {
|
||||||
TINT_ICE(Resolver, diagnostics_)
|
TINT_ICE(Resolver, diagnostics_)
|
||||||
|
@ -1621,7 +1625,7 @@ sem::Expression* Resolver::Expression(const ast::Expression* root) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resolver::RegisterStore(const sem::Expression* expr) {
|
void Resolver::RegisterStore(const sem::ValueExpression* expr) {
|
||||||
auto& info = alias_analysis_infos_[current_function_];
|
auto& info = alias_analysis_infos_[current_function_];
|
||||||
Switch(
|
Switch(
|
||||||
expr->RootIdentifier(),
|
expr->RootIdentifier(),
|
||||||
|
@ -1643,11 +1647,11 @@ bool Resolver::AliasAnalysis(const sem::Call* call) {
|
||||||
|
|
||||||
// Helper to generate an aliasing error diagnostic.
|
// Helper to generate an aliasing error diagnostic.
|
||||||
struct Alias {
|
struct Alias {
|
||||||
const sem::Expression* expr; // the "other expression"
|
const sem::ValueExpression* expr; // the "other expression"
|
||||||
enum { Argument, ModuleScope } type; // the type of the "other" expression
|
enum { Argument, ModuleScope } type; // the type of the "other" expression
|
||||||
std::string access; // the access performed for the "other" expression
|
std::string access; // the access performed for the "other" expression
|
||||||
};
|
};
|
||||||
auto make_error = [&](const sem::Expression* arg, Alias&& var) {
|
auto make_error = [&](const sem::ValueExpression* arg, Alias&& var) {
|
||||||
// TODO(crbug.com/tint/1675): Switch to error and return false after deprecation period.
|
// TODO(crbug.com/tint/1675): Switch to error and return false after deprecation period.
|
||||||
AddWarning("invalid aliased pointer argument", arg->Declaration()->source);
|
AddWarning("invalid aliased pointer argument", arg->Declaration()->source);
|
||||||
switch (var.type) {
|
switch (var.type) {
|
||||||
|
@ -1672,8 +1676,8 @@ bool Resolver::AliasAnalysis(const sem::Call* call) {
|
||||||
auto& caller_info = alias_analysis_infos_[current_function_];
|
auto& caller_info = alias_analysis_infos_[current_function_];
|
||||||
|
|
||||||
// Track the set of root identifiers that are read and written by arguments passed in this call.
|
// Track the set of root identifiers that are read and written by arguments passed in this call.
|
||||||
std::unordered_map<const sem::Variable*, const sem::Expression*> arg_reads;
|
std::unordered_map<const sem::Variable*, const sem::ValueExpression*> arg_reads;
|
||||||
std::unordered_map<const sem::Variable*, const sem::Expression*> arg_writes;
|
std::unordered_map<const sem::Variable*, const sem::ValueExpression*> arg_writes;
|
||||||
for (size_t i = 0; i < args.Length(); i++) {
|
for (size_t i = 0; i < args.Length(); i++) {
|
||||||
auto* arg = args[i];
|
auto* arg = args[i];
|
||||||
if (!arg->Type()->Is<type::Pointer>()) {
|
if (!arg->Type()->Is<type::Pointer>()) {
|
||||||
|
@ -1787,7 +1791,7 @@ const type::Type* Resolver::ConcreteType(const type::Type* ty,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Expression* Resolver::Load(const sem::Expression* expr) {
|
const sem::ValueExpression* Resolver::Load(const sem::ValueExpression* expr) {
|
||||||
if (!expr) {
|
if (!expr) {
|
||||||
// Allow for Load(Expression(blah)), where failures pass through Load()
|
// Allow for Load(Expression(blah)), where failures pass through Load()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1814,8 +1818,8 @@ const sem::Expression* Resolver::Load(const sem::Expression* expr) {
|
||||||
return load;
|
return load;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Expression* Resolver::Materialize(const sem::Expression* expr,
|
const sem::ValueExpression* Resolver::Materialize(const sem::ValueExpression* expr,
|
||||||
const type::Type* target_type /* = nullptr */) {
|
const type::Type* target_type /* = nullptr */) {
|
||||||
if (!expr) {
|
if (!expr) {
|
||||||
// Allow for Materialize(Expression(blah)), where failures pass through Materialize()
|
// Allow for Materialize(Expression(blah)), where failures pass through Materialize()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1865,7 +1869,7 @@ const sem::Expression* Resolver::Materialize(const sem::Expression* expr,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
bool Resolver::MaybeMaterializeAndLoadArguments(utils::Vector<const sem::Expression*, N>& args,
|
bool Resolver::MaybeMaterializeAndLoadArguments(utils::Vector<const sem::ValueExpression*, N>& args,
|
||||||
const sem::CallTarget* target) {
|
const sem::CallTarget* target) {
|
||||||
for (size_t i = 0, n = std::min(args.Length(), target->Parameters().Length()); i < n; i++) {
|
for (size_t i = 0, n = std::min(args.Length(), target->Parameters().Length()); i < n; i++) {
|
||||||
const auto* param_ty = target->Parameters()[i]->Type();
|
const auto* param_ty = target->Parameters()[i]->Type();
|
||||||
|
@ -1905,7 +1909,7 @@ bool Resolver::Convert(const constant::Value*& c,
|
||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
utils::Result<utils::Vector<const constant::Value*, N>> Resolver::ConvertArguments(
|
utils::Result<utils::Vector<const constant::Value*, N>> Resolver::ConvertArguments(
|
||||||
const utils::Vector<const sem::Expression*, N>& args,
|
const utils::Vector<const sem::ValueExpression*, N>& args,
|
||||||
const sem::CallTarget* target) {
|
const sem::CallTarget* target) {
|
||||||
auto const_args = utils::Transform(args, [](auto* arg) { return arg->ConstantValue(); });
|
auto const_args = utils::Transform(args, [](auto* arg) { return arg->ConstantValue(); });
|
||||||
for (size_t i = 0, n = std::min(args.Length(), target->Parameters().Length()); i < n; i++) {
|
for (size_t i = 0, n = std::min(args.Length(), target->Parameters().Length()); i < n; i++) {
|
||||||
|
@ -1917,7 +1921,7 @@ utils::Result<utils::Vector<const constant::Value*, N>> Resolver::ConvertArgumen
|
||||||
return const_args;
|
return const_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Expression* Resolver::IndexAccessor(const ast::IndexAccessorExpression* expr) {
|
sem::ValueExpression* Resolver::IndexAccessor(const ast::IndexAccessorExpression* expr) {
|
||||||
auto* idx = Load(Materialize(sem_.Get(expr->index)));
|
auto* idx = Load(Materialize(sem_.Get(expr->index)));
|
||||||
if (!idx) {
|
if (!idx) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1980,7 +1984,7 @@ sem::Expression* Resolver::IndexAccessor(const ast::IndexAccessorExpression* exp
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Expression* Resolver::Bitcast(const ast::BitcastExpression* expr) {
|
sem::ValueExpression* Resolver::Bitcast(const ast::BitcastExpression* expr) {
|
||||||
auto* inner = Load(Materialize(sem_.Get(expr->expr)));
|
auto* inner = Load(Materialize(sem_.Get(expr->expr)));
|
||||||
if (!inner) {
|
if (!inner) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -2007,8 +2011,8 @@ sem::Expression* Resolver::Bitcast(const ast::BitcastExpression* expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* sem = builder_->create<sem::Expression>(expr, ty, stage, current_statement_,
|
auto* sem = builder_->create<sem::ValueExpression>(expr, ty, stage, current_statement_,
|
||||||
std::move(value), inner->HasSideEffects());
|
std::move(value), inner->HasSideEffects());
|
||||||
sem->Behaviors() = inner->Behaviors();
|
sem->Behaviors() = inner->Behaviors();
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
@ -2021,7 +2025,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
// * A type conversion.
|
// * A type conversion.
|
||||||
|
|
||||||
// Resolve all of the arguments, their types and the set of behaviors.
|
// Resolve all of the arguments, their types and the set of behaviors.
|
||||||
utils::Vector<const sem::Expression*, 8> args;
|
utils::Vector<const sem::ValueExpression*, 8> args;
|
||||||
args.Reserve(expr->args.Length());
|
args.Reserve(expr->args.Length());
|
||||||
auto args_stage = sem::EvaluationStage::kConstant;
|
auto args_stage = sem::EvaluationStage::kConstant;
|
||||||
sem::Behaviors arg_behaviors;
|
sem::Behaviors arg_behaviors;
|
||||||
|
@ -2094,8 +2098,8 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
// Constant evaluation failed.
|
// Constant evaluation failed.
|
||||||
// Can happen for expressions that will fail validation (later).
|
// Can happen for expressions that will fail validation (later).
|
||||||
// Use the kRuntime EvaluationStage, as kConstant will trigger an assertion in
|
// Use the kRuntime EvaluationStage, as kConstant will trigger an assertion in
|
||||||
// the sem::Expression initializer, which checks that kConstant is paired with a
|
// the sem::ValueExpression initializer, which checks that kConstant is paired with
|
||||||
// constant value.
|
// a constant value.
|
||||||
stage = sem::EvaluationStage::kRuntime;
|
stage = sem::EvaluationStage::kRuntime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2344,7 +2348,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
sem::Call* Resolver::BuiltinCall(const ast::CallExpression* expr,
|
sem::Call* Resolver::BuiltinCall(const ast::CallExpression* expr,
|
||||||
sem::BuiltinType builtin_type,
|
sem::BuiltinType builtin_type,
|
||||||
utils::Vector<const sem::Expression*, N>& args) {
|
utils::Vector<const sem::ValueExpression*, N>& args) {
|
||||||
auto arg_stage = sem::EvaluationStage::kConstant;
|
auto arg_stage = sem::EvaluationStage::kConstant;
|
||||||
for (auto* arg : args) {
|
for (auto* arg : args) {
|
||||||
arg_stage = sem::EarliestStage(arg_stage, arg->Stage());
|
arg_stage = sem::EarliestStage(arg_stage, arg->Stage());
|
||||||
|
@ -2515,8 +2519,9 @@ type::Type* Resolver::ShortName(Symbol sym, const Source& source) const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resolver::CollectTextureSamplerPairs(const sem::Builtin* builtin,
|
void Resolver::CollectTextureSamplerPairs(
|
||||||
utils::VectorRef<const sem::Expression*> args) const {
|
const sem::Builtin* builtin,
|
||||||
|
utils::VectorRef<const sem::ValueExpression*> args) const {
|
||||||
// Collect a texture/sampler pair for this builtin.
|
// Collect a texture/sampler pair for this builtin.
|
||||||
const auto& signature = builtin->Signature();
|
const auto& signature = builtin->Signature();
|
||||||
int texture_index = signature.IndexOf(sem::ParameterUsage::kTexture);
|
int texture_index = signature.IndexOf(sem::ParameterUsage::kTexture);
|
||||||
|
@ -2542,7 +2547,7 @@ void Resolver::CollectTextureSamplerPairs(const sem::Builtin* builtin,
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
sem::Call* Resolver::FunctionCall(const ast::CallExpression* expr,
|
sem::Call* Resolver::FunctionCall(const ast::CallExpression* expr,
|
||||||
sem::Function* target,
|
sem::Function* target,
|
||||||
utils::Vector<const sem::Expression*, N>& args,
|
utils::Vector<const sem::ValueExpression*, N>& args,
|
||||||
sem::Behaviors arg_behaviors) {
|
sem::Behaviors arg_behaviors) {
|
||||||
auto sym = expr->target.name->symbol;
|
auto sym = expr->target.name->symbol;
|
||||||
auto name = builder_->Symbols().NameFor(sym);
|
auto name = builder_->Symbols().NameFor(sym);
|
||||||
|
@ -2592,8 +2597,9 @@ sem::Call* Resolver::FunctionCall(const ast::CallExpression* expr,
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resolver::CollectTextureSamplerPairs(sem::Function* func,
|
void Resolver::CollectTextureSamplerPairs(
|
||||||
utils::VectorRef<const sem::Expression*> args) const {
|
sem::Function* func,
|
||||||
|
utils::VectorRef<const sem::ValueExpression*> args) const {
|
||||||
// Map all texture/sampler pairs from the target function to the
|
// Map all texture/sampler pairs from the target function to the
|
||||||
// current function. These can only be global or parameter
|
// current function. These can only be global or parameter
|
||||||
// variables. Resolve any parameter variables to the corresponding
|
// variables. Resolve any parameter variables to the corresponding
|
||||||
|
@ -2615,7 +2621,7 @@ void Resolver::CollectTextureSamplerPairs(sem::Function* func,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Expression* Resolver::Literal(const ast::LiteralExpression* literal) {
|
sem::ValueExpression* Resolver::Literal(const ast::LiteralExpression* literal) {
|
||||||
auto* ty = Switch(
|
auto* ty = Switch(
|
||||||
literal,
|
literal,
|
||||||
[&](const ast::IntLiteralExpression* i) -> type::Type* {
|
[&](const ast::IntLiteralExpression* i) -> type::Type* {
|
||||||
|
@ -2669,11 +2675,12 @@ sem::Expression* Resolver::Literal(const ast::LiteralExpression* literal) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder_->create<sem::Expression>(literal, ty, stage, current_statement_, std::move(val),
|
return builder_->create<sem::ValueExpression>(literal, ty, stage, current_statement_,
|
||||||
/* has_side_effects */ false);
|
std::move(val),
|
||||||
|
/* has_side_effects */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
|
sem::ValueExpression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
|
||||||
Mark(expr->identifier);
|
Mark(expr->identifier);
|
||||||
auto symbol = expr->identifier->symbol;
|
auto symbol = expr->identifier->symbol;
|
||||||
auto* sem_resolved = sem_.ResolvedSymbol<sem::Node>(expr);
|
auto* sem_resolved = sem_.ResolvedSymbol<sem::Node>(expr);
|
||||||
|
@ -2769,7 +2776,7 @@ sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* expr) {
|
sem::ValueExpression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* expr) {
|
||||||
auto* structure = sem_.TypeOf(expr->structure);
|
auto* structure = sem_.TypeOf(expr->structure);
|
||||||
auto* storage_ty = structure->UnwrapRef();
|
auto* storage_ty = structure->UnwrapRef();
|
||||||
auto* object = sem_.Get(expr->structure);
|
auto* object = sem_.Get(expr->structure);
|
||||||
|
@ -2784,7 +2791,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
||||||
|
|
||||||
return Switch(
|
return Switch(
|
||||||
storage_ty, //
|
storage_ty, //
|
||||||
[&](const sem::Struct* str) -> sem::Expression* {
|
[&](const sem::Struct* str) -> sem::ValueExpression* {
|
||||||
auto symbol = expr->member->symbol;
|
auto symbol = expr->member->symbol;
|
||||||
|
|
||||||
const sem::StructMember* member = nullptr;
|
const sem::StructMember* member = nullptr;
|
||||||
|
@ -2817,7 +2824,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
||||||
has_side_effects, root_ident);
|
has_side_effects, root_ident);
|
||||||
},
|
},
|
||||||
|
|
||||||
[&](const type::Vector* vec) -> sem::Expression* {
|
[&](const type::Vector* vec) -> sem::ValueExpression* {
|
||||||
std::string s = builder_->Symbols().NameFor(expr->member->symbol);
|
std::string s = builder_->Symbols().NameFor(expr->member->symbol);
|
||||||
auto size = s.size();
|
auto size = s.size();
|
||||||
utils::Vector<uint32_t, 4> swizzle;
|
utils::Vector<uint32_t, 4> swizzle;
|
||||||
|
@ -2868,7 +2875,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Expression* obj_expr = object;
|
const sem::ValueExpression* obj_expr = object;
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
// A single element swizzle is just the type of the vector.
|
// A single element swizzle is just the type of the vector.
|
||||||
ty = vec->type();
|
ty = vec->type();
|
||||||
|
@ -2900,7 +2907,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Expression* Resolver::Binary(const ast::BinaryExpression* expr) {
|
sem::ValueExpression* Resolver::Binary(const ast::BinaryExpression* expr) {
|
||||||
const auto* lhs = sem_.Get(expr->lhs);
|
const auto* lhs = sem_.Get(expr->lhs);
|
||||||
const auto* rhs = sem_.Get(expr->rhs);
|
const auto* rhs = sem_.Get(expr->rhs);
|
||||||
auto* lhs_ty = lhs->Type()->UnwrapRef();
|
auto* lhs_ty = lhs->Type()->UnwrapRef();
|
||||||
|
@ -2970,14 +2977,14 @@ sem::Expression* Resolver::Binary(const ast::BinaryExpression* expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_side_effects = lhs->HasSideEffects() || rhs->HasSideEffects();
|
bool has_side_effects = lhs->HasSideEffects() || rhs->HasSideEffects();
|
||||||
auto* sem = builder_->create<sem::Expression>(expr, op.result, stage, current_statement_, value,
|
auto* sem = builder_->create<sem::ValueExpression>(expr, op.result, stage, current_statement_,
|
||||||
has_side_effects);
|
value, has_side_effects);
|
||||||
sem->Behaviors() = lhs->Behaviors() + rhs->Behaviors();
|
sem->Behaviors() = lhs->Behaviors() + rhs->Behaviors();
|
||||||
|
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
sem::ValueExpression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
||||||
const auto* expr = sem_.Get(unary->expr);
|
const auto* expr = sem_.Get(unary->expr);
|
||||||
auto* expr_ty = expr->Type();
|
auto* expr_ty = expr->Type();
|
||||||
if (!expr_ty) {
|
if (!expr_ty) {
|
||||||
|
@ -3066,8 +3073,8 @@ sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* sem = builder_->create<sem::Expression>(unary, ty, stage, current_statement_, value,
|
auto* sem = builder_->create<sem::ValueExpression>(unary, ty, stage, current_statement_, value,
|
||||||
expr->HasSideEffects(), root_ident);
|
expr->HasSideEffects(), root_ident);
|
||||||
sem->Behaviors() = expr->Behaviors();
|
sem->Behaviors() = expr->Behaviors();
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ class Resolver {
|
||||||
/// list (leaf-first) of all the expression nodes. Each of the expressions are then resolved by
|
/// list (leaf-first) of all the expression nodes. Each of the expressions are then resolved by
|
||||||
/// dispatching to the appropriate expression handlers below.
|
/// dispatching to the appropriate expression handlers below.
|
||||||
/// @returns the resolved semantic node for the expression `expr`, or nullptr on failure.
|
/// @returns the resolved semantic node for the expression `expr`, or nullptr on failure.
|
||||||
sem::Expression* Expression(const ast::Expression* expr);
|
sem::ValueExpression* Expression(const ast::Expression* expr);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Expression resolving methods
|
// Expression resolving methods
|
||||||
|
@ -137,28 +137,28 @@ class Resolver {
|
||||||
// not attempt to resolve their children. This design avoids recursion, which is a common cause
|
// not attempt to resolve their children. This design avoids recursion, which is a common cause
|
||||||
// of stack-overflows.
|
// of stack-overflows.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
sem::Expression* IndexAccessor(const ast::IndexAccessorExpression*);
|
sem::ValueExpression* IndexAccessor(const ast::IndexAccessorExpression*);
|
||||||
sem::Expression* Binary(const ast::BinaryExpression*);
|
sem::ValueExpression* Binary(const ast::BinaryExpression*);
|
||||||
sem::Expression* Bitcast(const ast::BitcastExpression*);
|
sem::ValueExpression* Bitcast(const ast::BitcastExpression*);
|
||||||
sem::Call* Call(const ast::CallExpression*);
|
sem::Call* Call(const ast::CallExpression*);
|
||||||
sem::Function* Function(const ast::Function*);
|
sem::Function* Function(const ast::Function*);
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
sem::Call* FunctionCall(const ast::CallExpression*,
|
sem::Call* FunctionCall(const ast::CallExpression*,
|
||||||
sem::Function* target,
|
sem::Function* target,
|
||||||
utils::Vector<const sem::Expression*, N>& args,
|
utils::Vector<const sem::ValueExpression*, N>& args,
|
||||||
sem::Behaviors arg_behaviors);
|
sem::Behaviors arg_behaviors);
|
||||||
sem::Expression* Identifier(const ast::IdentifierExpression*);
|
sem::ValueExpression* Identifier(const ast::IdentifierExpression*);
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
sem::Call* BuiltinCall(const ast::CallExpression*,
|
sem::Call* BuiltinCall(const ast::CallExpression*,
|
||||||
sem::BuiltinType,
|
sem::BuiltinType,
|
||||||
utils::Vector<const sem::Expression*, N>& args);
|
utils::Vector<const sem::ValueExpression*, N>& args);
|
||||||
sem::Expression* Literal(const ast::LiteralExpression*);
|
sem::ValueExpression* Literal(const ast::LiteralExpression*);
|
||||||
sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*);
|
sem::ValueExpression* MemberAccessor(const ast::MemberAccessorExpression*);
|
||||||
sem::Expression* UnaryOp(const ast::UnaryOpExpression*);
|
sem::ValueExpression* UnaryOp(const ast::UnaryOpExpression*);
|
||||||
|
|
||||||
/// Register a memory store to an expression, to track accesses to root identifiers in order to
|
/// Register a memory store to an expression, to track accesses to root identifiers in order to
|
||||||
/// perform alias analysis.
|
/// perform alias analysis.
|
||||||
void RegisterStore(const sem::Expression* expr);
|
void RegisterStore(const sem::ValueExpression* expr);
|
||||||
|
|
||||||
/// Perform pointer alias analysis for `call`.
|
/// Perform pointer alias analysis for `call`.
|
||||||
/// @returns true is the call arguments are free from aliasing issues, false otherwise.
|
/// @returns true is the call arguments are free from aliasing issues, false otherwise.
|
||||||
|
@ -166,7 +166,7 @@ class Resolver {
|
||||||
|
|
||||||
/// If `expr` is of a reference type, then Load will create and return a sem::Load node wrapping
|
/// If `expr` is of a reference type, then Load will create and return a sem::Load node wrapping
|
||||||
/// `expr`. If `expr` is not of a reference type, then Load will just return `expr`.
|
/// `expr`. If `expr` is not of a reference type, then Load will just return `expr`.
|
||||||
const sem::Expression* Load(const sem::Expression* expr);
|
const sem::ValueExpression* Load(const sem::ValueExpression* expr);
|
||||||
|
|
||||||
/// If `expr` is not of an abstract-numeric type, then Materialize() will just return `expr`.
|
/// If `expr` is not of an abstract-numeric type, then Materialize() will just return `expr`.
|
||||||
/// * Materialize will create and return a sem::Materialize node wrapping `expr`.
|
/// * Materialize will create and return a sem::Materialize node wrapping `expr`.
|
||||||
|
@ -181,8 +181,8 @@ class Resolver {
|
||||||
/// materialized type.
|
/// materialized type.
|
||||||
/// If `expr` is not of an abstract-numeric type, then Materialize() will just return `expr`.
|
/// If `expr` is not of an abstract-numeric type, then Materialize() will just return `expr`.
|
||||||
/// If `expr` is nullptr, then Materialize() will also return nullptr.
|
/// If `expr` is nullptr, then Materialize() will also return nullptr.
|
||||||
const sem::Expression* Materialize(const sem::Expression* expr,
|
const sem::ValueExpression* Materialize(const sem::ValueExpression* expr,
|
||||||
const type::Type* target_type = nullptr);
|
const type::Type* target_type = nullptr);
|
||||||
|
|
||||||
/// For each argument in `args`:
|
/// For each argument in `args`:
|
||||||
/// * Calls Materialize() passing the argument and the corresponding parameter type.
|
/// * Calls Materialize() passing the argument and the corresponding parameter type.
|
||||||
|
@ -190,7 +190,7 @@ class Resolver {
|
||||||
/// reference type.
|
/// reference type.
|
||||||
/// @returns true on success, false on failure.
|
/// @returns true on success, false on failure.
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
bool MaybeMaterializeAndLoadArguments(utils::Vector<const sem::Expression*, N>& args,
|
bool MaybeMaterializeAndLoadArguments(utils::Vector<const sem::ValueExpression*, N>& args,
|
||||||
const sem::CallTarget* target);
|
const sem::CallTarget* target);
|
||||||
|
|
||||||
/// @returns true if an argument of an abstract numeric type, passed to a parameter of type
|
/// @returns true if an argument of an abstract numeric type, passed to a parameter of type
|
||||||
|
@ -206,7 +206,7 @@ class Resolver {
|
||||||
/// @returns the vector of constants, `utils::Failure` on failure.
|
/// @returns the vector of constants, `utils::Failure` on failure.
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
utils::Result<utils::Vector<const constant::Value*, N>> ConvertArguments(
|
utils::Result<utils::Vector<const constant::Value*, N>> ConvertArguments(
|
||||||
const utils::Vector<const sem::Expression*, N>& args,
|
const utils::Vector<const sem::ValueExpression*, N>& args,
|
||||||
const sem::CallTarget* target);
|
const sem::CallTarget* target);
|
||||||
|
|
||||||
/// @param ty the type that may hold abstract numeric types
|
/// @param ty the type that may hold abstract numeric types
|
||||||
|
@ -247,9 +247,9 @@ class Resolver {
|
||||||
// CollectTextureSamplerPairs() collects all the texture/sampler pairs from the target function
|
// CollectTextureSamplerPairs() collects all the texture/sampler pairs from the target function
|
||||||
// / builtin, and records these on the current function by calling AddTextureSamplerPair().
|
// / builtin, and records these on the current function by calling AddTextureSamplerPair().
|
||||||
void CollectTextureSamplerPairs(sem::Function* func,
|
void CollectTextureSamplerPairs(sem::Function* func,
|
||||||
utils::VectorRef<const sem::Expression*> args) const;
|
utils::VectorRef<const sem::ValueExpression*> args) const;
|
||||||
void CollectTextureSamplerPairs(const sem::Builtin* builtin,
|
void CollectTextureSamplerPairs(const sem::Builtin* builtin,
|
||||||
utils::VectorRef<const sem::Expression*> args) const;
|
utils::VectorRef<const sem::ValueExpression*> args) const;
|
||||||
|
|
||||||
/// Resolves the WorkgroupSize for the given function, assigning it to
|
/// Resolves the WorkgroupSize for the given function, assigning it to
|
||||||
/// current_function_
|
/// current_function_
|
||||||
|
@ -459,9 +459,9 @@ class Resolver {
|
||||||
/// of determining if any two arguments alias at any callsite.
|
/// of determining if any two arguments alias at any callsite.
|
||||||
struct AliasAnalysisInfo {
|
struct AliasAnalysisInfo {
|
||||||
/// The set of module-scope variables that are written to, and where that write occurs.
|
/// The set of module-scope variables that are written to, and where that write occurs.
|
||||||
std::unordered_map<const sem::Variable*, const sem::Expression*> module_scope_writes;
|
std::unordered_map<const sem::Variable*, const sem::ValueExpression*> module_scope_writes;
|
||||||
/// The set of module-scope variables that are read from, and where that read occurs.
|
/// The set of module-scope variables that are read from, and where that read occurs.
|
||||||
std::unordered_map<const sem::Variable*, const sem::Expression*> module_scope_reads;
|
std::unordered_map<const sem::Variable*, const sem::ValueExpression*> module_scope_reads;
|
||||||
/// The set of function parameters that are written to.
|
/// The set of function parameters that are written to.
|
||||||
std::unordered_set<const sem::Variable*> parameter_writes;
|
std::unordered_set<const sem::Variable*> parameter_writes;
|
||||||
/// The set of function parameters that are read from.
|
/// The set of function parameters that are read from.
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/tint/resolver/resolver_test_helper.h"
|
#include "src/tint/resolver/resolver_test_helper.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/for_loop_statement.h"
|
#include "src/tint/sem/for_loop_statement.h"
|
||||||
#include "src/tint/sem/if_statement.h"
|
#include "src/tint/sem/if_statement.h"
|
||||||
#include "src/tint/sem/switch_statement.h"
|
#include "src/tint/sem/switch_statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/sem/while_statement.h"
|
#include "src/tint/sem/while_statement.h"
|
||||||
|
|
||||||
using namespace tint::number_suffixes; // NOLINT
|
using namespace tint::number_suffixes; // NOLINT
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
#include "src/tint/resolver/resolver.h"
|
#include "src/tint/resolver/resolver.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/sem/variable.h"
|
#include "src/tint/sem/variable.h"
|
||||||
#include "src/tint/traits.h"
|
#include "src/tint/traits.h"
|
||||||
#include "src/tint/type/abstract_float.h"
|
#include "src/tint/type/abstract_float.h"
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "src/tint/resolver/sem_helper.h"
|
#include "src/tint/resolver/sem_helper.h"
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
|
|
||||||
namespace tint::resolver {
|
namespace tint::resolver {
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/tint/resolver/resolver_test_helper.h"
|
#include "src/tint/resolver/resolver_test_helper.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/index_accessor_expression.h"
|
#include "src/tint/sem/index_accessor_expression.h"
|
||||||
#include "src/tint/sem/member_accessor_expression.h"
|
#include "src/tint/sem/member_accessor_expression.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/type/texture_dimension.h"
|
#include "src/tint/type/texture_dimension.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
|
|
|
@ -384,7 +384,7 @@ bool Validator::Materialize(const type::Type* to,
|
||||||
bool Validator::VariableInitializer(const ast::Variable* v,
|
bool Validator::VariableInitializer(const ast::Variable* v,
|
||||||
type::AddressSpace address_space,
|
type::AddressSpace address_space,
|
||||||
const type::Type* storage_ty,
|
const type::Type* storage_ty,
|
||||||
const sem::Expression* initializer) const {
|
const sem::ValueExpression* initializer) const {
|
||||||
auto* initializer_ty = initializer->Type();
|
auto* initializer_ty = initializer->Type();
|
||||||
auto* value_type = initializer_ty->UnwrapRef(); // Implicit load of RHS
|
auto* value_type = initializer_ty->UnwrapRef(); // Implicit load of RHS
|
||||||
|
|
||||||
|
@ -1343,7 +1343,7 @@ bool Validator::EntryPoint(const sem::Function* func, ast::PipelineStage stage)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::EvaluationStage(const sem::Expression* expr,
|
bool Validator::EvaluationStage(const sem::ValueExpression* expr,
|
||||||
sem::EvaluationStage latest_stage,
|
sem::EvaluationStage latest_stage,
|
||||||
std::string_view constraint) const {
|
std::string_view constraint) const {
|
||||||
if (expr->Stage() == sem::EvaluationStage::kNotEvaluated) {
|
if (expr->Stage() == sem::EvaluationStage::kNotEvaluated) {
|
||||||
|
|
|
@ -245,7 +245,7 @@ class Validator {
|
||||||
/// @param latest_stage the latest evaluation stage that the expression can be evaluated
|
/// @param latest_stage the latest evaluation stage that the expression can be evaluated
|
||||||
/// @param constraint the 'thing' that is imposing the contraint. e.g. "var declaration"
|
/// @param constraint the 'thing' that is imposing the contraint. e.g. "var declaration"
|
||||||
/// @returns true if @p expr is evaluated in or before @p latest_stage, false otherwise
|
/// @returns true if @p expr is evaluated in or before @p latest_stage, false otherwise
|
||||||
bool EvaluationStage(const sem::Expression* expr,
|
bool EvaluationStage(const sem::ValueExpression* expr,
|
||||||
sem::EvaluationStage latest_stage,
|
sem::EvaluationStage latest_stage,
|
||||||
std::string_view constraint) const;
|
std::string_view constraint) const;
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ class Validator {
|
||||||
bool VariableInitializer(const ast::Variable* v,
|
bool VariableInitializer(const ast::Variable* v,
|
||||||
type::AddressSpace address_space,
|
type::AddressSpace address_space,
|
||||||
const type::Type* storage_type,
|
const type::Type* storage_type,
|
||||||
const sem::Expression* initializer) const;
|
const sem::ValueExpression* initializer) const;
|
||||||
|
|
||||||
/// Validates a vector
|
/// Validates a vector
|
||||||
/// @param ty the vector to validate
|
/// @param ty the vector to validate
|
||||||
|
|
|
@ -40,7 +40,7 @@ type::ArrayCount* NamedOverrideArrayCount::Clone(type::CloneContext&) const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnnamedOverrideArrayCount::UnnamedOverrideArrayCount(const Expression* e)
|
UnnamedOverrideArrayCount::UnnamedOverrideArrayCount(const ValueExpression* e)
|
||||||
: Base(static_cast<size_t>(TypeInfo::Of<UnnamedOverrideArrayCount>().full_hashcode)), expr(e) {}
|
: Base(static_cast<size_t>(TypeInfo::Of<UnnamedOverrideArrayCount>().full_hashcode)), expr(e) {}
|
||||||
UnnamedOverrideArrayCount::~UnnamedOverrideArrayCount() = default;
|
UnnamedOverrideArrayCount::~UnnamedOverrideArrayCount() = default;
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/sem/variable.h"
|
#include "src/tint/sem/variable.h"
|
||||||
#include "src/tint/type/array_count.h"
|
#include "src/tint/type/array_count.h"
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class UnnamedOverrideArrayCount final
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param e the override expression
|
/// @param e the override expression
|
||||||
explicit UnnamedOverrideArrayCount(const Expression* e);
|
explicit UnnamedOverrideArrayCount(const ValueExpression* e);
|
||||||
~UnnamedOverrideArrayCount() override;
|
~UnnamedOverrideArrayCount() override;
|
||||||
|
|
||||||
/// @param other the other node
|
/// @param other the other node
|
||||||
|
@ -90,7 +90,7 @@ class UnnamedOverrideArrayCount final
|
||||||
/// ```
|
/// ```
|
||||||
// The array count for `a` and `b` have equivalent AST expressions, but the types for `a` and
|
// The array count for `a` and `b` have equivalent AST expressions, but the types for `a` and
|
||||||
// `b` must not compare equal.
|
// `b` must not compare equal.
|
||||||
const Expression* expr;
|
const ValueExpression* expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace tint::ast {
|
||||||
class BreakIfStatement;
|
class BreakIfStatement;
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class Expression;
|
class ValueExpression;
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
@ -45,14 +45,14 @@ class BreakIfStatement final : public Castable<BreakIfStatement, CompoundStateme
|
||||||
const ast::BreakIfStatement* Declaration() const;
|
const ast::BreakIfStatement* Declaration() const;
|
||||||
|
|
||||||
/// @returns the break-if-statement condition expression
|
/// @returns the break-if-statement condition expression
|
||||||
const Expression* Condition() const { return condition_; }
|
const ValueExpression* Condition() const { return condition_; }
|
||||||
|
|
||||||
/// Sets the break-if-statement condition expression
|
/// Sets the break-if-statement condition expression
|
||||||
/// @param condition the break-if condition expression
|
/// @param condition the break-if condition expression
|
||||||
void SetCondition(const Expression* condition) { condition_ = condition; }
|
void SetCondition(const ValueExpression* condition) { condition_ = condition; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Expression* condition_ = nullptr;
|
const ValueExpression* condition_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace tint::sem {
|
||||||
Call::Call(const ast::CallExpression* declaration,
|
Call::Call(const ast::CallExpression* declaration,
|
||||||
const CallTarget* target,
|
const CallTarget* target,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
utils::VectorRef<const sem::Expression*> arguments,
|
utils::VectorRef<const sem::ValueExpression*> arguments,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
bool has_side_effects)
|
bool has_side_effects)
|
||||||
|
|
|
@ -19,14 +19,14 @@
|
||||||
|
|
||||||
#include "src/tint/ast/call_expression.h"
|
#include "src/tint/ast/call_expression.h"
|
||||||
#include "src/tint/sem/builtin.h"
|
#include "src/tint/sem/builtin.h"
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// Call is the base class for semantic nodes that hold semantic information for
|
/// Call is the base class for semantic nodes that hold semantic information for
|
||||||
/// ast::CallExpression nodes.
|
/// ast::CallExpression nodes.
|
||||||
class Call final : public Castable<Call, Expression> {
|
class Call final : public Castable<Call, ValueExpression> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param declaration the AST node
|
/// @param declaration the AST node
|
||||||
|
@ -39,7 +39,7 @@ class Call final : public Castable<Call, Expression> {
|
||||||
Call(const ast::CallExpression* declaration,
|
Call(const ast::CallExpression* declaration,
|
||||||
const CallTarget* target,
|
const CallTarget* target,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
utils::VectorRef<const sem::Expression*> arguments,
|
utils::VectorRef<const sem::ValueExpression*> arguments,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
bool has_side_effects);
|
bool has_side_effects);
|
||||||
|
@ -60,7 +60,7 @@ class Call final : public Castable<Call, Expression> {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CallTarget const* const target_;
|
CallTarget const* const target_;
|
||||||
utils::Vector<const sem::Expression*, 8> arguments_;
|
utils::Vector<const sem::ValueExpression*, 8> arguments_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace tint::ast {
|
||||||
class ForLoopStatement;
|
class ForLoopStatement;
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class Expression;
|
class ValueExpression;
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
@ -45,14 +45,14 @@ class ForLoopStatement final : public Castable<ForLoopStatement, CompoundStateme
|
||||||
const ast::ForLoopStatement* Declaration() const;
|
const ast::ForLoopStatement* Declaration() const;
|
||||||
|
|
||||||
/// @returns the for-loop condition expression
|
/// @returns the for-loop condition expression
|
||||||
const Expression* Condition() const { return condition_; }
|
const ValueExpression* Condition() const { return condition_; }
|
||||||
|
|
||||||
/// Sets the for-loop condition expression
|
/// Sets the for-loop condition expression
|
||||||
/// @param condition the for-loop condition expression
|
/// @param condition the for-loop condition expression
|
||||||
void SetCondition(const Expression* condition) { condition_ = condition; }
|
void SetCondition(const ValueExpression* condition) { condition_ = condition; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Expression* condition_ = nullptr;
|
const ValueExpression* condition_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace tint::ast {
|
||||||
class IfStatement;
|
class IfStatement;
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class Expression;
|
class ValueExpression;
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
@ -45,14 +45,14 @@ class IfStatement final : public Castable<IfStatement, CompoundStatement> {
|
||||||
const ast::IfStatement* Declaration() const;
|
const ast::IfStatement* Declaration() const;
|
||||||
|
|
||||||
/// @returns the if-statement condition expression
|
/// @returns the if-statement condition expression
|
||||||
const Expression* Condition() const { return condition_; }
|
const ValueExpression* Condition() const { return condition_; }
|
||||||
|
|
||||||
/// Sets the if-statement condition expression
|
/// Sets the if-statement condition expression
|
||||||
/// @param condition the if condition expression
|
/// @param condition the if condition expression
|
||||||
void SetCondition(const Expression* condition) { condition_ = condition; }
|
void SetCondition(const ValueExpression* condition) { condition_ = condition; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Expression* condition_ = nullptr;
|
const ValueExpression* condition_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -25,8 +25,8 @@ namespace tint::sem {
|
||||||
IndexAccessorExpression::IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
IndexAccessorExpression::IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Expression* object,
|
const ValueExpression* object,
|
||||||
const Expression* index,
|
const ValueExpression* index,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
namespace tint::ast {
|
namespace tint::ast {
|
||||||
|
@ -27,7 +27,7 @@ class IndexAccessorExpression;
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// IndexAccessorExpression holds the semantic information for a ast::IndexAccessorExpression node.
|
/// IndexAccessorExpression holds the semantic information for a ast::IndexAccessorExpression node.
|
||||||
class IndexAccessorExpression final : public Castable<IndexAccessorExpression, Expression> {
|
class IndexAccessorExpression final : public Castable<IndexAccessorExpression, ValueExpression> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param declaration the AST node
|
/// @param declaration the AST node
|
||||||
|
@ -42,8 +42,8 @@ class IndexAccessorExpression final : public Castable<IndexAccessorExpression, E
|
||||||
IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Expression* object,
|
const ValueExpression* object,
|
||||||
const Expression* index,
|
const ValueExpression* index,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
|
@ -53,14 +53,14 @@ class IndexAccessorExpression final : public Castable<IndexAccessorExpression, E
|
||||||
~IndexAccessorExpression() override;
|
~IndexAccessorExpression() override;
|
||||||
|
|
||||||
/// @returns the object expression that is being indexed
|
/// @returns the object expression that is being indexed
|
||||||
Expression const* Object() const { return object_; }
|
ValueExpression const* Object() const { return object_; }
|
||||||
|
|
||||||
/// @returns the index expression
|
/// @returns the index expression
|
||||||
Expression const* Index() const { return index_; }
|
ValueExpression const* Index() const { return index_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Expression const* const object_;
|
ValueExpression const* const object_;
|
||||||
Expression const* const index_;
|
ValueExpression const* const index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
|
|
||||||
#include "src/tint/sem/info.h"
|
#include "src/tint/sem/info.h"
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/function.h"
|
#include "src/tint/sem/function.h"
|
||||||
#include "src/tint/sem/module.h"
|
#include "src/tint/sem/module.h"
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ ast::DiagnosticSeverity Info::DiagnosticSeverity(const ast::Node* ast_node,
|
||||||
TINT_ASSERT(Resolver, sem != nullptr);
|
TINT_ASSERT(Resolver, sem != nullptr);
|
||||||
auto severity = Switch(
|
auto severity = Switch(
|
||||||
sem, //
|
sem, //
|
||||||
[&](const sem::Expression* expr) { return check_stmt(expr->Stmt()); },
|
[&](const sem::ValueExpression* expr) { return check_stmt(expr->Stmt()); },
|
||||||
[&](const sem::Statement* stmt) { return check_stmt(stmt); },
|
[&](const sem::Statement* stmt) { return check_stmt(stmt); },
|
||||||
[&](const sem::Function* func) { return check_func(func); },
|
[&](const sem::Function* func) { return check_func(func); },
|
||||||
[&](Default) {
|
[&](Default) {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Load);
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::Load);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
Load::Load(const Expression* ref, const Statement* statement)
|
Load::Load(const ValueExpression* ref, const Statement* statement)
|
||||||
: Base(/* declaration */ ref->Declaration(),
|
: Base(/* declaration */ ref->Declaration(),
|
||||||
/* type */ ref->Type()->UnwrapRef(),
|
/* type */ ref->Type()->UnwrapRef(),
|
||||||
/* stage */ EvaluationStage::kRuntime, // Loads can only be runtime
|
/* stage */ EvaluationStage::kRuntime, // Loads can only be runtime
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#ifndef SRC_TINT_SEM_LOAD_H_
|
#ifndef SRC_TINT_SEM_LOAD_H_
|
||||||
#define SRC_TINT_SEM_LOAD_H_
|
#define SRC_TINT_SEM_LOAD_H_
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/type/reference.h"
|
#include "src/tint/type/reference.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
@ -23,18 +23,18 @@ namespace tint::sem {
|
||||||
/// Load is a semantic expression which represents the load of a reference to a non-reference value.
|
/// Load is a semantic expression which represents the load of a reference to a non-reference value.
|
||||||
/// Loads from reference types are implicit in WGSL, so the Load semantic node shares the same AST
|
/// Loads from reference types are implicit in WGSL, so the Load semantic node shares the same AST
|
||||||
/// node as the inner semantic node.
|
/// node as the inner semantic node.
|
||||||
class Load final : public Castable<Load, Expression> {
|
class Load final : public Castable<Load, ValueExpression> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param reference the reference expression being loaded
|
/// @param reference the reference expression being loaded
|
||||||
/// @param statement the statement that owns this expression
|
/// @param statement the statement that owns this expression
|
||||||
Load(const Expression* reference, const Statement* statement);
|
Load(const ValueExpression* reference, const Statement* statement);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Load() override;
|
~Load() override;
|
||||||
|
|
||||||
/// @return the reference being loaded
|
/// @return the reference being loaded
|
||||||
const Expression* Reference() const { return reference_; }
|
const ValueExpression* Reference() const { return reference_; }
|
||||||
|
|
||||||
/// @returns the type of the loaded reference.
|
/// @returns the type of the loaded reference.
|
||||||
const type::Reference* ReferenceType() const {
|
const type::Reference* ReferenceType() const {
|
||||||
|
@ -42,7 +42,7 @@ class Load final : public Castable<Load, Expression> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Expression const* const reference_;
|
ValueExpression const* const reference_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Materialize);
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::Materialize);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
Materialize::Materialize(const Expression* expr,
|
Materialize::Materialize(const ValueExpression* expr,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
const constant::Value* constant)
|
const constant::Value* constant)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#ifndef SRC_TINT_SEM_MATERIALIZE_H_
|
#ifndef SRC_TINT_SEM_MATERIALIZE_H_
|
||||||
#define SRC_TINT_SEM_MATERIALIZE_H_
|
#define SRC_TINT_SEM_MATERIALIZE_H_
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
|
@ -25,14 +25,14 @@ namespace tint::sem {
|
||||||
/// the same AST node as the inner semantic node.
|
/// the same AST node as the inner semantic node.
|
||||||
/// Abstract numerics types may only be used by compile-time expressions, so a Materialize semantic
|
/// Abstract numerics types may only be used by compile-time expressions, so a Materialize semantic
|
||||||
/// node must have a valid Constant value.
|
/// node must have a valid Constant value.
|
||||||
class Materialize final : public Castable<Materialize, Expression> {
|
class Materialize final : public Castable<Materialize, ValueExpression> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param expr the inner expression, being materialized
|
/// @param expr the inner expression, being materialized
|
||||||
/// @param statement the statement that owns this expression
|
/// @param statement the statement that owns this expression
|
||||||
/// @param type concrete type to materialize to
|
/// @param type concrete type to materialize to
|
||||||
/// @param constant the constant value of this expression or nullptr
|
/// @param constant the constant value of this expression or nullptr
|
||||||
Materialize(const Expression* expr,
|
Materialize(const ValueExpression* expr,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
const constant::Value* constant);
|
const constant::Value* constant);
|
||||||
|
@ -41,10 +41,10 @@ class Materialize final : public Castable<Materialize, Expression> {
|
||||||
~Materialize() override;
|
~Materialize() override;
|
||||||
|
|
||||||
/// @return the expression being materialized
|
/// @return the expression being materialized
|
||||||
const Expression* Expr() const { return expr_; }
|
const ValueExpression* Expr() const { return expr_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Expression const* const expr_;
|
ValueExpression const* const expr_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -28,7 +28,7 @@ MemberAccessorExpression::MemberAccessorExpression(const ast::MemberAccessorExpr
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
const Expression* object,
|
const ValueExpression* object,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* root_ident /* = nullptr */)
|
const Variable* root_ident /* = nullptr */)
|
||||||
: Base(declaration, type, stage, statement, constant, has_side_effects, root_ident),
|
: Base(declaration, type, stage, statement, constant, has_side_effects, root_ident),
|
||||||
|
@ -40,7 +40,7 @@ StructMemberAccess::StructMemberAccess(const ast::MemberAccessorExpression* decl
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
const Expression* object,
|
const ValueExpression* object,
|
||||||
const StructMember* member,
|
const StructMember* member,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* root_ident /* = nullptr */)
|
const Variable* root_ident /* = nullptr */)
|
||||||
|
@ -60,7 +60,7 @@ Swizzle::Swizzle(const ast::MemberAccessorExpression* declaration,
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
const Expression* object,
|
const ValueExpression* object,
|
||||||
utils::VectorRef<uint32_t> indices,
|
utils::VectorRef<uint32_t> indices,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* root_ident /* = nullptr */)
|
const Variable* root_ident /* = nullptr */)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#ifndef SRC_TINT_SEM_MEMBER_ACCESSOR_EXPRESSION_H_
|
#ifndef SRC_TINT_SEM_MEMBER_ACCESSOR_EXPRESSION_H_
|
||||||
#define SRC_TINT_SEM_MEMBER_ACCESSOR_EXPRESSION_H_
|
#define SRC_TINT_SEM_MEMBER_ACCESSOR_EXPRESSION_H_
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
|
@ -30,13 +30,13 @@ namespace tint::sem {
|
||||||
|
|
||||||
/// MemberAccessorExpression holds the semantic information for a
|
/// MemberAccessorExpression holds the semantic information for a
|
||||||
/// ast::MemberAccessorExpression node.
|
/// ast::MemberAccessorExpression node.
|
||||||
class MemberAccessorExpression : public Castable<MemberAccessorExpression, Expression> {
|
class MemberAccessorExpression : public Castable<MemberAccessorExpression, ValueExpression> {
|
||||||
public:
|
public:
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~MemberAccessorExpression() override;
|
~MemberAccessorExpression() override;
|
||||||
|
|
||||||
/// @returns the object that holds the member being accessed
|
/// @returns the object that holds the member being accessed
|
||||||
const Expression* Object() const { return object_; }
|
const ValueExpression* Object() const { return object_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
|
@ -53,12 +53,12 @@ class MemberAccessorExpression : public Castable<MemberAccessorExpression, Expre
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
const Expression* object,
|
const ValueExpression* object,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* root_ident = nullptr);
|
const Variable* root_ident = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Expression const* const object_;
|
ValueExpression const* const object_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// StructMemberAccess holds the semantic information for a
|
/// StructMemberAccess holds the semantic information for a
|
||||||
|
@ -79,7 +79,7 @@ class StructMemberAccess final : public Castable<StructMemberAccess, MemberAcces
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
const Expression* object,
|
const ValueExpression* object,
|
||||||
const StructMember* member,
|
const StructMember* member,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* root_ident = nullptr);
|
const Variable* root_ident = nullptr);
|
||||||
|
@ -111,7 +111,7 @@ class Swizzle final : public Castable<Swizzle, MemberAccessorExpression> {
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
const Expression* object,
|
const ValueExpression* object,
|
||||||
utils::VectorRef<uint32_t> indices,
|
utils::VectorRef<uint32_t> indices,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* root_ident = nullptr);
|
const Variable* root_ident = nullptr);
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Value;
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class CaseStatement;
|
class CaseStatement;
|
||||||
class CaseSelector;
|
class CaseSelector;
|
||||||
class Expression;
|
class ValueExpression;
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
|
@ -39,16 +39,16 @@ class Variable;
|
||||||
class WhileStatement;
|
class WhileStatement;
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class Expression;
|
|
||||||
class ForLoopStatement;
|
class ForLoopStatement;
|
||||||
class Function;
|
class Function;
|
||||||
|
class GlobalVariable;
|
||||||
class IfStatement;
|
class IfStatement;
|
||||||
class Node;
|
class Node;
|
||||||
class GlobalVariable;
|
|
||||||
class Statement;
|
class Statement;
|
||||||
class Struct;
|
class Struct;
|
||||||
class StructMember;
|
class StructMember;
|
||||||
class SwitchStatement;
|
class SwitchStatement;
|
||||||
|
class ValueExpression;
|
||||||
class Variable;
|
class Variable;
|
||||||
class WhileStatement;
|
class WhileStatement;
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
@ -66,7 +66,6 @@ namespace tint::sem {
|
||||||
struct TypeMappings {
|
struct TypeMappings {
|
||||||
//! @cond Doxygen_Suppress
|
//! @cond Doxygen_Suppress
|
||||||
type::Array* operator()(ast::Array*);
|
type::Array* operator()(ast::Array*);
|
||||||
Expression* operator()(ast::Expression*);
|
|
||||||
ForLoopStatement* operator()(ast::ForLoopStatement*);
|
ForLoopStatement* operator()(ast::ForLoopStatement*);
|
||||||
Function* operator()(ast::Function*);
|
Function* operator()(ast::Function*);
|
||||||
IfStatement* operator()(ast::IfStatement*);
|
IfStatement* operator()(ast::IfStatement*);
|
||||||
|
@ -78,6 +77,7 @@ struct TypeMappings {
|
||||||
SwitchStatement* operator()(ast::SwitchStatement*);
|
SwitchStatement* operator()(ast::SwitchStatement*);
|
||||||
type::Type* operator()(ast::Type*);
|
type::Type* operator()(ast::Type*);
|
||||||
type::Type* operator()(ast::TypeDecl*);
|
type::Type* operator()(ast::TypeDecl*);
|
||||||
|
ValueExpression* operator()(ast::Expression*);
|
||||||
Variable* operator()(ast::Variable*);
|
Variable* operator()(ast::Variable*);
|
||||||
WhileStatement* operator()(ast::WhileStatement*);
|
WhileStatement* operator()(ast::WhileStatement*);
|
||||||
//! @endcond
|
//! @endcond
|
||||||
|
|
|
@ -12,24 +12,24 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "src/tint/sem/load.h"
|
#include "src/tint/sem/load.h"
|
||||||
#include "src/tint/sem/materialize.h"
|
#include "src/tint/sem/materialize.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Expression);
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::ValueExpression);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
Expression::Expression(const ast::Expression* declaration,
|
ValueExpression::ValueExpression(const ast::Expression* declaration,
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* root_ident /* = nullptr */)
|
const Variable* root_ident /* = nullptr */)
|
||||||
: declaration_(declaration),
|
: declaration_(declaration),
|
||||||
root_identifier_(root_ident),
|
root_identifier_(root_ident),
|
||||||
type_(type),
|
type_(type),
|
||||||
|
@ -44,23 +44,23 @@ Expression::Expression(const ast::Expression* declaration,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression::~Expression() = default;
|
ValueExpression::~ValueExpression() = default;
|
||||||
|
|
||||||
const Expression* Expression::UnwrapMaterialize() const {
|
const ValueExpression* ValueExpression::UnwrapMaterialize() const {
|
||||||
if (auto* m = As<Materialize>()) {
|
if (auto* m = As<Materialize>()) {
|
||||||
return m->Expr();
|
return m->Expr();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Expression* Expression::UnwrapLoad() const {
|
const ValueExpression* ValueExpression::UnwrapLoad() const {
|
||||||
if (auto* l = As<Load>()) {
|
if (auto* l = As<Load>()) {
|
||||||
return l->Reference();
|
return l->Reference();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Expression* Expression::Unwrap() const {
|
const ValueExpression* ValueExpression::Unwrap() const {
|
||||||
return Switch(
|
return Switch(
|
||||||
this, // note: An expression can only be wrapped by a Load or Materialize, not both.
|
this, // note: An expression can only be wrapped by a Load or Materialize, not both.
|
||||||
[&](const Load* load) { return load->Reference(); },
|
[&](const Load* load) { return load->Reference(); },
|
|
@ -12,8 +12,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_TINT_SEM_EXPRESSION_H_
|
#ifndef SRC_TINT_SEM_VALUE_EXPRESSION_H_
|
||||||
#define SRC_TINT_SEM_EXPRESSION_H_
|
#define SRC_TINT_SEM_VALUE_EXPRESSION_H_
|
||||||
|
|
||||||
#include "src/tint/ast/expression.h"
|
#include "src/tint/ast/expression.h"
|
||||||
#include "src/tint/constant/value.h"
|
#include "src/tint/constant/value.h"
|
||||||
|
@ -29,8 +29,8 @@ class Variable;
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// Expression holds the semantic information for expression nodes.
|
/// ValueExpression holds the semantic information for expression nodes.
|
||||||
class Expression : public Castable<Expression, Node> {
|
class ValueExpression : public Castable<ValueExpression, Node> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param declaration the AST node
|
/// @param declaration the AST node
|
||||||
|
@ -40,16 +40,16 @@ class Expression : public Castable<Expression, Node> {
|
||||||
/// @param constant the constant value of the expression. May be null
|
/// @param constant the constant value of the expression. May be null
|
||||||
/// @param has_side_effects true if this expression may have side-effects
|
/// @param has_side_effects true if this expression may have side-effects
|
||||||
/// @param root_ident the (optional) root identifier for this expression
|
/// @param root_ident the (optional) root identifier for this expression
|
||||||
Expression(const ast::Expression* declaration,
|
ValueExpression(const ast::Expression* declaration,
|
||||||
const type::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const constant::Value* constant,
|
const constant::Value* constant,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* root_ident = nullptr);
|
const Variable* root_ident = nullptr);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Expression() override;
|
~ValueExpression() override;
|
||||||
|
|
||||||
/// @returns the AST node
|
/// @returns the AST node
|
||||||
const ast::Expression* Declaration() const { return declaration_; }
|
const ast::Expression* Declaration() const { return declaration_; }
|
||||||
|
@ -83,13 +83,13 @@ class Expression : public Castable<Expression, Node> {
|
||||||
bool HasSideEffects() const { return has_side_effects_; }
|
bool HasSideEffects() const { return has_side_effects_; }
|
||||||
|
|
||||||
/// @return the inner expression node if this is a Materialize, otherwise this.
|
/// @return the inner expression node if this is a Materialize, otherwise this.
|
||||||
const Expression* UnwrapMaterialize() const;
|
const ValueExpression* UnwrapMaterialize() const;
|
||||||
|
|
||||||
/// @return the inner reference expression if this is a Load, otherwise this.
|
/// @return the inner reference expression if this is a Load, otherwise this.
|
||||||
const Expression* UnwrapLoad() const;
|
const ValueExpression* UnwrapLoad() const;
|
||||||
|
|
||||||
/// @return the inner expression node if this is a Materialize or Load, otherwise this.
|
/// @return the inner expression node if this is a Materialize or Load, otherwise this.
|
||||||
const Expression* Unwrap() const;
|
const ValueExpression* Unwrap() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// The AST expression node for this semantic expression
|
/// The AST expression node for this semantic expression
|
||||||
|
@ -108,4 +108,4 @@ class Expression : public Castable<Expression, Node> {
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
#endif // SRC_TINT_SEM_EXPRESSION_H_
|
#endif // SRC_TINT_SEM_VALUE_EXPRESSION_H_
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
|
|
||||||
#include "src/tint/sem/test_helper.h"
|
#include "src/tint/sem/test_helper.h"
|
||||||
|
|
||||||
|
@ -42,14 +42,14 @@ class MockConstant : public constant::Value {
|
||||||
const type::Type* type;
|
const type::Type* type;
|
||||||
};
|
};
|
||||||
|
|
||||||
using ExpressionTest = TestHelper;
|
using ValueExpressionTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(ExpressionTest, UnwrapMaterialize) {
|
TEST_F(ValueExpressionTest, UnwrapMaterialize) {
|
||||||
MockConstant c(create<type::I32>());
|
MockConstant c(create<type::I32>());
|
||||||
auto* a = create<Expression>(/* declaration */ nullptr, create<type::I32>(),
|
auto* a = create<ValueExpression>(/* declaration */ nullptr, create<type::I32>(),
|
||||||
sem::EvaluationStage::kRuntime, /* statement */ nullptr,
|
sem::EvaluationStage::kRuntime, /* statement */ nullptr,
|
||||||
/* constant_value */ nullptr,
|
/* constant_value */ nullptr,
|
||||||
/* has_side_effects */ false, /* root_ident */ nullptr);
|
/* has_side_effects */ false, /* root_ident */ nullptr);
|
||||||
auto* b = create<Materialize>(a, /* statement */ nullptr, c.Type(), &c);
|
auto* b = create<Materialize>(a, /* statement */ nullptr, c.Type(), &c);
|
||||||
|
|
||||||
EXPECT_EQ(a, a->UnwrapMaterialize());
|
EXPECT_EQ(a, a->UnwrapMaterialize());
|
|
@ -23,8 +23,8 @@
|
||||||
|
|
||||||
#include "src/tint/ast/parameter.h"
|
#include "src/tint/ast/parameter.h"
|
||||||
#include "src/tint/sem/binding_point.h"
|
#include "src/tint/sem/binding_point.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/parameter_usage.h"
|
#include "src/tint/sem/parameter_usage.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/type/access.h"
|
#include "src/tint/type/access.h"
|
||||||
#include "src/tint/type/address_space.h"
|
#include "src/tint/type/address_space.h"
|
||||||
#include "src/tint/type/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
@ -84,11 +84,11 @@ class Variable : public Castable<Variable, Node> {
|
||||||
|
|
||||||
/// @returns the variable initializer expression, or nullptr if the variable
|
/// @returns the variable initializer expression, or nullptr if the variable
|
||||||
/// does not have one.
|
/// does not have one.
|
||||||
const Expression* Initializer() const { return initializer_; }
|
const ValueExpression* Initializer() const { return initializer_; }
|
||||||
|
|
||||||
/// Sets the variable initializer expression.
|
/// Sets the variable initializer expression.
|
||||||
/// @param initializer the initializer expression to assign to this variable.
|
/// @param initializer the initializer expression to assign to this variable.
|
||||||
void SetInitializer(const Expression* initializer) { initializer_ = initializer; }
|
void SetInitializer(const ValueExpression* initializer) { initializer_ = initializer; }
|
||||||
|
|
||||||
/// @returns the expressions that use the variable
|
/// @returns the expressions that use the variable
|
||||||
const std::vector<const VariableUser*>& Users() const { return users_; }
|
const std::vector<const VariableUser*>& Users() const { return users_; }
|
||||||
|
@ -103,7 +103,7 @@ class Variable : public Castable<Variable, Node> {
|
||||||
const type::AddressSpace address_space_;
|
const type::AddressSpace address_space_;
|
||||||
const type::Access access_;
|
const type::Access access_;
|
||||||
const constant::Value* constant_value_;
|
const constant::Value* constant_value_;
|
||||||
const Expression* initializer_ = nullptr;
|
const ValueExpression* initializer_ = nullptr;
|
||||||
std::vector<const VariableUser*> users_;
|
std::vector<const VariableUser*> users_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ class Parameter final : public Castable<Parameter, Variable> {
|
||||||
|
|
||||||
/// VariableUser holds the semantic information for an identifier expression
|
/// VariableUser holds the semantic information for an identifier expression
|
||||||
/// node that resolves to a variable.
|
/// node that resolves to a variable.
|
||||||
class VariableUser final : public Castable<VariableUser, Expression> {
|
class VariableUser final : public Castable<VariableUser, ValueExpression> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param declaration the AST identifier node
|
/// @param declaration the AST identifier node
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace tint::ast {
|
||||||
class WhileStatement;
|
class WhileStatement;
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class Expression;
|
class ValueExpression;
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
@ -45,14 +45,14 @@ class WhileStatement final : public Castable<WhileStatement, CompoundStatement>
|
||||||
const ast::WhileStatement* Declaration() const;
|
const ast::WhileStatement* Declaration() const;
|
||||||
|
|
||||||
/// @returns the whilecondition expression
|
/// @returns the whilecondition expression
|
||||||
const Expression* Condition() const { return condition_; }
|
const ValueExpression* Condition() const { return condition_; }
|
||||||
|
|
||||||
/// Sets the while condition expression
|
/// Sets the while condition expression
|
||||||
/// @param condition the while condition expression
|
/// @param condition the while condition expression
|
||||||
void SetCondition(const Expression* condition) { condition_ = condition; }
|
void SetCondition(const ValueExpression* condition) { condition_ = condition; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Expression* condition_ = nullptr;
|
const ValueExpression* condition_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -260,7 +260,7 @@
|
||||||
<DisplayString>Type={*Type()} Value={Value()}</DisplayString>
|
<DisplayString>Type={*Type()} Value={Value()}</DisplayString>
|
||||||
</Type>
|
</Type>
|
||||||
|
|
||||||
<Type Name="tint::sem::Expression">
|
<Type Name="tint::sem::ValueExpression">
|
||||||
<DisplayString>Decl={*declaration_}</DisplayString>
|
<DisplayString>Decl={*declaration_}</DisplayString>
|
||||||
</Type>
|
</Type>
|
||||||
|
|
||||||
|
|
|
@ -240,14 +240,14 @@ struct CombineSamplers::State {
|
||||||
if (texture_index == -1) {
|
if (texture_index == -1) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const sem::Expression* texture =
|
const sem::ValueExpression* texture =
|
||||||
call->Arguments()[static_cast<size_t>(texture_index)];
|
call->Arguments()[static_cast<size_t>(texture_index)];
|
||||||
// We don't want to combine storage textures with anything, since
|
// We don't want to combine storage textures with anything, since
|
||||||
// they never have associated samplers in GLSL.
|
// they never have associated samplers in GLSL.
|
||||||
if (texture->Type()->UnwrapRef()->Is<type::StorageTexture>()) {
|
if (texture->Type()->UnwrapRef()->Is<type::StorageTexture>()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const sem::Expression* sampler =
|
const sem::ValueExpression* sampler =
|
||||||
sampler_index != -1 ? call->Arguments()[static_cast<size_t>(sampler_index)]
|
sampler_index != -1 ? call->Arguments()[static_cast<size_t>(sampler_index)]
|
||||||
: nullptr;
|
: nullptr;
|
||||||
auto* texture_var = texture->UnwrapLoad()->As<sem::VariableUser>()->Variable();
|
auto* texture_var = texture->UnwrapLoad()->As<sem::VariableUser>()->Variable();
|
||||||
|
@ -296,13 +296,14 @@ struct CombineSamplers::State {
|
||||||
const sem::Variable* texture_var = pair.first;
|
const sem::Variable* texture_var = pair.first;
|
||||||
const sem::Variable* sampler_var = pair.second;
|
const sem::Variable* sampler_var = pair.second;
|
||||||
if (auto* param = texture_var->As<sem::Parameter>()) {
|
if (auto* param = texture_var->As<sem::Parameter>()) {
|
||||||
const sem::Expression* texture = call->Arguments()[param->Index()];
|
const sem::ValueExpression* texture = call->Arguments()[param->Index()];
|
||||||
texture_var =
|
texture_var =
|
||||||
texture->UnwrapLoad()->As<sem::VariableUser>()->Variable();
|
texture->UnwrapLoad()->As<sem::VariableUser>()->Variable();
|
||||||
}
|
}
|
||||||
if (sampler_var) {
|
if (sampler_var) {
|
||||||
if (auto* param = sampler_var->As<sem::Parameter>()) {
|
if (auto* param = sampler_var->As<sem::Parameter>()) {
|
||||||
const sem::Expression* sampler = call->Arguments()[param->Index()];
|
const sem::ValueExpression* sampler =
|
||||||
|
call->Arguments()[param->Index()];
|
||||||
sampler_var =
|
sampler_var =
|
||||||
sampler->UnwrapLoad()->As<sem::VariableUser>()->Variable();
|
sampler->UnwrapLoad()->As<sem::VariableUser>()->Variable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,10 +305,10 @@ DecomposeMemoryAccess::Intrinsic* IntrinsicAtomicFor(ProgramBuilder* builder,
|
||||||
|
|
||||||
/// BufferAccess describes a single storage or uniform buffer access
|
/// BufferAccess describes a single storage or uniform buffer access
|
||||||
struct BufferAccess {
|
struct BufferAccess {
|
||||||
sem::Expression const* var = nullptr; // Storage buffer variable
|
sem::ValueExpression const* var = nullptr; // Storage buffer variable
|
||||||
Offset const* offset = nullptr; // The byte offset on var
|
Offset const* offset = nullptr; // The byte offset on var
|
||||||
type::Type const* type = nullptr; // The type of the access
|
type::Type const* type = nullptr; // The type of the access
|
||||||
operator bool() const { return var; } // Returns true if valid
|
operator bool() const { return var; } // Returns true if valid
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Store describes a single storage or uniform buffer write
|
/// Store describes a single storage or uniform buffer write
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
|
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
#include "src/tint/sem/call.h"
|
#include "src/tint/sem/call.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/member_accessor_expression.h"
|
#include "src/tint/sem/member_accessor_expression.h"
|
||||||
#include "src/tint/sem/type_initializer.h"
|
#include "src/tint/sem/type_initializer.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/transform/simplify_pointers.h"
|
#include "src/tint/transform/simplify_pointers.h"
|
||||||
#include "src/tint/utils/hash.h"
|
#include "src/tint/utils/hash.h"
|
||||||
#include "src/tint/utils/map.h"
|
#include "src/tint/utils/map.h"
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/member_accessor_expression.h"
|
#include "src/tint/sem/member_accessor_expression.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/transform/simplify_pointers.h"
|
#include "src/tint/transform/simplify_pointers.h"
|
||||||
#include "src/tint/utils/hash.h"
|
#include "src/tint/utils/hash.h"
|
||||||
#include "src/tint/utils/map.h"
|
#include "src/tint/utils/map.h"
|
||||||
|
|
|
@ -151,7 +151,7 @@ bool operator!=(const AccessShape& a, const AccessShape& b) {
|
||||||
struct AccessChain : AccessShape {
|
struct AccessChain : AccessShape {
|
||||||
/// The array accessor index expressions. This vector is indexed by the `DynamicIndex`s in
|
/// The array accessor index expressions. This vector is indexed by the `DynamicIndex`s in
|
||||||
/// #indices.
|
/// #indices.
|
||||||
tint::utils::Vector<const tint::sem::Expression*, 8> dynamic_indices;
|
tint::utils::Vector<const tint::sem::ValueExpression*, 8> dynamic_indices;
|
||||||
/// If true, then this access chain is used as an argument to call a variant.
|
/// If true, then this access chain is used as an argument to call a variant.
|
||||||
bool used_in_call = false;
|
bool used_in_call = false;
|
||||||
};
|
};
|
||||||
|
@ -216,7 +216,7 @@ struct DirectVariableAccess::State {
|
||||||
// are grown and moved up the expression tree. After this stage, we are left with all the
|
// are grown and moved up the expression tree. After this stage, we are left with all the
|
||||||
// expression access chains to variables that we may need to transform.
|
// expression access chains to variables that we may need to transform.
|
||||||
for (auto* node : ctx.src->ASTNodes().Objects()) {
|
for (auto* node : ctx.src->ASTNodes().Objects()) {
|
||||||
if (auto* expr = sem.Get<sem::Expression>(node)) {
|
if (auto* expr = sem.Get<sem::ValueExpression>(node)) {
|
||||||
AppendAccessChain(expr);
|
AppendAccessChain(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,7 +361,7 @@ struct DirectVariableAccess::State {
|
||||||
/// A map of variant signature to the variant data.
|
/// A map of variant signature to the variant data.
|
||||||
utils::Hashmap<FnVariant::Signature, FnVariant, 8> variants;
|
utils::Hashmap<FnVariant::Signature, FnVariant, 8> variants;
|
||||||
/// A map of expressions that have been hoisted to a 'let' declaration in the function.
|
/// A map of expressions that have been hoisted to a 'let' declaration in the function.
|
||||||
utils::Hashmap<const sem::Expression*, Symbol, 8> hoisted_exprs;
|
utils::Hashmap<const sem::ValueExpression*, Symbol, 8> hoisted_exprs;
|
||||||
|
|
||||||
/// @returns the variants of the function in a deterministically ordered vector.
|
/// @returns the variants of the function in a deterministically ordered vector.
|
||||||
utils::Vector<std::pair<const FnVariant::Signature*, FnVariant*>, 8> SortedVariants() {
|
utils::Vector<std::pair<const FnVariant::Signature*, FnVariant*>, 8> SortedVariants() {
|
||||||
|
@ -392,7 +392,7 @@ struct DirectVariableAccess::State {
|
||||||
/// pointer parameter.
|
/// pointer parameter.
|
||||||
utils::Hashmap<AccessShape, Symbol, 8> dynamic_index_array_aliases;
|
utils::Hashmap<AccessShape, Symbol, 8> dynamic_index_array_aliases;
|
||||||
/// Map of semantic expression to AccessChain
|
/// Map of semantic expression to AccessChain
|
||||||
utils::Hashmap<const sem::Expression*, AccessChain*, 32> access_chains;
|
utils::Hashmap<const sem::ValueExpression*, AccessChain*, 32> access_chains;
|
||||||
/// Allocator for FnInfo
|
/// Allocator for FnInfo
|
||||||
utils::BlockAllocator<FnInfo> fn_info_allocator;
|
utils::BlockAllocator<FnInfo> fn_info_allocator;
|
||||||
/// Allocator for AccessChain
|
/// Allocator for AccessChain
|
||||||
|
@ -418,10 +418,10 @@ struct DirectVariableAccess::State {
|
||||||
|
|
||||||
/// AppendAccessChain creates or extends an existing AccessChain for the given expression,
|
/// AppendAccessChain creates or extends an existing AccessChain for the given expression,
|
||||||
/// modifying the #access_chains map.
|
/// modifying the #access_chains map.
|
||||||
void AppendAccessChain(const sem::Expression* expr) {
|
void AppendAccessChain(const sem::ValueExpression* expr) {
|
||||||
// take_chain moves the AccessChain from the expression `from` to the expression `expr`.
|
// take_chain moves the AccessChain from the expression `from` to the expression `expr`.
|
||||||
// Returns nullptr if `from` did not hold an access chain.
|
// Returns nullptr if `from` did not hold an access chain.
|
||||||
auto take_chain = [&](const sem::Expression* from) -> AccessChain* {
|
auto take_chain = [&](const sem::ValueExpression* from) -> AccessChain* {
|
||||||
if (auto* chain = AccessChainFor(from)) {
|
if (auto* chain = AccessChainFor(from)) {
|
||||||
access_chains.Remove(from);
|
access_chains.Remove(from);
|
||||||
access_chains.Add(expr, chain);
|
access_chains.Add(expr, chain);
|
||||||
|
@ -492,7 +492,7 @@ struct DirectVariableAccess::State {
|
||||||
chain->dynamic_indices.Push(a->Index());
|
chain->dynamic_indices.Push(a->Index());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](const sem::Expression* e) {
|
[&](const sem::ValueExpression* e) {
|
||||||
if (auto* unary = e->Declaration()->As<ast::UnaryOpExpression>()) {
|
if (auto* unary = e->Declaration()->As<ast::UnaryOpExpression>()) {
|
||||||
// Unary op.
|
// Unary op.
|
||||||
// If this is a '&' or '*', simply move the chain to the unary op expression.
|
// If this is a '&' or '*', simply move the chain to the unary op expression.
|
||||||
|
@ -556,7 +556,7 @@ struct DirectVariableAccess::State {
|
||||||
/// * Casts the resulting expression to a u32 if @p cast_to_u32 is true, and the expression type
|
/// * Casts the resulting expression to a u32 if @p cast_to_u32 is true, and the expression type
|
||||||
/// isn't implicitly usable as a u32. This is to help feed the expression into a
|
/// isn't implicitly usable as a u32. This is to help feed the expression into a
|
||||||
/// `array<u32, N>` argument passed to a callee variant function.
|
/// `array<u32, N>` argument passed to a callee variant function.
|
||||||
const ast::Expression* BuildDynamicIndex(const sem::Expression* idx, bool cast_to_u32) {
|
const ast::Expression* BuildDynamicIndex(const sem::ValueExpression* idx, bool cast_to_u32) {
|
||||||
if (auto* val = idx->ConstantValue()) {
|
if (auto* val = idx->ConstantValue()) {
|
||||||
// Expression evaluated to a constant value. Just emit that constant.
|
// Expression evaluated to a constant value. Just emit that constant.
|
||||||
return b.Expr(val->ValueAs<AInt>());
|
return b.Expr(val->ValueAs<AInt>());
|
||||||
|
@ -766,7 +766,7 @@ struct DirectVariableAccess::State {
|
||||||
|
|
||||||
/// @returns the AccessChain for the expression @p expr, or nullptr if the expression does
|
/// @returns the AccessChain for the expression @p expr, or nullptr if the expression does
|
||||||
/// not hold an access chain.
|
/// not hold an access chain.
|
||||||
AccessChain* AccessChainFor(const sem::Expression* expr) const {
|
AccessChain* AccessChainFor(const sem::ValueExpression* expr) const {
|
||||||
if (auto chain = access_chains.Find(expr)) {
|
if (auto chain = access_chains.Find(expr)) {
|
||||||
return *chain;
|
return *chain;
|
||||||
}
|
}
|
||||||
|
@ -990,7 +990,7 @@ struct DirectVariableAccess::State {
|
||||||
return nullptr; // Just clone the expression.
|
return nullptr; // Just clone the expression.
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* expr = sem.Get<sem::Expression>(ast_expr);
|
auto* expr = sem.Get<sem::ValueExpression>(ast_expr);
|
||||||
if (!expr) {
|
if (!expr) {
|
||||||
// No semantic node for the expression.
|
// No semantic node for the expression.
|
||||||
return nullptr; // Just clone the expression.
|
return nullptr; // Just clone the expression.
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
#include "src/tint/ast/increment_decrement_statement.h"
|
#include "src/tint/ast/increment_decrement_statement.h"
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
#include "src/tint/sem/block_statement.h"
|
#include "src/tint/sem/block_statement.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/for_loop_statement.h"
|
#include "src/tint/sem/for_loop_statement.h"
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/transform/utils/hoist_to_decl_before.h"
|
#include "src/tint/transform/utils/hoist_to_decl_before.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::ExpandCompoundAssignment);
|
TINT_INSTANTIATE_TYPEINFO(tint::transform::ExpandCompoundAssignment);
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
#include "src/tint/ast/assignment_statement.h"
|
#include "src/tint/ast/assignment_statement.h"
|
||||||
#include "src/tint/ast/traverse_expressions.h"
|
#include "src/tint/ast/traverse_expressions.h"
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/member_accessor_expression.h"
|
#include "src/tint/sem/member_accessor_expression.h"
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/sem/variable.h"
|
#include "src/tint/sem/variable.h"
|
||||||
#include "src/tint/transform/simplify_pointers.h"
|
#include "src/tint/transform/simplify_pointers.h"
|
||||||
#include "src/tint/type/reference.h"
|
#include "src/tint/type/reference.h"
|
||||||
|
|
|
@ -72,11 +72,11 @@ struct PackedVec3::State {
|
||||||
|
|
||||||
// Walk the nodes, starting with the most deeply nested, finding all the AST expressions
|
// Walk the nodes, starting with the most deeply nested, finding all the AST expressions
|
||||||
// that load a whole packed vector (not a scalar / swizzle of the vector).
|
// that load a whole packed vector (not a scalar / swizzle of the vector).
|
||||||
utils::Hashset<const sem::Expression*, 16> refs;
|
utils::Hashset<const sem::ValueExpression*, 16> refs;
|
||||||
for (auto* node : ctx.src->ASTNodes().Objects()) {
|
for (auto* node : ctx.src->ASTNodes().Objects()) {
|
||||||
auto* sem_node = sem.Get(node);
|
auto* sem_node = sem.Get(node);
|
||||||
if (sem_node) {
|
if (sem_node) {
|
||||||
if (auto* expr = sem_node->As<sem::Expression>()) {
|
if (auto* expr = sem_node->As<sem::ValueExpression>()) {
|
||||||
sem_node = expr->UnwrapLoad();
|
sem_node = expr->UnwrapLoad();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ struct PackedVec3::State {
|
||||||
refs.Add(user); // then propagate tracking to pointer usage
|
refs.Add(user); // then propagate tracking to pointer usage
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](const sem::Expression* expr) {
|
[&](const sem::ValueExpression* expr) {
|
||||||
if (auto* unary = expr->Declaration()->As<ast::UnaryOpExpression>()) {
|
if (auto* unary = expr->Declaration()->As<ast::UnaryOpExpression>()) {
|
||||||
if (unary->op == ast::UnaryOp::kAddressOf ||
|
if (unary->op == ast::UnaryOp::kAddressOf ||
|
||||||
unary->op == ast::UnaryOp::kIndirection) {
|
unary->op == ast::UnaryOp::kIndirection) {
|
||||||
|
|
|
@ -41,7 +41,7 @@ Transform::ApplyResult PromoteInitializersToLet::Apply(const Program* src,
|
||||||
|
|
||||||
// Returns true if the expression should be hoisted to a new let statement before the
|
// Returns true if the expression should be hoisted to a new let statement before the
|
||||||
// expression's statement.
|
// expression's statement.
|
||||||
auto should_hoist = [&](const sem::Expression* expr) {
|
auto should_hoist = [&](const sem::ValueExpression* expr) {
|
||||||
if (!expr->Type()->IsAnyOf<type::Array, type::Struct>()) {
|
if (!expr->Type()->IsAnyOf<type::Array, type::Struct>()) {
|
||||||
// We only care about array and struct initializers
|
// We only care about array and struct initializers
|
||||||
return false;
|
return false;
|
||||||
|
@ -77,13 +77,13 @@ Transform::ApplyResult PromoteInitializersToLet::Apply(const Program* src,
|
||||||
};
|
};
|
||||||
|
|
||||||
// A list of expressions that should be hoisted.
|
// A list of expressions that should be hoisted.
|
||||||
utils::Vector<const sem::Expression*, 32> to_hoist;
|
utils::Vector<const sem::ValueExpression*, 32> to_hoist;
|
||||||
// A set of expressions that are constant, which _may_ need to be hoisted.
|
// A set of expressions that are constant, which _may_ need to be hoisted.
|
||||||
utils::Hashset<const ast::Expression*, 32> const_chains;
|
utils::Hashset<const ast::Expression*, 32> const_chains;
|
||||||
|
|
||||||
// Walk the AST nodes. This order guarantees that leaf-expressions are visited first.
|
// Walk the AST nodes. This order guarantees that leaf-expressions are visited first.
|
||||||
for (auto* node : src->ASTNodes().Objects()) {
|
for (auto* node : src->ASTNodes().Objects()) {
|
||||||
if (auto* sem = src->Sem().Get<sem::Expression>(node)) {
|
if (auto* sem = src->Sem().Get<sem::ValueExpression>(node)) {
|
||||||
auto* stmt = sem->Stmt();
|
auto* stmt = sem->Stmt();
|
||||||
if (!stmt) {
|
if (!stmt) {
|
||||||
// Expression is outside of a statement. This usually means the expression is part
|
// Expression is outside of a statement. This usually means the expression is part
|
||||||
|
|
|
@ -107,7 +107,7 @@ class DecomposeSideEffects::CollectHoistsState : public StateBase {
|
||||||
std::unordered_set<const ast::Expression*> no_side_effects;
|
std::unordered_set<const ast::Expression*> no_side_effects;
|
||||||
|
|
||||||
// Returns true if `expr` has side-effects. Unlike invoking
|
// Returns true if `expr` has side-effects. Unlike invoking
|
||||||
// sem::Expression::HasSideEffects(), this function takes into account whether
|
// sem::ValueExpression::HasSideEffects(), this function takes into account whether
|
||||||
// `expr` has been hoisted, returning false in that case. Furthermore, it
|
// `expr` has been hoisted, returning false in that case. Furthermore, it
|
||||||
// returns the correct result on parent expression nodes by traversing the
|
// returns the correct result on parent expression nodes by traversing the
|
||||||
// expression tree, memoizing the results to ensure O(1) amortized lookup.
|
// expression tree, memoizing the results to ensure O(1) amortized lookup.
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
#include "src/tint/sem/block_statement.h"
|
#include "src/tint/sem/block_statement.h"
|
||||||
#include "src/tint/sem/call.h"
|
#include "src/tint/sem/call.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/index_accessor_expression.h"
|
#include "src/tint/sem/index_accessor_expression.h"
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/type/reference.h"
|
#include "src/tint/type/reference.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::Robustness);
|
TINT_INSTANTIATE_TYPEINFO(tint::transform::Robustness);
|
||||||
|
|
|
@ -54,7 +54,7 @@ struct SpirvAtomic::State {
|
||||||
CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
|
CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
|
||||||
std::unordered_map<const ast::Struct*, ForkedStruct> forked_structs;
|
std::unordered_map<const ast::Struct*, ForkedStruct> forked_structs;
|
||||||
std::unordered_set<const sem::Variable*> atomic_variables;
|
std::unordered_set<const sem::Variable*> atomic_variables;
|
||||||
utils::UniqueVector<const sem::Expression*, 8> atomic_expressions;
|
utils::UniqueVector<const sem::ValueExpression*, 8> atomic_expressions;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
|
@ -184,7 +184,7 @@ struct SpirvAtomic::State {
|
||||||
[&](const sem::IndexAccessorExpression* index) {
|
[&](const sem::IndexAccessorExpression* index) {
|
||||||
atomic_expressions.Add(index->Object());
|
atomic_expressions.Add(index->Object());
|
||||||
},
|
},
|
||||||
[&](const sem::Expression* e) {
|
[&](const sem::ValueExpression* e) {
|
||||||
if (auto* unary = e->Declaration()->As<ast::UnaryOpExpression>()) {
|
if (auto* unary = e->Declaration()->As<ast::UnaryOpExpression>()) {
|
||||||
atomic_expressions.Add(ctx.src->Sem().Get(unary->expr));
|
atomic_expressions.Add(ctx.src->Sem().Get(unary->expr));
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ struct SpirvAtomic::State {
|
||||||
|
|
||||||
void ReplaceLoadsAndStores() {
|
void ReplaceLoadsAndStores() {
|
||||||
// Returns true if 'e' is a reference to an atomic variable or struct member
|
// Returns true if 'e' is a reference to an atomic variable or struct member
|
||||||
auto is_ref_to_atomic_var = [&](const sem::Expression* e) {
|
auto is_ref_to_atomic_var = [&](const sem::ValueExpression* e) {
|
||||||
if (tint::Is<type::Reference>(e->Type()) && e->RootIdentifier() &&
|
if (tint::Is<type::Reference>(e->Type()) && e->RootIdentifier() &&
|
||||||
(atomic_variables.count(e->RootIdentifier()) != 0)) {
|
(atomic_variables.count(e->RootIdentifier()) != 0)) {
|
||||||
// If it's a struct member, make sure it's one we marked as atomic
|
// If it's a struct member, make sure it's one we marked as atomic
|
||||||
|
|
|
@ -251,7 +251,7 @@ struct Std140::State {
|
||||||
/// The chain of access indices, starting with the first access on #var.
|
/// The chain of access indices, starting with the first access on #var.
|
||||||
AccessIndices indices;
|
AccessIndices indices;
|
||||||
/// The runtime-evaluated expressions. This vector is indexed by the DynamicIndex::slot
|
/// The runtime-evaluated expressions. This vector is indexed by the DynamicIndex::slot
|
||||||
utils::Vector<const sem::Expression*, 8> dynamic_indices;
|
utils::Vector<const sem::ValueExpression*, 8> dynamic_indices;
|
||||||
/// The type of the std140-decomposed matrix being accessed.
|
/// The type of the std140-decomposed matrix being accessed.
|
||||||
/// May be nullptr if the chain does not pass through a std140-decomposed matrix.
|
/// May be nullptr if the chain does not pass through a std140-decomposed matrix.
|
||||||
const type::Matrix* std140_mat_ty = nullptr;
|
const type::Matrix* std140_mat_ty = nullptr;
|
||||||
|
@ -573,7 +573,7 @@ struct Std140::State {
|
||||||
expr = s->Object();
|
expr = s->Object();
|
||||||
return Action::kContinue;
|
return Action::kContinue;
|
||||||
},
|
},
|
||||||
[&](const sem::Expression* e) {
|
[&](const sem::ValueExpression* e) {
|
||||||
// Walk past indirection and address-of unary ops.
|
// Walk past indirection and address-of unary ops.
|
||||||
return Switch(e->Declaration(), //
|
return Switch(e->Declaration(), //
|
||||||
[&](const ast::UnaryOpExpression* u) {
|
[&](const ast::UnaryOpExpression* u) {
|
||||||
|
@ -797,7 +797,7 @@ struct Std140::State {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build the arguments
|
// Build the arguments
|
||||||
auto args = utils::Transform(access.dynamic_indices, [&](const sem::Expression* e) {
|
auto args = utils::Transform(access.dynamic_indices, [&](const sem::ValueExpression* e) {
|
||||||
return b.Construct(b.ty.u32(), ctx.Clone(e->Declaration()));
|
return b.Construct(b.ty.u32(), ctx.Clone(e->Declaration()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct HoistToDeclBefore::State {
|
||||||
explicit State(CloneContext& ctx_in) : ctx(ctx_in), b(*ctx_in.dst) {}
|
explicit State(CloneContext& ctx_in) : ctx(ctx_in), b(*ctx_in.dst) {}
|
||||||
|
|
||||||
/// @copydoc HoistToDeclBefore::Add()
|
/// @copydoc HoistToDeclBefore::Add()
|
||||||
bool Add(const sem::Expression* before_expr,
|
bool Add(const sem::ValueExpression* before_expr,
|
||||||
const ast::Expression* expr,
|
const ast::Expression* expr,
|
||||||
VariableKind kind,
|
VariableKind kind,
|
||||||
const char* decl_name) {
|
const char* decl_name) {
|
||||||
|
@ -94,7 +94,7 @@ struct HoistToDeclBefore::State {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @copydoc HoistToDeclBefore::Prepare()
|
/// @copydoc HoistToDeclBefore::Prepare()
|
||||||
bool Prepare(const sem::Expression* before_expr) {
|
bool Prepare(const sem::ValueExpression* before_expr) {
|
||||||
return InsertBefore(before_expr->Stmt(), nullptr);
|
return InsertBefore(before_expr->Stmt(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ HoistToDeclBefore::HoistToDeclBefore(CloneContext& ctx) : state_(std::make_uniqu
|
||||||
|
|
||||||
HoistToDeclBefore::~HoistToDeclBefore() {}
|
HoistToDeclBefore::~HoistToDeclBefore() {}
|
||||||
|
|
||||||
bool HoistToDeclBefore::Add(const sem::Expression* before_expr,
|
bool HoistToDeclBefore::Add(const sem::ValueExpression* before_expr,
|
||||||
const ast::Expression* expr,
|
const ast::Expression* expr,
|
||||||
VariableKind kind,
|
VariableKind kind,
|
||||||
const char* decl_name) {
|
const char* decl_name) {
|
||||||
|
@ -393,7 +393,7 @@ bool HoistToDeclBefore::InsertBefore(const sem::Statement* before_stmt,
|
||||||
return state_->InsertBefore(before_stmt, builder);
|
return state_->InsertBefore(before_stmt, builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HoistToDeclBefore::Prepare(const sem::Expression* before_expr) {
|
bool HoistToDeclBefore::Prepare(const sem::ValueExpression* before_expr) {
|
||||||
return state_->Prepare(before_expr);
|
return state_->Prepare(before_expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/transform/transform.h"
|
#include "src/tint/transform/transform.h"
|
||||||
|
|
||||||
namespace tint::transform {
|
namespace tint::transform {
|
||||||
|
@ -52,7 +52,7 @@ class HoistToDeclBefore {
|
||||||
/// @param kind variable kind to hoist to
|
/// @param kind variable kind to hoist to
|
||||||
/// @param decl_name optional name to use for the variable/constant name
|
/// @param decl_name optional name to use for the variable/constant name
|
||||||
/// @return true on success
|
/// @return true on success
|
||||||
bool Add(const sem::Expression* before_expr,
|
bool Add(const sem::ValueExpression* before_expr,
|
||||||
const ast::Expression* expr,
|
const ast::Expression* expr,
|
||||||
VariableKind kind,
|
VariableKind kind,
|
||||||
const char* decl_name = "");
|
const char* decl_name = "");
|
||||||
|
@ -81,7 +81,7 @@ class HoistToDeclBefore {
|
||||||
/// needed.
|
/// needed.
|
||||||
/// @param before_expr expression we would hoist a decl before
|
/// @param before_expr expression we would hoist a decl before
|
||||||
/// @return true on success
|
/// @return true on success
|
||||||
bool Prepare(const sem::Expression* before_expr);
|
bool Prepare(const sem::ValueExpression* before_expr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct State;
|
struct State;
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
#include "src/tint/sem/call.h"
|
#include "src/tint/sem/call.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/type_conversion.h"
|
#include "src/tint/sem/type_conversion.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/type/abstract_numeric.h"
|
#include "src/tint/type/abstract_numeric.h"
|
||||||
#include "src/tint/utils/hash.h"
|
#include "src/tint/utils/hash.h"
|
||||||
#include "src/tint/utils/map.h"
|
#include "src/tint/utils/map.h"
|
||||||
|
@ -34,7 +34,7 @@ namespace {
|
||||||
|
|
||||||
bool ShouldRun(const Program* program) {
|
bool ShouldRun(const Program* program) {
|
||||||
for (auto* node : program->ASTNodes().Objects()) {
|
for (auto* node : program->ASTNodes().Objects()) {
|
||||||
if (auto* sem = program->Sem().Get<sem::Expression>(node)) {
|
if (auto* sem = program->Sem().Get<sem::ValueExpression>(node)) {
|
||||||
if (auto* call = sem->UnwrapMaterialize()->As<sem::Call>()) {
|
if (auto* call = sem->UnwrapMaterialize()->As<sem::Call>()) {
|
||||||
if (call->Target()->Is<sem::TypeConversion>() && call->Type()->Is<type::Matrix>()) {
|
if (call->Target()->Is<sem::TypeConversion>() && call->Type()->Is<type::Matrix>()) {
|
||||||
auto& args = call->Arguments();
|
auto& args = call->Arguments();
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
#include "src/tint/sem/call.h"
|
#include "src/tint/sem/call.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/type_initializer.h"
|
#include "src/tint/sem/type_initializer.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/type/abstract_numeric.h"
|
#include "src/tint/type/abstract_numeric.h"
|
||||||
#include "src/tint/utils/map.h"
|
#include "src/tint/utils/map.h"
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/tint/sem/call.h"
|
#include "src/tint/sem/call.h"
|
||||||
#include "src/tint/sem/expression.h"
|
|
||||||
#include "src/tint/sem/type_conversion.h"
|
#include "src/tint/sem/type_conversion.h"
|
||||||
#include "src/tint/sem/type_initializer.h"
|
#include "src/tint/sem/type_initializer.h"
|
||||||
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/utils/transform.h"
|
#include "src/tint/utils/transform.h"
|
||||||
|
|
||||||
using namespace tint::number_suffixes; // NOLINT
|
using namespace tint::number_suffixes; // NOLINT
|
||||||
|
@ -33,7 +33,7 @@ struct VectorInitializerInfo {
|
||||||
const sem::TypeInitializer* ctor = nullptr;
|
const sem::TypeInitializer* ctor = nullptr;
|
||||||
operator bool() const { return call != nullptr; }
|
operator bool() const { return call != nullptr; }
|
||||||
};
|
};
|
||||||
VectorInitializerInfo AsVectorInitializer(const sem::Expression* expr) {
|
VectorInitializerInfo AsVectorInitializer(const sem::ValueExpression* expr) {
|
||||||
if (auto* call = expr->As<sem::Call>()) {
|
if (auto* call = expr->As<sem::Call>()) {
|
||||||
if (auto* ctor = call->Target()->As<sem::TypeInitializer>()) {
|
if (auto* ctor = call->Target()->As<sem::TypeInitializer>()) {
|
||||||
if (ctor->ReturnType()->Is<type::Vector>()) {
|
if (ctor->ReturnType()->Is<type::Vector>()) {
|
||||||
|
@ -44,7 +44,9 @@ VectorInitializerInfo AsVectorInitializer(const sem::Expression* expr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Expression* Zero(ProgramBuilder& b, const type::Type* ty, const sem::Statement* stmt) {
|
const sem::ValueExpression* Zero(ProgramBuilder& b,
|
||||||
|
const type::Type* ty,
|
||||||
|
const sem::Statement* stmt) {
|
||||||
const ast::Expression* expr = nullptr;
|
const ast::Expression* expr = nullptr;
|
||||||
if (ty->Is<type::I32>()) {
|
if (ty->Is<type::I32>()) {
|
||||||
expr = b.Expr(0_i);
|
expr = b.Expr(0_i);
|
||||||
|
@ -59,9 +61,9 @@ const sem::Expression* Zero(ProgramBuilder& b, const type::Type* ty, const sem::
|
||||||
<< "unsupported vector element type: " << ty->TypeInfo().name;
|
<< "unsupported vector element type: " << ty->TypeInfo().name;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto* sem = b.create<sem::Expression>(expr, ty, sem::EvaluationStage::kRuntime, stmt,
|
auto* sem = b.create<sem::ValueExpression>(expr, ty, sem::EvaluationStage::kRuntime, stmt,
|
||||||
/* constant_value */ nullptr,
|
/* constant_value */ nullptr,
|
||||||
/* has_side_effects */ false);
|
/* has_side_effects */ false);
|
||||||
b.Sem().Add(expr, sem);
|
b.Sem().Add(expr, sem);
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +114,7 @@ const sem::Call* AppendVector(ProgramBuilder* b,
|
||||||
// to convert a vector of a different type, e.g. vec2<i32>(vec2<u32>()).
|
// to convert a vector of a different type, e.g. vec2<i32>(vec2<u32>()).
|
||||||
// In that case, preserve the original argument, or you'll get a type error.
|
// In that case, preserve the original argument, or you'll get a type error.
|
||||||
|
|
||||||
utils::Vector<const sem::Expression*, 4> packed;
|
utils::Vector<const sem::ValueExpression*, 4> packed;
|
||||||
if (auto vc = AsVectorInitializer(vector_sem)) {
|
if (auto vc = AsVectorInitializer(vector_sem)) {
|
||||||
const auto num_supplied = vc.call->Arguments().Length();
|
const auto num_supplied = vc.call->Arguments().Length();
|
||||||
if (num_supplied == 0) {
|
if (num_supplied == 0) {
|
||||||
|
@ -141,7 +143,7 @@ const sem::Call* AppendVector(ProgramBuilder* b,
|
||||||
sem::EvaluationStage::kRuntime);
|
sem::EvaluationStage::kRuntime);
|
||||||
auto* scalar_cast_sem = b->create<sem::Call>(
|
auto* scalar_cast_sem = b->create<sem::Call>(
|
||||||
scalar_cast_ast, scalar_cast_target, sem::EvaluationStage::kRuntime,
|
scalar_cast_ast, scalar_cast_target, sem::EvaluationStage::kRuntime,
|
||||||
utils::Vector<const sem::Expression*, 1>{scalar_sem}, statement,
|
utils::Vector<const sem::ValueExpression*, 1>{scalar_sem}, statement,
|
||||||
/* constant_value */ nullptr, /* has_side_effects */ false);
|
/* constant_value */ nullptr, /* has_side_effects */ false);
|
||||||
b->Sem().Add(scalar_cast_ast, scalar_cast_sem);
|
b->Sem().Add(scalar_cast_ast, scalar_cast_sem);
|
||||||
packed.Push(scalar_cast_sem);
|
packed.Push(scalar_cast_sem);
|
||||||
|
@ -149,17 +151,19 @@ const sem::Call* AppendVector(ProgramBuilder* b,
|
||||||
packed.Push(scalar_sem);
|
packed.Push(scalar_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* initializer_ast = b->Construct(
|
auto* initializer_ast =
|
||||||
packed_ast_ty,
|
b->Construct(packed_ast_ty, utils::Transform(packed, [&](const sem::ValueExpression* expr) {
|
||||||
utils::Transform(packed, [&](const sem::Expression* expr) { return expr->Declaration(); }));
|
return expr->Declaration();
|
||||||
|
}));
|
||||||
auto* initializer_target = b->create<sem::TypeInitializer>(
|
auto* initializer_target = b->create<sem::TypeInitializer>(
|
||||||
packed_sem_ty,
|
packed_sem_ty,
|
||||||
utils::Transform(packed,
|
utils::Transform(
|
||||||
[&](const tint::sem::Expression* arg, size_t i) -> const sem::Parameter* {
|
packed,
|
||||||
return b->create<sem::Parameter>(
|
[&](const tint::sem::ValueExpression* arg, size_t i) -> const sem::Parameter* {
|
||||||
nullptr, static_cast<uint32_t>(i), arg->Type()->UnwrapRef(),
|
return b->create<sem::Parameter>(
|
||||||
type::AddressSpace::kNone, type::Access::kUndefined);
|
nullptr, static_cast<uint32_t>(i), arg->Type()->UnwrapRef(),
|
||||||
}),
|
type::AddressSpace::kNone, type::Access::kUndefined);
|
||||||
|
}),
|
||||||
sem::EvaluationStage::kRuntime);
|
sem::EvaluationStage::kRuntime);
|
||||||
auto* initializer_sem =
|
auto* initializer_sem =
|
||||||
b->create<sem::Call>(initializer_ast, initializer_target, sem::EvaluationStage::kRuntime,
|
b->create<sem::Call>(initializer_ast, initializer_target, sem::EvaluationStage::kRuntime,
|
||||||
|
|
|
@ -1313,9 +1313,9 @@ bool GeneratorImpl::EmitBarrierCall(std::ostream& out, const sem::Builtin* built
|
||||||
const ast::Expression* GeneratorImpl::CreateF32Zero(const sem::Statement* stmt) {
|
const ast::Expression* GeneratorImpl::CreateF32Zero(const sem::Statement* stmt) {
|
||||||
auto* zero = builder_.Expr(0_f);
|
auto* zero = builder_.Expr(0_f);
|
||||||
auto* f32 = builder_.create<type::F32>();
|
auto* f32 = builder_.create<type::F32>();
|
||||||
auto* sem_zero = builder_.create<sem::Expression>(zero, f32, sem::EvaluationStage::kRuntime,
|
auto* sem_zero = builder_.create<sem::ValueExpression>(
|
||||||
stmt, /* constant_value */ nullptr,
|
zero, f32, sem::EvaluationStage::kRuntime, stmt, /* constant_value */ nullptr,
|
||||||
/* has_side_effects */ false);
|
/* has_side_effects */ false);
|
||||||
builder_.Sem().Add(zero, sem_zero);
|
builder_.Sem().Add(zero, sem_zero);
|
||||||
return zero;
|
return zero;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2569,10 +2569,10 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
|
||||||
auto* i32 = builder_.create<type::I32>();
|
auto* i32 = builder_.create<type::I32>();
|
||||||
auto* zero = builder_.Expr(0_i);
|
auto* zero = builder_.Expr(0_i);
|
||||||
auto* stmt = builder_.Sem().Get(vector)->Stmt();
|
auto* stmt = builder_.Sem().Get(vector)->Stmt();
|
||||||
builder_.Sem().Add(
|
builder_.Sem().Add(zero, builder_.create<sem::ValueExpression>(
|
||||||
zero, builder_.create<sem::Expression>(zero, i32, sem::EvaluationStage::kRuntime, stmt,
|
zero, i32, sem::EvaluationStage::kRuntime, stmt,
|
||||||
/* constant_value */ nullptr,
|
/* constant_value */ nullptr,
|
||||||
/* has_side_effects */ false));
|
/* has_side_effects */ false));
|
||||||
auto* packed = AppendVector(&builder_, vector, zero);
|
auto* packed = AppendVector(&builder_, vector, zero);
|
||||||
return EmitExpression(out, packed->Declaration());
|
return EmitExpression(out, packed->Declaration());
|
||||||
};
|
};
|
||||||
|
|
|
@ -558,7 +558,7 @@ bool Builder::GenerateExecutionModes(const ast::Function* func, uint32_t id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Builder::GenerateExpression(const sem::Expression* expr) {
|
uint32_t Builder::GenerateExpression(const sem::ValueExpression* expr) {
|
||||||
if (auto* constant = expr->ConstantValue()) {
|
if (auto* constant = expr->ConstantValue()) {
|
||||||
return GenerateConstantIfNeeded(constant);
|
return GenerateConstantIfNeeded(constant);
|
||||||
}
|
}
|
||||||
|
@ -2625,7 +2625,7 @@ bool Builder::GenerateTextureBuiltin(const sem::Call* call,
|
||||||
auto& arguments = call->Arguments();
|
auto& arguments = call->Arguments();
|
||||||
|
|
||||||
// Generates the given expression, returning the operand ID
|
// Generates the given expression, returning the operand ID
|
||||||
auto gen = [&](const sem::Expression* expr) { return Operand(GenerateExpression(expr)); };
|
auto gen = [&](const sem::ValueExpression* expr) { return Operand(GenerateExpression(expr)); };
|
||||||
|
|
||||||
// Returns the argument with the given usage
|
// Returns the argument with the given usage
|
||||||
auto arg = [&](Usage usage) {
|
auto arg = [&](Usage usage) {
|
||||||
|
|
|
@ -275,7 +275,7 @@ class Builder {
|
||||||
/// Generates an expression
|
/// Generates an expression
|
||||||
/// @param expr the expression to generate
|
/// @param expr the expression to generate
|
||||||
/// @returns the resulting ID of the expression or 0 on error
|
/// @returns the resulting ID of the expression or 0 on error
|
||||||
uint32_t GenerateExpression(const sem::Expression* expr);
|
uint32_t GenerateExpression(const sem::ValueExpression* expr);
|
||||||
/// Generates an expression
|
/// Generates an expression
|
||||||
/// @param expr the expression to generate
|
/// @param expr the expression to generate
|
||||||
/// @returns the resulting ID of the expression or 0 on error
|
/// @returns the resulting ID of the expression or 0 on error
|
||||||
|
|
Loading…
Reference in New Issue