Move type base classes into type/ folder.
This CL moves sem/type and copies sem/node into the type/ folder. The type subclasses are moved over to using type::Type while remaining in the sem:: namespace. They will be moved over in followup CLs. Bug: tint:1718 Change-Id: I3f3495328d734f88e4fc2dfbc6705343f1198dc5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/113180 Reviewed-by: Ben Clayton <bclayton@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
ad71dc1ab2
commit
5f764d8527
|
@ -458,7 +458,6 @@ libtint_source_set("libtint_core_all_src") {
|
||||||
"sem/storage_texture.h",
|
"sem/storage_texture.h",
|
||||||
"sem/switch_statement.h",
|
"sem/switch_statement.h",
|
||||||
"sem/texture.h",
|
"sem/texture.h",
|
||||||
"sem/type.h",
|
|
||||||
"sem/type_conversion.h",
|
"sem/type_conversion.h",
|
||||||
"sem/type_initializer.h",
|
"sem/type_initializer.h",
|
||||||
"sem/type_manager.h",
|
"sem/type_manager.h",
|
||||||
|
@ -577,6 +576,9 @@ libtint_source_set("libtint_core_all_src") {
|
||||||
"transform/while_to_loop.h",
|
"transform/while_to_loop.h",
|
||||||
"transform/zero_init_workgroup_memory.cc",
|
"transform/zero_init_workgroup_memory.cc",
|
||||||
"transform/zero_init_workgroup_memory.h",
|
"transform/zero_init_workgroup_memory.h",
|
||||||
|
"type/array_count.h",
|
||||||
|
"type/node.h",
|
||||||
|
"type/type.h",
|
||||||
"utils/bitcast.h",
|
"utils/bitcast.h",
|
||||||
"utils/bitset.h",
|
"utils/bitset.h",
|
||||||
"utils/block_allocator.h",
|
"utils/block_allocator.h",
|
||||||
|
@ -716,8 +718,6 @@ libtint_source_set("libtint_sem_src") {
|
||||||
"sem/switch_statement.h",
|
"sem/switch_statement.h",
|
||||||
"sem/texture.cc",
|
"sem/texture.cc",
|
||||||
"sem/texture.h",
|
"sem/texture.h",
|
||||||
"sem/type.cc",
|
|
||||||
"sem/type.h",
|
|
||||||
"sem/type_conversion.cc",
|
"sem/type_conversion.cc",
|
||||||
"sem/type_conversion.h",
|
"sem/type_conversion.h",
|
||||||
"sem/type_initializer.cc",
|
"sem/type_initializer.cc",
|
||||||
|
@ -739,10 +739,24 @@ libtint_source_set("libtint_sem_src") {
|
||||||
public_deps = [ ":libtint_core_all_src" ]
|
public_deps = [ ":libtint_core_all_src" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libtint_source_set("libtint_type_src") {
|
||||||
|
sources = [
|
||||||
|
"type/array_count.cc",
|
||||||
|
"type/array_count.h",
|
||||||
|
"type/node.cc",
|
||||||
|
"type/node.h",
|
||||||
|
"type/type.cc",
|
||||||
|
"type/type.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
public_deps = [ ":libtint_core_all_src" ]
|
||||||
|
}
|
||||||
|
|
||||||
libtint_source_set("libtint_core_src") {
|
libtint_source_set("libtint_core_src") {
|
||||||
public_deps = [
|
public_deps = [
|
||||||
":libtint_core_all_src",
|
":libtint_core_all_src",
|
||||||
":libtint_sem_src",
|
":libtint_sem_src",
|
||||||
|
":libtint_type_src",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1209,12 +1223,15 @@ if (tint_build_unittests) {
|
||||||
"sem/struct_test.cc",
|
"sem/struct_test.cc",
|
||||||
"sem/texture_test.cc",
|
"sem/texture_test.cc",
|
||||||
"sem/type_manager_test.cc",
|
"sem/type_manager_test.cc",
|
||||||
"sem/type_test.cc",
|
|
||||||
"sem/u32_test.cc",
|
"sem/u32_test.cc",
|
||||||
"sem/vector_test.cc",
|
"sem/vector_test.cc",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tint_unittests_source_set("tint_unittests_type_src") {
|
||||||
|
sources = [ "type/type_test.cc" ]
|
||||||
|
}
|
||||||
|
|
||||||
tint_unittests_source_set("tint_unittests_text_src") {
|
tint_unittests_source_set("tint_unittests_text_src") {
|
||||||
sources = [ "text/unicode_test.cc" ]
|
sources = [ "text/unicode_test.cc" ]
|
||||||
}
|
}
|
||||||
|
@ -1690,6 +1707,7 @@ if (tint_build_unittests) {
|
||||||
":tint_unittests_sem_src",
|
":tint_unittests_sem_src",
|
||||||
":tint_unittests_text_src",
|
":tint_unittests_text_src",
|
||||||
":tint_unittests_transform_src",
|
":tint_unittests_transform_src",
|
||||||
|
":tint_unittests_type_src",
|
||||||
":tint_unittests_utils_src",
|
":tint_unittests_utils_src",
|
||||||
":tint_unittests_writer_src",
|
":tint_unittests_writer_src",
|
||||||
]
|
]
|
||||||
|
|
|
@ -382,8 +382,6 @@ list(APPEND TINT_LIB_SRCS
|
||||||
sem/type_manager.cc
|
sem/type_manager.cc
|
||||||
sem/type_manager.h
|
sem/type_manager.h
|
||||||
sem/type_mappings.h
|
sem/type_mappings.h
|
||||||
sem/type.cc
|
|
||||||
sem/type.h
|
|
||||||
sem/u32.cc
|
sem/u32.cc
|
||||||
sem/u32.h
|
sem/u32.h
|
||||||
sem/variable.cc
|
sem/variable.cc
|
||||||
|
@ -501,6 +499,12 @@ list(APPEND TINT_LIB_SRCS
|
||||||
transform/while_to_loop.h
|
transform/while_to_loop.h
|
||||||
transform/zero_init_workgroup_memory.cc
|
transform/zero_init_workgroup_memory.cc
|
||||||
transform/zero_init_workgroup_memory.h
|
transform/zero_init_workgroup_memory.h
|
||||||
|
type/array_count.cc
|
||||||
|
type/array_count.h
|
||||||
|
type/node.cc
|
||||||
|
type/node.h
|
||||||
|
type/type.cc
|
||||||
|
type/type.h
|
||||||
utils/bitcast.h
|
utils/bitcast.h
|
||||||
utils/bitset.h
|
utils/bitset.h
|
||||||
utils/block_allocator.h
|
utils/block_allocator.h
|
||||||
|
@ -937,7 +941,6 @@ if(TINT_BUILD_TESTS)
|
||||||
sem/struct_test.cc
|
sem/struct_test.cc
|
||||||
sem/texture_test.cc
|
sem/texture_test.cc
|
||||||
sem/type_manager_test.cc
|
sem/type_manager_test.cc
|
||||||
sem/type_test.cc
|
|
||||||
sem/u32_test.cc
|
sem/u32_test.cc
|
||||||
sem/vector_test.cc
|
sem/vector_test.cc
|
||||||
source_test.cc
|
source_test.cc
|
||||||
|
@ -947,6 +950,7 @@ if(TINT_BUILD_TESTS)
|
||||||
text/unicode_test.cc
|
text/unicode_test.cc
|
||||||
traits_test.cc
|
traits_test.cc
|
||||||
transform/transform_test.cc
|
transform/transform_test.cc
|
||||||
|
type/type_test.cc
|
||||||
utils/bitcast_test.cc
|
utils/bitcast_test.cc
|
||||||
utils/bitset_test.cc
|
utils/bitset_test.cc
|
||||||
utils/block_allocator_test.cc
|
utils/block_allocator_test.cc
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/tint/ast/node.h"
|
#include "src/tint/ast/node.h"
|
||||||
#include "src/tint/sem/type.h"
|
|
||||||
|
|
||||||
namespace tint::ast {
|
namespace tint::ast {
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ const declaration_order_check_4 : i32 = 1;
|
||||||
for (auto* src_node : src.ASTNodes().Objects()) {
|
for (auto* src_node : src.ASTNodes().Objects()) {
|
||||||
src_nodes.emplace(src_node);
|
src_nodes.emplace(src_node);
|
||||||
}
|
}
|
||||||
std::unordered_set<const sem::Type*> src_types;
|
std::unordered_set<const type::Type*> src_types;
|
||||||
for (auto* src_type : src.Types()) {
|
for (auto* src_type : src.Types()) {
|
||||||
src_types.emplace(src_type);
|
src_types.emplace(src_type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,14 +93,14 @@ class CloneContext {
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~CloneContext();
|
~CloneContext();
|
||||||
|
|
||||||
/// Clones the Node or sem::Type `a` into the ProgramBuilder #dst if `a` is
|
/// Clones the Node or type::Type `a` into the ProgramBuilder #dst if `a` is
|
||||||
/// not null. If `a` is null, then Clone() returns null.
|
/// not null. If `a` is null, then Clone() returns null.
|
||||||
///
|
///
|
||||||
/// Clone() may use a function registered with ReplaceAll() to create a
|
/// Clone() may use a function registered with ReplaceAll() to create a
|
||||||
/// transformed version of the object. See ReplaceAll() for more information.
|
/// transformed version of the object. See ReplaceAll() for more information.
|
||||||
///
|
///
|
||||||
/// If the CloneContext is cloning from a Program to a ProgramBuilder, then
|
/// If the CloneContext is cloning from a Program to a ProgramBuilder, then
|
||||||
/// the Node or sem::Type `a` must be owned by the Program #src.
|
/// the Node or type::Type `a` must be owned by the Program #src.
|
||||||
///
|
///
|
||||||
/// @param object the type deriving from Cloneable to clone
|
/// @param object the type deriving from Cloneable to clone
|
||||||
/// @return the cloned node
|
/// @return the cloned node
|
||||||
|
@ -117,14 +117,14 @@ class CloneContext {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clones the Node or sem::Type `a` into the ProgramBuilder #dst if `a` is
|
/// Clones the Node or type::Type `a` into the ProgramBuilder #dst if `a` is
|
||||||
/// not null. If `a` is null, then Clone() returns null.
|
/// not null. If `a` is null, then Clone() returns null.
|
||||||
///
|
///
|
||||||
/// Unlike Clone(), this method does not invoke or use any transformations
|
/// Unlike Clone(), this method does not invoke or use any transformations
|
||||||
/// registered by ReplaceAll().
|
/// registered by ReplaceAll().
|
||||||
///
|
///
|
||||||
/// If the CloneContext is cloning from a Program to a ProgramBuilder, then
|
/// If the CloneContext is cloning from a Program to a ProgramBuilder, then
|
||||||
/// the Node or sem::Type `a` must be owned by the Program #src.
|
/// the Node or type::Type `a` must be owned by the Program #src.
|
||||||
///
|
///
|
||||||
/// @param a the type deriving from Cloneable to clone
|
/// @param a the type deriving from Cloneable to clone
|
||||||
/// @return the cloned node
|
/// @return the cloned node
|
||||||
|
|
|
@ -47,6 +47,7 @@ enum class System {
|
||||||
Symbol,
|
Symbol,
|
||||||
Test,
|
Test,
|
||||||
Transform,
|
Transform,
|
||||||
|
Type,
|
||||||
Utils,
|
Utils,
|
||||||
Writer,
|
Writer,
|
||||||
};
|
};
|
||||||
|
|
|
@ -75,7 +75,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
for (auto* src_node : src.ASTNodes().Objects()) {
|
for (auto* src_node : src.ASTNodes().Objects()) {
|
||||||
src_nodes.emplace(src_node);
|
src_nodes.emplace(src_node);
|
||||||
}
|
}
|
||||||
std::unordered_set<const tint::sem::Type*> src_types;
|
std::unordered_set<const tint::type::Type*> src_types;
|
||||||
for (auto* src_type : src.Types()) {
|
for (auto* src_type : src.Types()) {
|
||||||
src_types.emplace(src_type);
|
src_types.emplace(src_type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace tint::fuzzers::ast_fuzzer {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool IsSuitableForShift(const sem::Type* lhs_type, const sem::Type* rhs_type) {
|
bool IsSuitableForShift(const type::Type* lhs_type, const type::Type* rhs_type) {
|
||||||
// `a << b` requires b to be an unsigned scalar or vector, and `a` to be an
|
// `a << b` requires b to be an unsigned scalar or vector, and `a` to be an
|
||||||
// integer scalar or vector with the same width as `b`. Similar for `a >> b`.
|
// integer scalar or vector with the same width as `b`. Similar for `a >> b`.
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ bool IsSuitableForShift(const sem::Type* lhs_type, const sem::Type* rhs_type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanReplaceAddSubtractWith(const sem::Type* lhs_type,
|
bool CanReplaceAddSubtractWith(const type::Type* lhs_type,
|
||||||
const sem::Type* rhs_type,
|
const type::Type* rhs_type,
|
||||||
ast::BinaryOp new_operator) {
|
ast::BinaryOp new_operator) {
|
||||||
// The program is assumed to be well-typed, so this method determines when
|
// The program is assumed to be well-typed, so this method determines when
|
||||||
// 'new_operator' can be used as a type-preserving replacement in an '+' or
|
// 'new_operator' can be used as a type-preserving replacement in an '+' or
|
||||||
|
@ -71,8 +71,8 @@ bool CanReplaceAddSubtractWith(const sem::Type* lhs_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanReplaceMultiplyWith(const sem::Type* lhs_type,
|
bool CanReplaceMultiplyWith(const type::Type* lhs_type,
|
||||||
const sem::Type* rhs_type,
|
const type::Type* rhs_type,
|
||||||
ast::BinaryOp new_operator) {
|
ast::BinaryOp new_operator) {
|
||||||
// The program is assumed to be well-typed, so this method determines when
|
// The program is assumed to be well-typed, so this method determines when
|
||||||
// 'new_operator' can be used as a type-preserving replacement in a '*'
|
// 'new_operator' can be used as a type-preserving replacement in a '*'
|
||||||
|
@ -107,8 +107,8 @@ bool CanReplaceMultiplyWith(const sem::Type* lhs_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanReplaceDivideOrModuloWith(const sem::Type* lhs_type,
|
bool CanReplaceDivideOrModuloWith(const type::Type* lhs_type,
|
||||||
const sem::Type* rhs_type,
|
const type::Type* rhs_type,
|
||||||
ast::BinaryOp new_operator) {
|
ast::BinaryOp new_operator) {
|
||||||
// The program is assumed to be well-typed, so this method determines when
|
// The program is assumed to be well-typed, so this method determines when
|
||||||
// 'new_operator' can be used as a type-preserving replacement in a '/'
|
// 'new_operator' can be used as a type-preserving replacement in a '/'
|
||||||
|
@ -149,8 +149,8 @@ bool CanReplaceLogicalAndLogicalOrWith(ast::BinaryOp new_operator) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanReplaceAndOrWith(const sem::Type* lhs_type,
|
bool CanReplaceAndOrWith(const type::Type* lhs_type,
|
||||||
const sem::Type* rhs_type,
|
const type::Type* rhs_type,
|
||||||
ast::BinaryOp new_operator) {
|
ast::BinaryOp new_operator) {
|
||||||
switch (new_operator) {
|
switch (new_operator) {
|
||||||
case ast::BinaryOp::kAnd:
|
case ast::BinaryOp::kAnd:
|
||||||
|
@ -184,8 +184,8 @@ bool CanReplaceAndOrWith(const sem::Type* lhs_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanReplaceXorWith(const sem::Type* lhs_type,
|
bool CanReplaceXorWith(const type::Type* lhs_type,
|
||||||
const sem::Type* rhs_type,
|
const type::Type* rhs_type,
|
||||||
ast::BinaryOp new_operator) {
|
ast::BinaryOp new_operator) {
|
||||||
switch (new_operator) {
|
switch (new_operator) {
|
||||||
case ast::BinaryOp::kAdd:
|
case ast::BinaryOp::kAdd:
|
||||||
|
@ -207,8 +207,8 @@ bool CanReplaceXorWith(const sem::Type* lhs_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanReplaceShiftLeftShiftRightWith(const sem::Type* lhs_type,
|
bool CanReplaceShiftLeftShiftRightWith(const type::Type* lhs_type,
|
||||||
const sem::Type* rhs_type,
|
const type::Type* rhs_type,
|
||||||
ast::BinaryOp new_operator) {
|
ast::BinaryOp new_operator) {
|
||||||
switch (new_operator) {
|
switch (new_operator) {
|
||||||
case ast::BinaryOp::kShiftLeft:
|
case ast::BinaryOp::kShiftLeft:
|
||||||
|
@ -232,7 +232,7 @@ bool CanReplaceShiftLeftShiftRightWith(const sem::Type* lhs_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanReplaceEqualNotEqualWith(const sem::Type* lhs_type, ast::BinaryOp new_operator) {
|
bool CanReplaceEqualNotEqualWith(const type::Type* lhs_type, ast::BinaryOp new_operator) {
|
||||||
switch (new_operator) {
|
switch (new_operator) {
|
||||||
case ast::BinaryOp::kEqual:
|
case ast::BinaryOp::kEqual:
|
||||||
case ast::BinaryOp::kNotEqual:
|
case ast::BinaryOp::kNotEqual:
|
||||||
|
@ -301,9 +301,9 @@ bool MutationChangeBinaryOperator::CanReplaceBinaryOperator(
|
||||||
const auto* rhs_type = program.Sem().Get(binary_expr.rhs)->Type();
|
const auto* rhs_type = program.Sem().Get(binary_expr.rhs)->Type();
|
||||||
|
|
||||||
// If these are reference types, unwrap them to get the pointee type.
|
// If these are reference types, unwrap them to get the pointee type.
|
||||||
const sem::Type* lhs_basic_type =
|
const type::Type* lhs_basic_type =
|
||||||
lhs_type->Is<sem::Reference>() ? lhs_type->As<sem::Reference>()->StoreType() : lhs_type;
|
lhs_type->Is<sem::Reference>() ? lhs_type->As<sem::Reference>()->StoreType() : lhs_type;
|
||||||
const sem::Type* rhs_basic_type =
|
const type::Type* rhs_basic_type =
|
||||||
rhs_type->Is<sem::Reference>() ? rhs_type->As<sem::Reference>()->StoreType() : rhs_type;
|
rhs_type->Is<sem::Reference>() ? rhs_type->As<sem::Reference>()->StoreType() : rhs_type;
|
||||||
|
|
||||||
switch (binary_expr.op) {
|
switch (binary_expr.op) {
|
||||||
|
|
|
@ -68,12 +68,13 @@ void AppendResourceBindings(std::vector<ResourceBinding>* dest,
|
||||||
dest->insert(dest->end(), orig.begin(), orig.end());
|
dest->insert(dest->end(), orig.begin(), orig.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<ComponentType, CompositionType> CalculateComponentAndComposition(const sem::Type* type) {
|
std::tuple<ComponentType, CompositionType> CalculateComponentAndComposition(
|
||||||
|
const type::Type* type) {
|
||||||
// entry point in/out variables must of numeric scalar or vector types.
|
// entry point in/out variables must of numeric scalar or vector types.
|
||||||
TINT_ASSERT(Inspector, type->is_numeric_scalar_or_vector());
|
TINT_ASSERT(Inspector, type->is_numeric_scalar_or_vector());
|
||||||
|
|
||||||
ComponentType componentType = Switch(
|
ComponentType componentType = Switch(
|
||||||
sem::Type::DeepestElementOf(type), //
|
type::Type::DeepestElementOf(type), //
|
||||||
[&](const sem::F32*) { return ComponentType::kF32; },
|
[&](const sem::F32*) { return ComponentType::kF32; },
|
||||||
[&](const sem::F16*) { return ComponentType::kF16; },
|
[&](const sem::F16*) { return ComponentType::kF16; },
|
||||||
[&](const sem::I32*) { return ComponentType::kI32; },
|
[&](const sem::I32*) { return ComponentType::kI32; },
|
||||||
|
@ -114,7 +115,7 @@ std::tuple<ComponentType, CompositionType> CalculateComponentAndComposition(cons
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
|
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
utils::VectorRef<const ast::Attribute*> attributes) {
|
utils::VectorRef<const ast::Attribute*> attributes) {
|
||||||
auto* interpolation_attribute = ast::GetAttribute<ast::InterpolateAttribute>(attributes);
|
auto* interpolation_attribute = ast::GetAttribute<ast::InterpolateAttribute>(attributes);
|
||||||
if (type->is_integer_scalar_or_vector()) {
|
if (type->is_integer_scalar_or_vector()) {
|
||||||
|
@ -641,7 +642,7 @@ const ast::Function* Inspector::FindEntryPointByName(const std::string& name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inspector::AddEntryPointInOutVariables(std::string name,
|
void Inspector::AddEntryPointInOutVariables(std::string name,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
utils::VectorRef<const ast::Attribute*> attributes,
|
utils::VectorRef<const ast::Attribute*> attributes,
|
||||||
std::optional<uint32_t> location,
|
std::optional<uint32_t> location,
|
||||||
std::vector<StageVariable>& variables) const {
|
std::vector<StageVariable>& variables) const {
|
||||||
|
@ -680,7 +681,7 @@ void Inspector::AddEntryPointInOutVariables(std::string name,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Inspector::ContainsBuiltin(ast::BuiltinValue builtin,
|
bool Inspector::ContainsBuiltin(ast::BuiltinValue builtin,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
utils::VectorRef<const ast::Attribute*> attributes) const {
|
utils::VectorRef<const ast::Attribute*> attributes) const {
|
||||||
auto* unwrapped_type = type->UnwrapRef();
|
auto* unwrapped_type = type->UnwrapRef();
|
||||||
|
|
||||||
|
@ -768,7 +769,7 @@ std::vector<ResourceBinding> Inspector::GetSampledTextureResourceBindingsImpl(
|
||||||
auto* texture_type = var->Type()->UnwrapRef()->As<sem::Texture>();
|
auto* texture_type = var->Type()->UnwrapRef()->As<sem::Texture>();
|
||||||
entry.dim = TypeTextureDimensionToResourceBindingTextureDimension(texture_type->dim());
|
entry.dim = TypeTextureDimensionToResourceBindingTextureDimension(texture_type->dim());
|
||||||
|
|
||||||
const sem::Type* base_type = nullptr;
|
const type::Type* base_type = nullptr;
|
||||||
if (multisampled_only) {
|
if (multisampled_only) {
|
||||||
base_type = texture_type->As<sem::MultisampledTexture>()->type();
|
base_type = texture_type->As<sem::MultisampledTexture>()->type();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -175,7 +175,7 @@ class Inspector {
|
||||||
/// @param location the location value if provided
|
/// @param location the location value if provided
|
||||||
/// @param variables the list to add the variables to
|
/// @param variables the list to add the variables to
|
||||||
void AddEntryPointInOutVariables(std::string name,
|
void AddEntryPointInOutVariables(std::string name,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
utils::VectorRef<const ast::Attribute*> attributes,
|
utils::VectorRef<const ast::Attribute*> attributes,
|
||||||
std::optional<uint32_t> location,
|
std::optional<uint32_t> location,
|
||||||
std::vector<StageVariable>& variables) const;
|
std::vector<StageVariable>& variables) const;
|
||||||
|
@ -184,7 +184,7 @@ class Inspector {
|
||||||
/// If `type` is a struct, recurse into members to check for the attribute.
|
/// If `type` is a struct, recurse into members to check for the attribute.
|
||||||
/// Otherwise, check `attributes` for the attribute.
|
/// Otherwise, check `attributes` for the attribute.
|
||||||
bool ContainsBuiltin(ast::BuiltinValue builtin,
|
bool ContainsBuiltin(ast::BuiltinValue builtin,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
utils::VectorRef<const ast::Attribute*> attributes) const;
|
utils::VectorRef<const ast::Attribute*> attributes) const;
|
||||||
|
|
||||||
/// Gathers all the texture resource bindings of the given type for the given
|
/// Gathers all the texture resource bindings of the given type for the given
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
#include "src/tint/sem/f32.h"
|
#include "src/tint/sem/f32.h"
|
||||||
#include "src/tint/sem/i32.h"
|
#include "src/tint/sem/i32.h"
|
||||||
#include "src/tint/sem/matrix.h"
|
#include "src/tint/sem/matrix.h"
|
||||||
#include "src/tint/sem/type.h"
|
|
||||||
#include "src/tint/sem/u32.h"
|
#include "src/tint/sem/u32.h"
|
||||||
#include "src/tint/sem/vector.h"
|
#include "src/tint/sem/vector.h"
|
||||||
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::inspector {
|
namespace tint::inspector {
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ ResourceBinding::TextureDimension TypeTextureDimensionToResourceBindingTextureDi
|
||||||
return ResourceBinding::TextureDimension::kNone;
|
return ResourceBinding::TextureDimension::kNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceBinding::SampledKind BaseTypeToSampledKind(const sem::Type* base_type) {
|
ResourceBinding::SampledKind BaseTypeToSampledKind(const type::Type* base_type) {
|
||||||
if (!base_type) {
|
if (!base_type) {
|
||||||
return ResourceBinding::SampledKind::kUnknown;
|
return ResourceBinding::SampledKind::kUnknown;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,7 @@
|
||||||
|
|
||||||
#include "src/tint/ast/storage_texture.h"
|
#include "src/tint/ast/storage_texture.h"
|
||||||
#include "src/tint/ast/texture.h"
|
#include "src/tint/ast/texture.h"
|
||||||
|
#include "src/tint/type/type.h"
|
||||||
// Forward declarations
|
|
||||||
namespace tint::sem {
|
|
||||||
class Type;
|
|
||||||
} // namespace tint::sem
|
|
||||||
|
|
||||||
namespace tint::inspector {
|
namespace tint::inspector {
|
||||||
|
|
||||||
|
@ -114,10 +110,10 @@ struct ResourceBinding {
|
||||||
ResourceBinding::TextureDimension TypeTextureDimensionToResourceBindingTextureDimension(
|
ResourceBinding::TextureDimension TypeTextureDimensionToResourceBindingTextureDimension(
|
||||||
const ast::TextureDimension& type_dim);
|
const ast::TextureDimension& type_dim);
|
||||||
|
|
||||||
/// Infer ResourceBinding::SampledKind for a given sem::Type
|
/// Infer ResourceBinding::SampledKind for a given type::Type
|
||||||
/// @param base_type internal type to infer from
|
/// @param base_type internal type to infer from
|
||||||
/// @returns the publicly visible equivalent
|
/// @returns the publicly visible equivalent
|
||||||
ResourceBinding::SampledKind BaseTypeToSampledKind(const sem::Type* base_type);
|
ResourceBinding::SampledKind BaseTypeToSampledKind(const type::Type* base_type);
|
||||||
|
|
||||||
/// Convert from internal ast::TexelFormat to public
|
/// Convert from internal ast::TexelFormat to public
|
||||||
/// ResourceBinding::TexelFormat
|
/// ResourceBinding::TexelFormat
|
||||||
|
|
|
@ -117,16 +117,16 @@ bool Program::IsValid() const {
|
||||||
return is_valid_;
|
return is_valid_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* Program::TypeOf(const ast::Expression* expr) const {
|
const type::Type* Program::TypeOf(const ast::Expression* expr) const {
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
return sem ? sem->Type() : nullptr;
|
return sem ? sem->Type() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* Program::TypeOf(const ast::Type* type) const {
|
const type::Type* Program::TypeOf(const ast::Type* type) const {
|
||||||
return Sem().Get(type);
|
return Sem().Get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* Program::TypeOf(const ast::TypeDecl* type_decl) const {
|
const type::Type* Program::TypeOf(const ast::TypeDecl* type_decl) const {
|
||||||
return Sem().Get(type_decl);
|
return Sem().Get(type_decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ std::string Program::FriendlyName(const ast::Type* type) const {
|
||||||
return type ? type->FriendlyName(Symbols()) : "<null>";
|
return type ? type->FriendlyName(Symbols()) : "<null>";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Program::FriendlyName(const sem::Type* type) const {
|
std::string Program::FriendlyName(const type::Type* type) const {
|
||||||
return type ? type->FriendlyName(Symbols()) : "<null>";
|
return type ? type->FriendlyName(Symbols()) : "<null>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,20 +136,20 @@ class Program {
|
||||||
/// @param expr the AST expression
|
/// @param expr the AST expression
|
||||||
/// @return the resolved semantic type for the expression, or nullptr if the
|
/// @return the resolved semantic type for the expression, or nullptr if the
|
||||||
/// expression has no resolved type.
|
/// expression has no resolved type.
|
||||||
const sem::Type* TypeOf(const ast::Expression* expr) const;
|
const type::Type* TypeOf(const ast::Expression* expr) const;
|
||||||
|
|
||||||
/// Helper for returning the resolved semantic type of the AST type `type`.
|
/// Helper for returning the resolved semantic type of the AST type `type`.
|
||||||
/// @param type the AST type
|
/// @param type the AST type
|
||||||
/// @return the resolved semantic type for the type, or nullptr if the type
|
/// @return the resolved semantic type for the type, or nullptr if the type
|
||||||
/// has no resolved type.
|
/// has no resolved type.
|
||||||
const sem::Type* TypeOf(const ast::Type* type) const;
|
const type::Type* TypeOf(const ast::Type* type) const;
|
||||||
|
|
||||||
/// Helper for returning the resolved semantic type of the AST type
|
/// Helper for returning the resolved semantic type of the AST type
|
||||||
/// declaration `type_decl`.
|
/// declaration `type_decl`.
|
||||||
/// @param type_decl the AST type declaration
|
/// @param type_decl the AST type declaration
|
||||||
/// @return the resolved semantic type for the type declaration, or nullptr if
|
/// @return the resolved semantic type for the type declaration, or nullptr if
|
||||||
/// the type declaration has no resolved type.
|
/// the type declaration has no resolved type.
|
||||||
const sem::Type* TypeOf(const ast::TypeDecl* type_decl) const;
|
const type::Type* TypeOf(const ast::TypeDecl* type_decl) const;
|
||||||
|
|
||||||
/// @param type a type
|
/// @param type a type
|
||||||
/// @returns the name for `type` that closely resembles how it would be
|
/// @returns the name for `type` that closely resembles how it would be
|
||||||
|
@ -159,7 +159,7 @@ class Program {
|
||||||
/// @param type a type
|
/// @param type a type
|
||||||
/// @returns the name for `type` that closely resembles how it would be
|
/// @returns the name for `type` that closely resembles how it would be
|
||||||
/// declared in WGSL.
|
/// declared in WGSL.
|
||||||
std::string FriendlyName(const sem::Type* type) const;
|
std::string FriendlyName(const type::Type* type) const;
|
||||||
|
|
||||||
/// Overload of FriendlyName, which removes an ambiguity when passing nullptr.
|
/// Overload of FriendlyName, which removes an ambiguity when passing nullptr.
|
||||||
/// Simplifies test code.
|
/// Simplifies test code.
|
||||||
|
|
|
@ -95,21 +95,21 @@ void ProgramBuilder::AssertNotMoved() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* ProgramBuilder::TypeOf(const ast::Expression* expr) const {
|
const type::Type* ProgramBuilder::TypeOf(const ast::Expression* expr) const {
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
return sem ? sem->Type() : nullptr;
|
return sem ? sem->Type() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* ProgramBuilder::TypeOf(const ast::Variable* var) const {
|
const type::Type* ProgramBuilder::TypeOf(const ast::Variable* var) const {
|
||||||
auto* sem = Sem().Get(var);
|
auto* sem = Sem().Get(var);
|
||||||
return sem ? sem->Type() : nullptr;
|
return sem ? sem->Type() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* ProgramBuilder::TypeOf(const ast::Type* type) const {
|
const type::Type* ProgramBuilder::TypeOf(const ast::Type* type) const {
|
||||||
return Sem().Get(type);
|
return Sem().Get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* ProgramBuilder::TypeOf(const ast::TypeDecl* type_decl) const {
|
const type::Type* ProgramBuilder::TypeOf(const ast::TypeDecl* type_decl) const {
|
||||||
return Sem().Get(type_decl);
|
return Sem().Get(type_decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ std::string ProgramBuilder::FriendlyName(const ast::Type* type) const {
|
||||||
return type ? type->FriendlyName(Symbols()) : "<null>";
|
return type ? type->FriendlyName(Symbols()) : "<null>";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ProgramBuilder::FriendlyName(const sem::Type* type) const {
|
std::string ProgramBuilder::FriendlyName(const type::Type* type) const {
|
||||||
return type ? type->FriendlyName(Symbols()) : "<null>";
|
return type ? type->FriendlyName(Symbols()) : "<null>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -458,8 +458,7 @@ class ProgramBuilder {
|
||||||
/// @returns the node pointer
|
/// @returns the node pointer
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
traits::EnableIf<traits::IsTypeOrDerived<T, sem::Node> &&
|
traits::EnableIf<traits::IsTypeOrDerived<T, sem::Node> &&
|
||||||
!traits::IsTypeOrDerived<T, sem::Type> &&
|
!traits::IsTypeOrDerived<T, type::Node>,
|
||||||
!traits::IsTypeOrDerived<T, sem::ArrayCount>,
|
|
||||||
T>*
|
T>*
|
||||||
create(ARGS&&... args) {
|
create(ARGS&&... args) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
|
@ -476,7 +475,7 @@ class ProgramBuilder {
|
||||||
return constant_nodes_.Create<T>(std::forward<ARGS>(args)...);
|
return constant_nodes_.Create<T>(std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new sem::Type owned by the ProgramBuilder.
|
/// Creates a new type::Type owned by the ProgramBuilder.
|
||||||
/// When the ProgramBuilder is destructed, owned ProgramBuilder and the
|
/// When the ProgramBuilder is destructed, owned ProgramBuilder and the
|
||||||
/// returned `Type` will also be destructed.
|
/// returned `Type` will also be destructed.
|
||||||
/// Types are unique (de-aliased), and so calling create() for the same `T`
|
/// Types are unique (de-aliased), and so calling create() for the same `T`
|
||||||
|
@ -484,11 +483,12 @@ class ProgramBuilder {
|
||||||
/// @param args the arguments to pass to the type constructor
|
/// @param args the arguments to pass to the type constructor
|
||||||
/// @returns the de-aliased type pointer
|
/// @returns the de-aliased type pointer
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
traits::EnableIfIsType<T, sem::Type>* create(ARGS&&... args) {
|
traits::EnableIfIsType<T, type::Type>* create(ARGS&&... args) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
return types_.Get<T>(std::forward<ARGS>(args)...);
|
return types_.Get<T>(std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
/// Creates a new sem::ArrayCount owned by the ProgramBuilder.
|
|
||||||
|
/// Creates a new type::ArrayCount owned by the ProgramBuilder.
|
||||||
/// When the ProgramBuilder is destructed, owned ProgramBuilder and the
|
/// When the ProgramBuilder is destructed, owned ProgramBuilder and the
|
||||||
/// returned `ArrayCount` will also be destructed.
|
/// returned `ArrayCount` will also be destructed.
|
||||||
/// ArrayCounts are unique (de-aliased), and so calling create() for the same `T`
|
/// ArrayCounts are unique (de-aliased), and so calling create() for the same `T`
|
||||||
|
@ -496,9 +496,12 @@ class ProgramBuilder {
|
||||||
/// @param args the arguments to pass to the array count constructor
|
/// @param args the arguments to pass to the array count constructor
|
||||||
/// @returns the de-aliased array count pointer
|
/// @returns the de-aliased array count pointer
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
traits::EnableIfIsType<T, sem::ArrayCount>* create(ARGS&&... args) {
|
traits::EnableIf<traits::IsTypeOrDerived<T, type::ArrayCount> ||
|
||||||
|
traits::IsTypeOrDerived<T, sem::StructMemberBase>,
|
||||||
|
T>*
|
||||||
|
create(ARGS&&... args) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
return types_.GetArrayCount<T>(std::forward<ARGS>(args)...);
|
return types_.GetNode<T>(std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marks this builder as moved, preventing any further use of the builder.
|
/// Marks this builder as moved, preventing any further use of the builder.
|
||||||
|
@ -3159,7 +3162,7 @@ class ProgramBuilder {
|
||||||
/// @param expr the AST expression
|
/// @param expr the AST expression
|
||||||
/// @return the resolved semantic type for the expression, or nullptr if the
|
/// @return the resolved semantic type for the expression, or nullptr if the
|
||||||
/// expression has no resolved type.
|
/// expression has no resolved type.
|
||||||
const sem::Type* TypeOf(const ast::Expression* expr) const;
|
const type::Type* TypeOf(const ast::Expression* expr) const;
|
||||||
|
|
||||||
/// Helper for returning the resolved semantic type of the variable `var`.
|
/// Helper for returning the resolved semantic type of the variable `var`.
|
||||||
/// @note As the Resolver is run when the Program is built, this will only be
|
/// @note As the Resolver is run when the Program is built, this will only be
|
||||||
|
@ -3167,7 +3170,7 @@ class ProgramBuilder {
|
||||||
/// @param var the AST variable
|
/// @param var the AST variable
|
||||||
/// @return the resolved semantic type for the variable, or nullptr if the
|
/// @return the resolved semantic type for the variable, or nullptr if the
|
||||||
/// variable has no resolved type.
|
/// variable has no resolved type.
|
||||||
const sem::Type* TypeOf(const ast::Variable* var) const;
|
const type::Type* TypeOf(const ast::Variable* var) const;
|
||||||
|
|
||||||
/// Helper for returning the resolved semantic type of the AST type `type`.
|
/// Helper for returning the resolved semantic type of the AST type `type`.
|
||||||
/// @note As the Resolver is run when the Program is built, this will only be
|
/// @note As the Resolver is run when the Program is built, this will only be
|
||||||
|
@ -3175,7 +3178,7 @@ class ProgramBuilder {
|
||||||
/// @param type the AST type
|
/// @param type the AST type
|
||||||
/// @return the resolved semantic type for the type, or nullptr if the type
|
/// @return the resolved semantic type for the type, or nullptr if the type
|
||||||
/// has no resolved type.
|
/// has no resolved type.
|
||||||
const sem::Type* TypeOf(const ast::Type* type) const;
|
const type::Type* TypeOf(const ast::Type* type) const;
|
||||||
|
|
||||||
/// Helper for returning the resolved semantic type of the AST type
|
/// Helper for returning the resolved semantic type of the AST type
|
||||||
/// declaration `type_decl`.
|
/// declaration `type_decl`.
|
||||||
|
@ -3184,7 +3187,7 @@ class ProgramBuilder {
|
||||||
/// @param type_decl the AST type declaration
|
/// @param type_decl the AST type declaration
|
||||||
/// @return the resolved semantic type for the type declaration, or nullptr if
|
/// @return the resolved semantic type for the type declaration, or nullptr if
|
||||||
/// the type declaration has no resolved type.
|
/// the type declaration has no resolved type.
|
||||||
const sem::Type* TypeOf(const ast::TypeDecl* type_decl) const;
|
const type::Type* TypeOf(const ast::TypeDecl* type_decl) const;
|
||||||
|
|
||||||
/// @param type a type
|
/// @param type a type
|
||||||
/// @returns the name for `type` that closely resembles how it would be
|
/// @returns the name for `type` that closely resembles how it would be
|
||||||
|
@ -3194,7 +3197,7 @@ class ProgramBuilder {
|
||||||
/// @param type a type
|
/// @param type a type
|
||||||
/// @returns the name for `type` that closely resembles how it would be
|
/// @returns the name for `type` that closely resembles how it would be
|
||||||
/// declared in WGSL.
|
/// declared in WGSL.
|
||||||
std::string FriendlyName(const sem::Type* type) const;
|
std::string FriendlyName(const type::Type* type) const;
|
||||||
|
|
||||||
/// Overload of FriendlyName, which removes an ambiguity when passing nullptr.
|
/// Overload of FriendlyName, which removes an ambiguity when passing nullptr.
|
||||||
/// Simplifies test code.
|
/// Simplifies test code.
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#include "src/tint/sem/member_accessor_expression.h"
|
#include "src/tint/sem/member_accessor_expression.h"
|
||||||
#include "src/tint/sem/sampled_texture.h"
|
#include "src/tint/sem/sampled_texture.h"
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
#include "src/tint/sem/test_helper.h"
|
|
||||||
#include "src/tint/sem/variable.h"
|
#include "src/tint/sem/variable.h"
|
||||||
|
#include "src/tint/type/test_helper.h"
|
||||||
|
|
||||||
using ::testing::ElementsAre;
|
using ::testing::ElementsAre;
|
||||||
using ::testing::HasSubstr;
|
using ::testing::HasSubstr;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,6 +18,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "src/tint/type/type.h"
|
||||||
#include "src/tint/utils/result.h"
|
#include "src/tint/utils/result.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
|
@ -33,7 +34,6 @@ namespace tint::sem {
|
||||||
class Constant;
|
class Constant;
|
||||||
class Expression;
|
class Expression;
|
||||||
class StructMember;
|
class StructMember;
|
||||||
class Type;
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
namespace tint::resolver {
|
namespace tint::resolver {
|
||||||
|
@ -56,7 +56,7 @@ class ConstEval {
|
||||||
using Result = utils::Result<const sem::Constant*>;
|
using Result = utils::Result<const sem::Constant*>;
|
||||||
|
|
||||||
/// Typedef for a constant evaluation function
|
/// Typedef for a constant evaluation function
|
||||||
using Function = Result (ConstEval::*)(const sem::Type* result_ty,
|
using Function = Result (ConstEval::*)(const type::Type* result_ty,
|
||||||
utils::VectorRef<const sem::Constant*>,
|
utils::VectorRef<const sem::Constant*>,
|
||||||
const Source&);
|
const Source&);
|
||||||
|
|
||||||
|
@ -71,13 +71,13 @@ 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 sem::Type* ty, utils::VectorRef<const sem::Expression*> args);
|
Result ArrayOrStructInit(const type::Type* ty, utils::VectorRef<const sem::Expression*> args);
|
||||||
|
|
||||||
/// @param ty the target type
|
/// @param ty the target type
|
||||||
/// @param expr the input expression
|
/// @param expr the input expression
|
||||||
/// @return the bit-cast of the given expression to the given type, or null if the value cannot
|
/// @return the bit-cast of the given expression to the given type, or null if the value cannot
|
||||||
/// be calculated
|
/// be calculated
|
||||||
Result Bitcast(const sem::Type* ty, const sem::Expression* expr);
|
Result Bitcast(const type::Type* ty, const sem::Expression* expr);
|
||||||
|
|
||||||
/// @param obj the object being indexed
|
/// @param obj the object being indexed
|
||||||
/// @param idx the index expression
|
/// @param idx the index expression
|
||||||
|
@ -87,7 +87,7 @@ class ConstEval {
|
||||||
/// @param ty the result type
|
/// @param ty the result type
|
||||||
/// @param lit the literal AST node
|
/// @param lit the literal AST node
|
||||||
/// @return the constant value of the literal
|
/// @return the constant value of the literal
|
||||||
Result Literal(const sem::Type* ty, const ast::LiteralExpression* lit);
|
Result Literal(const type::Type* ty, const ast::LiteralExpression* lit);
|
||||||
|
|
||||||
/// @param obj the object being accessed
|
/// @param obj the object being accessed
|
||||||
/// @param member the member
|
/// @param member the member
|
||||||
|
@ -98,7 +98,7 @@ class ConstEval {
|
||||||
/// @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 sem::Type* ty,
|
Result Swizzle(const type::Type* ty,
|
||||||
const sem::Expression* vector,
|
const sem::Expression* vector,
|
||||||
utils::VectorRef<uint32_t> indices);
|
utils::VectorRef<uint32_t> indices);
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ class ConstEval {
|
||||||
/// @param value the value being converted
|
/// @param value the value being converted
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the converted value, or null if the value cannot be calculated
|
/// @return the converted value, or null if the value cannot be calculated
|
||||||
Result Convert(const sem::Type* ty, const sem::Constant* value, const Source& source);
|
Result Convert(const type::Type* ty, const sem::Constant* value, const Source& source);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constant value evaluation methods, to be indirectly called via the intrinsic table
|
// Constant value evaluation methods, to be indirectly called via the intrinsic table
|
||||||
|
@ -118,7 +118,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the converted value, or null if the value cannot be calculated
|
/// @return the converted value, or null if the value cannot be calculated
|
||||||
Result Conv(const sem::Type* ty,
|
Result Conv(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments (no arguments provided)
|
/// @param args the input arguments (no arguments provided)
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @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 Zero(const sem::Type* ty,
|
Result Zero(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @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 Identity(const sem::Type* ty,
|
Result Identity(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @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 VecSplat(const sem::Type* ty,
|
Result VecSplat(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @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 VecInitS(const sem::Type* ty,
|
Result VecInitS(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @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 VecInitM(const sem::Type* ty,
|
Result VecInitM(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @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 MatInitS(const sem::Type* ty,
|
Result MatInitS(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @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 MatInitV(const sem::Type* ty,
|
Result MatInitV(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpComplement(const sem::Type* ty,
|
Result OpComplement(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpUnaryMinus(const sem::Type* ty,
|
Result OpUnaryMinus(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpNot(const sem::Type* ty,
|
Result OpNot(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpPlus(const sem::Type* ty,
|
Result OpPlus(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpMinus(const sem::Type* ty,
|
Result OpMinus(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpMultiply(const sem::Type* ty,
|
Result OpMultiply(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpMultiplyMatVec(const sem::Type* ty,
|
Result OpMultiplyMatVec(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpMultiplyVecMat(const sem::Type* ty,
|
Result OpMultiplyVecMat(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpMultiplyMatMat(const sem::Type* ty,
|
Result OpMultiplyMatMat(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpDivide(const sem::Type* ty,
|
Result OpDivide(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpModulo(const sem::Type* ty,
|
Result OpModulo(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -297,7 +297,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpEqual(const sem::Type* ty,
|
Result OpEqual(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpNotEqual(const sem::Type* ty,
|
Result OpNotEqual(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpLessThan(const sem::Type* ty,
|
Result OpLessThan(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpGreaterThan(const sem::Type* ty,
|
Result OpGreaterThan(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpLessThanEqual(const sem::Type* ty,
|
Result OpLessThanEqual(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpGreaterThanEqual(const sem::Type* ty,
|
Result OpGreaterThanEqual(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpLogicalAnd(const sem::Type* ty,
|
Result OpLogicalAnd(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpLogicalOr(const sem::Type* ty,
|
Result OpLogicalOr(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpAnd(const sem::Type* ty,
|
Result OpAnd(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpOr(const sem::Type* ty,
|
Result OpOr(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpXor(const sem::Type* ty,
|
Result OpXor(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpShiftLeft(const sem::Type* ty,
|
Result OpShiftLeft(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result OpShiftRight(const sem::Type* ty,
|
Result OpShiftRight(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -418,7 +418,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result abs(const sem::Type* ty,
|
Result abs(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -427,7 +427,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result acos(const sem::Type* ty,
|
Result acos(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result acosh(const sem::Type* ty,
|
Result acosh(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -445,7 +445,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result all(const sem::Type* ty,
|
Result all(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -454,7 +454,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result any(const sem::Type* ty,
|
Result any(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result asin(const sem::Type* ty,
|
Result asin(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result asinh(const sem::Type* ty,
|
Result asinh(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -481,7 +481,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result atan(const sem::Type* ty,
|
Result atan(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -490,7 +490,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result atanh(const sem::Type* ty,
|
Result atanh(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -499,7 +499,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result atan2(const sem::Type* ty,
|
Result atan2(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -508,7 +508,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result ceil(const sem::Type* ty,
|
Result ceil(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result clamp(const sem::Type* ty,
|
Result clamp(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -526,7 +526,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result cos(const sem::Type* ty,
|
Result cos(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -535,7 +535,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result cosh(const sem::Type* ty,
|
Result cosh(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -544,7 +544,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result countLeadingZeros(const sem::Type* ty,
|
Result countLeadingZeros(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -553,7 +553,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result countOneBits(const sem::Type* ty,
|
Result countOneBits(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -562,7 +562,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result countTrailingZeros(const sem::Type* ty,
|
Result countTrailingZeros(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -571,7 +571,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result cross(const sem::Type* ty,
|
Result cross(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -580,7 +580,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location of the conversion
|
/// @param source the source location of the conversion
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result degrees(const sem::Type* ty,
|
Result degrees(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -589,7 +589,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location of the conversion
|
/// @param source the source location of the conversion
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result determinant(const sem::Type* ty,
|
Result determinant(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -598,7 +598,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location of the conversion
|
/// @param source the source location of the conversion
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result distance(const sem::Type* ty,
|
Result distance(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -607,7 +607,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result dot(const sem::Type* ty,
|
Result dot(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -616,7 +616,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result exp(const sem::Type* ty,
|
Result exp(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -625,7 +625,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result exp2(const sem::Type* ty,
|
Result exp2(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -634,7 +634,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result extractBits(const sem::Type* ty,
|
Result extractBits(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -643,7 +643,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result faceForward(const sem::Type* ty,
|
Result faceForward(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -652,7 +652,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result firstLeadingBit(const sem::Type* ty,
|
Result firstLeadingBit(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -661,7 +661,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result firstTrailingBit(const sem::Type* ty,
|
Result firstTrailingBit(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -670,7 +670,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result floor(const sem::Type* ty,
|
Result floor(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -679,7 +679,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result fma(const sem::Type* ty,
|
Result fma(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -688,7 +688,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result frexp(const sem::Type* ty,
|
Result frexp(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -697,7 +697,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result insertBits(const sem::Type* ty,
|
Result insertBits(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -706,7 +706,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result inverseSqrt(const sem::Type* ty,
|
Result inverseSqrt(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -715,7 +715,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result length(const sem::Type* ty,
|
Result length(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -724,7 +724,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result log(const sem::Type* ty,
|
Result log(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -733,7 +733,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result log2(const sem::Type* ty,
|
Result log2(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -742,7 +742,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result max(const sem::Type* ty,
|
Result max(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -751,7 +751,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result min(const sem::Type* ty, // NOLINT(build/include_what_you_use) -- confused by min
|
Result min(const type::Type* ty, // NOLINT(build/include_what_you_use) -- confused by min
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -760,7 +760,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result modf(const sem::Type* ty,
|
Result modf(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -769,7 +769,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result normalize(const sem::Type* ty,
|
Result normalize(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -778,7 +778,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result pack2x16float(const sem::Type* ty,
|
Result pack2x16float(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -787,7 +787,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result pack2x16snorm(const sem::Type* ty,
|
Result pack2x16snorm(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -796,7 +796,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result pack2x16unorm(const sem::Type* ty,
|
Result pack2x16unorm(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -805,7 +805,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result pack4x8snorm(const sem::Type* ty,
|
Result pack4x8snorm(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -814,7 +814,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result pack4x8unorm(const sem::Type* ty,
|
Result pack4x8unorm(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -823,7 +823,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location of the conversion
|
/// @param source the source location of the conversion
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result radians(const sem::Type* ty,
|
Result radians(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -832,7 +832,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location of the conversion
|
/// @param source the source location of the conversion
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result reflect(const sem::Type* ty,
|
Result reflect(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -841,7 +841,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location of the conversion
|
/// @param source the source location of the conversion
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result refract(const sem::Type* ty,
|
Result refract(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -850,7 +850,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result reverseBits(const sem::Type* ty,
|
Result reverseBits(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -859,7 +859,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result round(const sem::Type* ty,
|
Result round(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -868,7 +868,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result saturate(const sem::Type* ty,
|
Result saturate(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -877,7 +877,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result select_bool(const sem::Type* ty,
|
Result select_bool(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -886,7 +886,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result select_boolvec(const sem::Type* ty,
|
Result select_boolvec(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -895,7 +895,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result sign(const sem::Type* ty,
|
Result sign(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -904,7 +904,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result sin(const sem::Type* ty,
|
Result sin(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -913,7 +913,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result sinh(const sem::Type* ty,
|
Result sinh(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -922,7 +922,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result smoothstep(const sem::Type* ty,
|
Result smoothstep(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -931,7 +931,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result step(const sem::Type* ty,
|
Result step(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -940,7 +940,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result sqrt(const sem::Type* ty,
|
Result sqrt(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -949,7 +949,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result tan(const sem::Type* ty,
|
Result tan(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -958,7 +958,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result tanh(const sem::Type* ty,
|
Result tanh(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -967,7 +967,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result transpose(const sem::Type* ty,
|
Result transpose(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -976,7 +976,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result trunc(const sem::Type* ty,
|
Result trunc(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -985,7 +985,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result unpack2x16float(const sem::Type* ty,
|
Result unpack2x16float(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -994,7 +994,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result unpack2x16snorm(const sem::Type* ty,
|
Result unpack2x16snorm(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -1003,7 +1003,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result unpack2x16unorm(const sem::Type* ty,
|
Result unpack2x16unorm(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -1012,7 +1012,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result unpack4x8snorm(const sem::Type* ty,
|
Result unpack4x8snorm(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -1021,7 +1021,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result unpack4x8unorm(const sem::Type* ty,
|
Result unpack4x8unorm(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -1030,7 +1030,7 @@ class ConstEval {
|
||||||
/// @param args the input arguments
|
/// @param args the input arguments
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @return the result value, or null if the value cannot be calculated
|
/// @return the result value, or null if the value cannot be calculated
|
||||||
Result quantizeToF16(const sem::Type* ty,
|
Result quantizeToF16(const type::Type* ty,
|
||||||
utils::VectorRef<const sem::Constant*> args,
|
utils::VectorRef<const sem::Constant*> args,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
|
@ -1237,91 +1237,91 @@ class ConstEval {
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto AddFunc(const Source& source, const sem::Type* elem_ty);
|
auto AddFunc(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Sub, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Sub, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto SubFunc(const Source& source, const sem::Type* elem_ty);
|
auto SubFunc(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Mul, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Mul, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto MulFunc(const Source& source, const sem::Type* elem_ty);
|
auto MulFunc(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Div, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Div, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto DivFunc(const Source& source, const sem::Type* elem_ty);
|
auto DivFunc(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Mod, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Mod, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto ModFunc(const Source& source, const sem::Type* elem_ty);
|
auto ModFunc(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Dot2, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Dot2, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto Dot2Func(const Source& source, const sem::Type* elem_ty);
|
auto Dot2Func(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Dot3, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Dot3, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto Dot3Func(const Source& source, const sem::Type* elem_ty);
|
auto Dot3Func(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Dot4, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Dot4, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto Dot4Func(const Source& source, const sem::Type* elem_ty);
|
auto Dot4Func(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Det2, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Det2, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto Det2Func(const Source& source, const sem::Type* elem_ty);
|
auto Det2Func(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Det3, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Det3, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto Det3Func(const Source& source, const sem::Type* elem_ty);
|
auto Det3Func(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Det4, and creates a Constant with its result of type `elem_ty`
|
/// Returns a callable that calls Det4, and creates a Constant with its result of type `elem_ty`
|
||||||
/// if successful, or returns Failure otherwise.
|
/// if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto Det4Func(const Source& source, const sem::Type* elem_ty);
|
auto Det4Func(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls Clamp, and creates a Constant with its result of type
|
/// Returns a callable that calls Clamp, and creates a Constant with its result of type
|
||||||
/// `elem_ty` if successful, or returns Failure otherwise.
|
/// `elem_ty` if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto ClampFunc(const Source& source, const sem::Type* elem_ty);
|
auto ClampFunc(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns a callable that calls SqrtFunc, and creates a Constant with its
|
/// Returns a callable that calls SqrtFunc, and creates a Constant with its
|
||||||
/// result of type `elem_ty` if successful, or returns Failure otherwise.
|
/// result of type `elem_ty` if successful, or returns Failure otherwise.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
/// @param elem_ty the element type of the Constant to create on success
|
/// @param elem_ty the element type of the Constant to create on success
|
||||||
/// @returns the callable function
|
/// @returns the callable function
|
||||||
auto SqrtFunc(const Source& source, const sem::Type* elem_ty);
|
auto SqrtFunc(const Source& source, const type::Type* elem_ty);
|
||||||
|
|
||||||
/// Returns the dot product of v1 and v2.
|
/// Returns the dot product of v1 and v2.
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
|
@ -1335,7 +1335,7 @@ class ConstEval {
|
||||||
/// @param ty the return type
|
/// @param ty the return type
|
||||||
/// @param c0 the constant to calculate the length of
|
/// @param c0 the constant to calculate the length of
|
||||||
/// @returns the length of c0
|
/// @returns the length of c0
|
||||||
Result Length(const Source& source, const sem::Type* ty, const sem::Constant* c0);
|
Result Length(const Source& source, const type::Type* ty, const sem::Constant* c0);
|
||||||
|
|
||||||
/// Returns the product of v1 and v2
|
/// Returns the product of v1 and v2
|
||||||
/// @param source the source location
|
/// @param source the source location
|
||||||
|
@ -1344,7 +1344,7 @@ class ConstEval {
|
||||||
/// @param v2 rhs value
|
/// @param v2 rhs value
|
||||||
/// @returns the product of v1 and v2
|
/// @returns the product of v1 and v2
|
||||||
Result Mul(const Source& source,
|
Result Mul(const Source& source,
|
||||||
const sem::Type* ty,
|
const type::Type* ty,
|
||||||
const sem::Constant* v1,
|
const sem::Constant* v1,
|
||||||
const sem::Constant* v2);
|
const sem::Constant* v2);
|
||||||
|
|
||||||
|
@ -1355,7 +1355,7 @@ class ConstEval {
|
||||||
/// @param v2 rhs value
|
/// @param v2 rhs value
|
||||||
/// @returns the difference between v2 and v1
|
/// @returns the difference between v2 and v1
|
||||||
Result Sub(const Source& source,
|
Result Sub(const Source& source,
|
||||||
const sem::Type* ty,
|
const type::Type* ty,
|
||||||
const sem::Constant* v1,
|
const sem::Constant* v1,
|
||||||
const sem::Constant* v2);
|
const sem::Constant* v2);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#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/test_helper.h"
|
#include "src/tint/type/test_helper.h"
|
||||||
|
|
||||||
namespace tint::resolver {
|
namespace tint::resolver {
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ INSTANTIATE_TEST_SUITE_P(ResolverTest, ResolverInferredTypeParamTest, testing::V
|
||||||
TEST_F(ResolverInferredTypeTest, InferArray_Pass) {
|
TEST_F(ResolverInferredTypeTest, InferArray_Pass) {
|
||||||
auto* type = ty.array(ty.u32(), 10_u);
|
auto* type = ty.array(ty.u32(), 10_u);
|
||||||
auto* expected_type = create<sem::Array>(
|
auto* expected_type = create<sem::Array>(
|
||||||
create<sem::U32>(), create<sem::ConstantArrayCount>(10u), 4u, 4u * 10u, 4u, 4u);
|
create<sem::U32>(), create<type::ConstantArrayCount>(10u), 4u, 4u * 10u, 4u, 4u);
|
||||||
|
|
||||||
auto* ctor_expr = Construct(type);
|
auto* ctor_expr = Construct(type);
|
||||||
auto* var = Var("a", ast::AddressSpace::kFunction, ctor_expr);
|
auto* var = Var("a", ast::AddressSpace::kFunction, ctor_expr);
|
||||||
|
|
|
@ -55,14 +55,14 @@ constexpr static const size_t kNumFixedParams = 8;
|
||||||
constexpr static const size_t kNumFixedCandidates = 8;
|
constexpr static const size_t kNumFixedCandidates = 8;
|
||||||
|
|
||||||
/// A special type that matches all TypeMatchers
|
/// A special type that matches all TypeMatchers
|
||||||
class Any final : public Castable<Any, sem::Type> {
|
class Any final : public Castable<Any, type::Type> {
|
||||||
public:
|
public:
|
||||||
Any() : Base(sem::TypeFlags{}) {}
|
Any() : Base(type::TypeFlags{}) {}
|
||||||
~Any() override = default;
|
~Any() override = default;
|
||||||
|
|
||||||
// Stub implementations for sem::Type conformance.
|
// Stub implementations for type::Type conformance.
|
||||||
size_t Hash() const override { return 0; }
|
size_t Hash() const override { return 0; }
|
||||||
bool Equals(const sem::Type&) const override { return false; }
|
bool Equals(const type::Type&) const override { return false; }
|
||||||
std::string FriendlyName(const SymbolTable&) const override { return "<any>"; }
|
std::string FriendlyName(const SymbolTable&) const override { return "<any>"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ class TemplateState {
|
||||||
/// template type is replaced with `ty`, and `ty` is returned.
|
/// template type is replaced with `ty`, and `ty` is returned.
|
||||||
/// If none of the above applies, then `ty` is a type mismatch for the template type, and
|
/// If none of the above applies, then `ty` is a type mismatch for the template type, and
|
||||||
/// nullptr is returned.
|
/// nullptr is returned.
|
||||||
const sem::Type* Type(size_t idx, const sem::Type* ty) {
|
const type::Type* Type(size_t idx, const type::Type* ty) {
|
||||||
if (idx >= types_.Length()) {
|
if (idx >= types_.Length()) {
|
||||||
types_.Resize(idx + 1);
|
types_.Resize(idx + 1);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ class TemplateState {
|
||||||
t = ty;
|
t = ty;
|
||||||
return ty;
|
return ty;
|
||||||
}
|
}
|
||||||
ty = sem::Type::Common(utils::Vector{t, ty});
|
ty = type::Type::Common(utils::Vector{t, ty});
|
||||||
if (ty) {
|
if (ty) {
|
||||||
t = ty;
|
t = ty;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ class TemplateState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Type returns the template type with index `idx`, or nullptr if the type was not defined.
|
/// Type returns the template type with index `idx`, or nullptr if the type was not defined.
|
||||||
const sem::Type* Type(size_t idx) const {
|
const type::Type* Type(size_t idx) const {
|
||||||
if (idx >= types_.Length()) {
|
if (idx >= types_.Length()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ class TemplateState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SetType replaces the template type with index `idx` with type `ty`.
|
/// SetType replaces the template type with index `idx` with type `ty`.
|
||||||
void SetType(size_t idx, const sem::Type* ty) {
|
void SetType(size_t idx, const type::Type* ty) {
|
||||||
if (idx >= types_.Length()) {
|
if (idx >= types_.Length()) {
|
||||||
types_.Resize(idx + 1);
|
types_.Resize(idx + 1);
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ class TemplateState {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
utils::Vector<const sem::Type*, 4> types_;
|
utils::Vector<const type::Type*, 4> types_;
|
||||||
utils::Vector<Number, 2> numbers_;
|
utils::Vector<Number, 2> numbers_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ class MatchState {
|
||||||
/// `ty`. If the type matches, the canonical expected type is returned. If the
|
/// `ty`. If the type matches, the canonical expected type is returned. If the
|
||||||
/// type `ty` does not match, then nullptr is returned.
|
/// type `ty` does not match, then nullptr is returned.
|
||||||
/// @note: The matcher indices are progressed on calling.
|
/// @note: The matcher indices are progressed on calling.
|
||||||
const sem::Type* Type(const sem::Type* ty);
|
const type::Type* Type(const type::Type* ty);
|
||||||
|
|
||||||
/// Num uses the next NumMatcher from the matcher indices to match the number
|
/// Num uses the next NumMatcher from the matcher indices to match the number
|
||||||
/// `num`. If the number matches, the canonical expected number is returned.
|
/// `num`. If the number matches, the canonical expected number is returned.
|
||||||
|
@ -253,7 +253,7 @@ class TypeMatcher {
|
||||||
/// Match may define and refine the template types and numbers in state.
|
/// Match may define and refine the template types and numbers in state.
|
||||||
/// @param type the type to match
|
/// @param type the type to match
|
||||||
/// @returns the canonicalized type on match, otherwise nullptr
|
/// @returns the canonicalized type on match, otherwise nullptr
|
||||||
virtual const sem::Type* Match(MatchState& state, const sem::Type* type) const = 0;
|
virtual const type::Type* Match(MatchState& state, const type::Type* type) const = 0;
|
||||||
|
|
||||||
/// @return a string representation of the matcher. Used for printing error
|
/// @return a string representation of the matcher. Used for printing error
|
||||||
/// messages when no overload is found.
|
/// messages when no overload is found.
|
||||||
|
@ -286,7 +286,7 @@ class TemplateTypeMatcher : public TypeMatcher {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
explicit TemplateTypeMatcher(size_t index) : index_(index) {}
|
explicit TemplateTypeMatcher(size_t index) : index_(index) {}
|
||||||
|
|
||||||
const sem::Type* Match(MatchState& state, const sem::Type* type) const override {
|
const type::Type* Match(MatchState& state, const type::Type* type) const override {
|
||||||
if (type->Is<Any>()) {
|
if (type->Is<Any>()) {
|
||||||
return state.templates.Type(index_);
|
return state.templates.Type(index_);
|
||||||
}
|
}
|
||||||
|
@ -348,7 +348,7 @@ enum class OverloadFlag {
|
||||||
// An enum set of OverloadFlag, used by OperatorInfo
|
// An enum set of OverloadFlag, used by OperatorInfo
|
||||||
using OverloadFlags = utils::EnumSet<OverloadFlag>;
|
using OverloadFlags = utils::EnumSet<OverloadFlag>;
|
||||||
|
|
||||||
bool match_bool(MatchState&, const sem::Type* ty) {
|
bool match_bool(MatchState&, const type::Type* ty) {
|
||||||
return ty->IsAnyOf<Any, sem::Bool>();
|
return ty->IsAnyOf<Any, sem::Bool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ const sem::AbstractFloat* build_fa(MatchState& state) {
|
||||||
return state.builder.create<sem::AbstractFloat>();
|
return state.builder.create<sem::AbstractFloat>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_fa(MatchState& state, const sem::Type* ty) {
|
bool match_fa(MatchState& state, const type::Type* ty) {
|
||||||
return (state.earliest_eval_stage == sem::EvaluationStage::kConstant) &&
|
return (state.earliest_eval_stage == sem::EvaluationStage::kConstant) &&
|
||||||
ty->IsAnyOf<Any, sem::AbstractNumeric>();
|
ty->IsAnyOf<Any, sem::AbstractNumeric>();
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ const sem::AbstractInt* build_ia(MatchState& state) {
|
||||||
return state.builder.create<sem::AbstractInt>();
|
return state.builder.create<sem::AbstractInt>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_ia(MatchState& state, const sem::Type* ty) {
|
bool match_ia(MatchState& state, const type::Type* ty) {
|
||||||
return (state.earliest_eval_stage == sem::EvaluationStage::kConstant) &&
|
return (state.earliest_eval_stage == sem::EvaluationStage::kConstant) &&
|
||||||
ty->IsAnyOf<Any, sem::AbstractInt>();
|
ty->IsAnyOf<Any, sem::AbstractInt>();
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,7 @@ const sem::F16* build_f16(MatchState& state) {
|
||||||
return state.builder.create<sem::F16>();
|
return state.builder.create<sem::F16>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_f16(MatchState&, const sem::Type* ty) {
|
bool match_f16(MatchState&, const type::Type* ty) {
|
||||||
return ty->IsAnyOf<Any, sem::F16, sem::AbstractNumeric>();
|
return ty->IsAnyOf<Any, sem::F16, sem::AbstractNumeric>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +386,7 @@ const sem::F32* build_f32(MatchState& state) {
|
||||||
return state.builder.create<sem::F32>();
|
return state.builder.create<sem::F32>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_f32(MatchState&, const sem::Type* ty) {
|
bool match_f32(MatchState&, const type::Type* ty) {
|
||||||
return ty->IsAnyOf<Any, sem::F32, sem::AbstractNumeric>();
|
return ty->IsAnyOf<Any, sem::F32, sem::AbstractNumeric>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ const sem::I32* build_i32(MatchState& state) {
|
||||||
return state.builder.create<sem::I32>();
|
return state.builder.create<sem::I32>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_i32(MatchState&, const sem::Type* ty) {
|
bool match_i32(MatchState&, const type::Type* ty) {
|
||||||
return ty->IsAnyOf<Any, sem::I32, sem::AbstractInt>();
|
return ty->IsAnyOf<Any, sem::I32, sem::AbstractInt>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,11 +402,11 @@ const sem::U32* build_u32(MatchState& state) {
|
||||||
return state.builder.create<sem::U32>();
|
return state.builder.create<sem::U32>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_u32(MatchState&, const sem::Type* ty) {
|
bool match_u32(MatchState&, const type::Type* ty) {
|
||||||
return ty->IsAnyOf<Any, sem::U32, sem::AbstractInt>();
|
return ty->IsAnyOf<Any, sem::U32, sem::AbstractInt>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_vec(MatchState&, const sem::Type* ty, Number& N, const sem::Type*& T) {
|
bool match_vec(MatchState&, const type::Type* ty, Number& N, const type::Type*& T) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
N = Number::any;
|
N = Number::any;
|
||||||
T = ty;
|
T = ty;
|
||||||
|
@ -422,7 +422,7 @@ bool match_vec(MatchState&, const sem::Type* ty, Number& N, const sem::Type*& T)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t N>
|
template <uint32_t N>
|
||||||
bool match_vec(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
bool match_vec(MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
|
@ -437,12 +437,12 @@ bool match_vec(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Vector* build_vec(MatchState& state, Number N, const sem::Type* el) {
|
const sem::Vector* build_vec(MatchState& state, Number N, const type::Type* el) {
|
||||||
return state.builder.create<sem::Vector>(el, N.Value());
|
return state.builder.create<sem::Vector>(el, N.Value());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t N>
|
template <uint32_t N>
|
||||||
const sem::Vector* build_vec(MatchState& state, const sem::Type* el) {
|
const sem::Vector* build_vec(MatchState& state, const type::Type* el) {
|
||||||
return state.builder.create<sem::Vector>(el, N);
|
return state.builder.create<sem::Vector>(el, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +454,7 @@ constexpr auto build_vec2 = build_vec<2>;
|
||||||
constexpr auto build_vec3 = build_vec<3>;
|
constexpr auto build_vec3 = build_vec<3>;
|
||||||
constexpr auto build_vec4 = build_vec<4>;
|
constexpr auto build_vec4 = build_vec<4>;
|
||||||
|
|
||||||
bool match_mat(MatchState&, const sem::Type* ty, Number& M, Number& N, const sem::Type*& T) {
|
bool match_mat(MatchState&, const type::Type* ty, Number& M, Number& N, const type::Type*& T) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
M = Number::any;
|
M = Number::any;
|
||||||
N = Number::any;
|
N = Number::any;
|
||||||
|
@ -471,7 +471,7 @@ bool match_mat(MatchState&, const sem::Type* ty, Number& M, Number& N, const sem
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t C, uint32_t R>
|
template <uint32_t C, uint32_t R>
|
||||||
bool match_mat(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
bool match_mat(MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
|
@ -485,13 +485,13 @@ bool match_mat(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Matrix* build_mat(MatchState& state, Number C, Number R, const sem::Type* T) {
|
const sem::Matrix* build_mat(MatchState& state, Number C, Number R, const type::Type* T) {
|
||||||
auto* column_type = state.builder.create<sem::Vector>(T, R.Value());
|
auto* column_type = state.builder.create<sem::Vector>(T, R.Value());
|
||||||
return state.builder.create<sem::Matrix>(column_type, C.Value());
|
return state.builder.create<sem::Matrix>(column_type, C.Value());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t C, uint32_t R>
|
template <uint32_t C, uint32_t R>
|
||||||
const sem::Matrix* build_mat(MatchState& state, const sem::Type* T) {
|
const sem::Matrix* build_mat(MatchState& state, const type::Type* T) {
|
||||||
auto* column_type = state.builder.create<sem::Vector>(T, R);
|
auto* column_type = state.builder.create<sem::Vector>(T, R);
|
||||||
return state.builder.create<sem::Matrix>(column_type, C);
|
return state.builder.create<sem::Matrix>(column_type, C);
|
||||||
}
|
}
|
||||||
|
@ -516,14 +516,14 @@ constexpr auto match_mat4x2 = match_mat<4, 2>;
|
||||||
constexpr auto match_mat4x3 = match_mat<4, 3>;
|
constexpr auto match_mat4x3 = match_mat<4, 3>;
|
||||||
constexpr auto match_mat4x4 = match_mat<4, 4>;
|
constexpr auto match_mat4x4 = match_mat<4, 4>;
|
||||||
|
|
||||||
bool match_array(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
bool match_array(MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* a = ty->As<sem::Array>()) {
|
if (auto* a = ty->As<sem::Array>()) {
|
||||||
if (a->Count()->Is<sem::RuntimeArrayCount>()) {
|
if (a->Count()->Is<type::RuntimeArrayCount>()) {
|
||||||
T = a->ElemType();
|
T = a->ElemType();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -531,17 +531,17 @@ bool match_array(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Array* build_array(MatchState& state, const sem::Type* el) {
|
const sem::Array* build_array(MatchState& state, const type::Type* el) {
|
||||||
return state.builder.create<sem::Array>(
|
return state.builder.create<sem::Array>(
|
||||||
el,
|
el,
|
||||||
/* count */ state.builder.create<sem::RuntimeArrayCount>(),
|
/* count */ state.builder.create<type::RuntimeArrayCount>(),
|
||||||
/* align */ 0u,
|
/* align */ 0u,
|
||||||
/* size */ 0u,
|
/* size */ 0u,
|
||||||
/* stride */ 0u,
|
/* stride */ 0u,
|
||||||
/* stride_implicit */ 0u);
|
/* stride_implicit */ 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_ptr(MatchState&, const sem::Type* ty, Number& S, const sem::Type*& T, Number& A) {
|
bool match_ptr(MatchState&, const type::Type* ty, Number& S, const type::Type*& T, Number& A) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
S = Number::any;
|
S = Number::any;
|
||||||
T = ty;
|
T = ty;
|
||||||
|
@ -558,12 +558,12 @@ bool match_ptr(MatchState&, const sem::Type* ty, Number& S, const sem::Type*& T,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Pointer* build_ptr(MatchState& state, Number S, const sem::Type* T, Number& A) {
|
const sem::Pointer* build_ptr(MatchState& state, Number S, const type::Type* T, Number& A) {
|
||||||
return state.builder.create<sem::Pointer>(T, static_cast<ast::AddressSpace>(S.Value()),
|
return state.builder.create<sem::Pointer>(T, static_cast<ast::AddressSpace>(S.Value()),
|
||||||
static_cast<ast::Access>(A.Value()));
|
static_cast<ast::Access>(A.Value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_atomic(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
bool match_atomic(MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
|
@ -576,11 +576,11 @@ bool match_atomic(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Atomic* build_atomic(MatchState& state, const sem::Type* T) {
|
const sem::Atomic* build_atomic(MatchState& state, const type::Type* T) {
|
||||||
return state.builder.create<sem::Atomic>(T);
|
return state.builder.create<sem::Atomic>(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_sampler(MatchState&, const sem::Type* ty) {
|
bool match_sampler(MatchState&, const type::Type* ty) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -591,7 +591,7 @@ const sem::Sampler* build_sampler(MatchState& state) {
|
||||||
return state.builder.create<sem::Sampler>(ast::SamplerKind::kSampler);
|
return state.builder.create<sem::Sampler>(ast::SamplerKind::kSampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_sampler_comparison(MatchState&, const sem::Type* ty) {
|
bool match_sampler_comparison(MatchState&, const type::Type* ty) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -604,9 +604,9 @@ const sem::Sampler* build_sampler_comparison(MatchState& state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_texture(MatchState&,
|
bool match_texture(MatchState&,
|
||||||
const sem::Type* ty,
|
const type::Type* ty,
|
||||||
ast::TextureDimension dim,
|
ast::TextureDimension dim,
|
||||||
const sem::Type*& T) {
|
const type::Type*& T) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
|
@ -622,14 +622,14 @@ bool match_texture(MatchState&,
|
||||||
|
|
||||||
#define JOIN(a, b) a##b
|
#define JOIN(a, b) a##b
|
||||||
|
|
||||||
#define DECLARE_SAMPLED_TEXTURE(suffix, dim) \
|
#define DECLARE_SAMPLED_TEXTURE(suffix, dim) \
|
||||||
bool JOIN(match_texture_, suffix)(MatchState & state, const sem::Type* ty, \
|
bool JOIN(match_texture_, suffix)(MatchState & state, const type::Type* ty, \
|
||||||
const sem::Type*& T) { \
|
const type::Type*& T) { \
|
||||||
return match_texture(state, ty, dim, T); \
|
return match_texture(state, ty, dim, T); \
|
||||||
} \
|
} \
|
||||||
const sem::SampledTexture* JOIN(build_texture_, suffix)(MatchState & state, \
|
const sem::SampledTexture* JOIN(build_texture_, suffix)(MatchState & state, \
|
||||||
const sem::Type* T) { \
|
const type::Type* T) { \
|
||||||
return state.builder.create<sem::SampledTexture>(dim, T); \
|
return state.builder.create<sem::SampledTexture>(dim, T); \
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_SAMPLED_TEXTURE(1d, ast::TextureDimension::k1d)
|
DECLARE_SAMPLED_TEXTURE(1d, ast::TextureDimension::k1d)
|
||||||
|
@ -641,9 +641,9 @@ DECLARE_SAMPLED_TEXTURE(cube_array, ast::TextureDimension::kCubeArray)
|
||||||
#undef DECLARE_SAMPLED_TEXTURE
|
#undef DECLARE_SAMPLED_TEXTURE
|
||||||
|
|
||||||
bool match_texture_multisampled(MatchState&,
|
bool match_texture_multisampled(MatchState&,
|
||||||
const sem::Type* ty,
|
const type::Type* ty,
|
||||||
ast::TextureDimension dim,
|
ast::TextureDimension dim,
|
||||||
const sem::Type*& T) {
|
const type::Type*& T) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
|
@ -657,32 +657,32 @@ bool match_texture_multisampled(MatchState&,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_MULTISAMPLED_TEXTURE(suffix, dim) \
|
#define DECLARE_MULTISAMPLED_TEXTURE(suffix, dim) \
|
||||||
bool JOIN(match_texture_multisampled_, suffix)(MatchState & state, const sem::Type* ty, \
|
bool JOIN(match_texture_multisampled_, suffix)(MatchState & state, const type::Type* ty, \
|
||||||
const sem::Type*& T) { \
|
const type::Type*& T) { \
|
||||||
return match_texture_multisampled(state, ty, dim, T); \
|
return match_texture_multisampled(state, ty, dim, T); \
|
||||||
} \
|
} \
|
||||||
const sem::MultisampledTexture* JOIN(build_texture_multisampled_, suffix)( \
|
const sem::MultisampledTexture* JOIN(build_texture_multisampled_, suffix)( \
|
||||||
MatchState & state, const sem::Type* T) { \
|
MatchState & state, const type::Type* T) { \
|
||||||
return state.builder.create<sem::MultisampledTexture>(dim, T); \
|
return state.builder.create<sem::MultisampledTexture>(dim, T); \
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_MULTISAMPLED_TEXTURE(2d, ast::TextureDimension::k2d)
|
DECLARE_MULTISAMPLED_TEXTURE(2d, ast::TextureDimension::k2d)
|
||||||
#undef DECLARE_MULTISAMPLED_TEXTURE
|
#undef DECLARE_MULTISAMPLED_TEXTURE
|
||||||
|
|
||||||
bool match_texture_depth(MatchState&, const sem::Type* ty, ast::TextureDimension dim) {
|
bool match_texture_depth(MatchState&, const type::Type* ty, ast::TextureDimension dim) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return ty->Is([&](const sem::DepthTexture* t) { return t->dim() == dim; });
|
return ty->Is([&](const sem::DepthTexture* t) { return t->dim() == dim; });
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_DEPTH_TEXTURE(suffix, dim) \
|
#define DECLARE_DEPTH_TEXTURE(suffix, dim) \
|
||||||
bool JOIN(match_texture_depth_, suffix)(MatchState & state, const sem::Type* ty) { \
|
bool JOIN(match_texture_depth_, suffix)(MatchState & state, const type::Type* ty) { \
|
||||||
return match_texture_depth(state, ty, dim); \
|
return match_texture_depth(state, ty, dim); \
|
||||||
} \
|
} \
|
||||||
const sem::DepthTexture* JOIN(build_texture_depth_, suffix)(MatchState & state) { \
|
const sem::DepthTexture* JOIN(build_texture_depth_, suffix)(MatchState & state) { \
|
||||||
return state.builder.create<sem::DepthTexture>(dim); \
|
return state.builder.create<sem::DepthTexture>(dim); \
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_DEPTH_TEXTURE(2d, ast::TextureDimension::k2d)
|
DECLARE_DEPTH_TEXTURE(2d, ast::TextureDimension::k2d)
|
||||||
|
@ -691,7 +691,7 @@ DECLARE_DEPTH_TEXTURE(cube, ast::TextureDimension::kCube)
|
||||||
DECLARE_DEPTH_TEXTURE(cube_array, ast::TextureDimension::kCubeArray)
|
DECLARE_DEPTH_TEXTURE(cube_array, ast::TextureDimension::kCubeArray)
|
||||||
#undef DECLARE_DEPTH_TEXTURE
|
#undef DECLARE_DEPTH_TEXTURE
|
||||||
|
|
||||||
bool match_texture_depth_multisampled_2d(MatchState&, const sem::Type* ty) {
|
bool match_texture_depth_multisampled_2d(MatchState&, const type::Type* ty) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -705,7 +705,7 @@ sem::DepthMultisampledTexture* build_texture_depth_multisampled_2d(MatchState& s
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_texture_storage(MatchState&,
|
bool match_texture_storage(MatchState&,
|
||||||
const sem::Type* ty,
|
const type::Type* ty,
|
||||||
ast::TextureDimension dim,
|
ast::TextureDimension dim,
|
||||||
Number& F,
|
Number& F,
|
||||||
Number& A) {
|
Number& A) {
|
||||||
|
@ -724,17 +724,17 @@ bool match_texture_storage(MatchState&,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_STORAGE_TEXTURE(suffix, dim) \
|
#define DECLARE_STORAGE_TEXTURE(suffix, dim) \
|
||||||
bool JOIN(match_texture_storage_, suffix)(MatchState & state, const sem::Type* ty, Number& F, \
|
bool JOIN(match_texture_storage_, suffix)(MatchState & state, const type::Type* ty, Number& F, \
|
||||||
Number& A) { \
|
Number& A) { \
|
||||||
return match_texture_storage(state, ty, dim, F, A); \
|
return match_texture_storage(state, ty, dim, F, A); \
|
||||||
} \
|
} \
|
||||||
const sem::StorageTexture* JOIN(build_texture_storage_, suffix)(MatchState & state, Number F, \
|
const sem::StorageTexture* JOIN(build_texture_storage_, suffix)(MatchState & state, Number F, \
|
||||||
Number A) { \
|
Number A) { \
|
||||||
auto format = static_cast<TexelFormat>(F.Value()); \
|
auto format = static_cast<TexelFormat>(F.Value()); \
|
||||||
auto access = static_cast<Access>(A.Value()); \
|
auto access = static_cast<Access>(A.Value()); \
|
||||||
auto* T = sem::StorageTexture::SubtypeFor(format, state.builder.Types()); \
|
auto* T = sem::StorageTexture::SubtypeFor(format, state.builder.Types()); \
|
||||||
return state.builder.create<sem::StorageTexture>(dim, format, access, T); \
|
return state.builder.create<sem::StorageTexture>(dim, format, access, T); \
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_STORAGE_TEXTURE(1d, ast::TextureDimension::k1d)
|
DECLARE_STORAGE_TEXTURE(1d, ast::TextureDimension::k1d)
|
||||||
|
@ -743,7 +743,7 @@ DECLARE_STORAGE_TEXTURE(2d_array, ast::TextureDimension::k2dArray)
|
||||||
DECLARE_STORAGE_TEXTURE(3d, ast::TextureDimension::k3d)
|
DECLARE_STORAGE_TEXTURE(3d, ast::TextureDimension::k3d)
|
||||||
#undef DECLARE_STORAGE_TEXTURE
|
#undef DECLARE_STORAGE_TEXTURE
|
||||||
|
|
||||||
bool match_texture_external(MatchState&, const sem::Type* ty) {
|
bool match_texture_external(MatchState&, const type::Type* ty) {
|
||||||
return ty->IsAnyOf<Any, sem::ExternalTexture>();
|
return ty->IsAnyOf<Any, sem::ExternalTexture>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,14 +754,14 @@ const sem::ExternalTexture* build_texture_external(MatchState& state) {
|
||||||
// Builtin types starting with a _ prefix cannot be declared in WGSL, so they
|
// Builtin types starting with a _ prefix cannot be declared in WGSL, so they
|
||||||
// can only be used as return types. Because of this, they must only match Any,
|
// can only be used as return types. Because of this, they must only match Any,
|
||||||
// which is used as the return type matcher.
|
// which is used as the return type matcher.
|
||||||
bool match_modf_result(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
bool match_modf_result(MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||||
if (!ty->Is<Any>()) {
|
if (!ty->Is<Any>()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool match_modf_result_vec(MatchState&, const sem::Type* ty, Number& N, const sem::Type*& T) {
|
bool match_modf_result_vec(MatchState&, const type::Type* ty, Number& N, const type::Type*& T) {
|
||||||
if (!ty->Is<Any>()) {
|
if (!ty->Is<Any>()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -769,14 +769,14 @@ bool match_modf_result_vec(MatchState&, const sem::Type* ty, Number& N, const se
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool match_frexp_result(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
bool match_frexp_result(MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||||
if (!ty->Is<Any>()) {
|
if (!ty->Is<Any>()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool match_frexp_result_vec(MatchState&, const sem::Type* ty, Number& N, const sem::Type*& T) {
|
bool match_frexp_result_vec(MatchState&, const type::Type* ty, Number& N, const type::Type*& T) {
|
||||||
if (!ty->Is<Any>()) {
|
if (!ty->Is<Any>()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -785,7 +785,7 @@ bool match_frexp_result_vec(MatchState&, const sem::Type* ty, Number& N, const s
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_atomic_compare_exchange_result(MatchState&, const sem::Type* ty, const sem::Type*& T) {
|
bool match_atomic_compare_exchange_result(MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||||
if (ty->Is<Any>()) {
|
if (ty->Is<Any>()) {
|
||||||
T = ty;
|
T = ty;
|
||||||
return true;
|
return true;
|
||||||
|
@ -795,7 +795,7 @@ bool match_atomic_compare_exchange_result(MatchState&, const sem::Type* ty, cons
|
||||||
|
|
||||||
struct NameAndType {
|
struct NameAndType {
|
||||||
std::string name;
|
std::string name;
|
||||||
const sem::Type* type;
|
const type::Type* type;
|
||||||
};
|
};
|
||||||
sem::Struct* build_struct(ProgramBuilder& b,
|
sem::Struct* build_struct(ProgramBuilder& b,
|
||||||
std::string name,
|
std::string name,
|
||||||
|
@ -832,7 +832,7 @@ sem::Struct* build_struct(ProgramBuilder& b,
|
||||||
/* size_no_padding */ size_without_padding);
|
/* size_no_padding */ size_without_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Struct* build_modf_result(MatchState& state, const sem::Type* el) {
|
const sem::Struct* build_modf_result(MatchState& state, const type::Type* el) {
|
||||||
auto build_f32 = [&] {
|
auto build_f32 = [&] {
|
||||||
auto* ty = state.builder.create<sem::F32>();
|
auto* ty = state.builder.create<sem::F32>();
|
||||||
return build_struct(state.builder, "__modf_result_f32", {{"fract", ty}, {"whole", ty}});
|
return build_struct(state.builder, "__modf_result_f32", {{"fract", ty}, {"whole", ty}});
|
||||||
|
@ -859,7 +859,7 @@ const sem::Struct* build_modf_result(MatchState& state, const sem::Type* el) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Struct* build_modf_result_vec(MatchState& state, Number& n, const sem::Type* el) {
|
const sem::Struct* build_modf_result_vec(MatchState& state, Number& n, const type::Type* el) {
|
||||||
auto prefix = "__modf_result_vec" + std::to_string(n.Value());
|
auto prefix = "__modf_result_vec" + std::to_string(n.Value());
|
||||||
auto build_f32 = [&] {
|
auto build_f32 = [&] {
|
||||||
auto* vec = state.builder.create<sem::Vector>(state.builder.create<sem::F32>(), n.Value());
|
auto* vec = state.builder.create<sem::Vector>(state.builder.create<sem::F32>(), n.Value());
|
||||||
|
@ -888,7 +888,7 @@ const sem::Struct* build_modf_result_vec(MatchState& state, Number& n, const sem
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Struct* build_frexp_result(MatchState& state, const sem::Type* el) {
|
const sem::Struct* build_frexp_result(MatchState& state, const type::Type* el) {
|
||||||
auto build_f32 = [&] {
|
auto build_f32 = [&] {
|
||||||
auto* f = state.builder.create<sem::F32>();
|
auto* f = state.builder.create<sem::F32>();
|
||||||
auto* i = state.builder.create<sem::I32>();
|
auto* i = state.builder.create<sem::I32>();
|
||||||
|
@ -918,7 +918,7 @@ const sem::Struct* build_frexp_result(MatchState& state, const sem::Type* el) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Struct* build_frexp_result_vec(MatchState& state, Number& n, const sem::Type* el) {
|
const sem::Struct* build_frexp_result_vec(MatchState& state, Number& n, const type::Type* el) {
|
||||||
auto prefix = "__frexp_result_vec" + std::to_string(n.Value());
|
auto prefix = "__frexp_result_vec" + std::to_string(n.Value());
|
||||||
auto build_f32 = [&] {
|
auto build_f32 = [&] {
|
||||||
auto* f = state.builder.create<sem::Vector>(state.builder.create<sem::F32>(), n.Value());
|
auto* f = state.builder.create<sem::Vector>(state.builder.create<sem::F32>(), n.Value());
|
||||||
|
@ -951,11 +951,11 @@ const sem::Struct* build_frexp_result_vec(MatchState& state, Number& n, const se
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Struct* build_atomic_compare_exchange_result(MatchState& state, const sem::Type* ty) {
|
const sem::Struct* build_atomic_compare_exchange_result(MatchState& state, const type::Type* ty) {
|
||||||
return build_struct(
|
return build_struct(
|
||||||
state.builder,
|
state.builder,
|
||||||
"__atomic_compare_exchange_result" + ty->FriendlyName(state.builder.Symbols()),
|
"__atomic_compare_exchange_result" + ty->FriendlyName(state.builder.Symbols()),
|
||||||
{{"old_value", const_cast<sem::Type*>(ty)},
|
{{"old_value", const_cast<type::Type*>(ty)},
|
||||||
{"exchanged", state.builder.create<sem::Bool>()}});
|
{"exchanged", state.builder.create<sem::Bool>()}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1028,7 +1028,7 @@ struct IntrinsicPrototype {
|
||||||
/// Parameter describes a single parameter
|
/// Parameter describes a single parameter
|
||||||
struct Parameter {
|
struct Parameter {
|
||||||
/// Parameter type
|
/// Parameter type
|
||||||
const sem::Type* const type;
|
const type::Type* const type;
|
||||||
/// Parameter usage
|
/// Parameter usage
|
||||||
ParameterUsage const usage = ParameterUsage::kNone;
|
ParameterUsage const usage = ParameterUsage::kNone;
|
||||||
};
|
};
|
||||||
|
@ -1047,7 +1047,7 @@ struct IntrinsicPrototype {
|
||||||
};
|
};
|
||||||
|
|
||||||
const OverloadInfo* overload = nullptr;
|
const OverloadInfo* overload = nullptr;
|
||||||
sem::Type const* return_type = nullptr;
|
type::Type const* return_type = nullptr;
|
||||||
utils::Vector<Parameter, kNumFixedParams> parameters;
|
utils::Vector<Parameter, kNumFixedParams> parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1073,25 +1073,25 @@ class Impl : public IntrinsicTable {
|
||||||
explicit Impl(ProgramBuilder& builder);
|
explicit Impl(ProgramBuilder& builder);
|
||||||
|
|
||||||
Builtin Lookup(sem::BuiltinType builtin_type,
|
Builtin Lookup(sem::BuiltinType builtin_type,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source) override;
|
const Source& source) override;
|
||||||
|
|
||||||
UnaryOperator Lookup(ast::UnaryOp op,
|
UnaryOperator Lookup(ast::UnaryOp op,
|
||||||
const sem::Type* arg,
|
const type::Type* arg,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source) override;
|
const Source& source) override;
|
||||||
|
|
||||||
BinaryOperator Lookup(ast::BinaryOp op,
|
BinaryOperator Lookup(ast::BinaryOp op,
|
||||||
const sem::Type* lhs,
|
const type::Type* lhs,
|
||||||
const sem::Type* rhs,
|
const type::Type* rhs,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
bool is_compound) override;
|
bool is_compound) override;
|
||||||
|
|
||||||
InitOrConv Lookup(InitConvIntrinsic type,
|
InitOrConv Lookup(InitConvIntrinsic type,
|
||||||
const sem::Type* template_arg,
|
const type::Type* template_arg,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source) override;
|
const Source& source) override;
|
||||||
|
|
||||||
|
@ -1137,7 +1137,7 @@ class Impl : public IntrinsicTable {
|
||||||
/// IntrinsicPrototype::return_type.
|
/// IntrinsicPrototype::return_type.
|
||||||
IntrinsicPrototype MatchIntrinsic(const IntrinsicInfo& intrinsic,
|
IntrinsicPrototype MatchIntrinsic(const IntrinsicInfo& intrinsic,
|
||||||
const char* intrinsic_name,
|
const char* intrinsic_name,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
TemplateState templates,
|
TemplateState templates,
|
||||||
OnNoMatch on_no_match) const;
|
OnNoMatch on_no_match) const;
|
||||||
|
@ -1150,7 +1150,7 @@ class Impl : public IntrinsicTable {
|
||||||
/// template as `f32`.
|
/// template as `f32`.
|
||||||
/// @returns the evaluated Candidate information.
|
/// @returns the evaluated Candidate information.
|
||||||
Candidate ScoreOverload(const OverloadInfo* overload,
|
Candidate ScoreOverload(const OverloadInfo* overload,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
TemplateState templates) const;
|
TemplateState templates) const;
|
||||||
|
|
||||||
|
@ -1166,7 +1166,7 @@ class Impl : public IntrinsicTable {
|
||||||
/// @returns the resolved Candidate.
|
/// @returns the resolved Candidate.
|
||||||
Candidate ResolveCandidate(Candidates&& candidates,
|
Candidate ResolveCandidate(Candidates&& candidates,
|
||||||
const char* intrinsic_name,
|
const char* intrinsic_name,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
TemplateState templates) const;
|
TemplateState templates) const;
|
||||||
|
|
||||||
/// Match constructs a new MatchState
|
/// Match constructs a new MatchState
|
||||||
|
@ -1190,7 +1190,7 @@ class Impl : public IntrinsicTable {
|
||||||
|
|
||||||
/// Raises an error when no overload is a clear winner of overload resolution
|
/// Raises an error when no overload is a clear winner of overload resolution
|
||||||
void ErrAmbiguousOverload(const char* intrinsic_name,
|
void ErrAmbiguousOverload(const char* intrinsic_name,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
TemplateState templates,
|
TemplateState templates,
|
||||||
utils::VectorRef<Candidate> candidates) const;
|
utils::VectorRef<Candidate> candidates) const;
|
||||||
|
|
||||||
|
@ -1207,8 +1207,8 @@ class Impl : public IntrinsicTable {
|
||||||
/// types.
|
/// types.
|
||||||
std::string CallSignature(ProgramBuilder& builder,
|
std::string CallSignature(ProgramBuilder& builder,
|
||||||
const char* intrinsic_name,
|
const char* intrinsic_name,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
const sem::Type* template_arg = nullptr) {
|
const type::Type* template_arg = nullptr) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << intrinsic_name;
|
ss << intrinsic_name;
|
||||||
if (template_arg) {
|
if (template_arg) {
|
||||||
|
@ -1241,7 +1241,7 @@ std::string TemplateNumberMatcher::String(MatchState* state) const {
|
||||||
Impl::Impl(ProgramBuilder& b) : builder(b) {}
|
Impl::Impl(ProgramBuilder& b) : builder(b) {}
|
||||||
|
|
||||||
Impl::Builtin Impl::Lookup(sem::BuiltinType builtin_type,
|
Impl::Builtin Impl::Lookup(sem::BuiltinType builtin_type,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source) {
|
const Source& source) {
|
||||||
const char* intrinsic_name = sem::str(builtin_type);
|
const char* intrinsic_name = sem::str(builtin_type);
|
||||||
|
@ -1295,7 +1295,7 @@ Impl::Builtin Impl::Lookup(sem::BuiltinType builtin_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
IntrinsicTable::UnaryOperator Impl::Lookup(ast::UnaryOp op,
|
IntrinsicTable::UnaryOperator Impl::Lookup(ast::UnaryOp op,
|
||||||
const sem::Type* arg,
|
const type::Type* arg,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source) {
|
const Source& source) {
|
||||||
auto [intrinsic_index, intrinsic_name] = [&]() -> std::pair<size_t, const char*> {
|
auto [intrinsic_index, intrinsic_name] = [&]() -> std::pair<size_t, const char*> {
|
||||||
|
@ -1341,8 +1341,8 @@ IntrinsicTable::UnaryOperator Impl::Lookup(ast::UnaryOp op,
|
||||||
}
|
}
|
||||||
|
|
||||||
IntrinsicTable::BinaryOperator Impl::Lookup(ast::BinaryOp op,
|
IntrinsicTable::BinaryOperator Impl::Lookup(ast::BinaryOp op,
|
||||||
const sem::Type* lhs,
|
const type::Type* lhs,
|
||||||
const sem::Type* rhs,
|
const type::Type* rhs,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
bool is_compound) {
|
bool is_compound) {
|
||||||
|
@ -1420,8 +1420,8 @@ IntrinsicTable::BinaryOperator Impl::Lookup(ast::BinaryOp op,
|
||||||
}
|
}
|
||||||
|
|
||||||
IntrinsicTable::InitOrConv Impl::Lookup(InitConvIntrinsic type,
|
IntrinsicTable::InitOrConv Impl::Lookup(InitConvIntrinsic type,
|
||||||
const sem::Type* template_arg,
|
const type::Type* template_arg,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source) {
|
const Source& source) {
|
||||||
auto name = str(type);
|
auto name = str(type);
|
||||||
|
@ -1499,7 +1499,7 @@ IntrinsicTable::InitOrConv Impl::Lookup(InitConvIntrinsic type,
|
||||||
|
|
||||||
IntrinsicPrototype Impl::MatchIntrinsic(const IntrinsicInfo& intrinsic,
|
IntrinsicPrototype Impl::MatchIntrinsic(const IntrinsicInfo& intrinsic,
|
||||||
const char* intrinsic_name,
|
const char* intrinsic_name,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
TemplateState templates,
|
TemplateState templates,
|
||||||
OnNoMatch on_no_match) const {
|
OnNoMatch on_no_match) const {
|
||||||
|
@ -1539,7 +1539,7 @@ IntrinsicPrototype Impl::MatchIntrinsic(const IntrinsicInfo& intrinsic,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the return type
|
// Build the return type
|
||||||
const sem::Type* return_type = nullptr;
|
const type::Type* return_type = nullptr;
|
||||||
if (auto* indices = match.overload->return_matcher_indices) {
|
if (auto* indices = match.overload->return_matcher_indices) {
|
||||||
Any any;
|
Any any;
|
||||||
return_type =
|
return_type =
|
||||||
|
@ -1556,7 +1556,7 @@ IntrinsicPrototype Impl::MatchIntrinsic(const IntrinsicInfo& intrinsic,
|
||||||
}
|
}
|
||||||
|
|
||||||
Impl::Candidate Impl::ScoreOverload(const OverloadInfo* overload,
|
Impl::Candidate Impl::ScoreOverload(const OverloadInfo* overload,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
TemplateState templates) const {
|
TemplateState templates) const {
|
||||||
// Penalty weights for overload mismatching.
|
// Penalty weights for overload mismatching.
|
||||||
|
@ -1656,7 +1656,7 @@ Impl::Candidate Impl::ScoreOverload(const OverloadInfo* overload,
|
||||||
|
|
||||||
Impl::Candidate Impl::ResolveCandidate(Impl::Candidates&& candidates,
|
Impl::Candidate Impl::ResolveCandidate(Impl::Candidates&& candidates,
|
||||||
const char* intrinsic_name,
|
const char* intrinsic_name,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
TemplateState templates) const {
|
TemplateState templates) const {
|
||||||
utils::Vector<uint32_t, kNumFixedParams> best_ranks;
|
utils::Vector<uint32_t, kNumFixedParams> best_ranks;
|
||||||
best_ranks.Resize(args.Length(), 0xffffffff);
|
best_ranks.Resize(args.Length(), 0xffffffff);
|
||||||
|
@ -1669,7 +1669,7 @@ Impl::Candidate Impl::ResolveCandidate(Impl::Candidates&& candidates,
|
||||||
bool some_won = false; // An argument ranked less than the 'best' overload's argument
|
bool some_won = false; // An argument ranked less than the 'best' overload's argument
|
||||||
bool some_lost = false; // An argument ranked more than the 'best' overload's argument
|
bool some_lost = false; // An argument ranked more than the 'best' overload's argument
|
||||||
for (size_t i = 0; i < args.Length(); i++) {
|
for (size_t i = 0; i < args.Length(); i++) {
|
||||||
auto rank = sem::Type::ConversionRank(args[i], candidate.parameters[i].type);
|
auto rank = type::Type::ConversionRank(args[i], candidate.parameters[i].type);
|
||||||
if (best_ranks[i] > rank) {
|
if (best_ranks[i] > rank) {
|
||||||
best_ranks[i] = rank;
|
best_ranks[i] = rank;
|
||||||
some_won = true;
|
some_won = true;
|
||||||
|
@ -1808,7 +1808,7 @@ void Impl::PrintCandidates(std::ostream& ss,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* MatchState::Type(const sem::Type* ty) {
|
const type::Type* MatchState::Type(const type::Type* ty) {
|
||||||
MatcherIndex matcher_index = *matcher_indices_++;
|
MatcherIndex matcher_index = *matcher_indices_++;
|
||||||
auto* matcher = matchers.type[matcher_index];
|
auto* matcher = matchers.type[matcher_index];
|
||||||
return matcher->Match(*this, ty);
|
return matcher->Match(*this, ty);
|
||||||
|
@ -1833,7 +1833,7 @@ std::string MatchState::NumName() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Impl::ErrAmbiguousOverload(const char* intrinsic_name,
|
void Impl::ErrAmbiguousOverload(const char* intrinsic_name,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
TemplateState templates,
|
TemplateState templates,
|
||||||
utils::VectorRef<Candidate> candidates) const {
|
utils::VectorRef<Candidate> candidates) const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
|
@ -53,9 +53,9 @@ class IntrinsicTable {
|
||||||
/// UnaryOperator describes a resolved unary operator
|
/// UnaryOperator describes a resolved unary operator
|
||||||
struct UnaryOperator {
|
struct UnaryOperator {
|
||||||
/// The result type of the unary operator
|
/// The result type of the unary operator
|
||||||
const sem::Type* result = nullptr;
|
const type::Type* result = nullptr;
|
||||||
/// The type of the parameter of the unary operator
|
/// The type of the parameter of the unary operator
|
||||||
const sem::Type* parameter = nullptr;
|
const type::Type* parameter = nullptr;
|
||||||
/// The constant evaluation function
|
/// The constant evaluation function
|
||||||
ConstEval::Function const_eval_fn = nullptr;
|
ConstEval::Function const_eval_fn = nullptr;
|
||||||
};
|
};
|
||||||
|
@ -63,11 +63,11 @@ class IntrinsicTable {
|
||||||
/// BinaryOperator describes a resolved binary operator
|
/// BinaryOperator describes a resolved binary operator
|
||||||
struct BinaryOperator {
|
struct BinaryOperator {
|
||||||
/// The result type of the binary operator
|
/// The result type of the binary operator
|
||||||
const sem::Type* result = nullptr;
|
const type::Type* result = nullptr;
|
||||||
/// The type of LHS parameter of the binary operator
|
/// The type of LHS parameter of the binary operator
|
||||||
const sem::Type* lhs = nullptr;
|
const type::Type* lhs = nullptr;
|
||||||
/// The type of RHS parameter of the binary operator
|
/// The type of RHS parameter of the binary operator
|
||||||
const sem::Type* rhs = nullptr;
|
const type::Type* rhs = nullptr;
|
||||||
/// The constant evaluation function
|
/// The constant evaluation function
|
||||||
ConstEval::Function const_eval_fn = nullptr;
|
ConstEval::Function const_eval_fn = nullptr;
|
||||||
};
|
};
|
||||||
|
@ -93,7 +93,7 @@ class IntrinsicTable {
|
||||||
/// @param source the source of the builtin call
|
/// @param source the source of the builtin call
|
||||||
/// @return the semantic builtin if found, otherwise nullptr
|
/// @return the semantic builtin if found, otherwise nullptr
|
||||||
virtual Builtin Lookup(sem::BuiltinType type,
|
virtual Builtin Lookup(sem::BuiltinType type,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source) = 0;
|
const Source& source) = 0;
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ class IntrinsicTable {
|
||||||
/// @return the operator call target signature. If the operator was not found
|
/// @return the operator call target signature. If the operator was not found
|
||||||
/// UnaryOperator::result will be nullptr.
|
/// UnaryOperator::result will be nullptr.
|
||||||
virtual UnaryOperator Lookup(ast::UnaryOp op,
|
virtual UnaryOperator Lookup(ast::UnaryOp op,
|
||||||
const sem::Type* arg,
|
const type::Type* arg,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source) = 0;
|
const Source& source) = 0;
|
||||||
|
|
||||||
|
@ -131,8 +131,8 @@ class IntrinsicTable {
|
||||||
/// @return the operator call target signature. If the operator was not found
|
/// @return the operator call target signature. If the operator was not found
|
||||||
/// BinaryOperator::result will be nullptr.
|
/// BinaryOperator::result will be nullptr.
|
||||||
virtual BinaryOperator Lookup(ast::BinaryOp op,
|
virtual BinaryOperator Lookup(ast::BinaryOp op,
|
||||||
const sem::Type* lhs,
|
const type::Type* lhs,
|
||||||
const sem::Type* rhs,
|
const type::Type* rhs,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
bool is_compound) = 0;
|
bool is_compound) = 0;
|
||||||
|
@ -151,8 +151,8 @@ class IntrinsicTable {
|
||||||
/// @param source the source of the call
|
/// @param source the source of the call
|
||||||
/// @return a sem::TypeInitializer, sem::TypeConversion or nullptr if nothing matched
|
/// @return a sem::TypeInitializer, sem::TypeConversion or nullptr if nothing matched
|
||||||
virtual InitOrConv Lookup(InitConvIntrinsic type,
|
virtual InitOrConv Lookup(InitConvIntrinsic type,
|
||||||
const sem::Type* template_arg,
|
const type::Type* template_arg,
|
||||||
utils::VectorRef<const sem::Type*> args,
|
utils::VectorRef<const type::Type*> args,
|
||||||
sem::EvaluationStage earliest_eval_stage,
|
sem::EvaluationStage earliest_eval_stage,
|
||||||
const Source& source) = 0;
|
const Source& source) = 0;
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -190,14 +190,14 @@ class {{$class}} : public TypeMatcher {
|
||||||
/// @param state the MatchState
|
/// @param state the MatchState
|
||||||
/// @param type the type to match
|
/// @param type the type to match
|
||||||
/// @returns the canonicalized type on match, otherwise nullptr
|
/// @returns the canonicalized type on match, otherwise nullptr
|
||||||
const sem::Type* Match(MatchState& state,
|
const type::Type* Match(MatchState& state,
|
||||||
const sem::Type* type) const override;
|
const type::Type* type) const override;
|
||||||
/// @param state the MatchState
|
/// @param state the MatchState
|
||||||
/// @return a string representation of the matcher.
|
/// @return a string representation of the matcher.
|
||||||
std::string String(MatchState* state) const override;
|
std::string String(MatchState* state) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
const sem::Type* {{$class}}::Match(MatchState& state, const sem::Type* ty) const {
|
const type::Type* {{$class}}::Match(MatchState& state, const type::Type* ty) const {
|
||||||
{{- range .TemplateParams }}
|
{{- range .TemplateParams }}
|
||||||
{{- template "DeclareLocalTemplateParam" . }}
|
{{- template "DeclareLocalTemplateParam" . }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -245,14 +245,14 @@ class {{$class}} : public TypeMatcher {
|
||||||
/// @param state the MatchState
|
/// @param state the MatchState
|
||||||
/// @param type the type to match
|
/// @param type the type to match
|
||||||
/// @returns the canonicalized type on match, otherwise nullptr
|
/// @returns the canonicalized type on match, otherwise nullptr
|
||||||
const sem::Type* Match(MatchState& state,
|
const type::Type* Match(MatchState& state,
|
||||||
const sem::Type* type) const override;
|
const type::Type* type) const override;
|
||||||
/// @param state the MatchState
|
/// @param state the MatchState
|
||||||
/// @return a string representation of the matcher.
|
/// @return a string representation of the matcher.
|
||||||
std::string String(MatchState* state) const override;
|
std::string String(MatchState* state) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
const sem::Type* {{$class}}::Match(MatchState& state, const sem::Type* ty) const {
|
const type::Type* {{$class}}::Match(MatchState& state, const type::Type* ty) const {
|
||||||
{{- range .PrecedenceSortedTypes }}
|
{{- range .PrecedenceSortedTypes }}
|
||||||
if (match_{{.Name}}(state, ty)) {
|
if (match_{{.Name}}(state, ty)) {
|
||||||
return build_{{.Name}}(state);
|
return build_{{.Name}}(state);
|
||||||
|
@ -400,7 +400,7 @@ Matchers::~Matchers() = default;
|
||||||
{{- define "DeclareLocalTemplateParam" -}}
|
{{- define "DeclareLocalTemplateParam" -}}
|
||||||
{{- /* ------------------------------------------------------------------ */ -}}
|
{{- /* ------------------------------------------------------------------ */ -}}
|
||||||
{{- if IsTemplateTypeParam . }}
|
{{- if IsTemplateTypeParam . }}
|
||||||
const sem::Type* {{.Name}} = nullptr;
|
const type::Type* {{.Name}} = nullptr;
|
||||||
{{- else if IsTemplateNumberParam . }}
|
{{- else if IsTemplateNumberParam . }}
|
||||||
Number {{.Name}} = Number::invalid;
|
Number {{.Name}} = Number::invalid;
|
||||||
{{- else if IsTemplateEnumParam . }}
|
{{- else if IsTemplateEnumParam . }}
|
||||||
|
|
|
@ -27,9 +27,9 @@
|
||||||
#include "src/tint/sem/reference.h"
|
#include "src/tint/sem/reference.h"
|
||||||
#include "src/tint/sem/sampled_texture.h"
|
#include "src/tint/sem/sampled_texture.h"
|
||||||
#include "src/tint/sem/storage_texture.h"
|
#include "src/tint/sem/storage_texture.h"
|
||||||
#include "src/tint/sem/test_helper.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/type/test_helper.h"
|
||||||
|
|
||||||
namespace tint::resolver {
|
namespace tint::resolver {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -253,7 +253,7 @@ TEST_F(IntrinsicTableTest, MismatchPointer) {
|
||||||
|
|
||||||
TEST_F(IntrinsicTableTest, MatchArray) {
|
TEST_F(IntrinsicTableTest, MatchArray) {
|
||||||
auto* arr =
|
auto* arr =
|
||||||
create<sem::Array>(create<sem::U32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
create<sem::Array>(create<sem::U32>(), create<type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
||||||
auto* arr_ptr = create<sem::Pointer>(arr, ast::AddressSpace::kStorage, ast::Access::kReadWrite);
|
auto* arr_ptr = create<sem::Pointer>(arr, ast::AddressSpace::kStorage, ast::Access::kReadWrite);
|
||||||
auto result = table->Lookup(BuiltinType::kArrayLength, utils::Vector{arr_ptr},
|
auto result = table->Lookup(BuiltinType::kArrayLength, utils::Vector{arr_ptr},
|
||||||
sem::EvaluationStage::kConstant, Source{});
|
sem::EvaluationStage::kConstant, Source{});
|
||||||
|
@ -957,7 +957,7 @@ TEST_F(IntrinsicTableTest, MatchTypeConversion) {
|
||||||
|
|
||||||
TEST_F(IntrinsicTableTest, MismatchTypeConversion) {
|
TEST_F(IntrinsicTableTest, MismatchTypeConversion) {
|
||||||
auto* arr =
|
auto* arr =
|
||||||
create<sem::Array>(create<sem::U32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
create<sem::Array>(create<sem::U32>(), create<type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
||||||
auto* f32 = create<sem::F32>();
|
auto* f32 = create<sem::F32>();
|
||||||
auto result = table->Lookup(InitConvIntrinsic::kVec3, f32, utils::Vector{arr},
|
auto result = table->Lookup(InitConvIntrinsic::kVec3, f32, utils::Vector{arr},
|
||||||
sem::EvaluationStage::kConstant, Source{{12, 34}});
|
sem::EvaluationStage::kConstant, Source{{12, 34}});
|
||||||
|
@ -1017,7 +1017,7 @@ TEST_F(IntrinsicTableTest, MatchTypeConversion_RuntimeEval) {
|
||||||
|
|
||||||
TEST_F(IntrinsicTableTest, Err257Arguments) { // crbug.com/1323605
|
TEST_F(IntrinsicTableTest, Err257Arguments) { // crbug.com/1323605
|
||||||
auto* f32 = create<sem::F32>();
|
auto* f32 = create<sem::F32>();
|
||||||
utils::Vector<const sem::Type*, 0> arg_tys;
|
utils::Vector<const type::Type*, 0> arg_tys;
|
||||||
arg_tys.Resize(257, f32);
|
arg_tys.Resize(257, f32);
|
||||||
auto result = table->Lookup(BuiltinType::kAbs, std::move(arg_tys),
|
auto result = table->Lookup(BuiltinType::kAbs, std::move(arg_tys),
|
||||||
sem::EvaluationStage::kConstant, Source{});
|
sem::EvaluationStage::kConstant, Source{});
|
||||||
|
|
|
@ -106,14 +106,14 @@ TEST_F(ResolverIsHostShareable, Atomic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverIsHostShareable, ArraySizedOfHostShareable) {
|
TEST_F(ResolverIsHostShareable, ArraySizedOfHostShareable) {
|
||||||
auto* arr = create<sem::Array>(create<sem::I32>(), create<sem::ConstantArrayCount>(5u), 4u, 20u,
|
auto* arr = create<sem::Array>(create<sem::I32>(), create<type::ConstantArrayCount>(5u), 4u,
|
||||||
4u, 4u);
|
20u, 4u, 4u);
|
||||||
EXPECT_TRUE(r()->IsHostShareable(arr));
|
EXPECT_TRUE(r()->IsHostShareable(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverIsHostShareable, ArrayUnsizedOfHostShareable) {
|
TEST_F(ResolverIsHostShareable, ArrayUnsizedOfHostShareable) {
|
||||||
auto* arr =
|
auto* arr =
|
||||||
create<sem::Array>(create<sem::I32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
create<sem::Array>(create<sem::I32>(), create<type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
||||||
EXPECT_TRUE(r()->IsHostShareable(arr));
|
EXPECT_TRUE(r()->IsHostShareable(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,14 +89,14 @@ TEST_F(ResolverIsStorableTest, Atomic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverIsStorableTest, ArraySizedOfStorable) {
|
TEST_F(ResolverIsStorableTest, ArraySizedOfStorable) {
|
||||||
auto* arr = create<sem::Array>(create<sem::I32>(), create<sem::ConstantArrayCount>(5u), 4u, 20u,
|
auto* arr = create<sem::Array>(create<sem::I32>(), create<type::ConstantArrayCount>(5u), 4u,
|
||||||
4u, 4u);
|
20u, 4u, 4u);
|
||||||
EXPECT_TRUE(r()->IsStorable(arr));
|
EXPECT_TRUE(r()->IsStorable(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverIsStorableTest, ArrayUnsizedOfStorable) {
|
TEST_F(ResolverIsStorableTest, ArrayUnsizedOfStorable) {
|
||||||
auto* arr =
|
auto* arr =
|
||||||
create<sem::Array>(create<sem::I32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
create<sem::Array>(create<sem::I32>(), create<type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
||||||
EXPECT_TRUE(r()->IsStorable(arr));
|
EXPECT_TRUE(r()->IsStorable(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
#include "src/tint/resolver/resolver.h"
|
#include "src/tint/resolver/resolver.h"
|
||||||
#include "src/tint/resolver/resolver_test_helper.h"
|
#include "src/tint/resolver/resolver_test_helper.h"
|
||||||
#include "src/tint/sem/test_helper.h"
|
#include "src/tint/type/test_helper.h"
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class MaterializeTest : public resolver::ResolverTestWithParam<CASE> {
|
||||||
using ProgramBuilder::FriendlyName;
|
using ProgramBuilder::FriendlyName;
|
||||||
|
|
||||||
void CheckTypesAndValues(const sem::Expression* expr,
|
void CheckTypesAndValues(const sem::Expression* expr,
|
||||||
const tint::sem::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); },
|
||||||
expected_value);
|
expected_value);
|
||||||
|
@ -86,7 +86,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::Expression* expr,
|
||||||
const tint::sem::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);
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,7 @@ bool Resolver::ResolveInternal() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Type* Resolver::Type(const ast::Type* ty) {
|
type::Type* Resolver::Type(const ast::Type* ty) {
|
||||||
Mark(ty);
|
Mark(ty);
|
||||||
auto* s = Switch(
|
auto* s = Switch(
|
||||||
ty, //
|
ty, //
|
||||||
|
@ -317,7 +317,7 @@ sem::Type* Resolver::Type(const ast::Type* ty) {
|
||||||
auto* resolved = sem_.ResolvedSymbol(ty);
|
auto* resolved = sem_.ResolvedSymbol(ty);
|
||||||
return Switch(
|
return Switch(
|
||||||
resolved, //
|
resolved, //
|
||||||
[&](sem::Type* type) { return type; },
|
[&](type::Type* type) { return type; },
|
||||||
[&](sem::Variable* var) {
|
[&](sem::Variable* var) {
|
||||||
auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
|
auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
|
||||||
AddError("cannot use variable '" + name + "' as type", ty->source);
|
AddError("cannot use variable '" + name + "' as type", ty->source);
|
||||||
|
@ -330,7 +330,7 @@ sem::Type* Resolver::Type(const ast::Type* ty) {
|
||||||
AddNote("'" + name + "' declared here", func->Declaration()->source);
|
AddNote("'" + name + "' declared here", func->Declaration()->source);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
},
|
},
|
||||||
[&](Default) -> sem::Type* {
|
[&](Default) -> type::Type* {
|
||||||
if (auto* tn = ty->As<ast::TypeName>()) {
|
if (auto* tn = ty->As<ast::TypeName>()) {
|
||||||
if (IsBuiltin(tn->name)) {
|
if (IsBuiltin(tn->name)) {
|
||||||
auto name = builder_->Symbols().NameFor(tn->name);
|
auto name = builder_->Symbols().NameFor(tn->name);
|
||||||
|
@ -371,7 +371,7 @@ sem::Variable* Resolver::Variable(const ast::Variable* v, bool is_global) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Variable* Resolver::Let(const ast::Let* v, bool is_global) {
|
sem::Variable* Resolver::Let(const ast::Let* v, bool is_global) {
|
||||||
const sem::Type* ty = nullptr;
|
const type::Type* ty = nullptr;
|
||||||
|
|
||||||
// If the variable has a declared type, resolve it.
|
// If the variable has a declared type, resolve it.
|
||||||
if (v->type) {
|
if (v->type) {
|
||||||
|
@ -402,7 +402,7 @@ sem::Variable* Resolver::Let(const ast::Let* v, bool is_global) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<sem::Type*>(ty),
|
if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<type::Type*>(ty),
|
||||||
v->source)) {
|
v->source)) {
|
||||||
AddNote("while instantiating 'let' " + builder_->Symbols().NameFor(v->symbol), v->source);
|
AddNote("while instantiating 'let' " + builder_->Symbols().NameFor(v->symbol), v->source);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -427,7 +427,7 @@ sem::Variable* Resolver::Let(const ast::Let* v, bool is_global) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Variable* Resolver::Override(const ast::Override* v) {
|
sem::Variable* Resolver::Override(const ast::Override* v) {
|
||||||
const sem::Type* ty = nullptr;
|
const type::Type* ty = nullptr;
|
||||||
|
|
||||||
// If the variable has a declared type, resolve it.
|
// If the variable has a declared type, resolve it.
|
||||||
if (v->type) {
|
if (v->type) {
|
||||||
|
@ -461,7 +461,7 @@ sem::Variable* Resolver::Override(const ast::Override* v) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<sem::Type*>(ty),
|
if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<type::Type*>(ty),
|
||||||
v->source)) {
|
v->source)) {
|
||||||
AddNote("while instantiating 'override' " + builder_->Symbols().NameFor(v->symbol),
|
AddNote("while instantiating 'override' " + builder_->Symbols().NameFor(v->symbol),
|
||||||
v->source);
|
v->source);
|
||||||
|
@ -511,7 +511,7 @@ sem::Variable* Resolver::Override(const ast::Override* v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Variable* Resolver::Const(const ast::Const* c, bool is_global) {
|
sem::Variable* Resolver::Const(const ast::Const* c, bool is_global) {
|
||||||
const sem::Type* ty = nullptr;
|
const type::Type* ty = nullptr;
|
||||||
|
|
||||||
// If the variable has a declared type, resolve it.
|
// If the variable has a declared type, resolve it.
|
||||||
if (c->type) {
|
if (c->type) {
|
||||||
|
@ -551,7 +551,7 @@ sem::Variable* Resolver::Const(const ast::Const* c, bool is_global) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<sem::Type*>(ty),
|
if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<type::Type*>(ty),
|
||||||
c->source)) {
|
c->source)) {
|
||||||
AddNote("while instantiating 'const' " + builder_->Symbols().NameFor(c->symbol), c->source);
|
AddNote("while instantiating 'const' " + builder_->Symbols().NameFor(c->symbol), c->source);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -571,7 +571,7 @@ sem::Variable* Resolver::Const(const ast::Const* c, bool is_global) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Variable* Resolver::Var(const ast::Var* var, bool is_global) {
|
sem::Variable* Resolver::Var(const ast::Var* var, bool is_global) {
|
||||||
const sem::Type* storage_ty = nullptr;
|
const type::Type* storage_ty = nullptr;
|
||||||
|
|
||||||
// If the variable has a declared type, resolve it.
|
// If the variable has a declared type, resolve it.
|
||||||
if (auto* ty = var->type) {
|
if (auto* ty = var->type) {
|
||||||
|
@ -738,7 +738,7 @@ sem::Parameter* Resolver::Parameter(const ast::Parameter* param, uint32_t index)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Type* ty = Type(param->type);
|
type::Type* ty = Type(param->type);
|
||||||
if (!ty) {
|
if (!ty) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -752,7 +752,7 @@ sem::Parameter* Resolver::Parameter(const ast::Parameter* param, uint32_t index)
|
||||||
// For MSL, we push module-scope variables into the entry point as pointer
|
// For MSL, we push module-scope variables into the entry point as pointer
|
||||||
// parameters, so we also need to handle their store type.
|
// parameters, so we also need to handle their store type.
|
||||||
if (!ApplyAddressSpaceUsageToType(
|
if (!ApplyAddressSpaceUsageToType(
|
||||||
ptr->AddressSpace(), const_cast<sem::Type*>(ptr->StoreType()), param->source)) {
|
ptr->AddressSpace(), const_cast<type::Type*>(ptr->StoreType()), param->source)) {
|
||||||
add_note();
|
add_note();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -887,10 +887,18 @@ bool Resolver::AllocateOverridableConstantIds() {
|
||||||
|
|
||||||
void Resolver::SetShadows() {
|
void Resolver::SetShadows() {
|
||||||
for (auto it : dependencies_.shadows) {
|
for (auto it : dependencies_.shadows) {
|
||||||
|
CastableBase* b = sem_.Get(it.value);
|
||||||
|
if (!b) {
|
||||||
|
TINT_ICE(Resolver, builder_->Diagnostics())
|
||||||
|
<< "AST node '" << it.value->TypeInfo().name << "' had no semantic info\n"
|
||||||
|
<< "At: " << it.value->source << "\n"
|
||||||
|
<< "Pointer: " << it.value;
|
||||||
|
}
|
||||||
|
|
||||||
Switch(
|
Switch(
|
||||||
sem_.Get(it.key), //
|
sem_.Get(it.key), //
|
||||||
[&](sem::LocalVariable* local) { local->SetShadows(sem_.Get(it.value)); },
|
[&](sem::LocalVariable* local) { local->SetShadows(b); },
|
||||||
[&](sem::Parameter* param) { param->SetShadows(sem_.Get(it.value)); });
|
[&](sem::Parameter* param) { param->SetShadows(b); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,7 +992,7 @@ sem::Function* Resolver::Function(const ast::Function* decl) {
|
||||||
|
|
||||||
parameters.Push(p);
|
parameters.Push(p);
|
||||||
|
|
||||||
auto* p_ty = const_cast<sem::Type*>(p->Type());
|
auto* p_ty = const_cast<type::Type*>(p->Type());
|
||||||
if (auto* str = p_ty->As<sem::Struct>()) {
|
if (auto* str = p_ty->As<sem::Struct>()) {
|
||||||
switch (decl->PipelineStage()) {
|
switch (decl->PipelineStage()) {
|
||||||
case ast::PipelineStage::kVertex:
|
case ast::PipelineStage::kVertex:
|
||||||
|
@ -1003,7 +1011,7 @@ sem::Function* Resolver::Function(const ast::Function* decl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the return type
|
// Resolve the return type
|
||||||
sem::Type* return_type = nullptr;
|
type::Type* return_type = nullptr;
|
||||||
if (auto* ty = decl->return_type) {
|
if (auto* ty = decl->return_type) {
|
||||||
return_type = Type(ty);
|
return_type = Type(ty);
|
||||||
if (!return_type) {
|
if (!return_type) {
|
||||||
|
@ -1129,7 +1137,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::Expression*, 3> args;
|
||||||
utils::Vector<const sem::Type*, 3> arg_tys;
|
utils::Vector<const type::Type*, 3> arg_tys;
|
||||||
|
|
||||||
constexpr const char* kErrBadExpr =
|
constexpr const char* kErrBadExpr =
|
||||||
"workgroup_size argument must be a constant or override-expression of type "
|
"workgroup_size argument must be a constant or override-expression of type "
|
||||||
|
@ -1162,7 +1170,7 @@ bool Resolver::WorkgroupSize(const ast::Function* func) {
|
||||||
arg_tys.Push(ty);
|
arg_tys.Push(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* common_ty = sem::Type::Common(arg_tys);
|
auto* common_ty = type::Type::Common(arg_tys);
|
||||||
if (!common_ty) {
|
if (!common_ty) {
|
||||||
AddError("workgroup_size arguments must be of the same type, either i32 or u32",
|
AddError("workgroup_size arguments must be of the same type, either i32 or u32",
|
||||||
attr->source);
|
attr->source);
|
||||||
|
@ -1266,7 +1274,7 @@ sem::Statement* Resolver::Statement(const ast::Statement* stmt) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::CaseStatement* Resolver::CaseStatement(const ast::CaseStatement* stmt, const sem::Type* ty) {
|
sem::CaseStatement* Resolver::CaseStatement(const ast::CaseStatement* stmt, const type::Type* ty) {
|
||||||
auto* sem =
|
auto* sem =
|
||||||
builder_->create<sem::CaseStatement>(stmt, current_compound_statement_, current_function_);
|
builder_->create<sem::CaseStatement>(stmt, current_compound_statement_, current_function_);
|
||||||
return StatementScope(stmt, sem, [&] {
|
return StatementScope(stmt, sem, [&] {
|
||||||
|
@ -1705,9 +1713,9 @@ bool Resolver::AliasAnalysis(const sem::Call* call) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* Resolver::ConcreteType(const sem::Type* ty,
|
const type::Type* Resolver::ConcreteType(const type::Type* ty,
|
||||||
const sem::Type* target_ty,
|
const type::Type* target_ty,
|
||||||
const Source& source) {
|
const Source& source) {
|
||||||
auto i32 = [&] { return builder_->create<sem::I32>(); };
|
auto i32 = [&] { return builder_->create<sem::I32>(); };
|
||||||
auto f32 = [&] { return builder_->create<sem::F32>(); };
|
auto f32 = [&] { return builder_->create<sem::F32>(); };
|
||||||
auto i32v = [&](uint32_t width) { return builder_->create<sem::Vector>(i32(), width); };
|
auto i32v = [&](uint32_t width) { return builder_->create<sem::Vector>(i32(), width); };
|
||||||
|
@ -1734,8 +1742,8 @@ const sem::Type* Resolver::ConcreteType(const sem::Type* ty,
|
||||||
return target_ty ? target_ty : f32m(m->columns(), m->rows());
|
return target_ty ? target_ty : f32m(m->columns(), m->rows());
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[&](const sem::Array* a) -> const sem::Type* {
|
[&](const sem::Array* a) -> const type::Type* {
|
||||||
const sem::Type* target_el_ty = nullptr;
|
const type::Type* target_el_ty = nullptr;
|
||||||
if (auto* target_arr_ty = As<sem::Array>(target_ty)) {
|
if (auto* target_arr_ty = As<sem::Array>(target_ty)) {
|
||||||
target_el_ty = target_arr_ty->ElemType();
|
target_el_ty = target_arr_ty->ElemType();
|
||||||
}
|
}
|
||||||
|
@ -1744,7 +1752,7 @@ const sem::Type* Resolver::ConcreteType(const sem::Type* ty,
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
},
|
},
|
||||||
[&](const sem::Struct* s) -> const sem::Type* {
|
[&](const sem::Struct* s) -> const type::Type* {
|
||||||
if (auto tys = s->ConcreteTypes(); !tys.IsEmpty()) {
|
if (auto tys = s->ConcreteTypes(); !tys.IsEmpty()) {
|
||||||
return target_ty ? target_ty : tys[0];
|
return target_ty ? target_ty : tys[0];
|
||||||
}
|
}
|
||||||
|
@ -1753,7 +1761,7 @@ const sem::Type* Resolver::ConcreteType(const sem::Type* ty,
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Expression* Resolver::Materialize(const sem::Expression* expr,
|
const sem::Expression* Resolver::Materialize(const sem::Expression* expr,
|
||||||
const sem::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;
|
||||||
|
@ -1813,12 +1821,12 @@ bool Resolver::MaybeMaterializeArguments(utils::Vector<const sem::Expression*, N
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resolver::ShouldMaterializeArgument(const sem::Type* parameter_ty) const {
|
bool Resolver::ShouldMaterializeArgument(const type::Type* parameter_ty) const {
|
||||||
const auto* param_el_ty = sem::Type::DeepestElementOf(parameter_ty);
|
const auto* param_el_ty = type::Type::DeepestElementOf(parameter_ty);
|
||||||
return param_el_ty && !param_el_ty->Is<sem::AbstractNumeric>();
|
return param_el_ty && !param_el_ty->Is<sem::AbstractNumeric>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resolver::Convert(const sem::Constant*& c, const sem::Type* target_ty, const Source& source) {
|
bool Resolver::Convert(const sem::Constant*& c, const type::Type* target_ty, const Source& source) {
|
||||||
auto r = const_eval_.Convert(target_ty, c, source);
|
auto r = const_eval_.Convert(target_ty, c, source);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1963,7 +1971,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
|
|
||||||
// ct_init_or_conv is a helper for building either a sem::TypeInitializer or
|
// ct_init_or_conv is a helper for building either a sem::TypeInitializer or
|
||||||
// sem::TypeConversion call for a InitConvIntrinsic with an optional template argument type.
|
// sem::TypeConversion call for a InitConvIntrinsic with an optional template argument type.
|
||||||
auto ct_init_or_conv = [&](InitConvIntrinsic ty, const sem::Type* template_arg) -> sem::Call* {
|
auto ct_init_or_conv = [&](InitConvIntrinsic ty, const type::Type* template_arg) -> sem::Call* {
|
||||||
auto arg_tys = utils::Transform(args, [](auto* arg) { return arg->Type(); });
|
auto arg_tys = utils::Transform(args, [](auto* arg) { return arg->Type(); });
|
||||||
auto ctor_or_conv =
|
auto ctor_or_conv =
|
||||||
intrinsic_table_->Lookup(ty, template_arg, arg_tys, args_stage, expr->source);
|
intrinsic_table_->Lookup(ty, template_arg, arg_tys, args_stage, expr->source);
|
||||||
|
@ -1993,7 +2001,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
|
|
||||||
// arr_or_str_init is a helper for building a sem::TypeInitializer for an array or structure
|
// arr_or_str_init is a helper for building a sem::TypeInitializer for an array or structure
|
||||||
// initializer call target.
|
// initializer call target.
|
||||||
auto arr_or_str_init = [&](const sem::Type* ty,
|
auto arr_or_str_init = [&](const type::Type* ty,
|
||||||
const sem::CallTarget* call_target) -> sem::Call* {
|
const sem::CallTarget* call_target) -> sem::Call* {
|
||||||
if (!MaybeMaterializeArguments(args, call_target)) {
|
if (!MaybeMaterializeArguments(args, call_target)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -2023,7 +2031,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
|
|
||||||
// ty_init_or_conv is a helper for building either a sem::TypeInitializer or
|
// ty_init_or_conv is a helper for building either a sem::TypeInitializer or
|
||||||
// sem::TypeConversion call for the given semantic type.
|
// sem::TypeConversion call for the given semantic type.
|
||||||
auto ty_init_or_conv = [&](const sem::Type* ty) {
|
auto ty_init_or_conv = [&](const type::Type* ty) {
|
||||||
return Switch(
|
return Switch(
|
||||||
ty, //
|
ty, //
|
||||||
[&](const sem::Vector* v) {
|
[&](const sem::Vector* v) {
|
||||||
|
@ -2110,7 +2118,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
[&](const ast::Vector* v) -> sem::Call* {
|
[&](const ast::Vector* v) -> sem::Call* {
|
||||||
Mark(v);
|
Mark(v);
|
||||||
// vector element type must be inferred if it was not specified.
|
// vector element type must be inferred if it was not specified.
|
||||||
sem::Type* template_arg = nullptr;
|
type::Type* template_arg = nullptr;
|
||||||
if (v->type) {
|
if (v->type) {
|
||||||
template_arg = Type(v->type);
|
template_arg = Type(v->type);
|
||||||
if (!template_arg) {
|
if (!template_arg) {
|
||||||
|
@ -2126,7 +2134,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
[&](const ast::Matrix* m) -> sem::Call* {
|
[&](const ast::Matrix* m) -> sem::Call* {
|
||||||
Mark(m);
|
Mark(m);
|
||||||
// matrix element type must be inferred if it was not specified.
|
// matrix element type must be inferred if it was not specified.
|
||||||
sem::Type* template_arg = nullptr;
|
type::Type* template_arg = nullptr;
|
||||||
if (m->type) {
|
if (m->type) {
|
||||||
template_arg = Type(m->type);
|
template_arg = Type(m->type);
|
||||||
if (!template_arg) {
|
if (!template_arg) {
|
||||||
|
@ -2143,8 +2151,8 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
[&](const ast::Array* a) -> sem::Call* {
|
[&](const ast::Array* a) -> sem::Call* {
|
||||||
Mark(a);
|
Mark(a);
|
||||||
// array element type must be inferred if it was not specified.
|
// array element type must be inferred if it was not specified.
|
||||||
const sem::ArrayCount* el_count = nullptr;
|
const type::ArrayCount* el_count = nullptr;
|
||||||
const sem::Type* el_ty = nullptr;
|
const type::Type* el_ty = nullptr;
|
||||||
if (a->type) {
|
if (a->type) {
|
||||||
el_ty = Type(a->type);
|
el_ty = Type(a->type);
|
||||||
if (!el_ty) {
|
if (!el_ty) {
|
||||||
|
@ -2161,16 +2169,16 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
// Note: validation later will detect any mismatches between explicit array
|
// Note: validation later will detect any mismatches between explicit array
|
||||||
// size and number of initializer expressions.
|
// size and number of initializer expressions.
|
||||||
} else {
|
} else {
|
||||||
el_count = builder_->create<sem::ConstantArrayCount>(
|
el_count = builder_->create<type::ConstantArrayCount>(
|
||||||
static_cast<uint32_t>(args.Length()));
|
static_cast<uint32_t>(args.Length()));
|
||||||
auto arg_tys =
|
auto arg_tys =
|
||||||
utils::Transform(args, [](auto* arg) { return arg->Type()->UnwrapRef(); });
|
utils::Transform(args, [](auto* arg) { return arg->Type()->UnwrapRef(); });
|
||||||
el_ty = sem::Type::Common(arg_tys);
|
el_ty = type::Type::Common(arg_tys);
|
||||||
if (!el_ty) {
|
if (!el_ty) {
|
||||||
AddError(
|
AddError(
|
||||||
"cannot infer common array element type from initializer arguments",
|
"cannot infer common array element type from initializer arguments",
|
||||||
expr->source);
|
expr->source);
|
||||||
utils::Hashset<const sem::Type*, 8> types;
|
utils::Hashset<const type::Type*, 8> types;
|
||||||
for (size_t i = 0; i < args.Length(); i++) {
|
for (size_t i = 0; i < args.Length(); i++) {
|
||||||
if (types.Add(args[i]->Type())) {
|
if (types.Add(args[i]->Type())) {
|
||||||
AddNote("argument " + std::to_string(i) + " is of type '" +
|
AddNote("argument " + std::to_string(i) + " is of type '" +
|
||||||
|
@ -2216,16 +2224,17 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
||||||
// conversion.
|
// conversion.
|
||||||
auto* ident = expr->target.name;
|
auto* ident = expr->target.name;
|
||||||
Mark(ident);
|
Mark(ident);
|
||||||
auto* resolved = sem_.ResolvedSymbol(ident);
|
if (auto* resolved = sem_.ResolvedSymbol<type::Type>(ident)) {
|
||||||
|
// A type initializer or conversions.
|
||||||
|
// Note: Unlike the code path where we're resolving the call target from an
|
||||||
|
// ast::Type, all types must already have the element type explicitly specified,
|
||||||
|
// so there's no need to infer element types.
|
||||||
|
return ty_init_or_conv(resolved);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* resolved = sem_.ResolvedSymbol<sem::Node>(ident);
|
||||||
call = Switch<sem::Call*>(
|
call = Switch<sem::Call*>(
|
||||||
resolved, //
|
resolved, //
|
||||||
[&](sem::Type* ty) {
|
|
||||||
// A type initializer or conversions.
|
|
||||||
// Note: Unlike the code path where we're resolving the call target from an
|
|
||||||
// ast::Type, all types must already have the element type explicitly specified,
|
|
||||||
// so there's no need to infer element types.
|
|
||||||
return ty_init_or_conv(ty);
|
|
||||||
},
|
|
||||||
[&](sem::Function* func) { return FunctionCall(expr, func, args, arg_behaviors); },
|
[&](sem::Function* func) { return FunctionCall(expr, func, args, arg_behaviors); },
|
||||||
[&](sem::Variable* var) {
|
[&](sem::Variable* var) {
|
||||||
auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
|
auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
|
||||||
|
@ -2337,7 +2346,7 @@ sem::Call* Resolver::BuiltinCall(const ast::CallExpression* expr,
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Type* Resolver::BuiltinTypeAlias(Symbol sym) const {
|
type::Type* Resolver::BuiltinTypeAlias(Symbol sym) const {
|
||||||
auto name = builder_->Symbols().NameFor(sym);
|
auto name = builder_->Symbols().NameFor(sym);
|
||||||
auto& b = *builder_;
|
auto& b = *builder_;
|
||||||
switch (ParseTypeAlias(name)) {
|
switch (ParseTypeAlias(name)) {
|
||||||
|
@ -2471,7 +2480,7 @@ void Resolver::CollectTextureSamplerPairs(sem::Function* func,
|
||||||
sem::Expression* Resolver::Literal(const ast::LiteralExpression* literal) {
|
sem::Expression* Resolver::Literal(const ast::LiteralExpression* literal) {
|
||||||
auto* ty = Switch(
|
auto* ty = Switch(
|
||||||
literal,
|
literal,
|
||||||
[&](const ast::IntLiteralExpression* i) -> sem::Type* {
|
[&](const ast::IntLiteralExpression* i) -> type::Type* {
|
||||||
switch (i->suffix) {
|
switch (i->suffix) {
|
||||||
case ast::IntLiteralExpression::Suffix::kNone:
|
case ast::IntLiteralExpression::Suffix::kNone:
|
||||||
return builder_->create<sem::AbstractInt>();
|
return builder_->create<sem::AbstractInt>();
|
||||||
|
@ -2482,7 +2491,7 @@ sem::Expression* Resolver::Literal(const ast::LiteralExpression* literal) {
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
},
|
},
|
||||||
[&](const ast::FloatLiteralExpression* f) -> sem::Type* {
|
[&](const ast::FloatLiteralExpression* f) -> type::Type* {
|
||||||
switch (f->suffix) {
|
switch (f->suffix) {
|
||||||
case ast::FloatLiteralExpression::Suffix::kNone:
|
case ast::FloatLiteralExpression::Suffix::kNone:
|
||||||
return builder_->create<sem::AbstractFloat>();
|
return builder_->create<sem::AbstractFloat>();
|
||||||
|
@ -2520,8 +2529,8 @@ sem::Expression* Resolver::Literal(const ast::LiteralExpression* literal) {
|
||||||
|
|
||||||
sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
|
sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
|
||||||
auto symbol = expr->symbol;
|
auto symbol = expr->symbol;
|
||||||
auto* resolved = sem_.ResolvedSymbol(expr);
|
auto* sem_resolved = sem_.ResolvedSymbol<sem::Node>(expr);
|
||||||
if (auto* variable = As<sem::Variable>(resolved)) {
|
if (auto* variable = As<sem::Variable>(sem_resolved)) {
|
||||||
auto* user = builder_->create<sem::VariableUser>(expr, current_statement_, variable);
|
auto* user = builder_->create<sem::VariableUser>(expr, current_statement_, variable);
|
||||||
|
|
||||||
if (current_statement_) {
|
if (current_statement_) {
|
||||||
|
@ -2589,7 +2598,7 @@ sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Is<sem::Function>(resolved)) {
|
if (Is<sem::Function>(sem_resolved)) {
|
||||||
AddError("missing '(' for function call", expr->source.End());
|
AddError("missing '(' for function call", expr->source.End());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -2599,14 +2608,14 @@ sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolved->Is<sem::Type>() || BuiltinTypeAlias(symbol)) {
|
if (sem_.ResolvedSymbol<type::Type>(expr)) {
|
||||||
AddError("missing '(' for type initializer or cast", expr->source.End());
|
AddError("missing '(' for type initializer or cast", expr->source.End());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TINT_ICE(Resolver, diagnostics_)
|
TINT_ICE(Resolver, diagnostics_)
|
||||||
<< expr->source << " unresolved identifier:\n"
|
<< expr->source << " unresolved identifier:\n"
|
||||||
<< "resolved: " << (resolved ? resolved->TypeInfo().name : "<null>") << "\n"
|
<< "resolved: " << (sem_resolved ? sem_resolved->TypeInfo().name : "<null>") << "\n"
|
||||||
<< "name: " << builder_->Symbols().NameFor(symbol);
|
<< "name: " << builder_->Symbols().NameFor(symbol);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -2617,7 +2626,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
||||||
auto* object = sem_.Get(expr->structure);
|
auto* object = sem_.Get(expr->structure);
|
||||||
auto* root_ident = object->RootIdentifier();
|
auto* root_ident = object->RootIdentifier();
|
||||||
|
|
||||||
const sem::Type* ty = nullptr;
|
const type::Type* ty = nullptr;
|
||||||
|
|
||||||
// Object may be a side-effecting expression (e.g. function call).
|
// Object may be a side-effecting expression (e.g. function call).
|
||||||
bool has_side_effects = object && object->HasSideEffects();
|
bool has_side_effects = object && object->HasSideEffects();
|
||||||
|
@ -2812,7 +2821,7 @@ sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* ty = nullptr;
|
const type::Type* ty = nullptr;
|
||||||
const sem::Variable* root_ident = nullptr;
|
const sem::Variable* root_ident = nullptr;
|
||||||
const sem::Constant* value = nullptr;
|
const sem::Constant* value = nullptr;
|
||||||
auto stage = sem::EvaluationStage::kRuntime;
|
auto stage = sem::EvaluationStage::kRuntime;
|
||||||
|
@ -2898,8 +2907,8 @@ bool Resolver::Enable(const ast::Enable* enable) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Type* Resolver::TypeDecl(const ast::TypeDecl* named_type) {
|
type::Type* Resolver::TypeDecl(const ast::TypeDecl* named_type) {
|
||||||
sem::Type* result = nullptr;
|
type::Type* result = nullptr;
|
||||||
if (auto* alias = named_type->As<ast::Alias>()) {
|
if (auto* alias = named_type->As<ast::Alias>()) {
|
||||||
result = Alias(alias);
|
result = Alias(alias);
|
||||||
} else if (auto* str = named_type->As<ast::Struct>()) {
|
} else if (auto* str = named_type->As<ast::Struct>()) {
|
||||||
|
@ -2936,7 +2945,7 @@ sem::Array* Resolver::Array(const ast::Array* arr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::ArrayCount* el_count = nullptr;
|
const type::ArrayCount* el_count = nullptr;
|
||||||
|
|
||||||
// Evaluate the constant array count expression.
|
// Evaluate the constant array count expression.
|
||||||
if (auto* count_expr = arr->count) {
|
if (auto* count_expr = arr->count) {
|
||||||
|
@ -2945,7 +2954,7 @@ sem::Array* Resolver::Array(const ast::Array* arr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
el_count = builder_->create<sem::RuntimeArrayCount>();
|
el_count = builder_->create<type::RuntimeArrayCount>();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* out = Array(arr->type->source, //
|
auto* out = Array(arr->type->source, //
|
||||||
|
@ -2972,7 +2981,7 @@ sem::Array* Resolver::Array(const ast::Array* arr) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::ArrayCount* Resolver::ArrayCount(const ast::Expression* count_expr) {
|
const type::ArrayCount* Resolver::ArrayCount(const ast::Expression* count_expr) {
|
||||||
// Evaluate the constant array count expression.
|
// Evaluate the constant array count expression.
|
||||||
const auto* count_sem = Materialize(Expression(count_expr));
|
const auto* count_sem = Materialize(Expression(count_expr));
|
||||||
if (!count_sem) {
|
if (!count_sem) {
|
||||||
|
@ -3011,11 +3020,11 @@ const sem::ArrayCount* Resolver::ArrayCount(const ast::Expression* count_expr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder_->create<sem::ConstantArrayCount>(static_cast<uint32_t>(count));
|
return builder_->create<type::ConstantArrayCount>(static_cast<uint32_t>(count));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resolver::ArrayAttributes(utils::VectorRef<const ast::Attribute*> attributes,
|
bool Resolver::ArrayAttributes(utils::VectorRef<const ast::Attribute*> attributes,
|
||||||
const sem::Type* el_ty,
|
const type::Type* el_ty,
|
||||||
uint32_t& explicit_stride) {
|
uint32_t& explicit_stride) {
|
||||||
if (!validator_.NoDuplicateAttributes(attributes)) {
|
if (!validator_.NoDuplicateAttributes(attributes)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -3046,8 +3055,8 @@ bool Resolver::ArrayAttributes(utils::VectorRef<const ast::Attribute*> attribute
|
||||||
|
|
||||||
sem::Array* Resolver::Array(const Source& el_source,
|
sem::Array* Resolver::Array(const Source& el_source,
|
||||||
const Source& count_source,
|
const Source& count_source,
|
||||||
const sem::Type* el_ty,
|
const type::Type* el_ty,
|
||||||
const sem::ArrayCount* el_count,
|
const type::ArrayCount* el_count,
|
||||||
uint32_t explicit_stride) {
|
uint32_t explicit_stride) {
|
||||||
uint32_t el_align = el_ty->Align();
|
uint32_t el_align = el_ty->Align();
|
||||||
uint32_t el_size = el_ty->Size();
|
uint32_t el_size = el_ty->Size();
|
||||||
|
@ -3055,7 +3064,7 @@ sem::Array* Resolver::Array(const Source& el_source,
|
||||||
uint64_t stride = explicit_stride ? explicit_stride : implicit_stride;
|
uint64_t stride = explicit_stride ? explicit_stride : implicit_stride;
|
||||||
uint64_t size = 0;
|
uint64_t size = 0;
|
||||||
|
|
||||||
if (auto const_count = el_count->As<sem::ConstantArrayCount>()) {
|
if (auto const_count = el_count->As<type::ConstantArrayCount>()) {
|
||||||
size = const_count->value * stride;
|
size = const_count->value * stride;
|
||||||
if (size > std::numeric_limits<uint32_t>::max()) {
|
if (size > std::numeric_limits<uint32_t>::max()) {
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
|
@ -3064,7 +3073,7 @@ sem::Array* Resolver::Array(const Source& el_source,
|
||||||
AddError(msg.str(), count_source);
|
AddError(msg.str(), count_source);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else if (el_count->Is<sem::RuntimeArrayCount>()) {
|
} else if (el_count->Is<type::RuntimeArrayCount>()) {
|
||||||
size = stride;
|
size = stride;
|
||||||
}
|
}
|
||||||
auto* out = builder_->create<sem::Array>(el_ty, el_count, el_align, static_cast<uint32_t>(size),
|
auto* out = builder_->create<sem::Array>(el_ty, el_count, el_align, static_cast<uint32_t>(size),
|
||||||
|
@ -3078,7 +3087,7 @@ sem::Array* Resolver::Array(const Source& el_source,
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Type* Resolver::Alias(const ast::Alias* alias) {
|
type::Type* Resolver::Alias(const ast::Alias* alias) {
|
||||||
auto* ty = Type(alias->type);
|
auto* ty = Type(alias->type);
|
||||||
if (!ty) {
|
if (!ty) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -3329,7 +3338,7 @@ sem::Statement* Resolver::ReturnStatement(const ast::ReturnStatement* stmt) {
|
||||||
auto& behaviors = current_statement_->Behaviors();
|
auto& behaviors = current_statement_->Behaviors();
|
||||||
behaviors = sem::Behavior::kReturn;
|
behaviors = sem::Behavior::kReturn;
|
||||||
|
|
||||||
const sem::Type* value_ty = nullptr;
|
const type::Type* value_ty = nullptr;
|
||||||
if (auto* value = stmt->value) {
|
if (auto* value = stmt->value) {
|
||||||
const auto* expr = Expression(value);
|
const auto* expr = Expression(value);
|
||||||
if (!expr) {
|
if (!expr) {
|
||||||
|
@ -3374,7 +3383,7 @@ sem::SwitchStatement* Resolver::SwitchStatement(const ast::SwitchStatement* stmt
|
||||||
|
|
||||||
// Determine the common type across all selectors and the switch expression
|
// Determine the common type across all selectors and the switch expression
|
||||||
// This must materialize to an integer scalar (non-abstract).
|
// This must materialize to an integer scalar (non-abstract).
|
||||||
utils::Vector<const sem::Type*, 8> types;
|
utils::Vector<const type::Type*, 8> types;
|
||||||
types.Push(cond_ty);
|
types.Push(cond_ty);
|
||||||
for (auto* case_stmt : stmt->body) {
|
for (auto* case_stmt : stmt->body) {
|
||||||
for (auto* sel : case_stmt->selectors) {
|
for (auto* sel : case_stmt->selectors) {
|
||||||
|
@ -3388,7 +3397,7 @@ sem::SwitchStatement* Resolver::SwitchStatement(const ast::SwitchStatement* stmt
|
||||||
types.Push(sem_expr->Type()->UnwrapRef());
|
types.Push(sem_expr->Type()->UnwrapRef());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto* common_ty = sem::Type::Common(types);
|
auto* common_ty = type::Type::Common(types);
|
||||||
if (!common_ty || !common_ty->is_integer_scalar()) {
|
if (!common_ty || !common_ty->is_integer_scalar()) {
|
||||||
// No common type found or the common type was abstract.
|
// No common type found or the common type was abstract.
|
||||||
// Pick i32 and let validation deal with any mismatches.
|
// Pick i32 and let validation deal with any mismatches.
|
||||||
|
@ -3607,9 +3616,9 @@ sem::Statement* Resolver::IncrementDecrementStatement(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resolver::ApplyAddressSpaceUsageToType(ast::AddressSpace address_space,
|
bool Resolver::ApplyAddressSpaceUsageToType(ast::AddressSpace address_space,
|
||||||
sem::Type* ty,
|
type::Type* ty,
|
||||||
const Source& usage) {
|
const Source& usage) {
|
||||||
ty = const_cast<sem::Type*>(ty->UnwrapRef());
|
ty = const_cast<type::Type*>(ty->UnwrapRef());
|
||||||
|
|
||||||
if (auto* str = ty->As<sem::Struct>()) {
|
if (auto* str = ty->As<sem::Struct>()) {
|
||||||
if (str->AddressSpaceUsage().count(address_space)) {
|
if (str->AddressSpaceUsage().count(address_space)) {
|
||||||
|
@ -3621,8 +3630,8 @@ bool Resolver::ApplyAddressSpaceUsageToType(ast::AddressSpace address_space,
|
||||||
for (auto* member : str->Members()) {
|
for (auto* member : str->Members()) {
|
||||||
auto decl = member->Declaration();
|
auto decl = member->Declaration();
|
||||||
if (decl &&
|
if (decl &&
|
||||||
!ApplyAddressSpaceUsageToType(address_space, const_cast<sem::Type*>(member->Type()),
|
!ApplyAddressSpaceUsageToType(
|
||||||
decl->type->source)) {
|
address_space, const_cast<type::Type*>(member->Type()), decl->type->source)) {
|
||||||
std::stringstream err;
|
std::stringstream err;
|
||||||
err << "while analyzing structure member " << sem_.TypeNameOf(str) << "."
|
err << "while analyzing structure member " << sem_.TypeNameOf(str) << "."
|
||||||
<< builder_->Symbols().NameFor(member->Name());
|
<< builder_->Symbols().NameFor(member->Name());
|
||||||
|
@ -3635,7 +3644,7 @@ bool Resolver::ApplyAddressSpaceUsageToType(ast::AddressSpace address_space,
|
||||||
|
|
||||||
if (auto* arr = ty->As<sem::Array>()) {
|
if (auto* arr = ty->As<sem::Array>()) {
|
||||||
if (address_space != ast::AddressSpace::kStorage) {
|
if (address_space != ast::AddressSpace::kStorage) {
|
||||||
if (arr->Count()->Is<sem::RuntimeArrayCount>()) {
|
if (arr->Count()->Is<type::RuntimeArrayCount>()) {
|
||||||
AddError("runtime-sized arrays can only be used in the <storage> address space",
|
AddError("runtime-sized arrays can only be used in the <storage> address space",
|
||||||
usage);
|
usage);
|
||||||
return false;
|
return false;
|
||||||
|
@ -3649,7 +3658,7 @@ bool Resolver::ApplyAddressSpaceUsageToType(ast::AddressSpace address_space,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ApplyAddressSpaceUsageToType(address_space, const_cast<sem::Type*>(arr->ElemType()),
|
return ApplyAddressSpaceUsageToType(address_space, const_cast<type::Type*>(arr->ElemType()),
|
||||||
usage);
|
usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,19 +93,21 @@ class Resolver {
|
||||||
|
|
||||||
/// @param type the given type
|
/// @param type the given type
|
||||||
/// @returns true if the given type is a plain type
|
/// @returns true if the given type is a plain type
|
||||||
bool IsPlain(const sem::Type* type) const { return validator_.IsPlain(type); }
|
bool IsPlain(const type::Type* type) const { return validator_.IsPlain(type); }
|
||||||
|
|
||||||
/// @param type the given type
|
/// @param type the given type
|
||||||
/// @returns true if the given type is a fixed-footprint type
|
/// @returns true if the given type is a fixed-footprint type
|
||||||
bool IsFixedFootprint(const sem::Type* type) const { return validator_.IsFixedFootprint(type); }
|
bool IsFixedFootprint(const type::Type* type) const {
|
||||||
|
return validator_.IsFixedFootprint(type);
|
||||||
|
}
|
||||||
|
|
||||||
/// @param type the given type
|
/// @param type the given type
|
||||||
/// @returns true if the given type is storable
|
/// @returns true if the given type is storable
|
||||||
bool IsStorable(const sem::Type* type) const { return validator_.IsStorable(type); }
|
bool IsStorable(const type::Type* type) const { return validator_.IsStorable(type); }
|
||||||
|
|
||||||
/// @param type the given type
|
/// @param type the given type
|
||||||
/// @returns true if the given type is host-shareable
|
/// @returns true if the given type is host-shareable
|
||||||
bool IsHostShareable(const sem::Type* type) const { return validator_.IsHostShareable(type); }
|
bool IsHostShareable(const type::Type* type) const { return validator_.IsHostShareable(type); }
|
||||||
|
|
||||||
/// @returns the validator for testing
|
/// @returns the validator for testing
|
||||||
const Validator* GetValidatorForTesting() const { return &validator_; }
|
const Validator* GetValidatorForTesting() const { return &validator_; }
|
||||||
|
@ -179,7 +181,7 @@ class Resolver {
|
||||||
/// materialized type.
|
/// materialized type.
|
||||||
/// 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::Expression* Materialize(const sem::Expression* expr,
|
||||||
const sem::Type* target_type = nullptr);
|
const type::Type* target_type = nullptr);
|
||||||
|
|
||||||
/// Materializes all the arguments in `args` to the parameter types of `target`.
|
/// Materializes all the arguments in `args` to the parameter types of `target`.
|
||||||
/// @returns true on success, false on failure.
|
/// @returns true on success, false on failure.
|
||||||
|
@ -189,11 +191,11 @@ class Resolver {
|
||||||
|
|
||||||
/// @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
|
||||||
/// `parameter_ty` should be materialized.
|
/// `parameter_ty` should be materialized.
|
||||||
bool ShouldMaterializeArgument(const sem::Type* parameter_ty) const;
|
bool ShouldMaterializeArgument(const type::Type* parameter_ty) const;
|
||||||
|
|
||||||
/// Converts `c` to `target_ty`
|
/// Converts `c` to `target_ty`
|
||||||
/// @returns true on success, false on failure.
|
/// @returns true on success, false on failure.
|
||||||
bool Convert(const sem::Constant*& c, const sem::Type* target_ty, const Source& source);
|
bool Convert(const sem::Constant*& c, const type::Type* target_ty, const Source& source);
|
||||||
|
|
||||||
/// Transforms `args` to a vector of constants, and converts each constant to the call target's
|
/// Transforms `args` to a vector of constants, and converts each constant to the call target's
|
||||||
/// parameter type.
|
/// parameter type.
|
||||||
|
@ -209,9 +211,9 @@ class Resolver {
|
||||||
/// @param source the source of the expression requiring materialization
|
/// @param source the source of the expression requiring materialization
|
||||||
/// @returns the concrete (materialized) type for the given type, or nullptr if the type is
|
/// @returns the concrete (materialized) type for the given type, or nullptr if the type is
|
||||||
/// already concrete.
|
/// already concrete.
|
||||||
const sem::Type* ConcreteType(const sem::Type* ty,
|
const type::Type* ConcreteType(const type::Type* ty,
|
||||||
const sem::Type* target_ty,
|
const type::Type* target_ty,
|
||||||
const Source& source);
|
const Source& source);
|
||||||
|
|
||||||
// Statement resolving methods
|
// Statement resolving methods
|
||||||
// Each return true on success, false on failure.
|
// Each return true on success, false on failure.
|
||||||
|
@ -220,7 +222,7 @@ class Resolver {
|
||||||
sem::Statement* BreakStatement(const ast::BreakStatement*);
|
sem::Statement* BreakStatement(const ast::BreakStatement*);
|
||||||
sem::Statement* BreakIfStatement(const ast::BreakIfStatement*);
|
sem::Statement* BreakIfStatement(const ast::BreakIfStatement*);
|
||||||
sem::Statement* CallStatement(const ast::CallStatement*);
|
sem::Statement* CallStatement(const ast::CallStatement*);
|
||||||
sem::CaseStatement* CaseStatement(const ast::CaseStatement*, const sem::Type*);
|
sem::CaseStatement* CaseStatement(const ast::CaseStatement*, const type::Type*);
|
||||||
sem::Statement* CompoundAssignmentStatement(const ast::CompoundAssignmentStatement*);
|
sem::Statement* CompoundAssignmentStatement(const ast::CompoundAssignmentStatement*);
|
||||||
sem::Statement* ContinueStatement(const ast::ContinueStatement*);
|
sem::Statement* ContinueStatement(const ast::ContinueStatement*);
|
||||||
sem::Statement* DiscardStatement(const ast::DiscardStatement*);
|
sem::Statement* DiscardStatement(const ast::DiscardStatement*);
|
||||||
|
@ -249,11 +251,11 @@ class Resolver {
|
||||||
/// current_function_
|
/// current_function_
|
||||||
bool WorkgroupSize(const ast::Function*);
|
bool WorkgroupSize(const ast::Function*);
|
||||||
|
|
||||||
/// @returns the sem::Type for the ast::Type `ty`, building it if it
|
/// @returns the type::Type for the ast::Type `ty`, building it if it
|
||||||
/// hasn't been constructed already. If an error is raised, nullptr is
|
/// hasn't been constructed already. If an error is raised, nullptr is
|
||||||
/// returned.
|
/// returned.
|
||||||
/// @param ty the ast::Type
|
/// @param ty the ast::Type
|
||||||
sem::Type* Type(const ast::Type* ty);
|
type::Type* Type(const ast::Type* ty);
|
||||||
|
|
||||||
/// @param enable the enable declaration
|
/// @param enable the enable declaration
|
||||||
/// @returns the resolved extension
|
/// @returns the resolved extension
|
||||||
|
@ -261,7 +263,7 @@ class Resolver {
|
||||||
|
|
||||||
/// @param named_type the named type to resolve
|
/// @param named_type the named type to resolve
|
||||||
/// @returns the resolved semantic type
|
/// @returns the resolved semantic type
|
||||||
sem::Type* TypeDecl(const ast::TypeDecl* named_type);
|
type::Type* TypeDecl(const ast::TypeDecl* named_type);
|
||||||
|
|
||||||
/// Builds and returns the semantic information for the AST array `arr`.
|
/// Builds and returns the semantic information for the AST array `arr`.
|
||||||
/// This method does not mark the ast::Array node, nor attach the generated semantic information
|
/// This method does not mark the ast::Array node, nor attach the generated semantic information
|
||||||
|
@ -273,7 +275,7 @@ class Resolver {
|
||||||
/// Resolves and validates the expression used as the count parameter of an array.
|
/// Resolves and validates the expression used as the count parameter of an array.
|
||||||
/// @param count_expr the expression used as the second template parameter to an array<>.
|
/// @param count_expr the expression used as the second template parameter to an array<>.
|
||||||
/// @returns the number of elements in the array.
|
/// @returns the number of elements in the array.
|
||||||
const sem::ArrayCount* ArrayCount(const ast::Expression* count_expr);
|
const type::ArrayCount* ArrayCount(const ast::Expression* count_expr);
|
||||||
|
|
||||||
/// Resolves and validates the attributes on an array.
|
/// Resolves and validates the attributes on an array.
|
||||||
/// @param attributes the attributes on the array type.
|
/// @param attributes the attributes on the array type.
|
||||||
|
@ -281,7 +283,7 @@ class Resolver {
|
||||||
/// @param explicit_stride assigned the specified stride of the array in bytes.
|
/// @param explicit_stride assigned the specified stride of the array in bytes.
|
||||||
/// @returns true on success, false on failure
|
/// @returns true on success, false on failure
|
||||||
bool ArrayAttributes(utils::VectorRef<const ast::Attribute*> attributes,
|
bool ArrayAttributes(utils::VectorRef<const ast::Attribute*> attributes,
|
||||||
const sem::Type* el_ty,
|
const type::Type* el_ty,
|
||||||
uint32_t& explicit_stride);
|
uint32_t& explicit_stride);
|
||||||
|
|
||||||
/// Builds and returns the semantic information for an array.
|
/// Builds and returns the semantic information for an array.
|
||||||
|
@ -295,15 +297,15 @@ class Resolver {
|
||||||
/// @param explicit_stride the explicit byte stride of the array. Zero means implicit stride.
|
/// @param explicit_stride the explicit byte stride of the array. Zero means implicit stride.
|
||||||
sem::Array* Array(const Source& el_source,
|
sem::Array* Array(const Source& el_source,
|
||||||
const Source& count_source,
|
const Source& count_source,
|
||||||
const sem::Type* el_ty,
|
const type::Type* el_ty,
|
||||||
const sem::ArrayCount* el_count,
|
const type::ArrayCount* el_count,
|
||||||
uint32_t explicit_stride);
|
uint32_t explicit_stride);
|
||||||
|
|
||||||
/// Builds and returns the semantic information for the alias `alias`.
|
/// Builds and returns the semantic information for the alias `alias`.
|
||||||
/// This method does not mark the ast::Alias node, nor attach the generated
|
/// This method does not mark the ast::Alias node, nor attach the generated
|
||||||
/// semantic information to the AST node.
|
/// semantic information to the AST node.
|
||||||
/// @returns the aliased type, or nullptr if an error is raised.
|
/// @returns the aliased type, or nullptr if an error is raised.
|
||||||
sem::Type* Alias(const ast::Alias* alias);
|
type::Type* Alias(const ast::Alias* alias);
|
||||||
|
|
||||||
/// Builds and returns the semantic information for the structure `str`.
|
/// Builds and returns the semantic information for the structure `str`.
|
||||||
/// This method does not mark the ast::Struct node, nor attach the generated
|
/// This method does not mark the ast::Struct node, nor attach the generated
|
||||||
|
@ -371,7 +373,7 @@ class Resolver {
|
||||||
/// given type and address space. Used for generating sensible error
|
/// given type and address space. Used for generating sensible error
|
||||||
/// messages.
|
/// messages.
|
||||||
/// @returns true on success, false on error
|
/// @returns true on success, false on error
|
||||||
bool ApplyAddressSpaceUsageToType(ast::AddressSpace sc, sem::Type* ty, const Source& usage);
|
bool ApplyAddressSpaceUsageToType(ast::AddressSpace sc, type::Type* ty, const Source& usage);
|
||||||
|
|
||||||
/// @param address_space the address space
|
/// @param address_space the address space
|
||||||
/// @returns the default access control for the given address space
|
/// @returns the default access control for the given address space
|
||||||
|
@ -417,7 +419,7 @@ class Resolver {
|
||||||
bool IsBuiltin(Symbol) const;
|
bool IsBuiltin(Symbol) const;
|
||||||
|
|
||||||
/// @returns the builtin type alias for the given symbol
|
/// @returns the builtin type alias for the given symbol
|
||||||
sem::Type* BuiltinTypeAlias(Symbol) const;
|
type::Type* BuiltinTypeAlias(Symbol) const;
|
||||||
|
|
||||||
// ArrayInitializerSig represents a unique array initializer signature.
|
// ArrayInitializerSig represents a unique array initializer signature.
|
||||||
// It is a tuple of the array type, number of arguments provided and earliest evaluation stage.
|
// It is a tuple of the array type, number of arguments provided and earliest evaluation stage.
|
||||||
|
@ -461,7 +463,7 @@ class Resolver {
|
||||||
Validator validator_;
|
Validator validator_;
|
||||||
ast::Extensions enabled_extensions_;
|
ast::Extensions enabled_extensions_;
|
||||||
utils::Vector<sem::Function*, 8> entry_points_;
|
utils::Vector<sem::Function*, 8> entry_points_;
|
||||||
utils::Hashmap<const sem::Type*, const Source*, 8> atomic_composite_info_;
|
utils::Hashmap<const type::Type*, const Source*, 8> atomic_composite_info_;
|
||||||
utils::Bitset<0> marked_;
|
utils::Bitset<0> marked_;
|
||||||
ExprEvalStageConstraint expr_eval_stage_constraint_;
|
ExprEvalStageConstraint expr_eval_stage_constraint_;
|
||||||
std::unordered_map<const sem::Function*, AliasAnalysisInfo> alias_analysis_infos_;
|
std::unordered_map<const sem::Function*, AliasAnalysisInfo> alias_analysis_infos_;
|
||||||
|
|
|
@ -440,7 +440,7 @@ TEST_F(ResolverTest, ArraySize_UnsignedLiteral) {
|
||||||
auto* ref = TypeOf(a)->As<sem::Reference>();
|
auto* ref = TypeOf(a)->As<sem::Reference>();
|
||||||
ASSERT_NE(ref, nullptr);
|
ASSERT_NE(ref, nullptr);
|
||||||
auto* ary = ref->StoreType()->As<sem::Array>();
|
auto* ary = ref->StoreType()->As<sem::Array>();
|
||||||
EXPECT_EQ(ary->Count(), create<sem::ConstantArrayCount>(10u));
|
EXPECT_EQ(ary->Count(), create<type::ConstantArrayCount>(10u));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, ArraySize_SignedLiteral) {
|
TEST_F(ResolverTest, ArraySize_SignedLiteral) {
|
||||||
|
@ -453,7 +453,7 @@ TEST_F(ResolverTest, ArraySize_SignedLiteral) {
|
||||||
auto* ref = TypeOf(a)->As<sem::Reference>();
|
auto* ref = TypeOf(a)->As<sem::Reference>();
|
||||||
ASSERT_NE(ref, nullptr);
|
ASSERT_NE(ref, nullptr);
|
||||||
auto* ary = ref->StoreType()->As<sem::Array>();
|
auto* ary = ref->StoreType()->As<sem::Array>();
|
||||||
EXPECT_EQ(ary->Count(), create<sem::ConstantArrayCount>(10u));
|
EXPECT_EQ(ary->Count(), create<type::ConstantArrayCount>(10u));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, ArraySize_UnsignedConst) {
|
TEST_F(ResolverTest, ArraySize_UnsignedConst) {
|
||||||
|
@ -468,7 +468,7 @@ TEST_F(ResolverTest, ArraySize_UnsignedConst) {
|
||||||
auto* ref = TypeOf(a)->As<sem::Reference>();
|
auto* ref = TypeOf(a)->As<sem::Reference>();
|
||||||
ASSERT_NE(ref, nullptr);
|
ASSERT_NE(ref, nullptr);
|
||||||
auto* ary = ref->StoreType()->As<sem::Array>();
|
auto* ary = ref->StoreType()->As<sem::Array>();
|
||||||
EXPECT_EQ(ary->Count(), create<sem::ConstantArrayCount>(10u));
|
EXPECT_EQ(ary->Count(), create<type::ConstantArrayCount>(10u));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, ArraySize_SignedConst) {
|
TEST_F(ResolverTest, ArraySize_SignedConst) {
|
||||||
|
@ -483,7 +483,7 @@ TEST_F(ResolverTest, ArraySize_SignedConst) {
|
||||||
auto* ref = TypeOf(a)->As<sem::Reference>();
|
auto* ref = TypeOf(a)->As<sem::Reference>();
|
||||||
ASSERT_NE(ref, nullptr);
|
ASSERT_NE(ref, nullptr);
|
||||||
auto* ary = ref->StoreType()->As<sem::Array>();
|
auto* ary = ref->StoreType()->As<sem::Array>();
|
||||||
EXPECT_EQ(ary->Count(), create<sem::ConstantArrayCount>(10u));
|
EXPECT_EQ(ary->Count(), create<type::ConstantArrayCount>(10u));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, ArraySize_NamedOverride) {
|
TEST_F(ResolverTest, ArraySize_NamedOverride) {
|
||||||
|
@ -1767,7 +1767,7 @@ TEST_P(Expr_Binary_Test_Invalid_VectorMatrixMultiply, All) {
|
||||||
|
|
||||||
const ast::Type* lhs_type = nullptr;
|
const ast::Type* lhs_type = nullptr;
|
||||||
const ast::Type* rhs_type = nullptr;
|
const ast::Type* rhs_type = nullptr;
|
||||||
const sem::Type* result_type = nullptr;
|
const type::Type* result_type = nullptr;
|
||||||
bool is_valid_expr;
|
bool is_valid_expr;
|
||||||
|
|
||||||
if (vec_by_mat) {
|
if (vec_by_mat) {
|
||||||
|
|
|
@ -114,7 +114,7 @@ class TestHelper : public ProgramBuilder {
|
||||||
/// @param type a type
|
/// @param type a type
|
||||||
/// @returns the name for `type` that closely resembles how it would be
|
/// @returns the name for `type` that closely resembles how it would be
|
||||||
/// declared in WGSL.
|
/// declared in WGSL.
|
||||||
std::string FriendlyName(const sem::Type* type) { return type->FriendlyName(Symbols()); }
|
std::string FriendlyName(const type::Type* type) { return type->FriendlyName(Symbols()); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Resolver> resolver_;
|
std::unique_ptr<Resolver> resolver_;
|
||||||
|
@ -194,7 +194,7 @@ using ast_type_func_ptr = const ast::Type* (*)(ProgramBuilder& b);
|
||||||
using ast_expr_func_ptr = const ast::Expression* (*)(ProgramBuilder& b,
|
using ast_expr_func_ptr = const ast::Expression* (*)(ProgramBuilder& b,
|
||||||
utils::VectorRef<Scalar> args);
|
utils::VectorRef<Scalar> args);
|
||||||
using ast_expr_from_double_func_ptr = const ast::Expression* (*)(ProgramBuilder& b, double v);
|
using ast_expr_from_double_func_ptr = const ast::Expression* (*)(ProgramBuilder& b, double v);
|
||||||
using sem_type_func_ptr = const sem::Type* (*)(ProgramBuilder& b);
|
using sem_type_func_ptr = const type::Type* (*)(ProgramBuilder& b);
|
||||||
using type_name_func_ptr = std::string (*)();
|
using type_name_func_ptr = std::string (*)();
|
||||||
|
|
||||||
struct UnspecializedElementType {};
|
struct UnspecializedElementType {};
|
||||||
|
@ -215,7 +215,7 @@ struct DataType<void> {
|
||||||
/// @return nullptr
|
/// @return nullptr
|
||||||
static inline const ast::Type* AST(ProgramBuilder&) { return nullptr; }
|
static inline const ast::Type* AST(ProgramBuilder&) { return nullptr; }
|
||||||
/// @return nullptr
|
/// @return nullptr
|
||||||
static inline const sem::Type* Sem(ProgramBuilder&) { return nullptr; }
|
static inline const type::Type* Sem(ProgramBuilder&) { return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Helper for building bool types and expressions
|
/// Helper for building bool types and expressions
|
||||||
|
@ -232,7 +232,7 @@ struct DataType<bool> {
|
||||||
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.bool_(); }
|
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.bool_(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic bool type
|
/// @return the semantic bool type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::Bool>(); }
|
static inline const type::Type* Sem(ProgramBuilder& b) { return b.create<sem::Bool>(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the boolean value to init with
|
/// @param args args of size 1 with the boolean value to init with
|
||||||
/// @return a new AST expression of the bool type
|
/// @return a new AST expression of the bool type
|
||||||
|
@ -263,7 +263,7 @@ struct DataType<i32> {
|
||||||
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.i32(); }
|
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.i32(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic i32 type
|
/// @return the semantic i32 type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::I32>(); }
|
static inline const type::Type* Sem(ProgramBuilder& b) { return b.create<sem::I32>(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the i32 value to init with
|
/// @param args args of size 1 with the i32 value to init with
|
||||||
/// @return a new AST i32 literal value expression
|
/// @return a new AST i32 literal value expression
|
||||||
|
@ -294,7 +294,7 @@ struct DataType<u32> {
|
||||||
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.u32(); }
|
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.u32(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic u32 type
|
/// @return the semantic u32 type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::U32>(); }
|
static inline const type::Type* Sem(ProgramBuilder& b) { return b.create<sem::U32>(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the u32 value to init with
|
/// @param args args of size 1 with the u32 value to init with
|
||||||
/// @return a new AST u32 literal value expression
|
/// @return a new AST u32 literal value expression
|
||||||
|
@ -325,7 +325,7 @@ struct DataType<f32> {
|
||||||
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.f32(); }
|
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.f32(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic f32 type
|
/// @return the semantic f32 type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::F32>(); }
|
static inline const type::Type* Sem(ProgramBuilder& b) { return b.create<sem::F32>(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the f32 value to init with
|
/// @param args args of size 1 with the f32 value to init with
|
||||||
/// @return a new AST f32 literal value expression
|
/// @return a new AST f32 literal value expression
|
||||||
|
@ -356,7 +356,7 @@ struct DataType<f16> {
|
||||||
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.f16(); }
|
static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.f16(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic f16 type
|
/// @return the semantic f16 type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::F16>(); }
|
static inline const type::Type* Sem(ProgramBuilder& b) { return b.create<sem::F16>(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the f16 value to init with
|
/// @param args args of size 1 with the f16 value to init with
|
||||||
/// @return a new AST f16 literal value expression
|
/// @return a new AST f16 literal value expression
|
||||||
|
@ -386,7 +386,9 @@ struct DataType<AFloat> {
|
||||||
static inline const ast::Type* AST(ProgramBuilder&) { return nullptr; }
|
static inline const ast::Type* AST(ProgramBuilder&) { return nullptr; }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic abstract-float type
|
/// @return the semantic abstract-float type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::AbstractFloat>(); }
|
static inline const type::Type* Sem(ProgramBuilder& b) {
|
||||||
|
return b.create<sem::AbstractFloat>();
|
||||||
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the abstract-float value to init with
|
/// @param args args of size 1 with the abstract-float value to init with
|
||||||
/// @return a new AST abstract-float literal value expression
|
/// @return a new AST abstract-float literal value expression
|
||||||
|
@ -416,7 +418,7 @@ struct DataType<AInt> {
|
||||||
static inline const ast::Type* AST(ProgramBuilder&) { return nullptr; }
|
static inline const ast::Type* AST(ProgramBuilder&) { return nullptr; }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic abstract-int type
|
/// @return the semantic abstract-int type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::AbstractInt>(); }
|
static inline const type::Type* Sem(ProgramBuilder& b) { return b.create<sem::AbstractInt>(); }
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the abstract-int value to init with
|
/// @param args args of size 1 with the abstract-int value to init with
|
||||||
/// @return a new AST abstract-int literal value expression
|
/// @return a new AST abstract-int literal value expression
|
||||||
|
@ -449,7 +451,7 @@ struct DataType<vec<N, T>> {
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic vector type
|
/// @return the semantic vector type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) {
|
static inline const type::Type* Sem(ProgramBuilder& b) {
|
||||||
return b.create<sem::Vector>(DataType<T>::Sem(b), N);
|
return b.create<sem::Vector>(DataType<T>::Sem(b), N);
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
|
@ -497,7 +499,7 @@ struct DataType<mat<N, M, T>> {
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic matrix type
|
/// @return the semantic matrix type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) {
|
static inline const type::Type* Sem(ProgramBuilder& b) {
|
||||||
auto* column_type = b.create<sem::Vector>(DataType<T>::Sem(b), M);
|
auto* column_type = b.create<sem::Vector>(DataType<T>::Sem(b), M);
|
||||||
return b.create<sem::Matrix>(column_type, N);
|
return b.create<sem::Matrix>(column_type, N);
|
||||||
}
|
}
|
||||||
|
@ -561,7 +563,7 @@ struct DataType<alias<T, ID>> {
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic aliased type
|
/// @return the semantic aliased type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) { return DataType<T>::Sem(b); }
|
static inline const type::Type* Sem(ProgramBuilder& b) { return DataType<T>::Sem(b); }
|
||||||
|
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args the value nested elements will be initialized with
|
/// @param args the value nested elements will be initialized with
|
||||||
|
@ -613,7 +615,7 @@ struct DataType<ptr<T>> {
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic aliased type
|
/// @return the semantic aliased type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) {
|
static inline const type::Type* Sem(ProgramBuilder& b) {
|
||||||
return b.create<sem::Pointer>(DataType<T>::Sem(b), ast::AddressSpace::kPrivate,
|
return b.create<sem::Pointer>(DataType<T>::Sem(b), ast::AddressSpace::kPrivate,
|
||||||
ast::Access::kReadWrite);
|
ast::Access::kReadWrite);
|
||||||
}
|
}
|
||||||
|
@ -657,13 +659,13 @@ struct DataType<array<N, T>> {
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return the semantic array type
|
/// @return the semantic array type
|
||||||
static inline const sem::Type* Sem(ProgramBuilder& b) {
|
static inline const type::Type* Sem(ProgramBuilder& b) {
|
||||||
auto* el = DataType<T>::Sem(b);
|
auto* el = DataType<T>::Sem(b);
|
||||||
const sem::ArrayCount* count = nullptr;
|
const type::ArrayCount* count = nullptr;
|
||||||
if (N == 0) {
|
if (N == 0) {
|
||||||
count = b.create<sem::RuntimeArrayCount>();
|
count = b.create<type::RuntimeArrayCount>();
|
||||||
} else {
|
} else {
|
||||||
count = b.create<sem::ConstantArrayCount>(N);
|
count = b.create<type::ConstantArrayCount>(N);
|
||||||
}
|
}
|
||||||
return b.create<sem::Array>(
|
return b.create<sem::Array>(
|
||||||
/* element */ el,
|
/* element */ el,
|
||||||
|
|
|
@ -23,17 +23,17 @@ SemHelper::SemHelper(ProgramBuilder* builder, DependencyGraph& dependencies)
|
||||||
|
|
||||||
SemHelper::~SemHelper() = default;
|
SemHelper::~SemHelper() = default;
|
||||||
|
|
||||||
std::string SemHelper::TypeNameOf(const sem::Type* ty) const {
|
std::string SemHelper::TypeNameOf(const type::Type* ty) const {
|
||||||
return RawTypeNameOf(ty->UnwrapRef());
|
return RawTypeNameOf(ty->UnwrapRef());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SemHelper::RawTypeNameOf(const sem::Type* ty) const {
|
std::string SemHelper::RawTypeNameOf(const type::Type* ty) const {
|
||||||
return ty->FriendlyName(builder_->Symbols());
|
return ty->FriendlyName(builder_->Symbols());
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Type* SemHelper::TypeOf(const ast::Expression* expr) const {
|
type::Type* SemHelper::TypeOf(const ast::Expression* expr) const {
|
||||||
auto* sem = Get(expr);
|
auto* sem = Get(expr);
|
||||||
return sem ? const_cast<sem::Type*>(sem->Type()) : nullptr;
|
return sem ? const_cast<type::Type*>(sem->Type()) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tint::resolver
|
} // namespace tint::resolver
|
||||||
|
|
|
@ -49,10 +49,10 @@ class SemHelper {
|
||||||
return const_cast<T*>(As<T>(sem));
|
return const_cast<T*>(As<T>(sem));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns the resolved symbol (function, type or variable) for the given
|
/// @returns the resolved symbol (function, type or variable) for the given ast::Identifier or
|
||||||
/// ast::Identifier or ast::TypeName cast to the given semantic type.
|
/// ast::TypeName cast to the given semantic type.
|
||||||
/// @param node the node to retrieve
|
/// @param node the node to retrieve
|
||||||
template <typename SEM = sem::Node>
|
template <typename SEM = CastableBase>
|
||||||
SEM* ResolvedSymbol(const ast::Node* node) const {
|
SEM* ResolvedSymbol(const ast::Node* node) const {
|
||||||
auto resolved = dependencies_.resolved_symbols.Find(node);
|
auto resolved = dependencies_.resolved_symbols.Find(node);
|
||||||
return resolved ? const_cast<SEM*>(builder_->Sem().Get<SEM>(*resolved)) : nullptr;
|
return resolved ? const_cast<SEM*>(builder_->Sem().Get<SEM>(*resolved)) : nullptr;
|
||||||
|
@ -60,17 +60,17 @@ class SemHelper {
|
||||||
|
|
||||||
/// @returns the resolved type of the ast::Expression `expr`
|
/// @returns the resolved type of the ast::Expression `expr`
|
||||||
/// @param expr the expression
|
/// @param expr the expression
|
||||||
sem::Type* TypeOf(const ast::Expression* expr) const;
|
type::Type* TypeOf(const ast::Expression* expr) const;
|
||||||
|
|
||||||
/// @returns the type name of the given semantic type, unwrapping
|
/// @returns the type name of the given semantic type, unwrapping
|
||||||
/// references.
|
/// references.
|
||||||
/// @param ty the type to look up
|
/// @param ty the type to look up
|
||||||
std::string TypeNameOf(const sem::Type* ty) const;
|
std::string TypeNameOf(const type::Type* ty) const;
|
||||||
|
|
||||||
/// @returns the type name of the given semantic type, without unwrapping
|
/// @returns the type name of the given semantic type, without unwrapping
|
||||||
/// references.
|
/// references.
|
||||||
/// @param ty the type to look up
|
/// @param ty the type to look up
|
||||||
std::string RawTypeNameOf(const sem::Type* ty) const;
|
std::string RawTypeNameOf(const type::Type* ty) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProgramBuilder* builder_;
|
ProgramBuilder* builder_;
|
||||||
|
|
|
@ -157,7 +157,7 @@ Validator::Validator(
|
||||||
ProgramBuilder* builder,
|
ProgramBuilder* builder,
|
||||||
SemHelper& sem,
|
SemHelper& sem,
|
||||||
const ast::Extensions& enabled_extensions,
|
const ast::Extensions& enabled_extensions,
|
||||||
const utils::Hashmap<const sem::Type*, const Source*, 8>& atomic_composite_info,
|
const utils::Hashmap<const type::Type*, const Source*, 8>& atomic_composite_info,
|
||||||
utils::Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts)
|
utils::Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts)
|
||||||
: symbols_(builder->Symbols()),
|
: symbols_(builder->Symbols()),
|
||||||
diagnostics_(builder->Diagnostics()),
|
diagnostics_(builder->Diagnostics()),
|
||||||
|
@ -181,20 +181,21 @@ void Validator::AddNote(const std::string& msg, const Source& source) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section
|
// https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section
|
||||||
bool Validator::IsPlain(const sem::Type* type) const {
|
bool Validator::IsPlain(const type::Type* type) const {
|
||||||
return type->is_scalar() ||
|
return type->is_scalar() ||
|
||||||
type->IsAnyOf<sem::Atomic, sem::Vector, sem::Matrix, sem::Array, sem::Struct>();
|
type->IsAnyOf<sem::Atomic, sem::Vector, sem::Matrix, sem::Array, sem::Struct>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl/#fixed-footprint-types
|
// https://gpuweb.github.io/gpuweb/wgsl/#fixed-footprint-types
|
||||||
bool Validator::IsFixedFootprint(const sem::Type* type) const {
|
bool Validator::IsFixedFootprint(const type::Type* type) const {
|
||||||
return Switch(
|
return Switch(
|
||||||
type, //
|
type, //
|
||||||
[&](const sem::Vector*) { return true; }, //
|
[&](const sem::Vector*) { return true; }, //
|
||||||
[&](const sem::Matrix*) { return true; }, //
|
[&](const sem::Matrix*) { return true; }, //
|
||||||
[&](const sem::Atomic*) { return true; },
|
[&](const sem::Atomic*) { return true; },
|
||||||
[&](const sem::Array* arr) {
|
[&](const sem::Array* arr) {
|
||||||
return !arr->Count()->Is<sem::RuntimeArrayCount>() && IsFixedFootprint(arr->ElemType());
|
return !arr->Count()->Is<type::RuntimeArrayCount>() &&
|
||||||
|
IsFixedFootprint(arr->ElemType());
|
||||||
},
|
},
|
||||||
[&](const sem::Struct* str) {
|
[&](const sem::Struct* str) {
|
||||||
for (auto* member : str->Members()) {
|
for (auto* member : str->Members()) {
|
||||||
|
@ -208,7 +209,7 @@ bool Validator::IsFixedFootprint(const sem::Type* type) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable-types
|
// https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable-types
|
||||||
bool Validator::IsHostShareable(const sem::Type* type) const {
|
bool Validator::IsHostShareable(const type::Type* type) const {
|
||||||
if (type->IsAnyOf<sem::I32, sem::U32, sem::F32, sem::F16>()) {
|
if (type->IsAnyOf<sem::I32, sem::U32, sem::F32, sem::F16>()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -229,7 +230,7 @@ bool Validator::IsHostShareable(const sem::Type* type) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl.html#storable-types
|
// https://gpuweb.github.io/gpuweb/wgsl.html#storable-types
|
||||||
bool Validator::IsStorable(const sem::Type* type) const {
|
bool Validator::IsStorable(const type::Type* type) const {
|
||||||
return IsPlain(type) || type->IsAnyOf<sem::Texture, sem::Sampler>();
|
return IsPlain(type) || type->IsAnyOf<sem::Texture, sem::Sampler>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,10 +342,10 @@ bool Validator::MultisampledTexture(const sem::MultisampledTexture* t, const Sou
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::Materialize(const sem::Type* to,
|
bool Validator::Materialize(const type::Type* to,
|
||||||
const sem::Type* from,
|
const type::Type* from,
|
||||||
const Source& source) const {
|
const Source& source) const {
|
||||||
if (sem::Type::ConversionRank(from, to) == sem::Type::kNoConversion) {
|
if (type::Type::ConversionRank(from, to) == type::Type::kNoConversion) {
|
||||||
AddError("cannot convert value of type '" + sem_.TypeNameOf(from) + "' to type '" +
|
AddError("cannot convert value of type '" + sem_.TypeNameOf(from) + "' to type '" +
|
||||||
sem_.TypeNameOf(to) + "'",
|
sem_.TypeNameOf(to) + "'",
|
||||||
source);
|
source);
|
||||||
|
@ -355,7 +356,7 @@ bool Validator::Materialize(const sem::Type* to,
|
||||||
|
|
||||||
bool Validator::VariableInitializer(const ast::Variable* v,
|
bool Validator::VariableInitializer(const ast::Variable* v,
|
||||||
ast::AddressSpace address_space,
|
ast::AddressSpace address_space,
|
||||||
const sem::Type* storage_ty,
|
const type::Type* storage_ty,
|
||||||
const sem::Expression* initializer) const {
|
const sem::Expression* 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
|
||||||
|
@ -389,21 +390,21 @@ bool Validator::VariableInitializer(const ast::Variable* v,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::AddressSpaceLayout(const sem::Type* store_ty,
|
bool Validator::AddressSpaceLayout(const type::Type* store_ty,
|
||||||
ast::AddressSpace address_space,
|
ast::AddressSpace address_space,
|
||||||
Source source) const {
|
Source source) const {
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class-layout-constraints
|
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class-layout-constraints
|
||||||
|
|
||||||
auto is_uniform_struct_or_array = [address_space](const sem::Type* ty) {
|
auto is_uniform_struct_or_array = [address_space](const type::Type* ty) {
|
||||||
return address_space == ast::AddressSpace::kUniform &&
|
return address_space == ast::AddressSpace::kUniform &&
|
||||||
ty->IsAnyOf<sem::Array, sem::Struct>();
|
ty->IsAnyOf<sem::Array, sem::Struct>();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto is_uniform_struct = [address_space](const sem::Type* ty) {
|
auto is_uniform_struct = [address_space](const type::Type* ty) {
|
||||||
return address_space == ast::AddressSpace::kUniform && ty->Is<sem::Struct>();
|
return address_space == ast::AddressSpace::kUniform && ty->Is<sem::Struct>();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto required_alignment_of = [&](const sem::Type* ty) {
|
auto required_alignment_of = [&](const type::Type* ty) {
|
||||||
uint32_t actual_align = ty->Align();
|
uint32_t actual_align = ty->Align();
|
||||||
uint32_t required_align = actual_align;
|
uint32_t required_align = actual_align;
|
||||||
if (is_uniform_struct_or_array(ty)) {
|
if (is_uniform_struct_or_array(ty)) {
|
||||||
|
@ -433,7 +434,7 @@ bool Validator::AddressSpaceLayout(const sem::Type* store_ty,
|
||||||
|
|
||||||
// Among three host-shareable address spaces, f16 is supported in "uniform" and
|
// Among three host-shareable address spaces, f16 is supported in "uniform" and
|
||||||
// "storage" address space, but not "push_constant" address space yet.
|
// "storage" address space, but not "push_constant" address space yet.
|
||||||
if (Is<sem::F16>(sem::Type::DeepestElementOf(store_ty)) &&
|
if (Is<sem::F16>(type::Type::DeepestElementOf(store_ty)) &&
|
||||||
address_space == ast::AddressSpace::kPushConstant) {
|
address_space == ast::AddressSpace::kPushConstant) {
|
||||||
AddError("using f16 types in 'push_constant' address space is not implemented yet", source);
|
AddError("using f16 types in 'push_constant' address space is not implemented yet", source);
|
||||||
return false;
|
return false;
|
||||||
|
@ -840,7 +841,7 @@ bool Validator::Parameter(const ast::Function* func, const sem::Variable* var) c
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::BuiltinAttribute(const ast::BuiltinAttribute* attr,
|
bool Validator::BuiltinAttribute(const ast::BuiltinAttribute* attr,
|
||||||
const sem::Type* storage_ty,
|
const type::Type* storage_ty,
|
||||||
ast::PipelineStage stage,
|
ast::PipelineStage stage,
|
||||||
const bool is_input) const {
|
const bool is_input) const {
|
||||||
auto* type = storage_ty->UnwrapRef();
|
auto* type = storage_ty->UnwrapRef();
|
||||||
|
@ -950,7 +951,7 @@ bool Validator::BuiltinAttribute(const ast::BuiltinAttribute* attr,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::InterpolateAttribute(const ast::InterpolateAttribute* attr,
|
bool Validator::InterpolateAttribute(const ast::InterpolateAttribute* attr,
|
||||||
const sem::Type* storage_ty) const {
|
const type::Type* storage_ty) const {
|
||||||
auto* type = storage_ty->UnwrapRef();
|
auto* type = storage_ty->UnwrapRef();
|
||||||
|
|
||||||
if (type->is_integer_scalar_or_vector() && attr->type != ast::InterpolationType::kFlat) {
|
if (type->is_integer_scalar_or_vector() && attr->type != ast::InterpolationType::kFlat) {
|
||||||
|
@ -1064,7 +1065,7 @@ bool Validator::EntryPoint(const sem::Function* func, ast::PipelineStage stage)
|
||||||
|
|
||||||
// Inner lambda that is applied to a type and all of its members.
|
// Inner lambda that is applied to a type and all of its members.
|
||||||
auto validate_entry_point_attributes_inner = [&](utils::VectorRef<const ast::Attribute*> attrs,
|
auto validate_entry_point_attributes_inner = [&](utils::VectorRef<const ast::Attribute*> attrs,
|
||||||
const sem::Type* ty, Source source,
|
const type::Type* ty, Source source,
|
||||||
ParamOrRetType param_or_ret,
|
ParamOrRetType param_or_ret,
|
||||||
bool is_struct_member,
|
bool is_struct_member,
|
||||||
std::optional<uint32_t> location) {
|
std::optional<uint32_t> location) {
|
||||||
|
@ -1207,7 +1208,7 @@ bool Validator::EntryPoint(const sem::Function* func, ast::PipelineStage stage)
|
||||||
|
|
||||||
// Outer lambda for validating the entry point attributes for a type.
|
// Outer lambda for validating the entry point attributes for a type.
|
||||||
auto validate_entry_point_attributes = [&](utils::VectorRef<const ast::Attribute*> attrs,
|
auto validate_entry_point_attributes = [&](utils::VectorRef<const ast::Attribute*> attrs,
|
||||||
const sem::Type* ty, Source source,
|
const type::Type* ty, Source source,
|
||||||
ParamOrRetType param_or_ret,
|
ParamOrRetType param_or_ret,
|
||||||
std::optional<uint32_t> location) {
|
std::optional<uint32_t> location) {
|
||||||
if (!validate_entry_point_attributes_inner(attrs, ty, source, param_or_ret,
|
if (!validate_entry_point_attributes_inner(attrs, ty, source, param_or_ret,
|
||||||
|
@ -1357,7 +1358,7 @@ bool Validator::Statements(utils::VectorRef<const ast::Statement*> stmts) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::Bitcast(const ast::BitcastExpression* cast, const sem::Type* to) const {
|
bool Validator::Bitcast(const ast::BitcastExpression* cast, const type::Type* to) const {
|
||||||
auto* from = sem_.TypeOf(cast->expr)->UnwrapRef();
|
auto* from = sem_.TypeOf(cast->expr)->UnwrapRef();
|
||||||
if (!from->is_numeric_scalar_or_vector()) {
|
if (!from->is_numeric_scalar_or_vector()) {
|
||||||
AddError("'" + sem_.TypeNameOf(from) + "' cannot be bitcast", cast->expr->source);
|
AddError("'" + sem_.TypeNameOf(from) + "' cannot be bitcast", cast->expr->source);
|
||||||
|
@ -1368,7 +1369,7 @@ bool Validator::Bitcast(const ast::BitcastExpression* cast, const sem::Type* to)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto width = [&](const sem::Type* ty) {
|
auto width = [&](const type::Type* ty) {
|
||||||
if (auto* vec = ty->As<sem::Vector>()) {
|
if (auto* vec = ty->As<sem::Vector>()) {
|
||||||
return vec->Width();
|
return vec->Width();
|
||||||
}
|
}
|
||||||
|
@ -1672,7 +1673,7 @@ bool Validator::FunctionCall(const sem::Call* call, sem::Statement* current_stat
|
||||||
auto* root_ptr_ty = root->Type()->As<sem::Pointer>();
|
auto* root_ptr_ty = root->Type()->As<sem::Pointer>();
|
||||||
auto* root_ref_ty = root->Type()->As<sem::Reference>();
|
auto* root_ref_ty = root->Type()->As<sem::Reference>();
|
||||||
TINT_ASSERT(Resolver, root_ptr_ty || root_ref_ty);
|
TINT_ASSERT(Resolver, root_ptr_ty || root_ref_ty);
|
||||||
const sem::Type* root_store_type;
|
const type::Type* root_store_type;
|
||||||
if (root_ptr_ty) {
|
if (root_ptr_ty) {
|
||||||
root_store_type = root_ptr_ty->StoreType();
|
root_store_type = root_ptr_ty->StoreType();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1747,7 +1748,7 @@ bool Validator::ArrayInitializer(const ast::CallExpression* ctor,
|
||||||
auto* elem_ty = array_type->ElemType();
|
auto* elem_ty = array_type->ElemType();
|
||||||
for (auto* value : values) {
|
for (auto* value : values) {
|
||||||
auto* value_ty = sem_.TypeOf(value)->UnwrapRef();
|
auto* value_ty = sem_.TypeOf(value)->UnwrapRef();
|
||||||
if (sem::Type::ConversionRank(value_ty, elem_ty) == sem::Type::kNoConversion) {
|
if (type::Type::ConversionRank(value_ty, elem_ty) == type::Type::kNoConversion) {
|
||||||
AddError("'" + sem_.TypeNameOf(value_ty) +
|
AddError("'" + sem_.TypeNameOf(value_ty) +
|
||||||
"' cannot be used to construct an array of '" + sem_.TypeNameOf(elem_ty) +
|
"' cannot be used to construct an array of '" + sem_.TypeNameOf(elem_ty) +
|
||||||
"'",
|
"'",
|
||||||
|
@ -1757,7 +1758,7 @@ bool Validator::ArrayInitializer(const ast::CallExpression* ctor,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* c = array_type->Count();
|
auto* c = array_type->Count();
|
||||||
if (c->Is<sem::RuntimeArrayCount>()) {
|
if (c->Is<type::RuntimeArrayCount>()) {
|
||||||
AddError("cannot construct a runtime-sized array", ctor->source);
|
AddError("cannot construct a runtime-sized array", ctor->source);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1772,12 +1773,12 @@ bool Validator::ArrayInitializer(const ast::CallExpression* ctor,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!c->Is<sem::ConstantArrayCount>()) {
|
if (!c->Is<type::ConstantArrayCount>()) {
|
||||||
TINT_ICE(Resolver, diagnostics_) << "Invalid ArrayCount found";
|
TINT_ICE(Resolver, diagnostics_) << "Invalid ArrayCount found";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto count = c->As<sem::ConstantArrayCount>()->value;
|
const auto count = c->As<type::ConstantArrayCount>()->value;
|
||||||
if (!values.IsEmpty() && (values.Length() != count)) {
|
if (!values.IsEmpty() && (values.Length() != count)) {
|
||||||
std::string fm = values.Length() < count ? "few" : "many";
|
std::string fm = values.Length() < count ? "few" : "many";
|
||||||
AddError("array initializer has too " + fm + " elements: expected " +
|
AddError("array initializer has too " + fm + " elements: expected " +
|
||||||
|
@ -2020,7 +2021,7 @@ bool Validator::Structure(const sem::Struct* str, ast::PipelineStage stage) cons
|
||||||
utils::Hashset<uint32_t, 8> locations;
|
utils::Hashset<uint32_t, 8> locations;
|
||||||
for (auto* member : str->Members()) {
|
for (auto* member : str->Members()) {
|
||||||
if (auto* r = member->Type()->As<sem::Array>()) {
|
if (auto* r = member->Type()->As<sem::Array>()) {
|
||||||
if (r->Count()->Is<sem::RuntimeArrayCount>()) {
|
if (r->Count()->Is<type::RuntimeArrayCount>()) {
|
||||||
if (member != str->Members().Back()) {
|
if (member != str->Members().Back()) {
|
||||||
AddError("runtime arrays may only appear as the last member of a struct",
|
AddError("runtime arrays may only appear as the last member of a struct",
|
||||||
member->Source());
|
member->Source());
|
||||||
|
@ -2134,7 +2135,7 @@ bool Validator::Structure(const sem::Struct* str, ast::PipelineStage stage) cons
|
||||||
|
|
||||||
bool Validator::LocationAttribute(const ast::LocationAttribute* loc_attr,
|
bool Validator::LocationAttribute(const ast::LocationAttribute* loc_attr,
|
||||||
uint32_t location,
|
uint32_t location,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
utils::Hashset<uint32_t, 8>& locations,
|
utils::Hashset<uint32_t, 8>& locations,
|
||||||
ast::PipelineStage stage,
|
ast::PipelineStage stage,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
|
@ -2166,8 +2167,8 @@ bool Validator::LocationAttribute(const ast::LocationAttribute* loc_attr,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::Return(const ast::ReturnStatement* ret,
|
bool Validator::Return(const ast::ReturnStatement* ret,
|
||||||
const sem::Type* func_type,
|
const type::Type* func_type,
|
||||||
const sem::Type* ret_type,
|
const type::Type* ret_type,
|
||||||
sem::Statement* current_statement) const {
|
sem::Statement* current_statement) const {
|
||||||
if (func_type->UnwrapRef() != ret_type) {
|
if (func_type->UnwrapRef() != ret_type) {
|
||||||
AddError("return statement type must match its function return type, returned '" +
|
AddError("return statement type must match its function return type, returned '" +
|
||||||
|
@ -2246,7 +2247,7 @@ bool Validator::SwitchStatement(const ast::SwitchStatement* s) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::Assignment(const ast::Statement* a, const sem::Type* rhs_ty) const {
|
bool Validator::Assignment(const ast::Statement* a, const type::Type* rhs_ty) const {
|
||||||
const ast::Expression* lhs;
|
const ast::Expression* lhs;
|
||||||
const ast::Expression* rhs;
|
const ast::Expression* rhs;
|
||||||
if (auto* assign = a->As<ast::AssignmentStatement>()) {
|
if (auto* assign = a->As<ast::AssignmentStatement>()) {
|
||||||
|
@ -2390,7 +2391,7 @@ bool Validator::IsValidationEnabled(utils::VectorRef<const ast::Attribute*> attr
|
||||||
return !IsValidationDisabled(attributes, validation);
|
return !IsValidationDisabled(attributes, validation);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::IsArrayWithOverrideCount(const sem::Type* ty) const {
|
bool Validator::IsArrayWithOverrideCount(const type::Type* ty) const {
|
||||||
if (auto* arr = ty->UnwrapRef()->As<sem::Array>()) {
|
if (auto* arr = ty->UnwrapRef()->As<sem::Array>()) {
|
||||||
if (arr->Count()->IsAnyOf<sem::NamedOverrideArrayCount, sem::UnnamedOverrideArrayCount>()) {
|
if (arr->Count()->IsAnyOf<sem::NamedOverrideArrayCount, sem::UnnamedOverrideArrayCount>()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -2406,13 +2407,13 @@ void Validator::RaiseArrayWithOverrideCountError(const Source& source) const {
|
||||||
source);
|
source);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Validator::VectorPretty(uint32_t size, const sem::Type* element_type) const {
|
std::string Validator::VectorPretty(uint32_t size, const type::Type* element_type) const {
|
||||||
sem::Vector vec_type(element_type, size);
|
sem::Vector vec_type(element_type, size);
|
||||||
return vec_type.FriendlyName(symbols_);
|
return vec_type.FriendlyName(symbols_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Validator::CheckTypeAccessAddressSpace(
|
bool Validator::CheckTypeAccessAddressSpace(
|
||||||
const sem::Type* store_ty,
|
const type::Type* store_ty,
|
||||||
ast::Access access,
|
ast::Access access,
|
||||||
ast::AddressSpace address_space,
|
ast::AddressSpace address_space,
|
||||||
utils::VectorRef<const tint::ast::Attribute*> attributes,
|
utils::VectorRef<const tint::ast::Attribute*> attributes,
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace tint::resolver {
|
||||||
/// TypeAndAddressSpace is a pair of type and address space
|
/// TypeAndAddressSpace is a pair of type and address space
|
||||||
struct TypeAndAddressSpace {
|
struct TypeAndAddressSpace {
|
||||||
/// The type
|
/// The type
|
||||||
const sem::Type* type;
|
const type::Type* type;
|
||||||
/// The address space
|
/// The address space
|
||||||
ast::AddressSpace address_space;
|
ast::AddressSpace address_space;
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ class Validator {
|
||||||
Validator(ProgramBuilder* builder,
|
Validator(ProgramBuilder* builder,
|
||||||
SemHelper& helper,
|
SemHelper& helper,
|
||||||
const ast::Extensions& enabled_extensions,
|
const ast::Extensions& enabled_extensions,
|
||||||
const utils::Hashmap<const sem::Type*, const Source*, 8>& atomic_composite_info,
|
const utils::Hashmap<const type::Type*, const Source*, 8>& atomic_composite_info,
|
||||||
utils::Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts);
|
utils::Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts);
|
||||||
~Validator();
|
~Validator();
|
||||||
|
|
||||||
|
@ -118,19 +118,19 @@ class Validator {
|
||||||
|
|
||||||
/// @param type the given type
|
/// @param type the given type
|
||||||
/// @returns true if the given type is a plain type
|
/// @returns true if the given type is a plain type
|
||||||
bool IsPlain(const sem::Type* type) const;
|
bool IsPlain(const type::Type* type) const;
|
||||||
|
|
||||||
/// @param type the given type
|
/// @param type the given type
|
||||||
/// @returns true if the given type is a fixed-footprint type
|
/// @returns true if the given type is a fixed-footprint type
|
||||||
bool IsFixedFootprint(const sem::Type* type) const;
|
bool IsFixedFootprint(const type::Type* type) const;
|
||||||
|
|
||||||
/// @param type the given type
|
/// @param type the given type
|
||||||
/// @returns true if the given type is storable
|
/// @returns true if the given type is storable
|
||||||
bool IsStorable(const sem::Type* type) const;
|
bool IsStorable(const type::Type* type) const;
|
||||||
|
|
||||||
/// @param type the given type
|
/// @param type the given type
|
||||||
/// @returns true if the given type is host-shareable
|
/// @returns true if the given type is host-shareable
|
||||||
bool IsHostShareable(const sem::Type* type) const;
|
bool IsHostShareable(const type::Type* type) const;
|
||||||
|
|
||||||
/// Validates pipeline stages
|
/// Validates pipeline stages
|
||||||
/// @param entry_points the entry points to the module
|
/// @param entry_points the entry points to the module
|
||||||
|
@ -179,13 +179,13 @@ class Validator {
|
||||||
/// @param a the assignment statement
|
/// @param a the assignment statement
|
||||||
/// @param rhs_ty the type of the right hand side
|
/// @param rhs_ty the type of the right hand side
|
||||||
/// @returns true on success, false otherwise.
|
/// @returns true on success, false otherwise.
|
||||||
bool Assignment(const ast::Statement* a, const sem::Type* rhs_ty) const;
|
bool Assignment(const ast::Statement* a, const type::Type* rhs_ty) const;
|
||||||
|
|
||||||
/// Validates a bitcase
|
/// Validates a bitcase
|
||||||
/// @param cast the bitcast expression
|
/// @param cast the bitcast expression
|
||||||
/// @param to the destination type
|
/// @param to the destination type
|
||||||
/// @returns true on success, false otherwise
|
/// @returns true on success, false otherwise
|
||||||
bool Bitcast(const ast::BitcastExpression* cast, const sem::Type* to) const;
|
bool Bitcast(const ast::BitcastExpression* cast, const type::Type* to) const;
|
||||||
|
|
||||||
/// Validates a break statement
|
/// Validates a break statement
|
||||||
/// @param stmt the break statement to validate
|
/// @param stmt the break statement to validate
|
||||||
|
@ -200,7 +200,7 @@ class Validator {
|
||||||
/// @param is_input true if this is an input attribute
|
/// @param is_input true if this is an input attribute
|
||||||
/// @returns true on success, false otherwise.
|
/// @returns true on success, false otherwise.
|
||||||
bool BuiltinAttribute(const ast::BuiltinAttribute* attr,
|
bool BuiltinAttribute(const ast::BuiltinAttribute* attr,
|
||||||
const sem::Type* storage_type,
|
const type::Type* storage_type,
|
||||||
ast::PipelineStage stage,
|
ast::PipelineStage stage,
|
||||||
const bool is_input) const;
|
const bool is_input) const;
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ class Validator {
|
||||||
/// @param storage_type the storage type of the attached variable
|
/// @param storage_type the storage type of the attached variable
|
||||||
/// @returns true on succes, false otherwise
|
/// @returns true on succes, false otherwise
|
||||||
bool InterpolateAttribute(const ast::InterpolateAttribute* attr,
|
bool InterpolateAttribute(const ast::InterpolateAttribute* attr,
|
||||||
const sem::Type* storage_type) const;
|
const type::Type* storage_type) const;
|
||||||
|
|
||||||
/// Validates a builtin call
|
/// Validates a builtin call
|
||||||
/// @param call the builtin call to validate
|
/// @param call the builtin call to validate
|
||||||
|
@ -306,7 +306,7 @@ class Validator {
|
||||||
/// @returns true on success, false otherwise.
|
/// @returns true on success, false otherwise.
|
||||||
bool LocationAttribute(const ast::LocationAttribute* loc_attr,
|
bool LocationAttribute(const ast::LocationAttribute* loc_attr,
|
||||||
uint32_t location,
|
uint32_t location,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
utils::Hashset<uint32_t, 8>& locations,
|
utils::Hashset<uint32_t, 8>& locations,
|
||||||
ast::PipelineStage stage,
|
ast::PipelineStage stage,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
|
@ -322,7 +322,7 @@ class Validator {
|
||||||
/// @param from the abstract numeric type
|
/// @param from the abstract numeric type
|
||||||
/// @param source the source of the materialization
|
/// @param source the source of the materialization
|
||||||
/// @returns true on success, false otherwise
|
/// @returns true on success, false otherwise
|
||||||
bool Materialize(const sem::Type* to, const sem::Type* from, const Source& source) const;
|
bool Materialize(const type::Type* to, const type::Type* from, const Source& source) const;
|
||||||
|
|
||||||
/// Validates a matrix
|
/// Validates a matrix
|
||||||
/// @param ty the matrix to validate
|
/// @param ty the matrix to validate
|
||||||
|
@ -343,8 +343,8 @@ class Validator {
|
||||||
/// @param current_statement the current statement being resolved
|
/// @param current_statement the current statement being resolved
|
||||||
/// @returns true on success, false otherwise
|
/// @returns true on success, false otherwise
|
||||||
bool Return(const ast::ReturnStatement* ret,
|
bool Return(const ast::ReturnStatement* ret,
|
||||||
const sem::Type* func_type,
|
const type::Type* func_type,
|
||||||
const sem::Type* ret_type,
|
const type::Type* ret_type,
|
||||||
sem::Statement* current_statement) const;
|
sem::Statement* current_statement) const;
|
||||||
|
|
||||||
/// Validates a list of statements
|
/// Validates a list of statements
|
||||||
|
@ -417,7 +417,7 @@ class Validator {
|
||||||
/// @returns true on succes, false otherwise
|
/// @returns true on succes, false otherwise
|
||||||
bool VariableInitializer(const ast::Variable* v,
|
bool VariableInitializer(const ast::Variable* v,
|
||||||
ast::AddressSpace address_space,
|
ast::AddressSpace address_space,
|
||||||
const sem::Type* storage_type,
|
const type::Type* storage_type,
|
||||||
const sem::Expression* initializer) const;
|
const sem::Expression* initializer) const;
|
||||||
|
|
||||||
/// Validates a vector
|
/// Validates a vector
|
||||||
|
@ -452,7 +452,7 @@ class Validator {
|
||||||
/// @param sc the address space
|
/// @param sc the address space
|
||||||
/// @param source the source of the type
|
/// @param source the source of the type
|
||||||
/// @returns true on success, false otherwise
|
/// @returns true on success, false otherwise
|
||||||
bool AddressSpaceLayout(const sem::Type* type, ast::AddressSpace sc, Source source) const;
|
bool AddressSpaceLayout(const type::Type* type, ast::AddressSpace sc, Source source) const;
|
||||||
|
|
||||||
/// @returns true if the attribute list contains a
|
/// @returns true if the attribute list contains a
|
||||||
/// ast::DisableValidationAttribute with the validation mode equal to
|
/// ast::DisableValidationAttribute with the validation mode equal to
|
||||||
|
@ -474,7 +474,7 @@ class Validator {
|
||||||
/// @param ty the type to check
|
/// @param ty the type to check
|
||||||
/// @returns true if @p ty is an array with an `override` expression element count, otherwise
|
/// @returns true if @p ty is an array with an `override` expression element count, otherwise
|
||||||
/// false.
|
/// false.
|
||||||
bool IsArrayWithOverrideCount(const sem::Type* ty) const;
|
bool IsArrayWithOverrideCount(const type::Type* ty) const;
|
||||||
|
|
||||||
/// Raises an error about an array type using an `override` expression element count, outside
|
/// Raises an error about an array type using an `override` expression element count, outside
|
||||||
/// the single allowed use of a `var<workgroup>`.
|
/// the single allowed use of a `var<workgroup>`.
|
||||||
|
@ -496,7 +496,7 @@ class Validator {
|
||||||
/// @param size the vector dimension
|
/// @param size the vector dimension
|
||||||
/// @param element_type scalar vector sub-element type
|
/// @param element_type scalar vector sub-element type
|
||||||
/// @return pretty string representation
|
/// @return pretty string representation
|
||||||
std::string VectorPretty(uint32_t size, const sem::Type* element_type) const;
|
std::string VectorPretty(uint32_t size, const type::Type* element_type) const;
|
||||||
|
|
||||||
/// Raises an error if combination of @p store_ty, @p access and @p address_space are not valid
|
/// Raises an error if combination of @p store_ty, @p access and @p address_space are not valid
|
||||||
/// for a `var` or `ptr` declaration.
|
/// for a `var` or `ptr` declaration.
|
||||||
|
@ -505,7 +505,7 @@ class Validator {
|
||||||
/// @param address_space the var or pointer address space
|
/// @param address_space the var or pointer address space
|
||||||
/// @param source the source for the error
|
/// @param source the source for the error
|
||||||
/// @returns true on success, false if an error was raised.
|
/// @returns true on success, false if an error was raised.
|
||||||
bool CheckTypeAccessAddressSpace(const sem::Type* store_ty,
|
bool CheckTypeAccessAddressSpace(const type::Type* store_ty,
|
||||||
ast::Access access,
|
ast::Access access,
|
||||||
ast::AddressSpace address_space,
|
ast::AddressSpace address_space,
|
||||||
utils::VectorRef<const tint::ast::Attribute*> attributes,
|
utils::VectorRef<const tint::ast::Attribute*> attributes,
|
||||||
|
@ -514,7 +514,7 @@ class Validator {
|
||||||
diag::List& diagnostics_;
|
diag::List& diagnostics_;
|
||||||
SemHelper& sem_;
|
SemHelper& sem_;
|
||||||
const ast::Extensions& enabled_extensions_;
|
const ast::Extensions& enabled_extensions_;
|
||||||
const utils::Hashmap<const sem::Type*, const Source*, 8>& atomic_composite_info_;
|
const utils::Hashmap<const type::Type*, const Source*, 8>& atomic_composite_info_;
|
||||||
utils::Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts_;
|
utils::Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -89,14 +89,14 @@ TEST_F(ValidatorIsStorableTest, Atomic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ValidatorIsStorableTest, ArraySizedOfStorable) {
|
TEST_F(ValidatorIsStorableTest, ArraySizedOfStorable) {
|
||||||
auto* arr = create<sem::Array>(create<sem::I32>(), create<sem::ConstantArrayCount>(5u), 4u, 20u,
|
auto* arr = create<sem::Array>(create<sem::I32>(), create<type::ConstantArrayCount>(5u), 4u,
|
||||||
4u, 4u);
|
20u, 4u, 4u);
|
||||||
EXPECT_TRUE(v()->IsStorable(arr));
|
EXPECT_TRUE(v()->IsStorable(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ValidatorIsStorableTest, ArrayUnsizedOfStorable) {
|
TEST_F(ValidatorIsStorableTest, ArrayUnsizedOfStorable) {
|
||||||
auto* arr =
|
auto* arr =
|
||||||
create<sem::Array>(create<sem::I32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
create<sem::Array>(create<sem::I32>(), create<type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
|
||||||
EXPECT_TRUE(v()->IsStorable(arr));
|
EXPECT_TRUE(v()->IsStorable(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ size_t AbstractFloat::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<AbstractFloat>().full_hashcode);
|
return utils::Hash(TypeInfo::Of<AbstractFloat>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractFloat::Equals(const sem::Type& other) const {
|
bool AbstractFloat::Equals(const type::Type& other) const {
|
||||||
return other.Is<AbstractFloat>();
|
return other.Is<AbstractFloat>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ size_t AbstractInt::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<AbstractInt>().full_hashcode);
|
return utils::Hash(TypeInfo::Of<AbstractInt>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractInt::Equals(const sem::Type& other) const {
|
bool AbstractInt::Equals(const type::Type& other) const {
|
||||||
return other.Is<AbstractInt>();
|
return other.Is<AbstractInt>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::AbstractNumeric);
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
AbstractNumeric::AbstractNumeric()
|
AbstractNumeric::AbstractNumeric()
|
||||||
: Base(TypeFlags{
|
: Base(type::TypeFlags{
|
||||||
Flag::kConstructable,
|
Flag::kConstructable,
|
||||||
Flag::kCreationFixedFootprint,
|
Flag::kCreationFixedFootprint,
|
||||||
Flag::kFixedFootprint,
|
Flag::kFixedFootprint,
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// The base class for abstract-int and abstract-float types.
|
/// The base class for abstract-int and abstract-float types.
|
||||||
/// @see https://www.w3.org/TR/WGSL/#types-for-creation-time-constants
|
/// @see https://www.w3.org/TR/WGSL/#types-for-creation-time-constants
|
||||||
class AbstractNumeric : public Castable<AbstractNumeric, Type> {
|
class AbstractNumeric : public Castable<AbstractNumeric, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
AbstractNumeric();
|
AbstractNumeric();
|
||||||
|
|
|
@ -28,20 +28,21 @@ namespace tint::sem {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
TypeFlags FlagsFrom(const Type* element, const ArrayCount* count) {
|
type::TypeFlags FlagsFrom(const type::Type* element, const type::ArrayCount* count) {
|
||||||
TypeFlags flags;
|
type::TypeFlags flags;
|
||||||
// Only constant-expression sized arrays are constructible
|
// Only constant-expression sized arrays are constructible
|
||||||
if (count->Is<ConstantArrayCount>()) {
|
if (count->Is<type::ConstantArrayCount>()) {
|
||||||
if (element->IsConstructible()) {
|
if (element->IsConstructible()) {
|
||||||
flags.Add(TypeFlag::kConstructable);
|
flags.Add(type::TypeFlag::kConstructable);
|
||||||
}
|
}
|
||||||
if (element->HasCreationFixedFootprint()) {
|
if (element->HasCreationFixedFootprint()) {
|
||||||
flags.Add(TypeFlag::kCreationFixedFootprint);
|
flags.Add(type::TypeFlag::kCreationFixedFootprint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count->IsAnyOf<ConstantArrayCount, NamedOverrideArrayCount, UnnamedOverrideArrayCount>()) {
|
if (count->IsAnyOf<type::ConstantArrayCount, sem::NamedOverrideArrayCount,
|
||||||
|
sem::UnnamedOverrideArrayCount>()) {
|
||||||
if (element->HasFixedFootprint()) {
|
if (element->HasFixedFootprint()) {
|
||||||
flags.Add(TypeFlag::kFixedFootprint);
|
flags.Add(type::TypeFlag::kFixedFootprint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flags;
|
return flags;
|
||||||
|
@ -53,8 +54,8 @@ const char* const Array::kErrExpectedConstantCount =
|
||||||
"array size is an override-expression, when expected a constant-expression.\n"
|
"array size is an override-expression, when expected a constant-expression.\n"
|
||||||
"Was the SubstituteOverride transform run?";
|
"Was the SubstituteOverride transform run?";
|
||||||
|
|
||||||
Array::Array(const Type* element,
|
Array::Array(const type::Type* element,
|
||||||
const ArrayCount* count,
|
const type::ArrayCount* count,
|
||||||
uint32_t align,
|
uint32_t align,
|
||||||
uint32_t size,
|
uint32_t size,
|
||||||
uint32_t stride,
|
uint32_t stride,
|
||||||
|
@ -73,7 +74,7 @@ size_t Array::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Array>().full_hashcode, count_, align_, size_, stride_);
|
return utils::Hash(TypeInfo::Of<Array>().full_hashcode, count_, align_, size_, stride_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Array::Equals(const sem::Type& other) const {
|
bool Array::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<Array>()) {
|
if (auto* o = other.As<Array>()) {
|
||||||
// Note: implicit_stride is not part of the type_name string as this is
|
// Note: implicit_stride is not part of the type_name string as this is
|
||||||
// derived from the element type
|
// derived from the element type
|
||||||
|
@ -89,11 +90,11 @@ std::string Array::FriendlyName(const SymbolTable& symbols) const {
|
||||||
out << "@stride(" << stride_ << ") ";
|
out << "@stride(" << stride_ << ") ";
|
||||||
}
|
}
|
||||||
out << "array<" << element_->FriendlyName(symbols);
|
out << "array<" << element_->FriendlyName(symbols);
|
||||||
if (auto* const_count = count_->As<ConstantArrayCount>()) {
|
if (auto* const_count = count_->As<type::ConstantArrayCount>()) {
|
||||||
out << ", " << const_count->value;
|
out << ", " << const_count->value;
|
||||||
} else if (auto* named_override_count = count_->As<NamedOverrideArrayCount>()) {
|
} else if (auto* named_override_count = count_->As<sem::NamedOverrideArrayCount>()) {
|
||||||
out << ", " << symbols.NameFor(named_override_count->variable->Declaration()->symbol);
|
out << ", " << symbols.NameFor(named_override_count->variable->Declaration()->symbol);
|
||||||
} else if (count_->Is<UnnamedOverrideArrayCount>()) {
|
} else if (count_->Is<sem::UnnamedOverrideArrayCount>()) {
|
||||||
out << ", [unnamed override-expression]";
|
out << ", [unnamed override-expression]";
|
||||||
}
|
}
|
||||||
out << ">";
|
out << ">";
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "src/tint/sem/array_count.h"
|
#include "src/tint/sem/array_count.h"
|
||||||
#include "src/tint/sem/node.h"
|
#include "src/tint/sem/node.h"
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
#include "src/tint/utils/compiler_macros.h"
|
#include "src/tint/utils/compiler_macros.h"
|
||||||
#include "src/tint/utils/unique_vector.h"
|
#include "src/tint/utils/unique_vector.h"
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class GlobalVariable;
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// Array holds the semantic information for Array nodes.
|
/// Array holds the semantic information for Array nodes.
|
||||||
class Array final : public Castable<Array, Type> {
|
class Array final : public Castable<Array, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// An error message string stating that the array count was expected to be a constant
|
/// An error message string stating that the array count was expected to be a constant
|
||||||
/// expression. Used by multiple writers and transforms.
|
/// expression. Used by multiple writers and transforms.
|
||||||
|
@ -52,8 +52,8 @@ class Array final : public Castable<Array, Type> {
|
||||||
/// @param implicit_stride the number of bytes from the start of one element
|
/// @param implicit_stride the number of bytes from the start of one element
|
||||||
/// of the array to the start of the next element, if there was no `@stride`
|
/// of the array to the start of the next element, if there was no `@stride`
|
||||||
/// attribute applied.
|
/// attribute applied.
|
||||||
Array(Type const* element,
|
Array(type::Type const* element,
|
||||||
const ArrayCount* count,
|
const type::ArrayCount* count,
|
||||||
uint32_t align,
|
uint32_t align,
|
||||||
uint32_t size,
|
uint32_t size,
|
||||||
uint32_t stride,
|
uint32_t stride,
|
||||||
|
@ -64,17 +64,17 @@ class Array final : public Castable<Array, Type> {
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other type to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to the given type
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const type::Type& other) const override;
|
||||||
|
|
||||||
/// @return the array element type
|
/// @return the array element type
|
||||||
Type const* ElemType() const { return element_; }
|
type::Type const* ElemType() const { return element_; }
|
||||||
|
|
||||||
/// @returns the number of elements in the array.
|
/// @returns the number of elements in the array.
|
||||||
const ArrayCount* Count() const { return count_; }
|
const type::ArrayCount* Count() const { return count_; }
|
||||||
|
|
||||||
/// @returns the array count if the count is a const-expression, otherwise returns nullopt.
|
/// @returns the array count if the count is a const-expression, otherwise returns nullopt.
|
||||||
inline std::optional<uint32_t> ConstantCount() const {
|
inline std::optional<uint32_t> ConstantCount() const {
|
||||||
if (auto* count = count_->As<ConstantArrayCount>()) {
|
if (auto* count = count_->As<type::ConstantArrayCount>()) {
|
||||||
return count->value;
|
return count->value;
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -109,8 +109,8 @@ class Array final : public Castable<Array, Type> {
|
||||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type const* const element_;
|
type::Type const* const element_;
|
||||||
const ArrayCount* count_;
|
const type::ArrayCount* count_;
|
||||||
const uint32_t align_;
|
const uint32_t align_;
|
||||||
const uint32_t size_;
|
const uint32_t size_;
|
||||||
const uint32_t stride_;
|
const uint32_t stride_;
|
||||||
|
|
|
@ -14,42 +14,11 @@
|
||||||
|
|
||||||
#include "src/tint/sem/array_count.h"
|
#include "src/tint/sem/array_count.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::ArrayCount);
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::ConstantArrayCount);
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::RuntimeArrayCount);
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::NamedOverrideArrayCount);
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::NamedOverrideArrayCount);
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::UnnamedOverrideArrayCount);
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::UnnamedOverrideArrayCount);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
ArrayCount::ArrayCount() : Base() {}
|
|
||||||
ArrayCount::~ArrayCount() = default;
|
|
||||||
|
|
||||||
ConstantArrayCount::ConstantArrayCount(uint32_t val) : Base(), value(val) {}
|
|
||||||
ConstantArrayCount::~ConstantArrayCount() = default;
|
|
||||||
|
|
||||||
size_t ConstantArrayCount::Hash() const {
|
|
||||||
return static_cast<size_t>(TypeInfo::Of<ConstantArrayCount>().full_hashcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConstantArrayCount::Equals(const ArrayCount& other) const {
|
|
||||||
if (auto* v = other.As<ConstantArrayCount>()) {
|
|
||||||
return value == v->value;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RuntimeArrayCount::RuntimeArrayCount() : Base() {}
|
|
||||||
RuntimeArrayCount::~RuntimeArrayCount() = default;
|
|
||||||
|
|
||||||
size_t RuntimeArrayCount::Hash() const {
|
|
||||||
return static_cast<size_t>(TypeInfo::Of<RuntimeArrayCount>().full_hashcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RuntimeArrayCount::Equals(const ArrayCount& other) const {
|
|
||||||
return other.Is<RuntimeArrayCount>();
|
|
||||||
}
|
|
||||||
|
|
||||||
NamedOverrideArrayCount::NamedOverrideArrayCount(const GlobalVariable* var)
|
NamedOverrideArrayCount::NamedOverrideArrayCount(const GlobalVariable* var)
|
||||||
: Base(), variable(var) {}
|
: Base(), variable(var) {}
|
||||||
NamedOverrideArrayCount::~NamedOverrideArrayCount() = default;
|
NamedOverrideArrayCount::~NamedOverrideArrayCount() = default;
|
||||||
|
|
|
@ -15,81 +15,19 @@
|
||||||
#ifndef SRC_TINT_SEM_ARRAY_COUNT_H_
|
#ifndef SRC_TINT_SEM_ARRAY_COUNT_H_
|
||||||
#define SRC_TINT_SEM_ARRAY_COUNT_H_
|
#define SRC_TINT_SEM_ARRAY_COUNT_H_
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "src/tint/sem/expression.h"
|
#include "src/tint/sem/expression.h"
|
||||||
#include "src/tint/sem/node.h"
|
|
||||||
#include "src/tint/sem/variable.h"
|
#include "src/tint/sem/variable.h"
|
||||||
|
#include "src/tint/type/array_count.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// An array count
|
|
||||||
class ArrayCount : public Castable<ArrayCount, Node> {
|
|
||||||
public:
|
|
||||||
~ArrayCount() override;
|
|
||||||
|
|
||||||
/// @returns a hash of the array count.
|
|
||||||
virtual size_t Hash() const = 0;
|
|
||||||
|
|
||||||
/// @param t other array count
|
|
||||||
/// @returns true if this array count is equal to the given array count
|
|
||||||
virtual bool Equals(const ArrayCount& t) const = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ArrayCount();
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The variant of an ArrayCount when the array is a const-expression.
|
|
||||||
/// Example:
|
|
||||||
/// ```
|
|
||||||
/// const N = 123;
|
|
||||||
/// type arr = array<i32, N>
|
|
||||||
/// ```
|
|
||||||
class ConstantArrayCount final : public Castable<ConstantArrayCount, ArrayCount> {
|
|
||||||
public:
|
|
||||||
/// Constructor
|
|
||||||
/// @param val the constant-expression value
|
|
||||||
explicit ConstantArrayCount(uint32_t val);
|
|
||||||
~ConstantArrayCount() override;
|
|
||||||
|
|
||||||
/// @returns a hash of the array count.
|
|
||||||
size_t Hash() const override;
|
|
||||||
|
|
||||||
/// @param t other array count
|
|
||||||
/// @returns true if this array count is equal to the given array count
|
|
||||||
bool Equals(const ArrayCount& t) const override;
|
|
||||||
|
|
||||||
/// The array count constant-expression value.
|
|
||||||
uint32_t value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The variant of an ArrayCount when the array is is runtime-sized.
|
|
||||||
/// Example:
|
|
||||||
/// ```
|
|
||||||
/// type arr = array<i32>
|
|
||||||
/// ```
|
|
||||||
class RuntimeArrayCount final : public Castable<RuntimeArrayCount, ArrayCount> {
|
|
||||||
public:
|
|
||||||
/// Constructor
|
|
||||||
RuntimeArrayCount();
|
|
||||||
~RuntimeArrayCount() override;
|
|
||||||
|
|
||||||
/// @returns a hash of the array count.
|
|
||||||
size_t Hash() const override;
|
|
||||||
|
|
||||||
/// @param t other array count
|
|
||||||
/// @returns true if this array count is equal to the given array count
|
|
||||||
bool Equals(const ArrayCount& t) const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The variant of an ArrayCount when the count is a named override variable.
|
/// The variant of an ArrayCount when the count is a named override variable.
|
||||||
/// Example:
|
/// Example:
|
||||||
/// ```
|
/// ```
|
||||||
/// override N : i32;
|
/// override N : i32;
|
||||||
/// type arr = array<i32, N>
|
/// type arr = array<i32, N>
|
||||||
/// ```
|
/// ```
|
||||||
class NamedOverrideArrayCount final : public Castable<NamedOverrideArrayCount, ArrayCount> {
|
class NamedOverrideArrayCount final : public Castable<NamedOverrideArrayCount, type::ArrayCount> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param var the `override` variable
|
/// @param var the `override` variable
|
||||||
|
@ -101,7 +39,7 @@ class NamedOverrideArrayCount final : public Castable<NamedOverrideArrayCount, A
|
||||||
|
|
||||||
/// @param t other array count
|
/// @param t other array count
|
||||||
/// @returns true if this array count is equal to the given array count
|
/// @returns true if this array count is equal to the given array count
|
||||||
bool Equals(const ArrayCount& t) const override;
|
bool Equals(const type::ArrayCount& t) const override;
|
||||||
|
|
||||||
/// The `override` variable.
|
/// The `override` variable.
|
||||||
const GlobalVariable* variable;
|
const GlobalVariable* variable;
|
||||||
|
@ -113,7 +51,8 @@ class NamedOverrideArrayCount final : public Castable<NamedOverrideArrayCount, A
|
||||||
/// override N : i32;
|
/// override N : i32;
|
||||||
/// type arr = array<i32, N*2>
|
/// type arr = array<i32, N*2>
|
||||||
/// ```
|
/// ```
|
||||||
class UnnamedOverrideArrayCount final : public Castable<UnnamedOverrideArrayCount, ArrayCount> {
|
class UnnamedOverrideArrayCount final
|
||||||
|
: public Castable<UnnamedOverrideArrayCount, type::ArrayCount> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param e the override expression
|
/// @param e the override expression
|
||||||
|
@ -125,7 +64,7 @@ class UnnamedOverrideArrayCount final : public Castable<UnnamedOverrideArrayCoun
|
||||||
|
|
||||||
/// @param t other array count
|
/// @param t other array count
|
||||||
/// @returns true if this array count is equal to the given array count
|
/// @returns true if this array count is equal to the given array count
|
||||||
bool Equals(const ArrayCount& t) const override;
|
bool Equals(const type::ArrayCount& t) const override;
|
||||||
|
|
||||||
/// The unnamed override expression.
|
/// The unnamed override expression.
|
||||||
/// Note: Each AST expression gets a unique semantic expression node, so two equivalent AST
|
/// Note: Each AST expression gets a unique semantic expression node, so two equivalent AST
|
||||||
|
@ -144,27 +83,4 @@ class UnnamedOverrideArrayCount final : public Castable<UnnamedOverrideArrayCoun
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
namespace std {
|
|
||||||
|
|
||||||
/// std::hash specialization for tint::sem::ArrayCount
|
|
||||||
template <>
|
|
||||||
struct hash<tint::sem::ArrayCount> {
|
|
||||||
/// @param a the array count to obtain a hash from
|
|
||||||
/// @returns the hash of the array count
|
|
||||||
size_t operator()(const tint::sem::ArrayCount& a) const { return a.Hash(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/// std::equal_to specialization for tint::sem::ArrayCount
|
|
||||||
template <>
|
|
||||||
struct equal_to<tint::sem::ArrayCount> {
|
|
||||||
/// @param a the first array count to compare
|
|
||||||
/// @param b the second array count to compare
|
|
||||||
/// @returns true if the two array counts are equal
|
|
||||||
bool operator()(const tint::sem::ArrayCount& a, const tint::sem::ArrayCount& b) const {
|
|
||||||
return a.Equals(b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
#endif // SRC_TINT_SEM_ARRAY_COUNT_H_
|
#endif // SRC_TINT_SEM_ARRAY_COUNT_H_
|
||||||
|
|
|
@ -21,22 +21,22 @@ namespace {
|
||||||
using ArrayTest = TestHelper;
|
using ArrayTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(ArrayTest, CreateSizedArray) {
|
TEST_F(ArrayTest, CreateSizedArray) {
|
||||||
auto* a = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
auto* a = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
||||||
auto* b = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
auto* b = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
||||||
auto* c = create<Array>(create<U32>(), create<ConstantArrayCount>(3u), 4u, 8u, 32u, 16u);
|
auto* c = create<Array>(create<U32>(), create<type::ConstantArrayCount>(3u), 4u, 8u, 32u, 16u);
|
||||||
auto* d = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 5u, 8u, 32u, 16u);
|
auto* d = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 5u, 8u, 32u, 16u);
|
||||||
auto* e = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 9u, 32u, 16u);
|
auto* e = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 9u, 32u, 16u);
|
||||||
auto* f = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 16u);
|
auto* f = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 33u, 16u);
|
||||||
auto* g = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 17u);
|
auto* g = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 33u, 17u);
|
||||||
|
|
||||||
EXPECT_EQ(a->ElemType(), create<U32>());
|
EXPECT_EQ(a->ElemType(), create<U32>());
|
||||||
EXPECT_EQ(a->Count(), create<ConstantArrayCount>(2u));
|
EXPECT_EQ(a->Count(), create<type::ConstantArrayCount>(2u));
|
||||||
EXPECT_EQ(a->Align(), 4u);
|
EXPECT_EQ(a->Align(), 4u);
|
||||||
EXPECT_EQ(a->Size(), 8u);
|
EXPECT_EQ(a->Size(), 8u);
|
||||||
EXPECT_EQ(a->Stride(), 32u);
|
EXPECT_EQ(a->Stride(), 32u);
|
||||||
EXPECT_EQ(a->ImplicitStride(), 16u);
|
EXPECT_EQ(a->ImplicitStride(), 16u);
|
||||||
EXPECT_FALSE(a->IsStrideImplicit());
|
EXPECT_FALSE(a->IsStrideImplicit());
|
||||||
EXPECT_FALSE(a->Count()->Is<RuntimeArrayCount>());
|
EXPECT_FALSE(a->Count()->Is<type::RuntimeArrayCount>());
|
||||||
|
|
||||||
EXPECT_EQ(a, b);
|
EXPECT_EQ(a, b);
|
||||||
EXPECT_NE(a, c);
|
EXPECT_NE(a, c);
|
||||||
|
@ -47,21 +47,21 @@ TEST_F(ArrayTest, CreateSizedArray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayTest, CreateRuntimeArray) {
|
TEST_F(ArrayTest, CreateRuntimeArray) {
|
||||||
auto* a = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 32u);
|
auto* a = create<Array>(create<U32>(), create<type::RuntimeArrayCount>(), 4u, 8u, 32u, 32u);
|
||||||
auto* b = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 32u);
|
auto* b = create<Array>(create<U32>(), create<type::RuntimeArrayCount>(), 4u, 8u, 32u, 32u);
|
||||||
auto* c = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 5u, 8u, 32u, 32u);
|
auto* c = create<Array>(create<U32>(), create<type::RuntimeArrayCount>(), 5u, 8u, 32u, 32u);
|
||||||
auto* d = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 9u, 32u, 32u);
|
auto* d = create<Array>(create<U32>(), create<type::RuntimeArrayCount>(), 4u, 9u, 32u, 32u);
|
||||||
auto* e = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 33u, 32u);
|
auto* e = create<Array>(create<U32>(), create<type::RuntimeArrayCount>(), 4u, 8u, 33u, 32u);
|
||||||
auto* f = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 33u, 17u);
|
auto* f = create<Array>(create<U32>(), create<type::RuntimeArrayCount>(), 4u, 8u, 33u, 17u);
|
||||||
|
|
||||||
EXPECT_EQ(a->ElemType(), create<U32>());
|
EXPECT_EQ(a->ElemType(), create<U32>());
|
||||||
EXPECT_EQ(a->Count(), create<sem::RuntimeArrayCount>());
|
EXPECT_EQ(a->Count(), create<type::RuntimeArrayCount>());
|
||||||
EXPECT_EQ(a->Align(), 4u);
|
EXPECT_EQ(a->Align(), 4u);
|
||||||
EXPECT_EQ(a->Size(), 8u);
|
EXPECT_EQ(a->Size(), 8u);
|
||||||
EXPECT_EQ(a->Stride(), 32u);
|
EXPECT_EQ(a->Stride(), 32u);
|
||||||
EXPECT_EQ(a->ImplicitStride(), 32u);
|
EXPECT_EQ(a->ImplicitStride(), 32u);
|
||||||
EXPECT_TRUE(a->IsStrideImplicit());
|
EXPECT_TRUE(a->IsStrideImplicit());
|
||||||
EXPECT_TRUE(a->Count()->Is<RuntimeArrayCount>());
|
EXPECT_TRUE(a->Count()->Is<type::RuntimeArrayCount>());
|
||||||
|
|
||||||
EXPECT_EQ(a, b);
|
EXPECT_EQ(a, b);
|
||||||
EXPECT_NE(a, c);
|
EXPECT_NE(a, c);
|
||||||
|
@ -71,13 +71,13 @@ TEST_F(ArrayTest, CreateRuntimeArray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayTest, Hash) {
|
TEST_F(ArrayTest, Hash) {
|
||||||
auto* a = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
auto* a = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
||||||
auto* b = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
auto* b = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
||||||
auto* c = create<Array>(create<U32>(), create<ConstantArrayCount>(3u), 4u, 8u, 32u, 16u);
|
auto* c = create<Array>(create<U32>(), create<type::ConstantArrayCount>(3u), 4u, 8u, 32u, 16u);
|
||||||
auto* d = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 5u, 8u, 32u, 16u);
|
auto* d = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 5u, 8u, 32u, 16u);
|
||||||
auto* e = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 9u, 32u, 16u);
|
auto* e = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 9u, 32u, 16u);
|
||||||
auto* f = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 16u);
|
auto* f = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 33u, 16u);
|
||||||
auto* g = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 17u);
|
auto* g = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 33u, 17u);
|
||||||
|
|
||||||
EXPECT_EQ(a->Hash(), b->Hash());
|
EXPECT_EQ(a->Hash(), b->Hash());
|
||||||
EXPECT_NE(a->Hash(), c->Hash());
|
EXPECT_NE(a->Hash(), c->Hash());
|
||||||
|
@ -88,13 +88,13 @@ TEST_F(ArrayTest, Hash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayTest, Equals) {
|
TEST_F(ArrayTest, Equals) {
|
||||||
auto* a = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
auto* a = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
||||||
auto* b = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
auto* b = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
||||||
auto* c = create<Array>(create<U32>(), create<ConstantArrayCount>(3u), 4u, 8u, 32u, 16u);
|
auto* c = create<Array>(create<U32>(), create<type::ConstantArrayCount>(3u), 4u, 8u, 32u, 16u);
|
||||||
auto* d = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 5u, 8u, 32u, 16u);
|
auto* d = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 5u, 8u, 32u, 16u);
|
||||||
auto* e = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 9u, 32u, 16u);
|
auto* e = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 9u, 32u, 16u);
|
||||||
auto* f = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 16u);
|
auto* f = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 33u, 16u);
|
||||||
auto* g = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 17u);
|
auto* g = create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 33u, 17u);
|
||||||
|
|
||||||
EXPECT_TRUE(a->Equals(*b));
|
EXPECT_TRUE(a->Equals(*b));
|
||||||
EXPECT_FALSE(a->Equals(*c));
|
EXPECT_FALSE(a->Equals(*c));
|
||||||
|
@ -106,34 +106,34 @@ TEST_F(ArrayTest, Equals) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayTest, FriendlyNameRuntimeSized) {
|
TEST_F(ArrayTest, FriendlyNameRuntimeSized) {
|
||||||
auto* arr = create<Array>(create<I32>(), create<RuntimeArrayCount>(), 0u, 4u, 4u, 4u);
|
auto* arr = create<Array>(create<I32>(), create<type::RuntimeArrayCount>(), 0u, 4u, 4u, 4u);
|
||||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
|
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayTest, FriendlyNameStaticSized) {
|
TEST_F(ArrayTest, FriendlyNameStaticSized) {
|
||||||
auto* arr = create<Array>(create<I32>(), create<ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
|
auto* arr = create<Array>(create<I32>(), create<type::ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
|
||||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
|
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayTest, FriendlyNameRuntimeSizedNonImplicitStride) {
|
TEST_F(ArrayTest, FriendlyNameRuntimeSizedNonImplicitStride) {
|
||||||
auto* arr = create<Array>(create<I32>(), create<RuntimeArrayCount>(), 0u, 4u, 8u, 4u);
|
auto* arr = create<Array>(create<I32>(), create<type::RuntimeArrayCount>(), 0u, 4u, 8u, 4u);
|
||||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(8) array<i32>");
|
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(8) array<i32>");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayTest, FriendlyNameStaticSizedNonImplicitStride) {
|
TEST_F(ArrayTest, FriendlyNameStaticSizedNonImplicitStride) {
|
||||||
auto* arr = create<Array>(create<I32>(), create<ConstantArrayCount>(5u), 4u, 20u, 8u, 4u);
|
auto* arr = create<Array>(create<I32>(), create<type::ConstantArrayCount>(5u), 4u, 20u, 8u, 4u);
|
||||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(8) array<i32, 5>");
|
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(8) array<i32, 5>");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayTest, IsConstructable) {
|
TEST_F(ArrayTest, IsConstructable) {
|
||||||
auto* fixed_sized =
|
auto* fixed_sized =
|
||||||
create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
||||||
auto* named_override_sized =
|
auto* named_override_sized = create<Array>(
|
||||||
create<Array>(create<U32>(), create<NamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
create<U32>(), create<sem::NamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
||||||
auto* unnamed_override_sized =
|
auto* unnamed_override_sized = create<Array>(
|
||||||
create<Array>(create<U32>(), create<UnnamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
create<U32>(), create<sem::UnnamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
||||||
auto* runtime_sized =
|
auto* runtime_sized =
|
||||||
create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 16u);
|
create<Array>(create<U32>(), create<type::RuntimeArrayCount>(), 4u, 8u, 32u, 16u);
|
||||||
|
|
||||||
EXPECT_TRUE(fixed_sized->IsConstructible());
|
EXPECT_TRUE(fixed_sized->IsConstructible());
|
||||||
EXPECT_FALSE(named_override_sized->IsConstructible());
|
EXPECT_FALSE(named_override_sized->IsConstructible());
|
||||||
|
@ -143,13 +143,13 @@ TEST_F(ArrayTest, IsConstructable) {
|
||||||
|
|
||||||
TEST_F(ArrayTest, HasCreationFixedFootprint) {
|
TEST_F(ArrayTest, HasCreationFixedFootprint) {
|
||||||
auto* fixed_sized =
|
auto* fixed_sized =
|
||||||
create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
||||||
auto* named_override_sized =
|
auto* named_override_sized = create<Array>(
|
||||||
create<Array>(create<U32>(), create<NamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
create<U32>(), create<sem::NamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
||||||
auto* unnamed_override_sized =
|
auto* unnamed_override_sized = create<Array>(
|
||||||
create<Array>(create<U32>(), create<UnnamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
create<U32>(), create<sem::UnnamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
||||||
auto* runtime_sized =
|
auto* runtime_sized =
|
||||||
create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 16u);
|
create<Array>(create<U32>(), create<type::RuntimeArrayCount>(), 4u, 8u, 32u, 16u);
|
||||||
|
|
||||||
EXPECT_TRUE(fixed_sized->HasCreationFixedFootprint());
|
EXPECT_TRUE(fixed_sized->HasCreationFixedFootprint());
|
||||||
EXPECT_FALSE(named_override_sized->HasCreationFixedFootprint());
|
EXPECT_FALSE(named_override_sized->HasCreationFixedFootprint());
|
||||||
|
@ -159,13 +159,13 @@ TEST_F(ArrayTest, HasCreationFixedFootprint) {
|
||||||
|
|
||||||
TEST_F(ArrayTest, HasFixedFootprint) {
|
TEST_F(ArrayTest, HasFixedFootprint) {
|
||||||
auto* fixed_sized =
|
auto* fixed_sized =
|
||||||
create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
create<Array>(create<U32>(), create<type::ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
|
||||||
auto* named_override_sized =
|
auto* named_override_sized = create<Array>(
|
||||||
create<Array>(create<U32>(), create<NamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
create<U32>(), create<sem::NamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
||||||
auto* unnamed_override_sized =
|
auto* unnamed_override_sized = create<Array>(
|
||||||
create<Array>(create<U32>(), create<UnnamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
create<U32>(), create<sem::UnnamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
|
||||||
auto* runtime_sized =
|
auto* runtime_sized =
|
||||||
create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 16u);
|
create<Array>(create<U32>(), create<type::RuntimeArrayCount>(), 4u, 8u, 32u, 16u);
|
||||||
|
|
||||||
EXPECT_TRUE(fixed_sized->HasFixedFootprint());
|
EXPECT_TRUE(fixed_sized->HasFixedFootprint());
|
||||||
EXPECT_TRUE(named_override_sized->HasFixedFootprint());
|
EXPECT_TRUE(named_override_sized->HasFixedFootprint());
|
||||||
|
|
|
@ -22,8 +22,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Atomic);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
Atomic::Atomic(const sem::Type* subtype)
|
Atomic::Atomic(const type::Type* subtype)
|
||||||
: Base(TypeFlags{
|
: Base(type::TypeFlags{
|
||||||
Flag::kCreationFixedFootprint,
|
Flag::kCreationFixedFootprint,
|
||||||
Flag::kFixedFootprint,
|
Flag::kFixedFootprint,
|
||||||
}),
|
}),
|
||||||
|
@ -35,7 +35,7 @@ size_t Atomic::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Atomic>().full_hashcode, subtype_);
|
return utils::Hash(TypeInfo::Of<Atomic>().full_hashcode, subtype_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Atomic::Equals(const sem::Type& other) const {
|
bool Atomic::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<Atomic>()) {
|
if (auto* o = other.As<Atomic>()) {
|
||||||
return o->subtype_ == subtype_;
|
return o->subtype_ == subtype_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,16 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A atomic type.
|
/// A atomic type.
|
||||||
class Atomic final : public Castable<Atomic, Type> {
|
class Atomic final : public Castable<Atomic, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param subtype the atomic type
|
/// @param subtype the atomic type
|
||||||
explicit Atomic(const sem::Type* subtype);
|
explicit Atomic(const type::Type* subtype);
|
||||||
|
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
Atomic(Atomic&&);
|
Atomic(Atomic&&);
|
||||||
|
@ -40,7 +40,7 @@ class Atomic final : public Castable<Atomic, Type> {
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const Type& other) const override;
|
||||||
|
|
||||||
/// @returns the atomic type
|
/// @returns the atomic type
|
||||||
const sem::Type* Type() const { return subtype_; }
|
const type::Type* Type() const { return subtype_; }
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
@ -54,7 +54,7 @@ class Atomic final : public Castable<Atomic, Type> {
|
||||||
uint32_t Align() const override;
|
uint32_t Align() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sem::Type const* const subtype_;
|
type::Type const* const subtype_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -21,7 +21,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Bool);
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
Bool::Bool()
|
Bool::Bool()
|
||||||
: Base(TypeFlags{
|
: Base(type::TypeFlags{
|
||||||
Flag::kConstructable,
|
Flag::kConstructable,
|
||||||
Flag::kCreationFixedFootprint,
|
Flag::kCreationFixedFootprint,
|
||||||
Flag::kFixedFootprint,
|
Flag::kFixedFootprint,
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
// X11 likes to #define Bool leading to confusing error messages.
|
// X11 likes to #define Bool leading to confusing error messages.
|
||||||
// If its defined, undefine it.
|
// If its defined, undefine it.
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A boolean type
|
/// A boolean type
|
||||||
class Bool final : public Castable<Bool, Type> {
|
class Bool final : public Castable<Bool, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Bool();
|
Bool();
|
||||||
|
|
|
@ -106,7 +106,7 @@ bool IsDP4aBuiltin(BuiltinType i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Builtin::Builtin(BuiltinType type,
|
Builtin::Builtin(BuiltinType type,
|
||||||
const sem::Type* return_type,
|
const type::Type* return_type,
|
||||||
utils::VectorRef<Parameter*> parameters,
|
utils::VectorRef<Parameter*> parameters,
|
||||||
EvaluationStage eval_stage,
|
EvaluationStage eval_stage,
|
||||||
PipelineStageSet supported_stages,
|
PipelineStageSet supported_stages,
|
||||||
|
|
|
@ -89,7 +89,7 @@ class Builtin final : public Castable<Builtin, CallTarget> {
|
||||||
/// @param is_deprecated true if the particular overload is considered
|
/// @param is_deprecated true if the particular overload is considered
|
||||||
/// deprecated
|
/// deprecated
|
||||||
Builtin(BuiltinType type,
|
Builtin(BuiltinType type,
|
||||||
const sem::Type* return_type,
|
const type::Type* return_type,
|
||||||
utils::VectorRef<Parameter*> parameters,
|
utils::VectorRef<Parameter*> parameters,
|
||||||
EvaluationStage eval_stage,
|
EvaluationStage eval_stage,
|
||||||
PipelineStageSet supported_stages,
|
PipelineStageSet supported_stages,
|
||||||
|
|
|
@ -23,7 +23,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::CallTarget);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
CallTarget::CallTarget(const sem::Type* return_type,
|
CallTarget::CallTarget(const type::Type* return_type,
|
||||||
utils::VectorRef<const Parameter*> parameters,
|
utils::VectorRef<const Parameter*> parameters,
|
||||||
EvaluationStage stage)
|
EvaluationStage stage)
|
||||||
: signature_{return_type, std::move(parameters)}, stage_(stage) {
|
: signature_{return_type, std::move(parameters)}, stage_(stage) {
|
||||||
|
@ -33,7 +33,7 @@ CallTarget::CallTarget(const sem::Type* return_type,
|
||||||
CallTarget::CallTarget(const CallTarget&) = default;
|
CallTarget::CallTarget(const CallTarget&) = default;
|
||||||
CallTarget::~CallTarget() = default;
|
CallTarget::~CallTarget() = default;
|
||||||
|
|
||||||
CallTargetSignature::CallTargetSignature(const sem::Type* ret_ty,
|
CallTargetSignature::CallTargetSignature(const type::Type* ret_ty,
|
||||||
utils::VectorRef<const sem::Parameter*> params)
|
utils::VectorRef<const sem::Parameter*> params)
|
||||||
: return_type(ret_ty), parameters(std::move(params)) {}
|
: return_type(ret_ty), parameters(std::move(params)) {}
|
||||||
CallTargetSignature::CallTargetSignature(const CallTargetSignature&) = default;
|
CallTargetSignature::CallTargetSignature(const CallTargetSignature&) = default;
|
||||||
|
|
|
@ -23,11 +23,6 @@
|
||||||
#include "src/tint/utils/hash.h"
|
#include "src/tint/utils/hash.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
namespace tint::sem {
|
|
||||||
class Type;
|
|
||||||
} // namespace tint::sem
|
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// CallTargetSignature holds the return type and parameters for a call target
|
/// CallTargetSignature holds the return type and parameters for a call target
|
||||||
|
@ -35,7 +30,7 @@ struct CallTargetSignature {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param ret_ty the call target return type
|
/// @param ret_ty the call target return type
|
||||||
/// @param params the call target parameters
|
/// @param params the call target parameters
|
||||||
CallTargetSignature(const sem::Type* ret_ty, utils::VectorRef<const Parameter*> params);
|
CallTargetSignature(const type::Type* ret_ty, utils::VectorRef<const Parameter*> params);
|
||||||
|
|
||||||
/// Copy constructor
|
/// Copy constructor
|
||||||
CallTargetSignature(const CallTargetSignature&);
|
CallTargetSignature(const CallTargetSignature&);
|
||||||
|
@ -44,7 +39,7 @@ struct CallTargetSignature {
|
||||||
~CallTargetSignature();
|
~CallTargetSignature();
|
||||||
|
|
||||||
/// The type of the call target return value
|
/// The type of the call target return value
|
||||||
const sem::Type* const return_type = nullptr;
|
const type::Type* const return_type = nullptr;
|
||||||
/// The parameters of the call target
|
/// The parameters of the call target
|
||||||
const utils::Vector<const sem::Parameter*, 8> parameters;
|
const utils::Vector<const sem::Parameter*, 8> parameters;
|
||||||
|
|
||||||
|
@ -75,7 +70,7 @@ class CallTarget : public Castable<CallTarget, Node> {
|
||||||
/// @param stage the earliest evaluation stage for a call to this target
|
/// @param stage the earliest evaluation stage for a call to this target
|
||||||
/// @param return_type the return type of the call target
|
/// @param return_type the return type of the call target
|
||||||
/// @param parameters the parameters for the call target
|
/// @param parameters the parameters for the call target
|
||||||
CallTarget(const sem::Type* return_type,
|
CallTarget(const type::Type* return_type,
|
||||||
utils::VectorRef<const Parameter*> parameters,
|
utils::VectorRef<const Parameter*> parameters,
|
||||||
EvaluationStage stage);
|
EvaluationStage stage);
|
||||||
|
|
||||||
|
@ -86,7 +81,7 @@ class CallTarget : public Castable<CallTarget, Node> {
|
||||||
~CallTarget() override;
|
~CallTarget() override;
|
||||||
|
|
||||||
/// @return the return type of the call target
|
/// @return the return type of the call target
|
||||||
const sem::Type* ReturnType() const { return signature_.return_type; }
|
const type::Type* ReturnType() const { return signature_.return_type; }
|
||||||
|
|
||||||
/// @return the parameters of the call target
|
/// @return the parameters of the call target
|
||||||
auto& Parameters() const { return signature_.parameters; }
|
auto& Parameters() const { return signature_.parameters; }
|
||||||
|
|
|
@ -18,11 +18,7 @@
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include "src/tint/number.h"
|
#include "src/tint/number.h"
|
||||||
|
#include "src/tint/type/type.h"
|
||||||
// Forward declarations
|
|
||||||
namespace tint::sem {
|
|
||||||
class Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
|
@ -36,7 +32,7 @@ class Constant {
|
||||||
virtual ~Constant();
|
virtual ~Constant();
|
||||||
|
|
||||||
/// @returns the type of the constant
|
/// @returns the type of the constant
|
||||||
virtual const sem::Type* Type() const = 0;
|
virtual const type::Type* Type() const = 0;
|
||||||
|
|
||||||
/// @returns the value of this Constant, if this constant is of a scalar value or abstract
|
/// @returns the value of this Constant, if this constant is of a scalar value or abstract
|
||||||
/// numeric, otherwise std::monostate.
|
/// numeric, otherwise std::monostate.
|
||||||
|
|
|
@ -40,7 +40,7 @@ size_t DepthMultisampledTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<DepthMultisampledTexture>().full_hashcode, dim());
|
return utils::Hash(TypeInfo::Of<DepthMultisampledTexture>().full_hashcode, dim());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DepthMultisampledTexture::Equals(const sem::Type& other) const {
|
bool DepthMultisampledTexture::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<DepthMultisampledTexture>()) {
|
if (auto* o = other.As<DepthMultisampledTexture>()) {
|
||||||
return o->dim() == dim();
|
return o->dim() == dim();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ size_t DepthTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<DepthTexture>().full_hashcode, dim());
|
return utils::Hash(TypeInfo::Of<DepthTexture>().full_hashcode, dim());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DepthTexture::Equals(const sem::Type& other) const {
|
bool DepthTexture::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<DepthTexture>()) {
|
if (auto* o = other.As<DepthTexture>()) {
|
||||||
return o->dim() == dim();
|
return o->dim() == dim();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Expression);
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
Expression::Expression(const ast::Expression* declaration,
|
Expression::Expression(const ast::Expression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class Statement;
|
class Statement;
|
||||||
class Type;
|
|
||||||
class Variable;
|
class Variable;
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@ class Expression : public Castable<Expression, Node> {
|
||||||
/// @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,
|
Expression(const ast::Expression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
|
@ -56,7 +55,7 @@ class Expression : public Castable<Expression, Node> {
|
||||||
const ast::Expression* Declaration() const { return declaration_; }
|
const ast::Expression* Declaration() const { return declaration_; }
|
||||||
|
|
||||||
/// @return the resolved type of the expression
|
/// @return the resolved type of the expression
|
||||||
const sem::Type* Type() const { return type_; }
|
const type::Type* Type() const { return type_; }
|
||||||
|
|
||||||
/// @return the earliest evaluation stage for the expression
|
/// @return the earliest evaluation stage for the expression
|
||||||
EvaluationStage Stage() const { return stage_; }
|
EvaluationStage Stage() const { return stage_; }
|
||||||
|
@ -93,7 +92,7 @@ class Expression : public Castable<Expression, Node> {
|
||||||
const Variable* root_identifier_;
|
const Variable* root_identifier_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const sem::Type* const type_;
|
const type::Type* const type_;
|
||||||
const EvaluationStage stage_;
|
const EvaluationStage stage_;
|
||||||
const Statement* const statement_;
|
const Statement* const statement_;
|
||||||
const Constant* const constant_;
|
const Constant* const constant_;
|
||||||
|
|
|
@ -25,9 +25,9 @@ namespace {
|
||||||
|
|
||||||
class MockConstant : public sem::Constant {
|
class MockConstant : public sem::Constant {
|
||||||
public:
|
public:
|
||||||
explicit MockConstant(const sem::Type* ty) : type(ty) {}
|
explicit MockConstant(const type::Type* ty) : type(ty) {}
|
||||||
~MockConstant() override {}
|
~MockConstant() override {}
|
||||||
const sem::Type* Type() const override { return type; }
|
const type::Type* Type() const override { return type; }
|
||||||
std::variant<std::monostate, AInt, AFloat> Value() const override { return {}; }
|
std::variant<std::monostate, AInt, AFloat> Value() const override { return {}; }
|
||||||
const Constant* Index(size_t) const override { return {}; }
|
const Constant* Index(size_t) const override { return {}; }
|
||||||
bool AllZero() const override { return {}; }
|
bool AllZero() const override { return {}; }
|
||||||
|
@ -36,7 +36,7 @@ class MockConstant : public sem::Constant {
|
||||||
size_t Hash() const override { return 0; }
|
size_t Hash() const override { return 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const sem::Type* type;
|
const type::Type* type;
|
||||||
};
|
};
|
||||||
|
|
||||||
using ExpressionTest = TestHelper;
|
using ExpressionTest = TestHelper;
|
||||||
|
|
|
@ -30,7 +30,7 @@ size_t ExternalTexture::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<ExternalTexture>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<ExternalTexture>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExternalTexture::Equals(const sem::Type& other) const {
|
bool ExternalTexture::Equals(const type::Type& other) const {
|
||||||
return other.Is<ExternalTexture>();
|
return other.Is<ExternalTexture>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace tint {
|
||||||
namespace sem {
|
namespace sem {
|
||||||
|
|
||||||
F16::F16()
|
F16::F16()
|
||||||
: Base(TypeFlags{
|
: Base(type::TypeFlags{
|
||||||
Flag::kConstructable,
|
Flag::kConstructable,
|
||||||
Flag::kCreationFixedFootprint,
|
Flag::kCreationFixedFootprint,
|
||||||
Flag::kFixedFootprint,
|
Flag::kFixedFootprint,
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A float 16 type
|
/// A float 16 type
|
||||||
class F16 final : public Castable<F16, Type> {
|
class F16 final : public Castable<F16, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
F16();
|
F16();
|
||||||
|
|
|
@ -21,7 +21,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::F32);
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
F32::F32()
|
F32::F32()
|
||||||
: Base(TypeFlags{
|
: Base(type::TypeFlags{
|
||||||
Flag::kConstructable,
|
Flag::kConstructable,
|
||||||
Flag::kCreationFixedFootprint,
|
Flag::kCreationFixedFootprint,
|
||||||
Flag::kFixedFootprint,
|
Flag::kFixedFootprint,
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A float 32 type
|
/// A float 32 type
|
||||||
class F32 final : public Castable<F32, Type> {
|
class F32 final : public Castable<F32, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
F32();
|
F32();
|
||||||
|
|
|
@ -39,7 +39,7 @@ utils::VectorRef<const Parameter*> SetOwner(utils::VectorRef<Parameter*> paramet
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Function::Function(const ast::Function* declaration,
|
Function::Function(const ast::Function* declaration,
|
||||||
Type* return_type,
|
type::Type* return_type,
|
||||||
std::optional<uint32_t> return_location,
|
std::optional<uint32_t> return_location,
|
||||||
utils::VectorRef<Parameter*> parameters)
|
utils::VectorRef<Parameter*> parameters)
|
||||||
: Base(return_type, SetOwner(std::move(parameters), this), EvaluationStage::kRuntime),
|
: Base(return_type, SetOwner(std::move(parameters), this), EvaluationStage::kRuntime),
|
||||||
|
|
|
@ -57,7 +57,7 @@ class Function final : public Castable<Function, CallTarget> {
|
||||||
/// @param return_location the location value for the return, if provided
|
/// @param return_location the location value for the return, if provided
|
||||||
/// @param parameters the parameters to the function
|
/// @param parameters the parameters to the function
|
||||||
Function(const ast::Function* declaration,
|
Function(const ast::Function* declaration,
|
||||||
Type* return_type,
|
type::Type* return_type,
|
||||||
std::optional<uint32_t> return_location,
|
std::optional<uint32_t> return_location,
|
||||||
utils::VectorRef<Parameter*> parameters);
|
utils::VectorRef<Parameter*> parameters);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::I32);
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
I32::I32()
|
I32::I32()
|
||||||
: Base(TypeFlags{
|
: Base(type::TypeFlags{
|
||||||
Flag::kConstructable,
|
Flag::kConstructable,
|
||||||
Flag::kCreationFixedFootprint,
|
Flag::kCreationFixedFootprint,
|
||||||
Flag::kFixedFootprint,
|
Flag::kFixedFootprint,
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A signed int 32 type.
|
/// A signed int 32 type.
|
||||||
class I32 final : public Castable<I32, Type> {
|
class I32 final : public Castable<I32, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
I32();
|
I32();
|
||||||
|
|
|
@ -23,7 +23,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::IndexAccessorExpression);
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
IndexAccessorExpression::IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
IndexAccessorExpression::IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
const Expression* index,
|
const Expression* index,
|
||||||
|
|
|
@ -40,7 +40,7 @@ class IndexAccessorExpression final : public Castable<IndexAccessorExpression, E
|
||||||
/// @param has_side_effects whether this expression may have side effects
|
/// @param has_side_effects whether 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
|
||||||
IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
const Expression* index,
|
const Expression* index,
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class Module;
|
class Module;
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
namespace tint::type {
|
||||||
|
class Node;
|
||||||
|
class Type;
|
||||||
|
} // namespace tint::type
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
|
@ -142,7 +146,7 @@ class Info {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// AST node index to semantic node
|
// AST node index to semantic node
|
||||||
std::vector<const sem::Node*> nodes_;
|
std::vector<const CastableBase*> nodes_;
|
||||||
// Lists transitively referenced overrides for the given item
|
// Lists transitively referenced overrides for the given item
|
||||||
std::unordered_map<const CastableBase*, TransitivelyReferenced> referenced_overrides_;
|
std::unordered_map<const CastableBase*, TransitivelyReferenced> referenced_overrides_;
|
||||||
// The semantic module
|
// The semantic module
|
||||||
|
|
|
@ -23,7 +23,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Matrix);
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
Matrix::Matrix(const Vector* column_type, uint32_t columns)
|
Matrix::Matrix(const Vector* column_type, uint32_t columns)
|
||||||
: Base(TypeFlags{
|
: Base(type::TypeFlags{
|
||||||
Flag::kConstructable,
|
Flag::kConstructable,
|
||||||
Flag::kCreationFixedFootprint,
|
Flag::kCreationFixedFootprint,
|
||||||
Flag::kFixedFootprint,
|
Flag::kFixedFootprint,
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
@ -27,7 +27,7 @@ class Vector;
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A matrix type
|
/// A matrix type
|
||||||
class Matrix final : public Castable<Matrix, Type> {
|
class Matrix final : public Castable<Matrix, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param column_type the type of a column of the matrix
|
/// @param column_type the type of a column of the matrix
|
||||||
|
@ -45,7 +45,7 @@ class Matrix final : public Castable<Matrix, Type> {
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const Type& other) const override;
|
||||||
|
|
||||||
/// @returns the type of the matrix
|
/// @returns the type of the matrix
|
||||||
const Type* type() const { return subtype_; }
|
const type::Type* type() const { return subtype_; }
|
||||||
/// @returns the number of rows in the matrix
|
/// @returns the number of rows in the matrix
|
||||||
uint32_t rows() const { return rows_; }
|
uint32_t rows() const { return rows_; }
|
||||||
/// @returns the number of columns in the matrix
|
/// @returns the number of columns in the matrix
|
||||||
|
@ -70,7 +70,7 @@ class Matrix final : public Castable<Matrix, Type> {
|
||||||
uint32_t ColumnStride() const;
|
uint32_t ColumnStride() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Type* const subtype_;
|
const type::Type* const subtype_;
|
||||||
const Vector* const column_type_;
|
const Vector* const column_type_;
|
||||||
const uint32_t rows_;
|
const uint32_t rows_;
|
||||||
const uint32_t columns_;
|
const uint32_t columns_;
|
||||||
|
|
|
@ -24,7 +24,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Swizzle);
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
MemberAccessorExpression::MemberAccessorExpression(const ast::MemberAccessorExpression* declaration,
|
MemberAccessorExpression::MemberAccessorExpression(const ast::MemberAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
|
@ -37,7 +37,7 @@ MemberAccessorExpression::MemberAccessorExpression(const ast::MemberAccessorExpr
|
||||||
MemberAccessorExpression::~MemberAccessorExpression() = default;
|
MemberAccessorExpression::~MemberAccessorExpression() = default;
|
||||||
|
|
||||||
StructMemberAccess::StructMemberAccess(const ast::MemberAccessorExpression* declaration,
|
StructMemberAccess::StructMemberAccess(const ast::MemberAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
|
@ -57,7 +57,7 @@ StructMemberAccess::StructMemberAccess(const ast::MemberAccessorExpression* decl
|
||||||
StructMemberAccess::~StructMemberAccess() = default;
|
StructMemberAccess::~StructMemberAccess() = default;
|
||||||
|
|
||||||
Swizzle::Swizzle(const ast::MemberAccessorExpression* declaration,
|
Swizzle::Swizzle(const ast::MemberAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
|
|
|
@ -50,7 +50,7 @@ class MemberAccessorExpression : public Castable<MemberAccessorExpression, Expre
|
||||||
/// @param has_side_effects whether this expression may have side effects
|
/// @param has_side_effects whether 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
|
||||||
MemberAccessorExpression(const ast::MemberAccessorExpression* declaration,
|
MemberAccessorExpression(const ast::MemberAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
|
@ -77,7 +77,7 @@ class StructMemberAccess final : public Castable<StructMemberAccess, MemberAcces
|
||||||
/// @param has_side_effects whether this expression may have side effects
|
/// @param has_side_effects whether 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
|
||||||
StructMemberAccess(const ast::MemberAccessorExpression* declaration,
|
StructMemberAccess(const ast::MemberAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
|
@ -109,7 +109,7 @@ class Swizzle final : public Castable<Swizzle, MemberAccessorExpression> {
|
||||||
/// @param has_side_effects whether this expression may have side effects
|
/// @param has_side_effects whether 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
|
||||||
Swizzle(const ast::MemberAccessorExpression* declaration,
|
Swizzle(const ast::MemberAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
|
|
|
@ -21,7 +21,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::MultisampledTexture);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
MultisampledTexture::MultisampledTexture(ast::TextureDimension dim, const Type* type)
|
MultisampledTexture::MultisampledTexture(ast::TextureDimension dim, const type::Type* type)
|
||||||
: Base(dim), type_(type) {
|
: Base(dim), type_(type) {
|
||||||
TINT_ASSERT(Semantic, type_);
|
TINT_ASSERT(Semantic, type_);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ size_t MultisampledTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<MultisampledTexture>().full_hashcode, dim(), type_);
|
return utils::Hash(TypeInfo::Of<MultisampledTexture>().full_hashcode, dim(), type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MultisampledTexture::Equals(const sem::Type& other) const {
|
bool MultisampledTexture::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<MultisampledTexture>()) {
|
if (auto* o = other.As<MultisampledTexture>()) {
|
||||||
return o->dim() == dim() && o->type_ == type_;
|
return o->dim() == dim() && o->type_ == type_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class MultisampledTexture final : public Castable<MultisampledTexture, Texture>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param dim the dimensionality of the texture
|
/// @param dim the dimensionality of the texture
|
||||||
/// @param type the data type of the multisampled texture
|
/// @param type the data type of the multisampled texture
|
||||||
MultisampledTexture(ast::TextureDimension dim, const Type* type);
|
MultisampledTexture(ast::TextureDimension dim, const type::Type* type);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
MultisampledTexture(MultisampledTexture&&);
|
MultisampledTexture(MultisampledTexture&&);
|
||||||
~MultisampledTexture() override;
|
~MultisampledTexture() override;
|
||||||
|
@ -40,7 +40,7 @@ class MultisampledTexture final : public Castable<MultisampledTexture, Texture>
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const Type& other) const override;
|
||||||
|
|
||||||
/// @returns the subtype of the sampled texture
|
/// @returns the subtype of the sampled texture
|
||||||
const Type* type() const { return type_; }
|
const type::Type* type() const { return type_; }
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
@ -48,7 +48,7 @@ class MultisampledTexture final : public Castable<MultisampledTexture, Texture>
|
||||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Type* const type_;
|
const type::Type* const type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -22,8 +22,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Pointer);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
Pointer::Pointer(const Type* subtype, ast::AddressSpace address_space, ast::Access access)
|
Pointer::Pointer(const type::Type* subtype, ast::AddressSpace address_space, ast::Access access)
|
||||||
: Base(TypeFlags{}), subtype_(subtype), address_space_(address_space), access_(access) {
|
: Base(type::TypeFlags{}), subtype_(subtype), address_space_(address_space), access_(access) {
|
||||||
TINT_ASSERT(Semantic, !subtype->Is<Reference>());
|
TINT_ASSERT(Semantic, !subtype->Is<Reference>());
|
||||||
TINT_ASSERT(Semantic, access != ast::Access::kUndefined);
|
TINT_ASSERT(Semantic, access != ast::Access::kUndefined);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ size_t Pointer::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, address_space_, subtype_, access_);
|
return utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, address_space_, subtype_, access_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pointer::Equals(const sem::Type& other) const {
|
bool Pointer::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<Pointer>()) {
|
if (auto* o = other.As<Pointer>()) {
|
||||||
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
|
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
|
||||||
o->access_ == access_;
|
o->access_ == access_;
|
||||||
|
|
|
@ -19,18 +19,18 @@
|
||||||
|
|
||||||
#include "src/tint/ast/access.h"
|
#include "src/tint/ast/access.h"
|
||||||
#include "src/tint/ast/address_space.h"
|
#include "src/tint/ast/address_space.h"
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A pointer type.
|
/// A pointer type.
|
||||||
class Pointer final : public Castable<Pointer, Type> {
|
class Pointer final : public Castable<Pointer, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param subtype the pointee type
|
/// @param subtype the pointee type
|
||||||
/// @param address_space the address space of the pointer
|
/// @param address_space the address space of the pointer
|
||||||
/// @param access the resolved access control of the reference
|
/// @param access the resolved access control of the reference
|
||||||
Pointer(const Type* subtype, ast::AddressSpace address_space, ast::Access access);
|
Pointer(const type::Type* subtype, ast::AddressSpace address_space, ast::Access access);
|
||||||
|
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
Pointer(Pointer&&);
|
Pointer(Pointer&&);
|
||||||
|
@ -44,7 +44,7 @@ class Pointer final : public Castable<Pointer, Type> {
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const Type& other) const override;
|
||||||
|
|
||||||
/// @returns the pointee type
|
/// @returns the pointee type
|
||||||
const Type* StoreType() const { return subtype_; }
|
const type::Type* StoreType() const { return subtype_; }
|
||||||
|
|
||||||
/// @returns the address space of the pointer
|
/// @returns the address space of the pointer
|
||||||
ast::AddressSpace AddressSpace() const { return address_space_; }
|
ast::AddressSpace AddressSpace() const { return address_space_; }
|
||||||
|
|
|
@ -21,8 +21,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Reference);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
Reference::Reference(const Type* subtype, ast::AddressSpace address_space, ast::Access access)
|
Reference::Reference(const type::Type* subtype, ast::AddressSpace address_space, ast::Access access)
|
||||||
: Base(TypeFlags{}), subtype_(subtype), address_space_(address_space), access_(access) {
|
: Base(type::TypeFlags{}), subtype_(subtype), address_space_(address_space), access_(access) {
|
||||||
TINT_ASSERT(Semantic, !subtype->Is<Reference>());
|
TINT_ASSERT(Semantic, !subtype->Is<Reference>());
|
||||||
TINT_ASSERT(Semantic, access != ast::Access::kUndefined);
|
TINT_ASSERT(Semantic, access != ast::Access::kUndefined);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ size_t Reference::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Reference>().full_hashcode, address_space_, subtype_, access_);
|
return utils::Hash(TypeInfo::Of<Reference>().full_hashcode, address_space_, subtype_, access_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Reference::Equals(const sem::Type& other) const {
|
bool Reference::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<Reference>()) {
|
if (auto* o = other.As<Reference>()) {
|
||||||
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
|
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
|
||||||
o->access_ == access_;
|
o->access_ == access_;
|
||||||
|
|
|
@ -19,18 +19,18 @@
|
||||||
|
|
||||||
#include "src/tint/ast/access.h"
|
#include "src/tint/ast/access.h"
|
||||||
#include "src/tint/ast/address_space.h"
|
#include "src/tint/ast/address_space.h"
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A reference type.
|
/// A reference type.
|
||||||
class Reference final : public Castable<Reference, Type> {
|
class Reference final : public Castable<Reference, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param subtype the pointee type
|
/// @param subtype the pointee type
|
||||||
/// @param address_space the address space of the reference
|
/// @param address_space the address space of the reference
|
||||||
/// @param access the resolved access control of the reference
|
/// @param access the resolved access control of the reference
|
||||||
Reference(const Type* subtype, ast::AddressSpace address_space, ast::Access access);
|
Reference(const type::Type* subtype, ast::AddressSpace address_space, ast::Access access);
|
||||||
|
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
Reference(Reference&&);
|
Reference(Reference&&);
|
||||||
|
@ -44,7 +44,7 @@ class Reference final : public Castable<Reference, Type> {
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const Type& other) const override;
|
||||||
|
|
||||||
/// @returns the pointee type
|
/// @returns the pointee type
|
||||||
const Type* StoreType() const { return subtype_; }
|
const type::Type* StoreType() const { return subtype_; }
|
||||||
|
|
||||||
/// @returns the address space of the reference
|
/// @returns the address space of the reference
|
||||||
ast::AddressSpace AddressSpace() const { return address_space_; }
|
ast::AddressSpace AddressSpace() const { return address_space_; }
|
||||||
|
|
|
@ -21,7 +21,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::SampledTexture);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
SampledTexture::SampledTexture(ast::TextureDimension dim, const Type* type)
|
SampledTexture::SampledTexture(ast::TextureDimension dim, const type::Type* type)
|
||||||
: Base(dim), type_(type) {
|
: Base(dim), type_(type) {
|
||||||
TINT_ASSERT(Semantic, type_);
|
TINT_ASSERT(Semantic, type_);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ size_t SampledTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<SampledTexture>().full_hashcode, dim(), type_);
|
return utils::Hash(TypeInfo::Of<SampledTexture>().full_hashcode, dim(), type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SampledTexture::Equals(const sem::Type& other) const {
|
bool SampledTexture::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<SampledTexture>()) {
|
if (auto* o = other.As<SampledTexture>()) {
|
||||||
return o->dim() == dim() && o->type_ == type_;
|
return o->dim() == dim() && o->type_ == type_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class SampledTexture final : public Castable<SampledTexture, Texture> {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param dim the dimensionality of the texture
|
/// @param dim the dimensionality of the texture
|
||||||
/// @param type the data type of the sampled texture
|
/// @param type the data type of the sampled texture
|
||||||
SampledTexture(ast::TextureDimension dim, const Type* type);
|
SampledTexture(ast::TextureDimension dim, const type::Type* type);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
SampledTexture(SampledTexture&&);
|
SampledTexture(SampledTexture&&);
|
||||||
~SampledTexture() override;
|
~SampledTexture() override;
|
||||||
|
@ -40,7 +40,7 @@ class SampledTexture final : public Castable<SampledTexture, Texture> {
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const Type& other) const override;
|
||||||
|
|
||||||
/// @returns the subtype of the sampled texture
|
/// @returns the subtype of the sampled texture
|
||||||
Type* type() const { return const_cast<Type*>(type_); }
|
type::Type* type() const { return const_cast<type::Type*>(type_); }
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
@ -48,7 +48,7 @@ class SampledTexture final : public Castable<SampledTexture, Texture> {
|
||||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Type* const type_;
|
const type::Type* const type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -21,7 +21,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Sampler);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
Sampler::Sampler(ast::SamplerKind kind) : Base(TypeFlags{}), kind_(kind) {}
|
Sampler::Sampler(ast::SamplerKind kind) : Base(type::TypeFlags{}), kind_(kind) {}
|
||||||
|
|
||||||
Sampler::Sampler(Sampler&&) = default;
|
Sampler::Sampler(Sampler&&) = default;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ size_t Sampler::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Sampler>().full_hashcode, kind_);
|
return utils::Hash(TypeInfo::Of<Sampler>().full_hashcode, kind_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sampler::Equals(const sem::Type& other) const {
|
bool Sampler::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<Sampler>()) {
|
if (auto* o = other.As<Sampler>()) {
|
||||||
return o->kind_ == kind_;
|
return o->kind_ == kind_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/ast/sampler.h"
|
#include "src/tint/ast/sampler.h"
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A sampler type.
|
/// A sampler type.
|
||||||
class Sampler final : public Castable<Sampler, Type> {
|
class Sampler final : public Castable<Sampler, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param kind the kind of sampler
|
/// @param kind the kind of sampler
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace tint::sem {
|
||||||
StorageTexture::StorageTexture(ast::TextureDimension dim,
|
StorageTexture::StorageTexture(ast::TextureDimension dim,
|
||||||
ast::TexelFormat format,
|
ast::TexelFormat format,
|
||||||
ast::Access access,
|
ast::Access access,
|
||||||
sem::Type* subtype)
|
type::Type* subtype)
|
||||||
: Base(dim), texel_format_(format), access_(access), subtype_(subtype) {}
|
: Base(dim), texel_format_(format), access_(access), subtype_(subtype) {}
|
||||||
|
|
||||||
StorageTexture::StorageTexture(StorageTexture&&) = default;
|
StorageTexture::StorageTexture(StorageTexture&&) = default;
|
||||||
|
@ -35,7 +35,7 @@ size_t StorageTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<StorageTexture>().full_hashcode, dim(), texel_format_, access_);
|
return utils::Hash(TypeInfo::Of<StorageTexture>().full_hashcode, dim(), texel_format_, access_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StorageTexture::Equals(const sem::Type& other) const {
|
bool StorageTexture::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<StorageTexture>()) {
|
if (auto* o = other.As<StorageTexture>()) {
|
||||||
return o->dim() == dim() && o->texel_format_ == texel_format_ && o->access_ == access_;
|
return o->dim() == dim() && o->texel_format_ == texel_format_ && o->access_ == access_;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ std::string StorageTexture::FriendlyName(const SymbolTable&) const {
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Type* StorageTexture::SubtypeFor(ast::TexelFormat format, sem::TypeManager& type_mgr) {
|
type::Type* StorageTexture::SubtypeFor(ast::TexelFormat format, sem::TypeManager& type_mgr) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case ast::TexelFormat::kR32Uint:
|
case ast::TexelFormat::kR32Uint:
|
||||||
case ast::TexelFormat::kRgba8Uint:
|
case ast::TexelFormat::kRgba8Uint:
|
||||||
|
|
|
@ -39,7 +39,7 @@ class StorageTexture final : public Castable<StorageTexture, Texture> {
|
||||||
StorageTexture(ast::TextureDimension dim,
|
StorageTexture(ast::TextureDimension dim,
|
||||||
ast::TexelFormat format,
|
ast::TexelFormat format,
|
||||||
ast::Access access,
|
ast::Access access,
|
||||||
sem::Type* subtype);
|
type::Type* subtype);
|
||||||
|
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
StorageTexture(StorageTexture&&);
|
StorageTexture(StorageTexture&&);
|
||||||
|
@ -53,7 +53,7 @@ class StorageTexture final : public Castable<StorageTexture, Texture> {
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const Type& other) const override;
|
||||||
|
|
||||||
/// @returns the storage subtype
|
/// @returns the storage subtype
|
||||||
Type* type() const { return subtype_; }
|
type::Type* type() const { return subtype_; }
|
||||||
|
|
||||||
/// @returns the texel format
|
/// @returns the texel format
|
||||||
ast::TexelFormat texel_format() const { return texel_format_; }
|
ast::TexelFormat texel_format() const { return texel_format_; }
|
||||||
|
@ -69,12 +69,12 @@ class StorageTexture final : public Castable<StorageTexture, Texture> {
|
||||||
/// @param format the storage texture image format
|
/// @param format the storage texture image format
|
||||||
/// @param type_mgr the sem::TypeManager used to build the returned type
|
/// @param type_mgr the sem::TypeManager used to build the returned type
|
||||||
/// @returns the storage texture subtype for the given TexelFormat
|
/// @returns the storage texture subtype for the given TexelFormat
|
||||||
static sem::Type* SubtypeFor(ast::TexelFormat format, sem::TypeManager& type_mgr);
|
static type::Type* SubtypeFor(ast::TexelFormat format, sem::TypeManager& type_mgr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ast::TexelFormat const texel_format_;
|
ast::TexelFormat const texel_format_;
|
||||||
ast::Access const access_;
|
ast::Access const access_;
|
||||||
Type* const subtype_;
|
type::Type* const subtype_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -106,8 +106,8 @@ TEST_F(StorageTextureTest, FriendlyName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StorageTextureTest, F32) {
|
TEST_F(StorageTextureTest, F32) {
|
||||||
Type* s = Create(ast::TextureDimension::k2dArray, ast::TexelFormat::kRgba32Float,
|
type::Type* s = Create(ast::TextureDimension::k2dArray, ast::TexelFormat::kRgba32Float,
|
||||||
ast::Access::kReadWrite);
|
ast::Access::kReadWrite);
|
||||||
|
|
||||||
auto program = Build();
|
auto program = Build();
|
||||||
|
|
||||||
|
@ -119,8 +119,9 @@ TEST_F(StorageTextureTest, F32) {
|
||||||
|
|
||||||
TEST_F(StorageTextureTest, U32) {
|
TEST_F(StorageTextureTest, U32) {
|
||||||
auto* subtype = sem::StorageTexture::SubtypeFor(ast::TexelFormat::kRg32Uint, Types());
|
auto* subtype = sem::StorageTexture::SubtypeFor(ast::TexelFormat::kRg32Uint, Types());
|
||||||
Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray, ast::TexelFormat::kRg32Uint,
|
type::Type* s =
|
||||||
ast::Access::kReadWrite, subtype);
|
create<StorageTexture>(ast::TextureDimension::k2dArray, ast::TexelFormat::kRg32Uint,
|
||||||
|
ast::Access::kReadWrite, subtype);
|
||||||
|
|
||||||
auto program = Build();
|
auto program = Build();
|
||||||
|
|
||||||
|
@ -132,8 +133,9 @@ TEST_F(StorageTextureTest, U32) {
|
||||||
|
|
||||||
TEST_F(StorageTextureTest, I32) {
|
TEST_F(StorageTextureTest, I32) {
|
||||||
auto* subtype = sem::StorageTexture::SubtypeFor(ast::TexelFormat::kRgba32Sint, Types());
|
auto* subtype = sem::StorageTexture::SubtypeFor(ast::TexelFormat::kRgba32Sint, Types());
|
||||||
Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray, ast::TexelFormat::kRgba32Sint,
|
type::Type* s =
|
||||||
ast::Access::kReadWrite, subtype);
|
create<StorageTexture>(ast::TextureDimension::k2dArray, ast::TexelFormat::kRgba32Sint,
|
||||||
|
ast::Access::kReadWrite, subtype);
|
||||||
|
|
||||||
auto program = Build();
|
auto program = Build();
|
||||||
|
|
||||||
|
|
|
@ -31,21 +31,21 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::StructMember);
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
TypeFlags FlagsFrom(utils::VectorRef<const StructMemberBase*> members) {
|
type::TypeFlags FlagsFrom(utils::VectorRef<const StructMemberBase*> members) {
|
||||||
TypeFlags flags{
|
type::TypeFlags flags{
|
||||||
TypeFlag::kConstructable,
|
type::TypeFlag::kConstructable,
|
||||||
TypeFlag::kCreationFixedFootprint,
|
type::TypeFlag::kCreationFixedFootprint,
|
||||||
TypeFlag::kFixedFootprint,
|
type::TypeFlag::kFixedFootprint,
|
||||||
};
|
};
|
||||||
for (auto* member : members) {
|
for (auto* member : members) {
|
||||||
if (!member->Type()->IsConstructible()) {
|
if (!member->Type()->IsConstructible()) {
|
||||||
flags.Remove(TypeFlag::kConstructable);
|
flags.Remove(type::TypeFlag::kConstructable);
|
||||||
}
|
}
|
||||||
if (!member->Type()->HasFixedFootprint()) {
|
if (!member->Type()->HasFixedFootprint()) {
|
||||||
flags.Remove(TypeFlag::kFixedFootprint);
|
flags.Remove(type::TypeFlag::kFixedFootprint);
|
||||||
}
|
}
|
||||||
if (!member->Type()->HasCreationFixedFootprint()) {
|
if (!member->Type()->HasCreationFixedFootprint()) {
|
||||||
flags.Remove(TypeFlag::kCreationFixedFootprint);
|
flags.Remove(type::TypeFlag::kCreationFixedFootprint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flags;
|
return flags;
|
||||||
|
@ -84,7 +84,7 @@ size_t StructBase::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Struct>().full_hashcode, name_);
|
return utils::Hash(TypeInfo::Of<Struct>().full_hashcode, name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StructBase::Equals(const sem::Type& other) const {
|
bool StructBase::Equals(const type::Type& other) const {
|
||||||
if (auto* o = other.As<Struct>()) {
|
if (auto* o = other.As<Struct>()) {
|
||||||
return o->name_ == name_;
|
return o->name_ == name_;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ std::string StructBase::Layout(const tint::SymbolTable& symbols) const {
|
||||||
StructMember::StructMember(const ast::StructMember* declaration,
|
StructMember::StructMember(const ast::StructMember* declaration,
|
||||||
tint::Source source,
|
tint::Source source,
|
||||||
Symbol name,
|
Symbol name,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
uint32_t index,
|
uint32_t index,
|
||||||
uint32_t offset,
|
uint32_t offset,
|
||||||
uint32_t align,
|
uint32_t align,
|
||||||
|
@ -195,7 +195,7 @@ StructMember::~StructMember() = default;
|
||||||
|
|
||||||
StructMemberBase::StructMemberBase(tint::Source source,
|
StructMemberBase::StructMemberBase(tint::Source source,
|
||||||
Symbol name,
|
Symbol name,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
uint32_t index,
|
uint32_t index,
|
||||||
uint32_t offset,
|
uint32_t offset,
|
||||||
uint32_t align,
|
uint32_t align,
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
#include "src/tint/ast/address_space.h"
|
#include "src/tint/ast/address_space.h"
|
||||||
#include "src/tint/ast/struct.h"
|
#include "src/tint/ast/struct.h"
|
||||||
#include "src/tint/sem/node.h"
|
#include "src/tint/sem/node.h"
|
||||||
#include "src/tint/sem/type.h"
|
|
||||||
#include "src/tint/symbol.h"
|
#include "src/tint/symbol.h"
|
||||||
|
#include "src/tint/type/type.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
|
@ -35,7 +35,6 @@ class StructMember;
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
class StructMember;
|
class StructMember;
|
||||||
class StructMemberBase;
|
class StructMemberBase;
|
||||||
class Type;
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
@ -51,7 +50,7 @@ enum class PipelineStageUsage {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// StructBase holds the semantic information for structures.
|
/// StructBase holds the semantic information for structures.
|
||||||
class StructBase : public Castable<StructBase, Type> {
|
class StructBase : public Castable<StructBase, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param source the source of the structure
|
/// @param source the source of the structure
|
||||||
|
@ -208,7 +207,7 @@ class Struct final : public Castable<Struct, StructBase> {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// StructMemberBase holds the semantic information for structure members.
|
/// StructMemberBase holds the semantic information for structure members.
|
||||||
class StructMemberBase : public Castable<StructMemberBase, Node> {
|
class StructMemberBase : public Castable<StructMemberBase, type::Node> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param source the source of the struct member
|
/// @param source the source of the struct member
|
||||||
|
@ -221,7 +220,7 @@ class StructMemberBase : public Castable<StructMemberBase, Node> {
|
||||||
/// @param location the location attribute, if present
|
/// @param location the location attribute, if present
|
||||||
StructMemberBase(tint::Source source,
|
StructMemberBase(tint::Source source,
|
||||||
Symbol name,
|
Symbol name,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
uint32_t index,
|
uint32_t index,
|
||||||
uint32_t offset,
|
uint32_t offset,
|
||||||
uint32_t align,
|
uint32_t align,
|
||||||
|
@ -245,7 +244,7 @@ class StructMemberBase : public Castable<StructMemberBase, Node> {
|
||||||
const sem::StructBase* Struct() const { return struct_; }
|
const sem::StructBase* Struct() const { return struct_; }
|
||||||
|
|
||||||
/// @returns the type of the member
|
/// @returns the type of the member
|
||||||
const sem::Type* Type() const { return type_; }
|
const type::Type* Type() const { return type_; }
|
||||||
|
|
||||||
/// @returns the member index
|
/// @returns the member index
|
||||||
uint32_t Index() const { return index_; }
|
uint32_t Index() const { return index_; }
|
||||||
|
@ -266,7 +265,7 @@ class StructMemberBase : public Castable<StructMemberBase, Node> {
|
||||||
const tint::Source source_;
|
const tint::Source source_;
|
||||||
const Symbol name_;
|
const Symbol name_;
|
||||||
const sem::StructBase* struct_;
|
const sem::StructBase* struct_;
|
||||||
const sem::Type* type_;
|
const type::Type* type_;
|
||||||
const uint32_t index_;
|
const uint32_t index_;
|
||||||
const uint32_t offset_;
|
const uint32_t offset_;
|
||||||
const uint32_t align_;
|
const uint32_t align_;
|
||||||
|
@ -290,7 +289,7 @@ class StructMember final : public Castable<StructMember, StructMemberBase> {
|
||||||
StructMember(const ast::StructMember* declaration,
|
StructMember(const ast::StructMember* declaration,
|
||||||
tint::Source source,
|
tint::Source source,
|
||||||
Symbol name,
|
Symbol name,
|
||||||
const sem::Type* type,
|
const type::Type* type,
|
||||||
uint32_t index,
|
uint32_t index,
|
||||||
uint32_t offset,
|
uint32_t offset,
|
||||||
uint32_t align,
|
uint32_t align,
|
||||||
|
|
|
@ -44,16 +44,4 @@ using TestParamHelper = TestHelperBase<testing::TestWithParam<T>>;
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
/// Helper macro for testing that a semantic type was as expected
|
|
||||||
#define EXPECT_TYPE(GOT, EXPECT) \
|
|
||||||
do { \
|
|
||||||
const sem::Type* got = GOT; \
|
|
||||||
const sem::Type* expect = EXPECT; \
|
|
||||||
if (got != expect) { \
|
|
||||||
ADD_FAILURE() << #GOT " != " #EXPECT "\n" \
|
|
||||||
<< " " #GOT ": " << FriendlyName(got) << "\n" \
|
|
||||||
<< " " #EXPECT ": " << FriendlyName(expect); \
|
|
||||||
} \
|
|
||||||
} while (false)
|
|
||||||
|
|
||||||
#endif // SRC_TINT_SEM_TEST_HELPER_H_
|
#endif // SRC_TINT_SEM_TEST_HELPER_H_
|
||||||
|
|
|
@ -18,7 +18,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Texture);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
Texture::Texture(ast::TextureDimension dim) : Base(TypeFlags{}), dim_(dim) {}
|
Texture::Texture(ast::TextureDimension dim) : Base(type::TypeFlags{}), dim_(dim) {}
|
||||||
|
|
||||||
Texture::Texture(Texture&&) = default;
|
Texture::Texture(Texture&&) = default;
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,12 @@
|
||||||
#define SRC_TINT_SEM_TEXTURE_H_
|
#define SRC_TINT_SEM_TEXTURE_H_
|
||||||
|
|
||||||
#include "src/tint/ast/texture.h"
|
#include "src/tint/ast/texture.h"
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
/// A texture type.
|
/// A texture type.
|
||||||
class Texture : public Castable<Texture, Type> {
|
class Texture : public Castable<Texture, type::Type> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param dim the dimensionality of the texture
|
/// @param dim the dimensionality of the texture
|
||||||
|
|
|
@ -18,7 +18,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::TypeConversion);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
TypeConversion::TypeConversion(const sem::Type* type,
|
TypeConversion::TypeConversion(const type::Type* type,
|
||||||
const sem::Parameter* parameter,
|
const sem::Parameter* parameter,
|
||||||
EvaluationStage stage)
|
EvaluationStage stage)
|
||||||
: Base(type, utils::Vector<const sem::Parameter*, 1>{parameter}, stage) {}
|
: Base(type, utils::Vector<const sem::Parameter*, 1>{parameter}, stage) {}
|
||||||
|
|
|
@ -26,16 +26,16 @@ class TypeConversion final : public Castable<TypeConversion, CallTarget> {
|
||||||
/// @param type the target type of the cast
|
/// @param type the target type of the cast
|
||||||
/// @param parameter the type cast parameter
|
/// @param parameter the type cast parameter
|
||||||
/// @param stage the earliest evaluation stage for the expression
|
/// @param stage the earliest evaluation stage for the expression
|
||||||
TypeConversion(const sem::Type* type, const sem::Parameter* parameter, EvaluationStage stage);
|
TypeConversion(const type::Type* type, const sem::Parameter* parameter, EvaluationStage stage);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~TypeConversion() override;
|
~TypeConversion() override;
|
||||||
|
|
||||||
/// @returns the cast source type
|
/// @returns the cast source type
|
||||||
const sem::Type* Source() const { return Parameters()[0]->Type(); }
|
const type::Type* Source() const { return Parameters()[0]->Type(); }
|
||||||
|
|
||||||
/// @returns the cast target type
|
/// @returns the cast target type
|
||||||
const sem::Type* Target() const { return ReturnType(); }
|
const type::Type* Target() const { return ReturnType(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -20,7 +20,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::TypeInitializer);
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
|
||||||
TypeInitializer::TypeInitializer(const sem::Type* type,
|
TypeInitializer::TypeInitializer(const type::Type* type,
|
||||||
utils::VectorRef<const Parameter*> parameters,
|
utils::VectorRef<const Parameter*> parameters,
|
||||||
EvaluationStage stage)
|
EvaluationStage stage)
|
||||||
: Base(type, std::move(parameters), stage) {}
|
: Base(type, std::move(parameters), stage) {}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class TypeInitializer final : public Castable<TypeInitializer, CallTarget> {
|
||||||
/// @param type the type that's being constructed
|
/// @param type the type that's being constructed
|
||||||
/// @param parameters the type initializer parameters
|
/// @param parameters the type initializer parameters
|
||||||
/// @param stage the earliest evaluation stage for the expression
|
/// @param stage the earliest evaluation stage for the expression
|
||||||
TypeInitializer(const sem::Type* type,
|
TypeInitializer(const type::Type* type,
|
||||||
utils::VectorRef<const Parameter*> parameters,
|
utils::VectorRef<const Parameter*> parameters,
|
||||||
EvaluationStage stage);
|
EvaluationStage stage);
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,15 @@
|
||||||
#ifndef SRC_TINT_SEM_TYPE_MANAGER_H_
|
#ifndef SRC_TINT_SEM_TYPE_MANAGER_H_
|
||||||
#define SRC_TINT_SEM_TYPE_MANAGER_H_
|
#define SRC_TINT_SEM_TYPE_MANAGER_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "src/tint/sem/array_count.h"
|
#include "src/tint/sem/struct.h"
|
||||||
#include "src/tint/sem/type.h"
|
#include "src/tint/type/array_count.h"
|
||||||
|
#include "src/tint/type/node.h"
|
||||||
|
#include "src/tint/type/type.h"
|
||||||
#include "src/tint/utils/unique_allocator.h"
|
#include "src/tint/utils/unique_allocator.h"
|
||||||
|
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
|
@ -29,7 +32,7 @@ namespace tint::sem {
|
||||||
class TypeManager final {
|
class TypeManager final {
|
||||||
public:
|
public:
|
||||||
/// Iterator is the type returned by begin() and end()
|
/// Iterator is the type returned by begin() and end()
|
||||||
using TypeIterator = utils::BlockAllocator<Type>::ConstIterator;
|
using TypeIterator = utils::BlockAllocator<type::Type>::ConstIterator;
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
TypeManager();
|
TypeManager();
|
||||||
|
@ -57,7 +60,7 @@ class TypeManager final {
|
||||||
static TypeManager Wrap(const TypeManager& inner) {
|
static TypeManager Wrap(const TypeManager& inner) {
|
||||||
TypeManager out;
|
TypeManager out;
|
||||||
out.types_.Wrap(inner.types_);
|
out.types_.Wrap(inner.types_);
|
||||||
out.array_counts_.Wrap(inner.array_counts_);
|
out.nodes_.Wrap(inner.nodes_);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +69,7 @@ class TypeManager final {
|
||||||
/// If an existing instance of `T` has been constructed, then the same
|
/// If an existing instance of `T` has been constructed, then the same
|
||||||
/// pointer is returned.
|
/// pointer is returned.
|
||||||
template <typename TYPE,
|
template <typename TYPE,
|
||||||
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, sem::Type>>,
|
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, type::Type>>,
|
||||||
typename... ARGS>
|
typename... ARGS>
|
||||||
TYPE* Get(ARGS&&... args) {
|
TYPE* Get(ARGS&&... args) {
|
||||||
return types_.Get<TYPE>(std::forward<ARGS>(args)...);
|
return types_.Get<TYPE>(std::forward<ARGS>(args)...);
|
||||||
|
@ -76,7 +79,7 @@ class TypeManager final {
|
||||||
/// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item
|
/// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item
|
||||||
/// was not found.
|
/// was not found.
|
||||||
template <typename TYPE,
|
template <typename TYPE,
|
||||||
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, sem::Type>>,
|
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, type::Type>>,
|
||||||
typename... ARGS>
|
typename... ARGS>
|
||||||
TYPE* Find(ARGS&&... args) const {
|
TYPE* Find(ARGS&&... args) const {
|
||||||
return types_.Find<TYPE>(std::forward<ARGS>(args)...);
|
return types_.Find<TYPE>(std::forward<ARGS>(args)...);
|
||||||
|
@ -87,10 +90,11 @@ class TypeManager final {
|
||||||
/// If an existing instance of `T` has been constructed, then the same
|
/// If an existing instance of `T` has been constructed, then the same
|
||||||
/// pointer is returned.
|
/// pointer is returned.
|
||||||
template <typename TYPE,
|
template <typename TYPE,
|
||||||
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, sem::ArrayCount>>,
|
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, type::ArrayCount> ||
|
||||||
|
traits::IsTypeOrDerived<TYPE, sem::StructMemberBase>>,
|
||||||
typename... ARGS>
|
typename... ARGS>
|
||||||
TYPE* GetArrayCount(ARGS&&... args) {
|
TYPE* GetNode(ARGS&&... args) {
|
||||||
return array_counts_.Get<TYPE>(std::forward<ARGS>(args)...);
|
return nodes_.Get<TYPE>(std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns an iterator to the beginning of the types
|
/// @returns an iterator to the beginning of the types
|
||||||
|
@ -99,10 +103,50 @@ class TypeManager final {
|
||||||
TypeIterator end() const { return types_.end(); }
|
TypeIterator end() const { return types_.end(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
utils::UniqueAllocator<Type> types_;
|
utils::UniqueAllocator<type::Type> types_;
|
||||||
utils::UniqueAllocator<ArrayCount> array_counts_;
|
utils::UniqueAllocator<type::Node> nodes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
/// std::hash specialization for tint::type::Node
|
||||||
|
template <>
|
||||||
|
struct hash<tint::type::Node> {
|
||||||
|
/// @param type the type to obtain a hash from
|
||||||
|
/// @returns the hash of the type
|
||||||
|
size_t operator()(const tint::type::Node& type) const {
|
||||||
|
if (const auto* ac = type.As<tint::type::ArrayCount>()) {
|
||||||
|
return ac->Hash();
|
||||||
|
} else if (type.Is<tint::sem::StructMemberBase>()) {
|
||||||
|
return tint::TypeInfo::Of<tint::sem::StructMemberBase>().full_hashcode;
|
||||||
|
}
|
||||||
|
TINT_ASSERT(Type, false && "Unreachable");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// std::equal_to specialization for tint::type::Node
|
||||||
|
template <>
|
||||||
|
struct equal_to<tint::type::Node> {
|
||||||
|
/// @param a the first type to compare
|
||||||
|
/// @param b the second type to compare
|
||||||
|
/// @returns true if the two types are equal
|
||||||
|
bool operator()(const tint::type::Node& a, const tint::type::Node& b) const {
|
||||||
|
if (const auto* ac = a.As<tint::type::ArrayCount>()) {
|
||||||
|
if (const auto* bc = b.As<tint::type::ArrayCount>()) {
|
||||||
|
return ac->Equals(*bc);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else if (a.Is<tint::sem::StructMemberBase>()) {
|
||||||
|
return &a == &b;
|
||||||
|
}
|
||||||
|
TINT_ASSERT(Type, false && "Unreachable");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
#endif // SRC_TINT_SEM_TYPE_MANAGER_H_
|
#endif // SRC_TINT_SEM_TYPE_MANAGER_H_
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue