diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def index a8f4e05ffb..3d4a3699c9 100644 --- a/src/tint/intrinsics.def +++ b/src/tint/intrinsics.def @@ -636,150 +636,166 @@ fn textureLoad(texture: texture_external, coords: vec2) -> vec4 //////////////////////////////////////////////////////////////////////////////// // Zero value constructors -ctor i32() -> i32 -ctor u32() -> u32 -ctor f32() -> f32 -ctor f16() -> f16 -ctor bool() -> bool -ctor vec2() -> vec2 -ctor vec3() -> vec3 -ctor vec4() -> vec4 -ctor mat2x2() -> mat2x2 -ctor mat2x3() -> mat2x3 -ctor mat2x4() -> mat2x4 -ctor mat3x2() -> mat3x2 -ctor mat3x3() -> mat3x3 -ctor mat3x4() -> mat3x4 -ctor mat4x2() -> mat4x2 -ctor mat4x3() -> mat4x3 -ctor mat4x4() -> mat4x4 +@const("Zero") ctor i32() -> i32 +@const("Zero") ctor u32() -> u32 +@const("Zero") ctor f32() -> f32 +@const("Zero") ctor f16() -> f16 +@const("Zero") ctor bool() -> bool +@const("Zero") ctor vec2() -> vec2 +@const("Zero") ctor vec3() -> vec3 +@const("Zero") ctor vec4() -> vec4 +@const("Zero") ctor mat2x2() -> mat2x2 +@const("Zero") ctor mat2x3() -> mat2x3 +@const("Zero") ctor mat2x4() -> mat2x4 +@const("Zero") ctor mat3x2() -> mat3x2 +@const("Zero") ctor mat3x3() -> mat3x3 +@const("Zero") ctor mat3x4() -> mat3x4 +@const("Zero") ctor mat4x2() -> mat4x2 +@const("Zero") ctor mat4x3() -> mat4x3 +@const("Zero") ctor mat4x4() -> mat4x4 // Identity constructors -ctor i32(i32) -> i32 -ctor u32(u32) -> u32 -ctor f32(f32) -> f32 -ctor f16(f16) -> f16 -ctor bool(bool) -> bool -ctor vec2(vec2) -> vec2 -ctor vec3(vec3) -> vec3 -ctor vec4(vec4) -> vec4 -ctor mat2x2(mat2x2) -> mat2x2 -ctor mat2x3(mat2x3) -> mat2x3 -ctor mat2x4(mat2x4) -> mat2x4 -ctor mat3x2(mat3x2) -> mat3x2 -ctor mat3x3(mat3x3) -> mat3x3 -ctor mat3x4(mat3x4) -> mat3x4 -ctor mat4x2(mat4x2) -> mat4x2 -ctor mat4x3(mat4x3) -> mat4x3 -ctor mat4x4(mat4x4) -> mat4x4 +@const("Identity") ctor i32(i32) -> i32 +@const("Identity") ctor u32(u32) -> u32 +@const("Identity") ctor f32(f32) -> f32 +@const("Identity") ctor f16(f16) -> f16 +@const("Identity") ctor bool(bool) -> bool +@const("Identity") ctor vec2(vec2) -> vec2 +@const("Identity") ctor vec3(vec3) -> vec3 +@const("Identity") ctor vec4(vec4) -> vec4 +@const("Identity") ctor mat2x2(mat2x2) -> mat2x2 +@const("Identity") ctor mat2x3(mat2x3) -> mat2x3 +@const("Identity") ctor mat2x4(mat2x4) -> mat2x4 +@const("Identity") ctor mat3x2(mat3x2) -> mat3x2 +@const("Identity") ctor mat3x3(mat3x3) -> mat3x3 +@const("Identity") ctor mat3x4(mat3x4) -> mat3x4 +@const("Identity") ctor mat4x2(mat4x2) -> mat4x2 +@const("Identity") ctor mat4x3(mat4x3) -> mat4x3 +@const("Identity") ctor mat4x4(mat4x4) -> mat4x4 -// Vector constructors -ctor vec2(T) -> vec2 -ctor vec2(x: T, y: T) -> vec2 -ctor vec3(T) -> vec3 -ctor vec3(x: T, y: T, z: T) -> vec3 -ctor vec3(xy: vec2, z: T) -> vec3 -ctor vec3(x: T, yz: vec2) -> vec3 -ctor vec4(T) -> vec4 -ctor vec4(x: T, y: T, z: T, w: T) -> vec4 -ctor vec4(xy: vec2, z: T, w: T) -> vec4 -ctor vec4(x: T, yz: vec2, w: T) -> vec4 -ctor vec4(x: T, y: T, zw: vec2) -> vec4 -ctor vec4(xy: vec2, zw: vec2) -> vec4 -ctor vec4(xyz: vec3, w: T) -> vec4 -ctor vec4(x: T, zyw: vec3) -> vec4 +// Vector constructors (splat) +@const("VecSplat") ctor vec2(T) -> vec2 +@const("VecSplat") ctor vec3(T) -> vec3 +@const("VecSplat") ctor vec4(T) -> vec4 -// Matrix constructors +// Vector constructors (scalar) +@const("VecCtorS") ctor vec2(x: T, y: T) -> vec2 +@const("VecCtorS") ctor vec3(x: T, y: T, z: T) -> vec3 +@const("VecCtorS") ctor vec4(x: T, y: T, z: T, w: T) -> vec4 + +// Vector constructors (mixed) +@const("VecCtorM") ctor vec3(xy: vec2, z: T) -> vec3 +@const("VecCtorM") ctor vec3(x: T, yz: vec2) -> vec3 +@const("VecCtorM") ctor vec4(xy: vec2, z: T, w: T) -> vec4 +@const("VecCtorM") ctor vec4(x: T, yz: vec2, w: T) -> vec4 +@const("VecCtorM") ctor vec4(x: T, y: T, zw: vec2) -> vec4 +@const("VecCtorM") ctor vec4(xy: vec2, zw: vec2) -> vec4 +@const("VecCtorM") ctor vec4(xyz: vec3, w: T) -> vec4 +@const("VecCtorM") ctor vec4(x: T, zyw: vec3) -> vec4 + +// Matrix constructors (scalar) +@const("MatCtorS") ctor mat2x2(T, T, T, T) -> mat2x2 -ctor mat2x2(vec2, vec2) -> mat2x2 - +@const("MatCtorS") ctor mat2x3(T, T, T, T, T, T) -> mat2x3 -ctor mat2x3(vec3, vec3) -> mat2x3 - +@const("MatCtorS") ctor mat2x4(T, T, T, T, T, T, T, T) -> mat2x4 -ctor mat2x4(vec4, vec4) -> mat2x4 - +@const("MatCtorS") ctor mat3x2(T, T, T, T, T, T) -> mat3x2 -ctor mat3x2(vec2, vec2, vec2) -> mat3x2 - +@const("MatCtorS") ctor mat3x3(T, T, T, T, T, T, T, T, T) -> mat3x3 -ctor mat3x3(vec3, vec3, vec3) -> mat3x3 - +@const("MatCtorS") ctor mat3x4(T, T, T, T, T, T, T, T, T, T, T, T) -> mat3x4 -ctor mat3x4(vec4, vec4, vec4) -> mat3x4 - +@const("MatCtorS") ctor mat4x2(T, T, T, T, T, T, T, T) -> mat4x2 -ctor mat4x2(vec2, vec2, vec2, vec2) -> mat4x2 - +@const("MatCtorS") ctor mat4x3(T, T, T, T, T, T, T, T, T, T, T, T) -> mat4x3 -ctor mat4x3(vec3, vec3, vec3, vec3) -> mat4x3 - +@const("MatCtorS") ctor mat4x4(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) -> mat4x4 + +// Matrix constructors (column vectors) +@const("MatCtorV") +ctor mat2x2(vec2, vec2) -> mat2x2 +@const("MatCtorV") +ctor mat2x3(vec3, vec3) -> mat2x3 +@const("MatCtorV") +ctor mat2x4(vec4, vec4) -> mat2x4 +@const("MatCtorV") +ctor mat3x2(vec2, vec2, vec2) -> mat3x2 +@const("MatCtorV") +ctor mat3x3(vec3, vec3, vec3) -> mat3x3 +@const("MatCtorV") +ctor mat3x4(vec4, vec4, vec4) -> mat3x4 +@const("MatCtorV") +ctor mat4x2(vec2, vec2, vec2, vec2) -> mat4x2 +@const("MatCtorV") +ctor mat4x3(vec3, vec3, vec3, vec3) -> mat4x3 +@const("MatCtorV") ctor mat4x4(vec4, vec4, vec4, vec4) -> mat4x4 //////////////////////////////////////////////////////////////////////////////// // Type conversions // //////////////////////////////////////////////////////////////////////////////// -conv f32(T) -> f32 -conv f16(T) -> f16 -conv i32(T) -> i32 -conv u32(T) -> u32 -conv bool(T) -> bool +@const conv f32(T) -> f32 +@const conv f16(T) -> f16 +@const conv i32(T) -> i32 +@const conv u32(T) -> u32 +@const conv bool(T) -> bool -conv vec2(vec2) -> vec2 -conv vec2(vec2) -> vec2 -conv vec2(vec2) -> vec2 -conv vec2(vec2) -> vec2 -conv vec2(vec2) -> vec2 +@const conv vec2(vec2) -> vec2 +@const conv vec2(vec2) -> vec2 +@const conv vec2(vec2) -> vec2 +@const conv vec2(vec2) -> vec2 +@const conv vec2(vec2) -> vec2 -conv vec3(vec3) -> vec3 -conv vec3(vec3) -> vec3 -conv vec3(vec3) -> vec3 -conv vec3(vec3) -> vec3 -conv vec3(vec3) -> vec3 +@const conv vec3(vec3) -> vec3 +@const conv vec3(vec3) -> vec3 +@const conv vec3(vec3) -> vec3 +@const conv vec3(vec3) -> vec3 +@const conv vec3(vec3) -> vec3 -conv vec4(vec4) -> vec4 -conv vec4(vec4) -> vec4 -conv vec4(vec4) -> vec4 -conv vec4(vec4) -> vec4 -conv vec4(vec4) -> vec4 +@const conv vec4(vec4) -> vec4 +@const conv vec4(vec4) -> vec4 +@const conv vec4(vec4) -> vec4 +@const conv vec4(vec4) -> vec4 +@const conv vec4(vec4) -> vec4 -conv mat2x2(mat2x2) -> mat2x2 -conv mat2x2(mat2x2) -> mat2x2 -conv mat2x3(mat2x3) -> mat2x3 -conv mat2x3(mat2x3) -> mat2x3 -conv mat2x4(mat2x4) -> mat2x4 -conv mat2x4(mat2x4) -> mat2x4 -conv mat3x2(mat3x2) -> mat3x2 -conv mat3x2(mat3x2) -> mat3x2 -conv mat3x3(mat3x3) -> mat3x3 -conv mat3x3(mat3x3) -> mat3x3 -conv mat3x4(mat3x4) -> mat3x4 -conv mat3x4(mat3x4) -> mat3x4 -conv mat4x2(mat4x2) -> mat4x2 -conv mat4x2(mat4x2) -> mat4x2 -conv mat4x3(mat4x3) -> mat4x3 -conv mat4x3(mat4x3) -> mat4x3 -conv mat4x4(mat4x4) -> mat4x4 -conv mat4x4(mat4x4) -> mat4x4 +@const conv mat2x2(mat2x2) -> mat2x2 +@const conv mat2x2(mat2x2) -> mat2x2 +@const conv mat2x3(mat2x3) -> mat2x3 +@const conv mat2x3(mat2x3) -> mat2x3 +@const conv mat2x4(mat2x4) -> mat2x4 +@const conv mat2x4(mat2x4) -> mat2x4 +@const conv mat3x2(mat3x2) -> mat3x2 +@const conv mat3x2(mat3x2) -> mat3x2 +@const conv mat3x3(mat3x3) -> mat3x3 +@const conv mat3x3(mat3x3) -> mat3x3 +@const conv mat3x4(mat3x4) -> mat3x4 +@const conv mat3x4(mat3x4) -> mat3x4 +@const conv mat4x2(mat4x2) -> mat4x2 +@const conv mat4x2(mat4x2) -> mat4x2 +@const conv mat4x3(mat4x3) -> mat4x3 +@const conv mat4x3(mat4x3) -> mat4x3 +@const conv mat4x4(mat4x4) -> mat4x4 +@const conv mat4x4(mat4x4) -> mat4x4 //////////////////////////////////////////////////////////////////////////////// // Operators // diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc index 95d8ba9996..033c565177 100644 --- a/src/tint/resolver/const_eval.cc +++ b/src/tint/resolver/const_eval.cc @@ -94,7 +94,7 @@ struct Constant : public sem::Constant { // Forward declaration const Constant* CreateComposite(ProgramBuilder& builder, const sem::Type* type, - std::vector elements); + std::vector elements); /// Element holds a single scalar or abstract-numeric value. /// Element implements the Constant interface. @@ -110,7 +110,7 @@ struct Element : Constant { return static_cast(value); } } - const Constant* Index(size_t) const override { return nullptr; } + const sem::Constant* Index(size_t) const override { return nullptr; } bool AllZero() const override { return IsPositiveZero(value); } bool AnyZero() const override { return IsPositiveZero(value); } bool AllEqual() const override { return true; } @@ -185,11 +185,11 @@ struct Element : Constant { /// identical. Splat may be of a vector, matrix or array type. /// Splat implements the Constant interface. struct Splat : Constant { - Splat(const sem::Type* t, const Constant* e, size_t n) : type(t), el(e), count(n) {} + Splat(const sem::Type* t, const sem::Constant* e, size_t n) : type(t), el(e), count(n) {} ~Splat() override = default; const sem::Type* Type() const override { return type; } std::variant Value() const override { return {}; } - const Constant* Index(size_t i) const override { return i < count ? el : nullptr; } + const sem::Constant* Index(size_t i) const override { return i < count ? el : nullptr; } bool AllZero() const override { return el->AllZero(); } bool AnyZero() const override { return el->AnyZero(); } bool AllEqual() const override { return true; } @@ -199,7 +199,10 @@ struct Splat : Constant { const sem::Type* target_ty, const Source& source) const override { // Convert the single splatted element type. - auto conv_el = el->Convert(builder, sem::Type::ElementOf(target_ty), source); + // Note: This file is the only place where `sem::Constant`s are created, so this static_cast + // is safe. + auto conv_el = static_cast(el)->Convert( + builder, sem::Type::ElementOf(target_ty), source); if (!conv_el) { return utils::Failure; } @@ -210,7 +213,7 @@ struct Splat : Constant { } sem::Type const* const type; - const Constant* el; + const sem::Constant* el; const size_t count; }; @@ -220,12 +223,12 @@ struct Splat : Constant { /// implementation. Use CreateComposite() to create the appropriate Constant type. /// Composite implements the Constant interface. struct Composite : Constant { - Composite(const sem::Type* t, std::vector els, bool all_0, bool any_0) + Composite(const sem::Type* t, std::vector els, bool all_0, bool any_0) : type(t), elements(std::move(els)), all_zero(all_0), any_zero(any_0), hash(CalcHash()) {} ~Composite() override = default; const sem::Type* Type() const override { return type; } std::variant Value() const override { return {}; } - const Constant* Index(size_t i) const override { + const sem::Constant* Index(size_t i) const override { return i < elements.size() ? elements[i] : nullptr; } bool AllZero() const override { return all_zero; } @@ -238,10 +241,12 @@ struct Composite : Constant { const Source& source) const override { // Convert each of the composite element types. auto* el_ty = sem::Type::ElementOf(target_ty); - std::vector conv_els; + std::vector conv_els; conv_els.reserve(elements.size()); for (auto* el : elements) { - auto conv_el = el->Convert(builder, el_ty, source); + // Note: This file is the only place where `sem::Constant`s are created, so this + // static_cast is safe. + auto conv_el = static_cast(el)->Convert(builder, el_ty, source); if (!conv_el) { return utils::Failure; } @@ -262,7 +267,7 @@ struct Composite : Constant { } sem::Type const* const type; - const std::vector elements; + const std::vector elements; const bool all_zero; const bool any_zero; const size_t hash; @@ -294,7 +299,7 @@ const Constant* ZeroValue(ProgramBuilder& builder, const sem::Type* type) { }, [&](const sem::Struct* s) -> const Constant* { std::unordered_map zero_by_type; - std::vector zeros; + std::vector zeros; zeros.reserve(s->Members().size()); for (auto* member : s->Members()) { auto* zero = utils::GetOrCreate(zero_by_type, member->Type(), @@ -359,7 +364,7 @@ bool Equal(const sem::Constant* a, const sem::Constant* b) { /// depending on the element types and values. const Constant* CreateComposite(ProgramBuilder& builder, const sem::Type* type, - std::vector elements) { + std::vector elements) { if (elements.size() == 0) { return nullptr; } @@ -425,112 +430,119 @@ const sem::Constant* ConstEval::Literal(const sem::Type* ty, }); } -const sem::Constant* ConstEval::CtorOrConv(const sem::Type* ty, - const std::vector& args) { - // For zero value init, return 0s +const sem::Constant* ConstEval::ArrayOrStructCtor(const sem::Type* ty, + const std::vector& args) { if (args.empty()) { return ZeroValue(builder, ty); } - if (auto* el_ty = sem::Type::ElementOf(ty); el_ty && args.size() == 1) { - // Type constructor or conversion that takes a single argument. - auto& src = args[0]->Declaration()->source; - auto* arg = static_cast(args[0]->ConstantValue()); - if (!arg) { - return nullptr; // Single argument is not constant. - } + if (args.size() == 1 && args[0]->Type() == ty) { + // Identity constructor. + return args[0]->ConstantValue(); + } - if (ty->is_scalar()) { // Scalar type conversion: i32(x), u32(x), bool(x), etc - return Convert(el_ty, arg, src).Get(); - } - - if (arg->Type() == el_ty) { - // Argument type matches function type. This is a splat. - auto splat = [&](size_t n) { return builder.create(ty, arg, n); }; - return Switch( - ty, // - [&](const sem::Vector* v) { return splat(v->Width()); }, - [&](const sem::Matrix* m) { return splat(m->columns()); }, - [&](const sem::Array* a) { return splat(a->Count()); }); - } - - // Argument type and function type mismatch. This is a type conversion. - if (auto conv = Convert(ty, arg, src)) { - return conv.Get(); - } + // Multiple arguments. Must be a type constructor. + std::vector els; + els.reserve(args.size()); + for (auto* arg : args) { + els.emplace_back(arg->ConstantValue()); + } + return CreateComposite(builder, ty, std::move(els)); +} +const sem::Constant* ConstEval::Conv(const sem::Type* ty, ArgumentList args, size_t) { + uint32_t el_count = 0; + auto* el_ty = sem::Type::ElementOf(ty, &el_count); + if (!el_ty) { return nullptr; } - // Helper for pushing all the argument constants to `els`. - auto args_as_constants = [&] { - return utils::Transform( - args, [&](auto* expr) { return static_cast(expr->ConstantValue()); }); - }; + auto& src = args[0]->Declaration()->source; + auto* arg = args[0]->ConstantValue(); + if (!arg) { + return nullptr; // Single argument is not constant. + } - // Multiple arguments. Must be a type constructor. + if (auto conv = Convert(ty, arg, src)) { + return conv.Get(); + } - return Switch( - ty, // What's the target type being constructed? - [&](const sem::Vector*) -> const Constant* { - // Vector can be constructed with a mix of scalars / abstract numerics and smaller - // vectors. - std::vector els; - els.reserve(args.size()); - for (auto* expr : args) { - auto* arg = static_cast(expr->ConstantValue()); - if (!arg) { + return nullptr; +} + +const sem::Constant* ConstEval::Zero(const sem::Type* ty, ArgumentList, size_t) { + return ZeroValue(builder, ty); +} + +const sem::Constant* ConstEval::Identity(const sem::Type*, ArgumentList args, size_t) { + return args[0]->ConstantValue(); +} + +const sem::Constant* ConstEval::VecSplat(const sem::Type* ty, ArgumentList args, size_t) { + if (auto* arg = args[0]->ConstantValue()) { + return builder.create(ty, arg, static_cast(ty)->Width()); + } + return nullptr; +} + +const sem::Constant* ConstEval::VecCtorS(const sem::Type* ty, ArgumentList args, size_t num_args) { + std::vector els; + els.reserve(num_args); + for (size_t i = 0; i < num_args; i++) { + els.emplace_back(args[i]->ConstantValue()); + } + return CreateComposite(builder, ty, std::move(els)); +} + +const sem::Constant* ConstEval::VecCtorM(const sem::Type* ty, ArgumentList args, size_t num_args) { + std::vector els; + els.reserve(num_args); + for (size_t i = 0; i < num_args; i++) { + auto* arg = args[i]->ConstantValue(); + if (!arg) { + return nullptr; + } + auto* arg_ty = arg->Type(); + if (auto* arg_vec = arg_ty->As()) { + // Extract out vector elements. + for (uint32_t j = 0; j < arg_vec->Width(); j++) { + auto* el = arg->Index(j); + if (!el) { return nullptr; } - auto* arg_ty = arg->Type(); - if (auto* arg_vec = arg_ty->As()) { - // Extract out vector elements. - for (uint32_t i = 0; i < arg_vec->Width(); i++) { - auto* el = static_cast(arg->Index(i)); - if (!el) { - return nullptr; - } - els.emplace_back(el); - } - } else { - els.emplace_back(arg); - } + els.emplace_back(el); } - return CreateComposite(builder, ty, std::move(els)); - }, - [&](const sem::Matrix* m) -> const Constant* { - // Matrix can be constructed with a set of scalars / abstract numerics, or column - // vectors. - if (args.size() == m->columns() * m->rows()) { - // Matrix built from scalars / abstract numerics - std::vector els; - els.reserve(args.size()); - for (uint32_t c = 0; c < m->columns(); c++) { - std::vector column; - column.reserve(m->rows()); - for (uint32_t r = 0; r < m->rows(); r++) { - auto* arg = - static_cast(args[r + c * m->rows()]->ConstantValue()); - if (!arg) { - return nullptr; - } - column.emplace_back(arg); - } - els.push_back(CreateComposite(builder, m->ColumnType(), std::move(column))); - } - return CreateComposite(builder, ty, std::move(els)); - } - // Matrix built from column vectors - return CreateComposite(builder, ty, args_as_constants()); - }, - [&](const sem::Array*) { - // Arrays must be constructed using a list of elements - return CreateComposite(builder, ty, args_as_constants()); - }, - [&](const sem::Struct*) { - // Structures must be constructed using a list of elements - return CreateComposite(builder, ty, args_as_constants()); - }); + } else { + els.emplace_back(arg); + } + } + return CreateComposite(builder, ty, std::move(els)); +} + +const sem::Constant* ConstEval::MatCtorS(const sem::Type* ty, ArgumentList args, size_t num_args) { + auto* m = static_cast(ty); + + std::vector els; + els.reserve(num_args); + for (uint32_t c = 0; c < m->columns(); c++) { + std::vector column; + column.reserve(m->rows()); + for (uint32_t r = 0; r < m->rows(); r++) { + auto i = r + c * m->rows(); + column.emplace_back(args[i]->ConstantValue()); + } + els.push_back(CreateComposite(builder, m->ColumnType(), std::move(column))); + } + return CreateComposite(builder, ty, std::move(els)); +} + +const sem::Constant* ConstEval::MatCtorV(const sem::Type* ty, ArgumentList args, size_t num_args) { + std::vector els; + els.reserve(num_args); + for (size_t i = 0; i < num_args; i++) { + els.emplace_back(args[i]->ConstantValue()); + } + return CreateComposite(builder, ty, std::move(els)); } const sem::Constant* ConstEval::Index(const sem::Expression* obj_expr, @@ -578,11 +590,10 @@ const sem::Constant* ConstEval::Swizzle(const sem::Type* ty, return nullptr; } if (indices.size() == 1) { - return static_cast(vec_val->Index(static_cast(indices[0]))); + return vec_val->Index(static_cast(indices[0])); } else { - auto values = utils::Transform(indices, [&](uint32_t i) { - return static_cast(vec_val->Index(static_cast(i))); - }); + auto values = utils::Transform( + indices, [&](uint32_t i) { return vec_val->Index(static_cast(i)); }); return CreateComposite(builder, ty, std::move(values)); } } diff --git a/src/tint/resolver/const_eval.h b/src/tint/resolver/const_eval.h index 540908bb1d..405e3db4be 100644 --- a/src/tint/resolver/const_eval.h +++ b/src/tint/resolver/const_eval.h @@ -44,9 +44,13 @@ namespace tint::resolver { /// before calling a method to evaluate an expression's value. class ConstEval { public: + /// Typedef for a pointer to an array of `const sem::Expression*`, where each expression is an + /// argument to the function. + using ArgumentList = sem::Expression const* const*; + /// Typedef for a constant evaluation function using Function = const sem::Constant* (ConstEval::*)(const sem::Type* result_ty, - sem::Expression const* const* args, + ArgumentList args, size_t num_args); /// The result type of a method that may raise a diagnostic error and the caller should abort @@ -68,19 +72,18 @@ class ConstEval { // Constant value evaluation methods, to be called directly from Resolver //////////////////////////////////////////////////////////////////////////////////////////////// + /// @param ty the target type - must be an array or constructor + /// @param args the input arguments + /// @return the constructed value, or null if the value cannot be calculated + const sem::Constant* ArrayOrStructCtor(const sem::Type* ty, + const std::vector& args); + /// @param ty the target type /// @param expr the input expression /// @return the bit-cast of the given expression to the given type, or null if the value cannot /// be calculated const sem::Constant* Bitcast(const sem::Type* ty, const sem::Expression* expr); - /// @param ty the target type - /// @param args the input arguments - /// @return the resulting type constructor or conversion, or null if the value cannot be - /// calculated - const sem::Constant* CtorOrConv(const sem::Type* ty, - const std::vector& args); - /// @param obj the object being indexed /// @param idx the index expression /// @return the result of the index, or null if the value cannot be calculated @@ -111,6 +114,66 @@ class ConstEval { /// @return the converted value, or null if the value cannot be calculated ConstantResult Convert(const sem::Type* ty, const sem::Constant* value, const Source& source); + //////////////////////////////////////////////////////////////////////////////////////////////// + // Constant value evaluation methods, to be indirectly called via the intrinsic table + //////////////////////////////////////////////////////////////////////////////////////////////// + + /// Type conversion + /// @param ty the result type + /// @param args the input arguments + /// @param num_args the number of input arguments + /// @return the converted value, or null if the value cannot be calculated + const sem::Constant* Conv(const sem::Type* ty, ArgumentList args, size_t num_args); + + /// Zero value type constructor + /// @param ty the result type + /// @param args the input arguments (no arguments provided) + /// @param num_args the number of input arguments (no arguments provided) + /// @return the constructed value, or null if the value cannot be calculated + const sem::Constant* Zero(const sem::Type* ty, ArgumentList args, size_t num_args); + + /// Identity value type constructor + /// @param ty the result type + /// @param args the input arguments + /// @param num_args the number of input arguments (must be 1) + /// @return the constructed value, or null if the value cannot be calculated + const sem::Constant* Identity(const sem::Type* ty, ArgumentList args, size_t num_args); + + /// Vector splat constructor + /// @param ty the vector type + /// @param args the input arguments + /// @param num_args the number of input arguments (must be 1) + /// @return the constructed value, or null if the value cannot be calculated + const sem::Constant* VecSplat(const sem::Type* ty, ArgumentList args, size_t num_args); + + /// Vector constructor using scalars + /// @param ty the vector type + /// @param args the input arguments + /// @param num_args the number of input arguments (must be equal to vector width) + /// @return the constructed value, or null if the value cannot be calculated + const sem::Constant* VecCtorS(const sem::Type* ty, ArgumentList args, size_t num_args); + + /// Vector constructor using a mix of scalars and smaller vectors + /// @param ty the vector type + /// @param args the input arguments + /// @param num_args the number of input arguments + /// @return the constructed value, or null if the value cannot be calculated + const sem::Constant* VecCtorM(const sem::Type* ty, ArgumentList args, size_t num_args); + + /// Matrix constructor using scalar values + /// @param ty the matrix type + /// @param args the input arguments + /// @param num_args the number of input arguments (must equal num-columns * num-rows) + /// @return the constructed value, or null if the value cannot be calculated + const sem::Constant* MatCtorS(const sem::Type* ty, ArgumentList args, size_t num_args); + + /// Matrix constructor using column vectors + /// @param ty the matrix type + /// @param args the input arguments + /// @param num_args the number of input arguments (must equal num-columns) + /// @return the constructed value, or null if the value cannot be calculated + const sem::Constant* MatCtorV(const sem::Type* ty, ArgumentList args, size_t num_args); + private: /// Adds the given error message to the diagnostics void AddError(const std::string& msg, const Source& source) const; diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc index 9f4210f861..bd7dc30933 100644 --- a/src/tint/resolver/intrinsic_table.cc +++ b/src/tint/resolver/intrinsic_table.cc @@ -928,10 +928,10 @@ class Impl : public IntrinsicTable { const Source& source, bool is_compound) override; - const sem::CallTarget* Lookup(CtorConvIntrinsic type, - const sem::Type* template_arg, - const std::vector& args, - const Source& source) override; + CtorOrConv Lookup(CtorConvIntrinsic type, + const sem::Type* template_arg, + const std::vector& args, + const Source& source) override; private: /// Candidate holds information about an overload evaluated for resolution. @@ -1236,10 +1236,10 @@ IntrinsicTable::BinaryOperator Impl::Lookup(ast::BinaryOp op, return BinaryOperator{match.return_type, match.parameters[0].type, match.parameters[1].type}; } -const sem::CallTarget* Impl::Lookup(CtorConvIntrinsic type, - const sem::Type* template_arg, - const std::vector& args, - const Source& source) { +IntrinsicTable::CtorOrConv Impl::Lookup(CtorConvIntrinsic type, + const sem::Type* template_arg, + const std::vector& args, + const Source& source) { auto name = str(type); // Generates an error when no overloads match the provided arguments @@ -1292,18 +1292,20 @@ const sem::CallTarget* Impl::Lookup(CtorConvIntrinsic type, nullptr, static_cast(params.size()), p.type, ast::StorageClass::kNone, ast::Access::kUndefined, p.usage)); } - return utils::GetOrCreate(constructors, match, [&]() { + auto* target = utils::GetOrCreate(constructors, match, [&]() { return builder.create(match.return_type, std::move(params)); }); + return CtorOrConv{target, match.overload->const_eval_fn}; } // Conversion. - return utils::GetOrCreate(converters, match, [&]() { + auto* target = utils::GetOrCreate(converters, match, [&]() { auto param = builder.create( nullptr, 0u, match.parameters[0].type, ast::StorageClass::kNone, ast::Access::kUndefined, match.parameters[0].usage); return builder.create(match.return_type, param); }); + return CtorOrConv{target, match.overload->const_eval_fn}; } IntrinsicPrototype Impl::MatchIntrinsic(const IntrinsicInfo& intrinsic, diff --git a/src/tint/resolver/intrinsic_table.h b/src/tint/resolver/intrinsic_table.h index 269a935b90..79eb82fb5e 100644 --- a/src/tint/resolver/intrinsic_table.h +++ b/src/tint/resolver/intrinsic_table.h @@ -72,6 +72,14 @@ class IntrinsicTable { ConstEval::Function const_eval_fn = nullptr; }; + /// CtorOrConv describes a resolved type constructor or type conversion + struct CtorOrConv { + /// The result type of the type constructor or type conversion + const sem::CallTarget* target = nullptr; + /// The constant evaluation function + ConstEval::Function const_eval_fn = nullptr; + }; + /// Lookup looks for the builtin overload with the given signature, raising an error diagnostic /// if the builtin was not found. /// @param type the builtin type @@ -113,10 +121,10 @@ class IntrinsicTable { /// @param args the argument types passed to the constructor / conversion call /// @param source the source of the call /// @return a sem::TypeConstructor, sem::TypeConversion or nullptr if nothing matched - virtual const sem::CallTarget* Lookup(CtorConvIntrinsic type, - const sem::Type* template_arg, - const std::vector& args, - const Source& source) = 0; + virtual CtorOrConv Lookup(CtorConvIntrinsic type, + const sem::Type* template_arg, + const std::vector& args, + const Source& source) = 0; }; } // namespace tint::resolver diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl index b81c25ff6e..0fe0faf705 100644 --- a/src/tint/resolver/intrinsic_table.inl +++ b/src/tint/resolver/intrinsic_table.inl @@ -8280,7 +8280,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [28] */ @@ -8292,7 +8292,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[955], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [29] */ @@ -8304,7 +8304,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[956], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecSplat, }, { /* [30] */ @@ -8316,7 +8316,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[399], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorS, }, { /* [31] */ @@ -8328,7 +8328,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[564], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorM, }, { /* [32] */ @@ -8340,7 +8340,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[573], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorM, }, { /* [33] */ @@ -8352,7 +8352,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[576], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorM, }, { /* [34] */ @@ -8364,7 +8364,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[605], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorM, }, { /* [35] */ @@ -8376,7 +8376,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[603], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorM, }, { /* [36] */ @@ -8388,7 +8388,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[601], /* return matcher indices */ &kMatcherIndices[4], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorM, }, { /* [37] */ @@ -8400,7 +8400,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1003], /* return matcher indices */ &kMatcherIndices[112], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [38] */ @@ -8412,7 +8412,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[965], /* return matcher indices */ &kMatcherIndices[132], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [39] */ @@ -8424,7 +8424,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[966], /* return matcher indices */ &kMatcherIndices[136], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [40] */ @@ -8436,7 +8436,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[967], /* return matcher indices */ &kMatcherIndices[142], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [41] */ @@ -8448,7 +8448,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[968], /* return matcher indices */ &kMatcherIndices[146], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [42] */ @@ -9108,7 +9108,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[61], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [97] */ @@ -9120,7 +9120,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[944], /* return matcher indices */ &kMatcherIndices[61], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [98] */ @@ -9132,7 +9132,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[945], /* return matcher indices */ &kMatcherIndices[61], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecSplat, }, { /* [99] */ @@ -9144,7 +9144,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[588], /* return matcher indices */ &kMatcherIndices[61], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorS, }, { /* [100] */ @@ -9156,7 +9156,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[609], /* return matcher indices */ &kMatcherIndices[61], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorM, }, { /* [101] */ @@ -9168,7 +9168,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[607], /* return matcher indices */ &kMatcherIndices[61], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorM, }, { /* [102] */ @@ -9180,7 +9180,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[949], /* return matcher indices */ &kMatcherIndices[43], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [103] */ @@ -9192,7 +9192,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[950], /* return matcher indices */ &kMatcherIndices[50], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [104] */ @@ -9204,7 +9204,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[951], /* return matcher indices */ &kMatcherIndices[57], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [105] */ @@ -9216,7 +9216,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[952], /* return matcher indices */ &kMatcherIndices[65], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [106] */ @@ -9228,7 +9228,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[953], /* return matcher indices */ &kMatcherIndices[69], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [107] */ @@ -9576,7 +9576,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[106], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [136] */ @@ -9588,7 +9588,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[935], /* return matcher indices */ &kMatcherIndices[106], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [137] */ @@ -9600,7 +9600,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[936], /* return matcher indices */ &kMatcherIndices[106], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecSplat, }, { /* [138] */ @@ -9612,7 +9612,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[611], /* return matcher indices */ &kMatcherIndices[106], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::VecCtorS, }, { /* [139] */ @@ -9624,7 +9624,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[938], /* return matcher indices */ &kMatcherIndices[120], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [140] */ @@ -9636,7 +9636,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[939], /* return matcher indices */ &kMatcherIndices[118], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [141] */ @@ -9648,7 +9648,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[940], /* return matcher indices */ &kMatcherIndices[116], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [142] */ @@ -9660,7 +9660,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[941], /* return matcher indices */ &kMatcherIndices[114], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [143] */ @@ -9672,7 +9672,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[942], /* return matcher indices */ &kMatcherIndices[108], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [144] */ @@ -9876,7 +9876,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[210], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [161] */ @@ -9888,7 +9888,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[922], /* return matcher indices */ &kMatcherIndices[210], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [162] */ @@ -9900,7 +9900,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[0], /* return matcher indices */ &kMatcherIndices[210], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorS, }, { /* [163] */ @@ -9912,7 +9912,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[443], /* return matcher indices */ &kMatcherIndices[210], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorV, }, { /* [164] */ @@ -9924,7 +9924,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[908], /* return matcher indices */ &kMatcherIndices[214], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [165] */ @@ -9936,7 +9936,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[906], /* return matcher indices */ &kMatcherIndices[212], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [166] */ @@ -10020,7 +10020,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[164], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [173] */ @@ -10032,7 +10032,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[982], /* return matcher indices */ &kMatcherIndices[164], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [174] */ @@ -10044,7 +10044,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[57], /* return matcher indices */ &kMatcherIndices[164], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorS, }, { /* [175] */ @@ -10056,7 +10056,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[593], /* return matcher indices */ &kMatcherIndices[164], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorV, }, { /* [176] */ @@ -10068,7 +10068,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[985], /* return matcher indices */ &kMatcherIndices[168], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [177] */ @@ -10080,7 +10080,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[986], /* return matcher indices */ &kMatcherIndices[166], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [178] */ @@ -10092,7 +10092,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[148], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [179] */ @@ -10104,7 +10104,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[970], /* return matcher indices */ &kMatcherIndices[148], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [180] */ @@ -10116,7 +10116,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[411], /* return matcher indices */ &kMatcherIndices[148], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorS, }, { /* [181] */ @@ -10128,7 +10128,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[597], /* return matcher indices */ &kMatcherIndices[148], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorV, }, { /* [182] */ @@ -10140,7 +10140,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[973], /* return matcher indices */ &kMatcherIndices[154], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [183] */ @@ -10152,7 +10152,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[974], /* return matcher indices */ &kMatcherIndices[150], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [184] */ @@ -10308,7 +10308,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[156], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [197] */ @@ -10320,7 +10320,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[976], /* return matcher indices */ &kMatcherIndices[156], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [198] */ @@ -10332,7 +10332,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[84], /* return matcher indices */ &kMatcherIndices[156], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorS, }, { /* [199] */ @@ -10344,7 +10344,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[595], /* return matcher indices */ &kMatcherIndices[156], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorV, }, { /* [200] */ @@ -10356,7 +10356,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[979], /* return matcher indices */ &kMatcherIndices[162], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [201] */ @@ -10368,7 +10368,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[980], /* return matcher indices */ &kMatcherIndices[160], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [202] */ @@ -10380,7 +10380,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[186], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [203] */ @@ -10392,7 +10392,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[987], /* return matcher indices */ &kMatcherIndices[186], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [204] */ @@ -10404,7 +10404,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[49], /* return matcher indices */ &kMatcherIndices[186], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorS, }, { /* [205] */ @@ -10416,7 +10416,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[415], /* return matcher indices */ &kMatcherIndices[186], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorV, }, { /* [206] */ @@ -10428,7 +10428,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[969], /* return matcher indices */ &kMatcherIndices[190], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [207] */ @@ -10440,7 +10440,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[954], /* return matcher indices */ &kMatcherIndices[188], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [208] */ @@ -10452,7 +10452,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[192], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [209] */ @@ -10464,7 +10464,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[943], /* return matcher indices */ &kMatcherIndices[192], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [210] */ @@ -10476,7 +10476,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[16], /* return matcher indices */ &kMatcherIndices[192], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorS, }, { /* [211] */ @@ -10488,7 +10488,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[391], /* return matcher indices */ &kMatcherIndices[192], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorV, }, { /* [212] */ @@ -10500,7 +10500,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[928], /* return matcher indices */ &kMatcherIndices[204], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [213] */ @@ -10512,7 +10512,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[925], /* return matcher indices */ &kMatcherIndices[202], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [214] */ @@ -10524,7 +10524,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[104], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [215] */ @@ -10536,7 +10536,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1000], /* return matcher indices */ &kMatcherIndices[104], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [216] */ @@ -10548,7 +10548,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[28], /* return matcher indices */ &kMatcherIndices[104], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorS, }, { /* [217] */ @@ -10560,7 +10560,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[468], /* return matcher indices */ &kMatcherIndices[104], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorV, }, { /* [218] */ @@ -10572,7 +10572,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[999], /* return matcher indices */ &kMatcherIndices[184], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [219] */ @@ -10584,7 +10584,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[993], /* return matcher indices */ &kMatcherIndices[182], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [220] */ @@ -10596,7 +10596,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[176], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [221] */ @@ -10608,7 +10608,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[994], /* return matcher indices */ &kMatcherIndices[176], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [222] */ @@ -10620,7 +10620,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[40], /* return matcher indices */ &kMatcherIndices[176], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorS, }, { /* [223] */ @@ -10632,7 +10632,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[582], /* return matcher indices */ &kMatcherIndices[176], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorV, }, { /* [224] */ @@ -10644,7 +10644,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[997], /* return matcher indices */ &kMatcherIndices[180], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [225] */ @@ -10656,7 +10656,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[998], /* return matcher indices */ &kMatcherIndices[178], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [226] */ @@ -10668,7 +10668,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[170], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [227] */ @@ -10680,7 +10680,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[988], /* return matcher indices */ &kMatcherIndices[170], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [228] */ @@ -10692,7 +10692,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[114], /* return matcher indices */ &kMatcherIndices[170], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorS, }, { /* [229] */ @@ -10704,7 +10704,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[579], /* return matcher indices */ &kMatcherIndices[170], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::MatCtorV, }, { /* [230] */ @@ -10716,7 +10716,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[991], /* return matcher indices */ &kMatcherIndices[174], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [231] */ @@ -10728,7 +10728,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[992], /* return matcher indices */ &kMatcherIndices[172], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [232] */ @@ -11112,7 +11112,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[38], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [264] */ @@ -11124,7 +11124,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[920], /* return matcher indices */ &kMatcherIndices[38], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [265] */ @@ -11136,7 +11136,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[921], /* return matcher indices */ &kMatcherIndices[38], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [266] */ @@ -11148,7 +11148,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[17], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [267] */ @@ -11160,7 +11160,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[932], /* return matcher indices */ &kMatcherIndices[17], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [268] */ @@ -11172,7 +11172,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[933], /* return matcher indices */ &kMatcherIndices[17], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [269] */ @@ -11184,7 +11184,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[51], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [270] */ @@ -11196,7 +11196,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[929], /* return matcher indices */ &kMatcherIndices[51], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [271] */ @@ -11208,7 +11208,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[930], /* return matcher indices */ &kMatcherIndices[51], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [272] */ @@ -11220,7 +11220,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[14], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [273] */ @@ -11232,7 +11232,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[926], /* return matcher indices */ &kMatcherIndices[14], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [274] */ @@ -11244,7 +11244,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[927], /* return matcher indices */ &kMatcherIndices[14], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [275] */ @@ -11292,7 +11292,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[1004], /* return matcher indices */ &kMatcherIndices[66], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Zero, }, { /* [279] */ @@ -11304,7 +11304,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[923], /* return matcher indices */ &kMatcherIndices[66], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Identity, }, { /* [280] */ @@ -11316,7 +11316,7 @@ constexpr OverloadInfo kOverloads[] = { /* parameters */ &kParameters[924], /* return matcher indices */ &kMatcherIndices[66], /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), - /* const eval */ nullptr, + /* const eval */ &ConstEval::Conv, }, { /* [281] */ diff --git a/src/tint/resolver/intrinsic_table_test.cc b/src/tint/resolver/intrinsic_table_test.cc index e2c22474cf..c9d9836851 100644 --- a/src/tint/resolver/intrinsic_table_test.cc +++ b/src/tint/resolver/intrinsic_table_test.cc @@ -676,36 +676,38 @@ TEST_F(IntrinsicTableTest, MismatchCompoundOp) { TEST_F(IntrinsicTableTest, MatchTypeConstructorImplicit) { auto* i32 = create(); auto* vec3_i32 = create(i32, 3u); - auto* result = + auto result = table->Lookup(CtorConvIntrinsic::kVec3, nullptr, {i32, i32, i32}, Source{{12, 34}}); - ASSERT_NE(result, nullptr); - EXPECT_EQ(result->ReturnType(), vec3_i32); - EXPECT_TRUE(result->Is()); - ASSERT_EQ(result->Parameters().size(), 3u); - EXPECT_EQ(result->Parameters()[0]->Type(), i32); - EXPECT_EQ(result->Parameters()[1]->Type(), i32); - EXPECT_EQ(result->Parameters()[2]->Type(), i32); + ASSERT_NE(result.target, nullptr); + EXPECT_EQ(result.target->ReturnType(), vec3_i32); + EXPECT_TRUE(result.target->Is()); + ASSERT_EQ(result.target->Parameters().size(), 3u); + EXPECT_EQ(result.target->Parameters()[0]->Type(), i32); + EXPECT_EQ(result.target->Parameters()[1]->Type(), i32); + EXPECT_EQ(result.target->Parameters()[2]->Type(), i32); + EXPECT_NE(result.const_eval_fn, nullptr); } TEST_F(IntrinsicTableTest, MatchTypeConstructorExplicit) { auto* i32 = create(); auto* vec3_i32 = create(i32, 3u); - auto* result = table->Lookup(CtorConvIntrinsic::kVec3, i32, {i32, i32, i32}, Source{{12, 34}}); - ASSERT_NE(result, nullptr); - EXPECT_EQ(result->ReturnType(), vec3_i32); - EXPECT_TRUE(result->Is()); - ASSERT_EQ(result->Parameters().size(), 3u); - EXPECT_EQ(result->Parameters()[0]->Type(), i32); - EXPECT_EQ(result->Parameters()[1]->Type(), i32); - EXPECT_EQ(result->Parameters()[2]->Type(), i32); + auto result = table->Lookup(CtorConvIntrinsic::kVec3, i32, {i32, i32, i32}, Source{{12, 34}}); + ASSERT_NE(result.target, nullptr); + EXPECT_EQ(result.target->ReturnType(), vec3_i32); + EXPECT_TRUE(result.target->Is()); + ASSERT_EQ(result.target->Parameters().size(), 3u); + EXPECT_EQ(result.target->Parameters()[0]->Type(), i32); + EXPECT_EQ(result.target->Parameters()[1]->Type(), i32); + EXPECT_EQ(result.target->Parameters()[2]->Type(), i32); + EXPECT_NE(result.const_eval_fn, nullptr); } TEST_F(IntrinsicTableTest, MismatchTypeConstructorImplicit) { auto* i32 = create(); auto* f32 = create(); - auto* result = + auto result = table->Lookup(CtorConvIntrinsic::kVec3, nullptr, {i32, f32, i32}, Source{{12, 34}}); - ASSERT_EQ(result, nullptr); + ASSERT_EQ(result.target, nullptr); EXPECT_EQ(Diagnostics().str(), R"(12:34 error: no matching constructor for vec3(i32, f32, i32) 6 candidate constructors: @@ -728,8 +730,8 @@ TEST_F(IntrinsicTableTest, MismatchTypeConstructorImplicit) { TEST_F(IntrinsicTableTest, MismatchTypeConstructorExplicit) { auto* i32 = create(); auto* f32 = create(); - auto* result = table->Lookup(CtorConvIntrinsic::kVec3, i32, {i32, f32, i32}, Source{{12, 34}}); - ASSERT_EQ(result, nullptr); + auto result = table->Lookup(CtorConvIntrinsic::kVec3, i32, {i32, f32, i32}, Source{{12, 34}}); + ASSERT_EQ(result.target, nullptr); EXPECT_EQ(Diagnostics().str(), R"(12:34 error: no matching constructor for vec3(i32, f32, i32) @@ -755,19 +757,19 @@ TEST_F(IntrinsicTableTest, MatchTypeConversion) { auto* vec3_i32 = create(i32, 3u); auto* f32 = create(); auto* vec3_f32 = create(f32, 3u); - auto* result = table->Lookup(CtorConvIntrinsic::kVec3, i32, {vec3_f32}, Source{{12, 34}}); - ASSERT_NE(result, nullptr); - EXPECT_EQ(result->ReturnType(), vec3_i32); - EXPECT_TRUE(result->Is()); - ASSERT_EQ(result->Parameters().size(), 1u); - EXPECT_EQ(result->Parameters()[0]->Type(), vec3_f32); + auto result = table->Lookup(CtorConvIntrinsic::kVec3, i32, {vec3_f32}, Source{{12, 34}}); + ASSERT_NE(result.target, nullptr); + EXPECT_EQ(result.target->ReturnType(), vec3_i32); + EXPECT_TRUE(result.target->Is()); + ASSERT_EQ(result.target->Parameters().size(), 1u); + EXPECT_EQ(result.target->Parameters()[0]->Type(), vec3_f32); } TEST_F(IntrinsicTableTest, MismatchTypeConversion) { auto* arr = create(create(), 0u, 4u, 4u, 4u, 4u); auto* f32 = create(); - auto* result = table->Lookup(CtorConvIntrinsic::kVec3, f32, {arr}, Source{{12, 34}}); - ASSERT_EQ(result, nullptr); + auto result = table->Lookup(CtorConvIntrinsic::kVec3, f32, {arr}, Source{{12, 34}}); + ASSERT_EQ(result.target, nullptr); EXPECT_EQ(Diagnostics().str(), R"(12:34 error: no matching constructor for vec3(array) @@ -804,10 +806,10 @@ TEST_F(IntrinsicTableTest, OverloadResolution) { auto* ai = create(); auto* i32 = create(); auto result = table->Lookup(CtorConvIntrinsic::kI32, nullptr, {ai}, Source{}); - ASSERT_NE(result, nullptr); - EXPECT_EQ(result->ReturnType(), i32); - EXPECT_EQ(result->Parameters().size(), 1u); - EXPECT_EQ(result->Parameters()[0]->Type(), i32); + ASSERT_NE(result.target, nullptr); + EXPECT_EQ(result.target->ReturnType(), i32); + EXPECT_EQ(result.target->Parameters().size(), 1u); + EXPECT_EQ(result.target->Parameters()[0]->Type(), i32); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index e364fa6dfe..8d09d19388 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -1483,16 +1483,20 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) { // call for a CtorConvIntrinsic with an optional template argument type. auto ct_ctor_or_conv = [&](CtorConvIntrinsic ty, const sem::Type* template_arg) -> sem::Call* { auto arg_tys = utils::Transform(args, [](auto* arg) { return arg->Type(); }); - auto* call_target = intrinsic_table_->Lookup(ty, template_arg, arg_tys, expr->source); - if (!call_target) { + auto ctor_or_conv = intrinsic_table_->Lookup(ty, template_arg, arg_tys, expr->source); + if (!ctor_or_conv.target) { return nullptr; } - if (!MaterializeArguments(args, call_target)) { + if (!MaterializeArguments(args, ctor_or_conv.target)) { return nullptr; } - auto val = const_eval_.CtorOrConv(call_target->ReturnType(), args); - return builder_->create(expr, call_target, std::move(args), current_statement_, - val, has_side_effects); + const sem::Constant* value = nullptr; + if (ctor_or_conv.const_eval_fn) { + value = (const_eval_.*ctor_or_conv.const_eval_fn)(ctor_or_conv.target->ReturnType(), + args.data(), args.size()); + } + return builder_->create(expr, ctor_or_conv.target, std::move(args), + current_statement_, value, has_side_effects); }; // ct_ctor_or_conv is a helper for building either a sem::TypeConstructor or sem::TypeConversion @@ -1529,7 +1533,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) { if (!MaterializeArguments(args, call_target)) { return nullptr; } - auto val = const_eval_.CtorOrConv(arr, args); + auto val = const_eval_.ArrayOrStructCtor(arr, args); return builder_->create(expr, call_target, std::move(args), current_statement_, val, has_side_effects); }, @@ -1551,7 +1555,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) { if (!MaterializeArguments(args, call_target)) { return nullptr; } - auto val = const_eval_.CtorOrConv(str, args); + auto val = const_eval_.ArrayOrStructCtor(str, args); return builder_->create(expr, call_target, std::move(args), current_statement_, std::move(val), has_side_effects); diff --git a/tools/src/cmd/intrinsic-gen/resolver/resolve.go b/tools/src/cmd/intrinsic-gen/resolver/resolve.go index 9044d2a590..e89a773dbe 100644 --- a/tools/src/cmd/intrinsic-gen/resolver/resolve.go +++ b/tools/src/cmd/intrinsic-gen/resolver/resolve.go @@ -329,7 +329,14 @@ func (r *resolver) intrinsic( if constEvalFn := a.Attributes.Take("const"); constEvalFn != nil { switch len(constEvalFn.Values) { case 0: - overload.ConstEvalFunction = overload.Decl.Name + switch overload.Decl.Kind { + case ast.Builtin, ast.Operator: + overload.ConstEvalFunction = overload.Decl.Name + case ast.Constructor: + overload.ConstEvalFunction = "Ctor" + case ast.Converter: + overload.ConstEvalFunction = "Conv" + } case 1: overload.ConstEvalFunction = constEvalFn.Values[0] default: