[tint][resolver] Move lambdas to methods
Should remove overhead of preparing the lamda captures, and reduce stack
size.
Change-Id: Iee40df2427be858a80bab1ed4afc333f753a9c85
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/154503
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index bf0e9b3..41849b9 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -2518,371 +2518,111 @@
core::type::Type* Resolver::BuiltinType(core::BuiltinType builtin_ty,
const ast::Identifier* ident) {
auto& b = *builder_;
-
auto check_no_tmpl_args = [&](core::type::Type* ty) -> core::type::Type* {
return TINT_LIKELY(CheckNotTemplated("type", ident)) ? ty : nullptr;
};
- auto af = [&] { return b.create<core::type::AbstractFloat>(); };
- auto f32 = [&] { return b.create<core::type::F32>(); };
- auto i32 = [&] { return b.create<core::type::I32>(); };
- auto u32 = [&] { return b.create<core::type::U32>(); };
- auto f16 = [&] {
- return validator_.CheckF16Enabled(ident->source) ? b.create<core::type::F16>() : nullptr;
- };
- auto templated_identifier =
- [&](size_t min_args, size_t max_args = /* use min */ 0) -> const ast::TemplatedIdentifier* {
- if (max_args == 0) {
- max_args = min_args;
- }
- auto* tmpl_ident = ident->As<ast::TemplatedIdentifier>();
- if (!tmpl_ident) {
- if (TINT_UNLIKELY(min_args != 0)) {
- AddError("expected '<' for '" + ident->symbol.Name() + "'",
- Source{ident->source.range.end});
- }
- return nullptr;
- }
- if (min_args == max_args) {
- if (TINT_UNLIKELY(tmpl_ident->arguments.Length() != min_args)) {
- AddError("'" + ident->symbol.Name() + "' requires " + std::to_string(min_args) +
- " template arguments",
- ident->source);
- return nullptr;
- }
- } else {
- if (TINT_UNLIKELY(tmpl_ident->arguments.Length() < min_args)) {
- AddError("'" + ident->symbol.Name() + "' requires at least " +
- std::to_string(min_args) + " template arguments",
- ident->source);
- return nullptr;
- }
- if (TINT_UNLIKELY(tmpl_ident->arguments.Length() > max_args)) {
- AddError("'" + ident->symbol.Name() + "' requires at most " +
- std::to_string(max_args) + " template arguments",
- ident->source);
- return nullptr;
- }
- }
- return tmpl_ident;
- };
- auto vec = [&](core::type::Type* el, uint32_t n) -> core::type::Vector* {
- if (TINT_UNLIKELY(!el)) {
- return nullptr;
- }
- if (TINT_UNLIKELY(!validator_.Vector(el, ident->source))) {
- return nullptr;
- }
- return b.create<core::type::Vector>(el, n);
- };
- auto mat = [&](core::type::Type* el, uint32_t num_columns,
- uint32_t num_rows) -> core::type::Matrix* {
- if (TINT_UNLIKELY(!el)) {
- return nullptr;
- }
- if (TINT_UNLIKELY(!validator_.Matrix(el, ident->source))) {
- return nullptr;
- }
- auto* column = vec(el, num_rows);
- if (!column) {
- return nullptr;
- }
- return b.create<core::type::Matrix>(column, num_columns);
- };
- auto vec_t = [&](uint32_t n) -> core::type::Vector* {
- auto* tmpl_ident = templated_identifier(1);
- if (TINT_UNLIKELY(!tmpl_ident)) {
- return nullptr;
- }
- auto* ty = Type(tmpl_ident->arguments[0]);
- if (TINT_UNLIKELY(!ty)) {
- return nullptr;
- }
- return vec(const_cast<core::type::Type*>(ty), n);
- };
- auto mat_t = [&](uint32_t num_columns, uint32_t num_rows) -> core::type::Matrix* {
- auto* tmpl_ident = templated_identifier(1);
- if (TINT_UNLIKELY(!tmpl_ident)) {
- return nullptr;
- }
- auto* ty = Type(tmpl_ident->arguments[0]);
- if (TINT_UNLIKELY(!ty)) {
- return nullptr;
- }
- return mat(const_cast<core::type::Type*>(ty), num_columns, num_rows);
- };
- auto array = [&]() -> core::type::Array* {
- UniqueVector<const sem::GlobalVariable*, 4> transitively_referenced_overrides;
- TINT_SCOPED_ASSIGNMENT(resolved_overrides_, &transitively_referenced_overrides);
-
- auto* tmpl_ident = templated_identifier(1, 2);
- if (TINT_UNLIKELY(!tmpl_ident)) {
- return nullptr;
- }
- auto* ast_el_ty = tmpl_ident->arguments[0];
- auto* ast_count = (tmpl_ident->arguments.Length() > 1) ? tmpl_ident->arguments[1] : nullptr;
-
- auto* el_ty = Type(ast_el_ty);
- if (!el_ty) {
- return nullptr;
- }
-
- const core::type::ArrayCount* el_count =
- ast_count ? ArrayCount(ast_count) : builder_->create<core::type::RuntimeArrayCount>();
- if (!el_count) {
- return nullptr;
- }
-
- // Look for explicit stride via @stride(n) attribute
- uint32_t explicit_stride = 0;
- if (!ArrayAttributes(tmpl_ident->attributes, el_ty, explicit_stride)) {
- return nullptr;
- }
-
- auto* out = Array(tmpl_ident->source, //
- ast_el_ty->source, //
- ast_count ? ast_count->source : ident->source, //
- el_ty, el_count, explicit_stride);
- if (!out) {
- return nullptr;
- }
-
- if (el_ty->Is<core::type::Atomic>()) {
- atomic_composite_info_.Add(out, &ast_el_ty->source);
- } else {
- if (auto found = atomic_composite_info_.Get(el_ty)) {
- atomic_composite_info_.Add(out, *found);
- }
- }
-
- // Track the pipeline-overridable constants that are transitively referenced by this
- // array type.
- for (auto* var : transitively_referenced_overrides) {
- builder_->Sem().AddTransitivelyReferencedOverride(out, var);
- }
- return out;
- };
- auto atomic = [&]() -> core::type::Atomic* {
- auto* tmpl_ident = templated_identifier(1); // atomic<type>
- if (TINT_UNLIKELY(!tmpl_ident)) {
- return nullptr;
- }
-
- auto* ty_expr = TypeExpression(tmpl_ident->arguments[0]);
- if (TINT_UNLIKELY(!ty_expr)) {
- return nullptr;
- }
- auto* ty = ty_expr->Type();
-
- auto* out = builder_->create<core::type::Atomic>(ty);
- if (!validator_.Atomic(tmpl_ident, out)) {
- return nullptr;
- }
- return out;
- };
- auto ptr = [&]() -> core::type::Pointer* {
- auto* tmpl_ident = templated_identifier(2, 3); // ptr<address, type [, access]>
- if (TINT_UNLIKELY(!tmpl_ident)) {
- return nullptr;
- }
-
- auto* address_space_expr = AddressSpaceExpression(tmpl_ident->arguments[0]);
- if (TINT_UNLIKELY(!address_space_expr)) {
- return nullptr;
- }
- auto address_space = address_space_expr->Value();
-
- auto* store_ty_expr = TypeExpression(tmpl_ident->arguments[1]);
- if (TINT_UNLIKELY(!store_ty_expr)) {
- return nullptr;
- }
- auto* store_ty = const_cast<core::type::Type*>(store_ty_expr->Type());
-
- auto access = DefaultAccessForAddressSpace(address_space);
- if (tmpl_ident->arguments.Length() > 2) {
- auto* access_expr = AccessExpression(tmpl_ident->arguments[2]);
- if (TINT_UNLIKELY(!access_expr)) {
- return nullptr;
- }
- access = access_expr->Value();
- }
-
- auto* out = b.create<core::type::Pointer>(address_space, store_ty, access);
- if (!validator_.Pointer(tmpl_ident, out)) {
- return nullptr;
- }
- if (!ApplyAddressSpaceUsageToType(address_space, store_ty,
- store_ty_expr->Declaration()->source)) {
- AddNote("while instantiating " + out->FriendlyName(), ident->source);
- return nullptr;
- }
- return out;
- };
- auto sampled_texture = [&](core::type::TextureDimension dim) -> core::type::SampledTexture* {
- auto* tmpl_ident = templated_identifier(1);
- if (TINT_UNLIKELY(!tmpl_ident)) {
- return nullptr;
- }
-
- auto* ty_expr = TypeExpression(tmpl_ident->arguments[0]);
- if (TINT_UNLIKELY(!ty_expr)) {
- return nullptr;
- }
- auto* out = b.create<core::type::SampledTexture>(dim, ty_expr->Type());
- return validator_.SampledTexture(out, ident->source) ? out : nullptr;
- };
- auto multisampled_texture =
- [&](core::type::TextureDimension dim) -> core::type::MultisampledTexture* {
- auto* tmpl_ident = templated_identifier(1);
- if (TINT_UNLIKELY(!tmpl_ident)) {
- return nullptr;
- }
-
- auto* ty_expr = TypeExpression(tmpl_ident->arguments[0]);
- if (TINT_UNLIKELY(!ty_expr)) {
- return nullptr;
- }
- auto* out = b.create<core::type::MultisampledTexture>(dim, ty_expr->Type());
- return validator_.MultisampledTexture(out, ident->source) ? out : nullptr;
- };
- auto storage_texture = [&](core::type::TextureDimension dim) -> core::type::StorageTexture* {
- auto* tmpl_ident = templated_identifier(2);
- if (TINT_UNLIKELY(!tmpl_ident)) {
- return nullptr;
- }
-
- auto* format = TexelFormatExpression(tmpl_ident->arguments[0]);
- if (TINT_UNLIKELY(!format)) {
- return nullptr;
- }
- auto* access = AccessExpression(tmpl_ident->arguments[1]);
- if (TINT_UNLIKELY(!access)) {
- return nullptr;
- }
- auto* subtype = core::type::StorageTexture::SubtypeFor(format->Value(), builder_->Types());
- auto* tex =
- b.create<core::type::StorageTexture>(dim, format->Value(), access->Value(), subtype);
- if (!validator_.StorageTexture(tex, ident->source)) {
- return nullptr;
- }
- return tex;
- };
- auto packed_vec3_t = [&]() -> core::type::Vector* {
- auto* tmpl_ident = templated_identifier(1);
- if (TINT_UNLIKELY(!tmpl_ident)) {
- return nullptr;
- }
- auto* el_ty = Type(tmpl_ident->arguments[0]);
- if (TINT_UNLIKELY(!el_ty)) {
- return nullptr;
- }
-
- if (TINT_UNLIKELY(!validator_.Vector(el_ty, ident->source))) {
- return nullptr;
- }
- return b.create<core::type::Vector>(el_ty, 3u, true);
- };
switch (builtin_ty) {
case core::BuiltinType::kBool:
return check_no_tmpl_args(b.create<core::type::Bool>());
case core::BuiltinType::kI32:
- return check_no_tmpl_args(i32());
+ return check_no_tmpl_args(I32());
case core::BuiltinType::kU32:
- return check_no_tmpl_args(u32());
+ return check_no_tmpl_args(U32());
case core::BuiltinType::kF16:
- return check_no_tmpl_args(f16());
+ return check_no_tmpl_args(F16(ident));
case core::BuiltinType::kF32:
return check_no_tmpl_args(b.create<core::type::F32>());
case core::BuiltinType::kVec2:
- return vec_t(2);
+ return VecT(ident, 2);
case core::BuiltinType::kVec3:
- return vec_t(3);
+ return VecT(ident, 3);
case core::BuiltinType::kVec4:
- return vec_t(4);
+ return VecT(ident, 4);
case core::BuiltinType::kMat2X2:
- return mat_t(2, 2);
+ return MatT(ident, 2, 2);
case core::BuiltinType::kMat2X3:
- return mat_t(2, 3);
+ return MatT(ident, 2, 3);
case core::BuiltinType::kMat2X4:
- return mat_t(2, 4);
+ return MatT(ident, 2, 4);
case core::BuiltinType::kMat3X2:
- return mat_t(3, 2);
+ return MatT(ident, 3, 2);
case core::BuiltinType::kMat3X3:
- return mat_t(3, 3);
+ return MatT(ident, 3, 3);
case core::BuiltinType::kMat3X4:
- return mat_t(3, 4);
+ return MatT(ident, 3, 4);
case core::BuiltinType::kMat4X2:
- return mat_t(4, 2);
+ return MatT(ident, 4, 2);
case core::BuiltinType::kMat4X3:
- return mat_t(4, 3);
+ return MatT(ident, 4, 3);
case core::BuiltinType::kMat4X4:
- return mat_t(4, 4);
+ return MatT(ident, 4, 4);
case core::BuiltinType::kMat2X2F:
- return check_no_tmpl_args(mat(f32(), 2u, 2u));
+ return check_no_tmpl_args(Mat(ident, F32(), 2u, 2u));
case core::BuiltinType::kMat2X3F:
- return check_no_tmpl_args(mat(f32(), 2u, 3u));
+ return check_no_tmpl_args(Mat(ident, F32(), 2u, 3u));
case core::BuiltinType::kMat2X4F:
- return check_no_tmpl_args(mat(f32(), 2u, 4u));
+ return check_no_tmpl_args(Mat(ident, F32(), 2u, 4u));
case core::BuiltinType::kMat3X2F:
- return check_no_tmpl_args(mat(f32(), 3u, 2u));
+ return check_no_tmpl_args(Mat(ident, F32(), 3u, 2u));
case core::BuiltinType::kMat3X3F:
- return check_no_tmpl_args(mat(f32(), 3u, 3u));
+ return check_no_tmpl_args(Mat(ident, F32(), 3u, 3u));
case core::BuiltinType::kMat3X4F:
- return check_no_tmpl_args(mat(f32(), 3u, 4u));
+ return check_no_tmpl_args(Mat(ident, F32(), 3u, 4u));
case core::BuiltinType::kMat4X2F:
- return check_no_tmpl_args(mat(f32(), 4u, 2u));
+ return check_no_tmpl_args(Mat(ident, F32(), 4u, 2u));
case core::BuiltinType::kMat4X3F:
- return check_no_tmpl_args(mat(f32(), 4u, 3u));
+ return check_no_tmpl_args(Mat(ident, F32(), 4u, 3u));
case core::BuiltinType::kMat4X4F:
- return check_no_tmpl_args(mat(f32(), 4u, 4u));
+ return check_no_tmpl_args(Mat(ident, F32(), 4u, 4u));
case core::BuiltinType::kMat2X2H:
- return check_no_tmpl_args(mat(f16(), 2u, 2u));
+ return check_no_tmpl_args(Mat(ident, F16(ident), 2u, 2u));
case core::BuiltinType::kMat2X3H:
- return check_no_tmpl_args(mat(f16(), 2u, 3u));
+ return check_no_tmpl_args(Mat(ident, F16(ident), 2u, 3u));
case core::BuiltinType::kMat2X4H:
- return check_no_tmpl_args(mat(f16(), 2u, 4u));
+ return check_no_tmpl_args(Mat(ident, F16(ident), 2u, 4u));
case core::BuiltinType::kMat3X2H:
- return check_no_tmpl_args(mat(f16(), 3u, 2u));
+ return check_no_tmpl_args(Mat(ident, F16(ident), 3u, 2u));
case core::BuiltinType::kMat3X3H:
- return check_no_tmpl_args(mat(f16(), 3u, 3u));
+ return check_no_tmpl_args(Mat(ident, F16(ident), 3u, 3u));
case core::BuiltinType::kMat3X4H:
- return check_no_tmpl_args(mat(f16(), 3u, 4u));
+ return check_no_tmpl_args(Mat(ident, F16(ident), 3u, 4u));
case core::BuiltinType::kMat4X2H:
- return check_no_tmpl_args(mat(f16(), 4u, 2u));
+ return check_no_tmpl_args(Mat(ident, F16(ident), 4u, 2u));
case core::BuiltinType::kMat4X3H:
- return check_no_tmpl_args(mat(f16(), 4u, 3u));
+ return check_no_tmpl_args(Mat(ident, F16(ident), 4u, 3u));
case core::BuiltinType::kMat4X4H:
- return check_no_tmpl_args(mat(f16(), 4u, 4u));
+ return check_no_tmpl_args(Mat(ident, F16(ident), 4u, 4u));
case core::BuiltinType::kVec2F:
- return check_no_tmpl_args(vec(f32(), 2u));
+ return check_no_tmpl_args(Vec(ident, F32(), 2u));
case core::BuiltinType::kVec3F:
- return check_no_tmpl_args(vec(f32(), 3u));
+ return check_no_tmpl_args(Vec(ident, F32(), 3u));
case core::BuiltinType::kVec4F:
- return check_no_tmpl_args(vec(f32(), 4u));
+ return check_no_tmpl_args(Vec(ident, F32(), 4u));
case core::BuiltinType::kVec2H:
- return check_no_tmpl_args(vec(f16(), 2u));
+ return check_no_tmpl_args(Vec(ident, F16(ident), 2u));
case core::BuiltinType::kVec3H:
- return check_no_tmpl_args(vec(f16(), 3u));
+ return check_no_tmpl_args(Vec(ident, F16(ident), 3u));
case core::BuiltinType::kVec4H:
- return check_no_tmpl_args(vec(f16(), 4u));
+ return check_no_tmpl_args(Vec(ident, F16(ident), 4u));
case core::BuiltinType::kVec2I:
- return check_no_tmpl_args(vec(i32(), 2u));
+ return check_no_tmpl_args(Vec(ident, I32(), 2u));
case core::BuiltinType::kVec3I:
- return check_no_tmpl_args(vec(i32(), 3u));
+ return check_no_tmpl_args(Vec(ident, I32(), 3u));
case core::BuiltinType::kVec4I:
- return check_no_tmpl_args(vec(i32(), 4u));
+ return check_no_tmpl_args(Vec(ident, I32(), 4u));
case core::BuiltinType::kVec2U:
- return check_no_tmpl_args(vec(u32(), 2u));
+ return check_no_tmpl_args(Vec(ident, U32(), 2u));
case core::BuiltinType::kVec3U:
- return check_no_tmpl_args(vec(u32(), 3u));
+ return check_no_tmpl_args(Vec(ident, U32(), 3u));
case core::BuiltinType::kVec4U:
- return check_no_tmpl_args(vec(u32(), 4u));
+ return check_no_tmpl_args(Vec(ident, U32(), 4u));
case core::BuiltinType::kArray:
- return array();
+ return Array(ident);
case core::BuiltinType::kAtomic:
- return atomic();
+ return Atomic(ident);
case core::BuiltinType::kPtr:
- return ptr();
+ return Ptr(ident);
case core::BuiltinType::kSampler:
return check_no_tmpl_args(
builder_->create<core::type::Sampler>(core::type::SamplerKind::kSampler));
@@ -2890,17 +2630,17 @@
return check_no_tmpl_args(
builder_->create<core::type::Sampler>(core::type::SamplerKind::kComparisonSampler));
case core::BuiltinType::kTexture1D:
- return sampled_texture(core::type::TextureDimension::k1d);
+ return SampledTexture(ident, core::type::TextureDimension::k1d);
case core::BuiltinType::kTexture2D:
- return sampled_texture(core::type::TextureDimension::k2d);
+ return SampledTexture(ident, core::type::TextureDimension::k2d);
case core::BuiltinType::kTexture2DArray:
- return sampled_texture(core::type::TextureDimension::k2dArray);
+ return SampledTexture(ident, core::type::TextureDimension::k2dArray);
case core::BuiltinType::kTexture3D:
- return sampled_texture(core::type::TextureDimension::k3d);
+ return SampledTexture(ident, core::type::TextureDimension::k3d);
case core::BuiltinType::kTextureCube:
- return sampled_texture(core::type::TextureDimension::kCube);
+ return SampledTexture(ident, core::type::TextureDimension::kCube);
case core::BuiltinType::kTextureCubeArray:
- return sampled_texture(core::type::TextureDimension::kCubeArray);
+ return SampledTexture(ident, core::type::TextureDimension::kCubeArray);
case core::BuiltinType::kTextureDepth2D:
return check_no_tmpl_args(
builder_->create<core::type::DepthTexture>(core::type::TextureDimension::k2d));
@@ -2919,89 +2659,90 @@
case core::BuiltinType::kTextureExternal:
return check_no_tmpl_args(builder_->create<core::type::ExternalTexture>());
case core::BuiltinType::kTextureMultisampled2D:
- return multisampled_texture(core::type::TextureDimension::k2d);
+ return MultisampledTexture(ident, core::type::TextureDimension::k2d);
case core::BuiltinType::kTextureStorage1D:
- return storage_texture(core::type::TextureDimension::k1d);
+ return StorageTexture(ident, core::type::TextureDimension::k1d);
case core::BuiltinType::kTextureStorage2D:
- return storage_texture(core::type::TextureDimension::k2d);
+ return StorageTexture(ident, core::type::TextureDimension::k2d);
case core::BuiltinType::kTextureStorage2DArray:
- return storage_texture(core::type::TextureDimension::k2dArray);
+ return StorageTexture(ident, core::type::TextureDimension::k2dArray);
case core::BuiltinType::kTextureStorage3D:
- return storage_texture(core::type::TextureDimension::k3d);
+ return StorageTexture(ident, core::type::TextureDimension::k3d);
case core::BuiltinType::kPackedVec3:
- return packed_vec3_t();
+ return PackedVec3T(ident);
case core::BuiltinType::kAtomicCompareExchangeResultI32:
return core::type::CreateAtomicCompareExchangeResult(builder_->Types(),
- builder_->Symbols(), i32());
+ builder_->Symbols(), I32());
case core::BuiltinType::kAtomicCompareExchangeResultU32:
return core::type::CreateAtomicCompareExchangeResult(builder_->Types(),
- builder_->Symbols(), u32());
+ builder_->Symbols(), U32());
case core::BuiltinType::kFrexpResultAbstract:
- return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), af());
+ return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), AF());
case core::BuiltinType::kFrexpResultF16:
- return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), f16());
+ return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
+ F16(ident));
case core::BuiltinType::kFrexpResultF32:
- return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), f32());
+ return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), F32());
case core::BuiltinType::kFrexpResultVec2Abstract:
return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
- vec(af(), 2));
+ Vec(ident, AF(), 2));
case core::BuiltinType::kFrexpResultVec2F16:
return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
- vec(f16(), 2));
+ Vec(ident, F16(ident), 2));
case core::BuiltinType::kFrexpResultVec2F32:
return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
- vec(f32(), 2));
+ Vec(ident, F32(), 2));
case core::BuiltinType::kFrexpResultVec3Abstract:
return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
- vec(af(), 3));
+ Vec(ident, AF(), 3));
case core::BuiltinType::kFrexpResultVec3F16:
return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
- vec(f16(), 3));
+ Vec(ident, F16(ident), 3));
case core::BuiltinType::kFrexpResultVec3F32:
return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
- vec(f32(), 3));
+ Vec(ident, F32(), 3));
case core::BuiltinType::kFrexpResultVec4Abstract:
return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
- vec(af(), 4));
+ Vec(ident, AF(), 4));
case core::BuiltinType::kFrexpResultVec4F16:
return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
- vec(f16(), 4));
+ Vec(ident, F16(ident), 4));
case core::BuiltinType::kFrexpResultVec4F32:
return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
- vec(f32(), 4));
+ Vec(ident, F32(), 4));
case core::BuiltinType::kModfResultAbstract:
- return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(), af());
+ return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(), AF());
case core::BuiltinType::kModfResultF16:
- return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(), f16());
+ return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(), F16(ident));
case core::BuiltinType::kModfResultF32:
- return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(), f32());
+ return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(), F32());
case core::BuiltinType::kModfResultVec2Abstract:
return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
- vec(af(), 2));
+ Vec(ident, AF(), 2));
case core::BuiltinType::kModfResultVec2F16:
return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
- vec(f16(), 2));
+ Vec(ident, F16(ident), 2));
case core::BuiltinType::kModfResultVec2F32:
return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
- vec(f32(), 2));
+ Vec(ident, F32(), 2));
case core::BuiltinType::kModfResultVec3Abstract:
return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
- vec(af(), 3));
+ Vec(ident, AF(), 3));
case core::BuiltinType::kModfResultVec3F16:
return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
- vec(f16(), 3));
+ Vec(ident, F16(ident), 3));
case core::BuiltinType::kModfResultVec3F32:
return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
- vec(f32(), 3));
+ Vec(ident, F32(), 3));
case core::BuiltinType::kModfResultVec4Abstract:
return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
- vec(af(), 4));
+ Vec(ident, AF(), 4));
case core::BuiltinType::kModfResultVec4F16:
return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
- vec(f16(), 4));
+ Vec(ident, F16(ident), 4));
case core::BuiltinType::kModfResultVec4F32:
return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
- vec(f32(), 4));
+ Vec(ident, F32(), 4));
case core::BuiltinType::kUndefined:
break;
}
@@ -3013,6 +2754,298 @@
return nullptr;
}
+core::type::AbstractFloat* Resolver::AF() {
+ return builder_->create<core::type::AbstractFloat>();
+}
+
+core::type::F32* Resolver::F32() {
+ return builder_->create<core::type::F32>();
+}
+
+core::type::I32* Resolver::I32() {
+ return builder_->create<core::type::I32>();
+}
+
+core::type::U32* Resolver::U32() {
+ return builder_->create<core::type::U32>();
+}
+
+core::type::F16* Resolver::F16(const ast::Identifier* ident) {
+ return validator_.CheckF16Enabled(ident->source) ? builder_->create<core::type::F16>()
+ : nullptr;
+}
+
+core::type::Vector* Resolver::Vec(const ast::Identifier* ident, core::type::Type* el, uint32_t n) {
+ if (TINT_UNLIKELY(!el)) {
+ return nullptr;
+ }
+ if (TINT_UNLIKELY(!validator_.Vector(el, ident->source))) {
+ return nullptr;
+ }
+ return builder_->create<core::type::Vector>(el, n);
+}
+
+core::type::Vector* Resolver::VecT(const ast::Identifier* ident, uint32_t n) {
+ auto* tmpl_ident = TemplatedIdentifier(ident, 1);
+ if (TINT_UNLIKELY(!tmpl_ident)) {
+ return nullptr;
+ }
+ auto* ty = Type(tmpl_ident->arguments[0]);
+ if (TINT_UNLIKELY(!ty)) {
+ return nullptr;
+ }
+ return Vec(ident, const_cast<core::type::Type*>(ty), n);
+}
+
+core::type::Matrix* Resolver::Mat(const ast::Identifier* ident,
+ core::type::Type* el,
+ uint32_t num_columns,
+ uint32_t num_rows) {
+ if (TINT_UNLIKELY(!el)) {
+ return nullptr;
+ }
+ if (TINT_UNLIKELY(!validator_.Matrix(el, ident->source))) {
+ return nullptr;
+ }
+ auto* column = Vec(ident, el, num_rows);
+ if (!column) {
+ return nullptr;
+ }
+ return builder_->create<core::type::Matrix>(column, num_columns);
+}
+
+core::type::Matrix* Resolver::MatT(const ast::Identifier* ident,
+ uint32_t num_columns,
+ uint32_t num_rows) {
+ auto* tmpl_ident = TemplatedIdentifier(ident, 1);
+ if (TINT_UNLIKELY(!tmpl_ident)) {
+ return nullptr;
+ }
+ auto* ty = Type(tmpl_ident->arguments[0]);
+ if (TINT_UNLIKELY(!ty)) {
+ return nullptr;
+ }
+ return Mat(ident, const_cast<core::type::Type*>(ty), num_columns, num_rows);
+}
+
+core::type::Array* Resolver::Array(const ast::Identifier* ident) {
+ UniqueVector<const sem::GlobalVariable*, 4> transitively_referenced_overrides;
+ TINT_SCOPED_ASSIGNMENT(resolved_overrides_, &transitively_referenced_overrides);
+
+ auto* tmpl_ident = TemplatedIdentifier(ident, 1, 2);
+ if (TINT_UNLIKELY(!tmpl_ident)) {
+ return nullptr;
+ }
+ auto* ast_el_ty = tmpl_ident->arguments[0];
+ auto* ast_count = (tmpl_ident->arguments.Length() > 1) ? tmpl_ident->arguments[1] : nullptr;
+
+ auto* el_ty = Type(ast_el_ty);
+ if (!el_ty) {
+ return nullptr;
+ }
+
+ const core::type::ArrayCount* el_count =
+ ast_count ? ArrayCount(ast_count) : builder_->create<core::type::RuntimeArrayCount>();
+ if (!el_count) {
+ return nullptr;
+ }
+
+ // Look for explicit stride via @stride(n) attribute
+ uint32_t explicit_stride = 0;
+ if (!ArrayAttributes(tmpl_ident->attributes, el_ty, explicit_stride)) {
+ return nullptr;
+ }
+
+ auto* out = Array(tmpl_ident->source, //
+ ast_el_ty->source, //
+ ast_count ? ast_count->source : ident->source, //
+ el_ty, el_count, explicit_stride);
+ if (!out) {
+ return nullptr;
+ }
+
+ if (el_ty->Is<core::type::Atomic>()) {
+ atomic_composite_info_.Add(out, &ast_el_ty->source);
+ } else {
+ if (auto found = atomic_composite_info_.Get(el_ty)) {
+ atomic_composite_info_.Add(out, *found);
+ }
+ }
+
+ // Track the pipeline-overridable constants that are transitively referenced by this
+ // array type.
+ for (auto* var : transitively_referenced_overrides) {
+ builder_->Sem().AddTransitivelyReferencedOverride(out, var);
+ }
+ return out;
+}
+
+core::type::Atomic* Resolver::Atomic(const ast::Identifier* ident) {
+ auto* tmpl_ident = TemplatedIdentifier(ident, 1); // atomic<type>
+ if (TINT_UNLIKELY(!tmpl_ident)) {
+ return nullptr;
+ }
+
+ auto* ty_expr = TypeExpression(tmpl_ident->arguments[0]);
+ if (TINT_UNLIKELY(!ty_expr)) {
+ return nullptr;
+ }
+ auto* ty = ty_expr->Type();
+
+ auto* out = builder_->create<core::type::Atomic>(ty);
+ if (!validator_.Atomic(tmpl_ident, out)) {
+ return nullptr;
+ }
+ return out;
+}
+
+core::type::Pointer* Resolver::Ptr(const ast::Identifier* ident) {
+ auto* tmpl_ident = TemplatedIdentifier(ident, 2, 3); // ptr<address, type [, access]>
+ if (TINT_UNLIKELY(!tmpl_ident)) {
+ return nullptr;
+ }
+
+ auto* address_space_expr = AddressSpaceExpression(tmpl_ident->arguments[0]);
+ if (TINT_UNLIKELY(!address_space_expr)) {
+ return nullptr;
+ }
+ auto address_space = address_space_expr->Value();
+
+ auto* store_ty_expr = TypeExpression(tmpl_ident->arguments[1]);
+ if (TINT_UNLIKELY(!store_ty_expr)) {
+ return nullptr;
+ }
+ auto* store_ty = const_cast<core::type::Type*>(store_ty_expr->Type());
+
+ auto access = DefaultAccessForAddressSpace(address_space);
+ if (tmpl_ident->arguments.Length() > 2) {
+ auto* access_expr = AccessExpression(tmpl_ident->arguments[2]);
+ if (TINT_UNLIKELY(!access_expr)) {
+ return nullptr;
+ }
+ access = access_expr->Value();
+ }
+
+ auto* out = builder_->create<core::type::Pointer>(address_space, store_ty, access);
+ if (!validator_.Pointer(tmpl_ident, out)) {
+ return nullptr;
+ }
+ if (!ApplyAddressSpaceUsageToType(address_space, store_ty,
+ store_ty_expr->Declaration()->source)) {
+ AddNote("while instantiating " + out->FriendlyName(), ident->source);
+ return nullptr;
+ }
+ return out;
+}
+
+core::type::SampledTexture* Resolver::SampledTexture(const ast::Identifier* ident,
+ core::type::TextureDimension dim) {
+ auto* tmpl_ident = TemplatedIdentifier(ident, 1);
+ if (TINT_UNLIKELY(!tmpl_ident)) {
+ return nullptr;
+ }
+
+ auto* ty_expr = TypeExpression(tmpl_ident->arguments[0]);
+ if (TINT_UNLIKELY(!ty_expr)) {
+ return nullptr;
+ }
+ auto* out = builder_->create<core::type::SampledTexture>(dim, ty_expr->Type());
+ return validator_.SampledTexture(out, ident->source) ? out : nullptr;
+}
+
+core::type::MultisampledTexture* Resolver::MultisampledTexture(const ast::Identifier* ident,
+ core::type::TextureDimension dim) {
+ auto* tmpl_ident = TemplatedIdentifier(ident, 1);
+ if (TINT_UNLIKELY(!tmpl_ident)) {
+ return nullptr;
+ }
+
+ auto* ty_expr = TypeExpression(tmpl_ident->arguments[0]);
+ if (TINT_UNLIKELY(!ty_expr)) {
+ return nullptr;
+ }
+ auto* out = builder_->create<core::type::MultisampledTexture>(dim, ty_expr->Type());
+ return validator_.MultisampledTexture(out, ident->source) ? out : nullptr;
+}
+
+core::type::StorageTexture* Resolver::StorageTexture(const ast::Identifier* ident,
+ core::type::TextureDimension dim) {
+ auto* tmpl_ident = TemplatedIdentifier(ident, 2);
+ if (TINT_UNLIKELY(!tmpl_ident)) {
+ return nullptr;
+ }
+
+ auto* format = TexelFormatExpression(tmpl_ident->arguments[0]);
+ if (TINT_UNLIKELY(!format)) {
+ return nullptr;
+ }
+ auto* access = AccessExpression(tmpl_ident->arguments[1]);
+ if (TINT_UNLIKELY(!access)) {
+ return nullptr;
+ }
+ auto* subtype = core::type::StorageTexture::SubtypeFor(format->Value(), builder_->Types());
+ auto* tex = builder_->create<core::type::StorageTexture>(dim, format->Value(), access->Value(),
+ subtype);
+ if (!validator_.StorageTexture(tex, ident->source)) {
+ return nullptr;
+ }
+ return tex;
+}
+
+core::type::Vector* Resolver::PackedVec3T(const ast::Identifier* ident) {
+ auto* tmpl_ident = TemplatedIdentifier(ident, 1);
+ if (TINT_UNLIKELY(!tmpl_ident)) {
+ return nullptr;
+ }
+ auto* el_ty = Type(tmpl_ident->arguments[0]);
+ if (TINT_UNLIKELY(!el_ty)) {
+ return nullptr;
+ }
+
+ if (TINT_UNLIKELY(!validator_.Vector(el_ty, ident->source))) {
+ return nullptr;
+ }
+ return builder_->create<core::type::Vector>(el_ty, 3u, true);
+}
+
+const ast::TemplatedIdentifier* Resolver::TemplatedIdentifier(const ast::Identifier* ident,
+ size_t min_args,
+ size_t max_args /* = use min 0 */) {
+ if (max_args == 0) {
+ max_args = min_args;
+ }
+ auto* tmpl_ident = ident->As<ast::TemplatedIdentifier>();
+ if (!tmpl_ident) {
+ if (TINT_UNLIKELY(min_args != 0)) {
+ AddError("expected '<' for '" + ident->symbol.Name() + "'",
+ Source{ident->source.range.end});
+ }
+ return nullptr;
+ }
+ if (min_args == max_args) {
+ if (TINT_UNLIKELY(tmpl_ident->arguments.Length() != min_args)) {
+ AddError("'" + ident->symbol.Name() + "' requires " + std::to_string(min_args) +
+ " template arguments",
+ ident->source);
+ return nullptr;
+ }
+ } else {
+ if (TINT_UNLIKELY(tmpl_ident->arguments.Length() < min_args)) {
+ AddError("'" + ident->symbol.Name() + "' requires at least " +
+ std::to_string(min_args) + " template arguments",
+ ident->source);
+ return nullptr;
+ }
+ if (TINT_UNLIKELY(tmpl_ident->arguments.Length() > max_args)) {
+ AddError("'" + ident->symbol.Name() + "' requires at most " + std::to_string(max_args) +
+ " template arguments",
+ ident->source);
+ return nullptr;
+ }
+ }
+ return tmpl_ident;
+}
+
size_t Resolver::NestDepth(const core::type::Type* ty) const {
return Switch(
ty, //
diff --git a/src/tint/lang/wgsl/resolver/resolver.h b/src/tint/lang/wgsl/resolver/resolver.h
index 3846d1a..7641849 100644
--- a/src/tint/lang/wgsl/resolver/resolver.h
+++ b/src/tint/lang/wgsl/resolver/resolver.h
@@ -145,6 +145,72 @@
/// @returns the resolved type from an expression, or nullptr on error
core::type::Type* Type(const ast::Expression* ast);
+ /// @returns a new abstract-float
+ core::type::AbstractFloat* AF();
+
+ /// @returns a new f32
+ core::type::F32* F32();
+
+ /// @returns a new i32
+ core::type::I32* I32();
+
+ /// @returns a new u32
+ core::type::U32* U32();
+
+ /// @returns a new f16, if the f16 extension is enabled, otherwise nullptr
+ core::type::F16* F16(const ast::Identifier* ident);
+
+ /// @returns a vector with the element type @p el of width @p n resolved from the identifier @p
+ /// ident.
+ core::type::Vector* Vec(const ast::Identifier* ident, core::type::Type* el, uint32_t n);
+
+ /// @returns a vector of width @p n resolved from the templated identifier @p ident.
+ core::type::Vector* VecT(const ast::Identifier* ident, uint32_t n);
+
+ /// @returns a matrix with the element type @p el of dimensions @p num_columns x @p num_rows
+ /// resolved from the identifier @p ident.
+ core::type::Matrix* Mat(const ast::Identifier* ident,
+ core::type::Type* el,
+ uint32_t num_columns,
+ uint32_t num_rows);
+
+ /// @returns a matrix of dimensions @p num_columns x @p num_rows resolved from the templated
+ /// identifier @p ident.
+ core::type::Matrix* MatT(const ast::Identifier* ident, uint32_t num_columns, uint32_t num_rows);
+
+ /// @returns an array resolved from the templated identifier @p ident.
+ core::type::Array* Array(const ast::Identifier* ident);
+
+ /// @returns an atomic resolved from the templated identifier @p ident.
+ core::type::Atomic* Atomic(const ast::Identifier* ident);
+
+ /// @returns a pointer resolved from the templated identifier @p ident.
+ core::type::Pointer* Ptr(const ast::Identifier* ident);
+
+ /// @returns a sampled texture resolved from the templated identifier @p ident with the
+ /// dimensions @p dim.
+ core::type::SampledTexture* SampledTexture(const ast::Identifier* ident,
+ core::type::TextureDimension dim);
+
+ /// @returns a multisampled texture resolved from the templated identifier @p ident with the
+ /// dimensions @p dim.
+ core::type::MultisampledTexture* MultisampledTexture(const ast::Identifier* ident,
+ core::type::TextureDimension dim);
+
+ /// @returns a storage texture resolved from the templated identifier @p ident with the
+ /// dimensions @p dim.
+ core::type::StorageTexture* StorageTexture(const ast::Identifier* ident,
+ core::type::TextureDimension dim);
+
+ /// @returns a packed vec3 resolved from the templated identifier @p ident.
+ core::type::Vector* PackedVec3T(const ast::Identifier* ident);
+
+ /// @returns @p ident cast to an ast::TemplatedIdentifier, if the identifier is templated and
+ /// the number of templated arguments are between @p min_args and @p max_args.
+ const ast::TemplatedIdentifier* TemplatedIdentifier(const ast::Identifier* ident,
+ size_t min_args,
+ size_t max_args = /* use min */ 0);
+
/// @returns the call of Expression() cast to a
/// sem::BuiltinEnumExpression<core::AddressSpace>. If the sem::Expression is not a
/// sem::BuiltinEnumExpression<core::AddressSpace>, then an error diagnostic is raised and