[tint][sem] Move variable attributes to separate structs
Similar to MemberAttributes, add GlobalVariableAttributes and
ParameterAttributes.
This avoids confusion over Parameter::Index() which is the index of the
parameter in the function, and the @index value.
Change-Id: If045ab5d70ef60580f51c5d701d892828253d844
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/160080
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/cmd/common/generate_external_texture_bindings.cc b/src/tint/cmd/common/generate_external_texture_bindings.cc
index 7002faa..fdb7704 100644
--- a/src/tint/cmd/common/generate_external_texture_bindings.cc
+++ b/src/tint/cmd/common/generate_external_texture_bindings.cc
@@ -48,7 +48,7 @@
std::vector<tint::BindingPoint> ext_tex_bps;
for (auto* var : program.AST().GlobalVariables()) {
if (auto* sem_var = program.Sem().Get(var)->As<sem::GlobalVariable>()) {
- if (auto bp = sem_var->BindingPoint()) {
+ if (auto bp = sem_var->Attributes().binding_point) {
auto& n = group_to_next_binding_number[bp->group];
n = std::max(n, bp->binding + 1);
diff --git a/src/tint/fuzzers/tint_common_fuzzer.cc b/src/tint/fuzzers/tint_common_fuzzer.cc
index 8f36a89..e6ae17b 100644
--- a/src/tint/fuzzers/tint_common_fuzzer.cc
+++ b/src/tint/fuzzers/tint_common_fuzzer.cc
@@ -284,7 +284,7 @@
std::vector<BindingPoint> ext_tex_bps;
for (auto* var : program.AST().GlobalVariables()) {
if (auto* sem_var = program.Sem().Get(var)->As<sem::GlobalVariable>()) {
- if (auto bp = sem_var->BindingPoint()) {
+ if (auto bp = sem_var->Attributes().binding_point) {
auto& n = group_to_next_binding_number[bp->group];
n = std::max(n, bp->binding + 1);
diff --git a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
index b0c7219..738844e 100644
--- a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
@@ -1929,7 +1929,7 @@
TINT_ICE() << "storage variable must be of struct type";
return;
}
- auto bp = *sem->As<sem::GlobalVariable>()->BindingPoint();
+ auto bp = *sem->As<sem::GlobalVariable>()->Attributes().binding_point;
{
auto out = Line();
out << "layout(binding = " << bp.binding << ", std140";
@@ -1948,7 +1948,7 @@
TINT_ICE() << "storage variable must be of struct type";
return;
}
- auto bp = *sem->As<sem::GlobalVariable>()->BindingPoint();
+ auto bp = *sem->As<sem::GlobalVariable>()->Attributes().binding_point;
Line() << "layout(binding = " << bp.binding << ", std430) buffer "
<< UniqueIdentifier(StructName(str) + "_ssbo") << " {";
EmitStructMembers(current_buffer_, str);
@@ -2080,7 +2080,7 @@
}
auto out = Line();
- EmitAttributes(out, var, decl->attributes);
+ EmitAttributes(out, var);
EmitInterpolationQualifiers(out, decl->attributes);
auto name = decl->name->symbol.Name();
@@ -2130,23 +2130,17 @@
}
}
-void ASTPrinter::EmitAttributes(StringStream& out,
- const sem::GlobalVariable* var,
- VectorRef<const ast::Attribute*> attributes) {
- if (attributes.IsEmpty()) {
- return;
- }
+void ASTPrinter::EmitAttributes(StringStream& out, const sem::GlobalVariable* var) {
+ auto& attrs = var->Attributes();
bool first = true;
- for (auto* attr : attributes) {
- if (attr->As<ast::LocationAttribute>()) {
- out << (first ? "layout(" : ", ");
- out << "location = " << std::to_string(var->Location().value());
- first = false;
- }
- if (attr->As<ast::IndexAttribute>()) {
- out << ", index = " << std::to_string(var->Index().value());
- }
+ if (attrs.location.has_value()) {
+ out << (first ? "layout(" : ", ");
+ out << "location = " << std::to_string(attrs.location.value());
+ first = false;
+ }
+ if (attrs.index.has_value()) {
+ out << ", index = " << std::to_string(attrs.index.value());
}
if (!first) {
out << ") ";
diff --git a/src/tint/lang/glsl/writer/ast_printer/ast_printer.h b/src/tint/lang/glsl/writer/ast_printer/ast_printer.h
index 519bdf8..f5cc633 100644
--- a/src/tint/lang/glsl/writer/ast_printer/ast_printer.h
+++ b/src/tint/lang/glsl/writer/ast_printer/ast_printer.h
@@ -317,10 +317,7 @@
/// Handles emitting attributes
/// @param out the output of the expression stream
/// @param var the global variable semantics
- /// @param attrs the attributes
- void EmitAttributes(StringStream& out,
- const sem::GlobalVariable* var,
- VectorRef<const ast::Attribute*> attrs);
+ void EmitAttributes(StringStream& out, const sem::GlobalVariable* var);
/// Handles emitting the entry point function
/// @param func the entry point
void EmitEntryPointFunction(const ast::Function* func);
diff --git a/src/tint/lang/glsl/writer/ast_raise/combine_samplers.cc b/src/tint/lang/glsl/writer/ast_raise/combine_samplers.cc
index b41e960..b056310 100644
--- a/src/tint/lang/glsl/writer/ast_raise/combine_samplers.cc
+++ b/src/tint/lang/glsl/writer/ast_raise/combine_samplers.cc
@@ -118,10 +118,10 @@
std::string name) {
SamplerTexturePair bp_pair;
bp_pair.texture_binding_point =
- texture_var ? *texture_var->As<sem::GlobalVariable>()->BindingPoint()
+ texture_var ? *texture_var->As<sem::GlobalVariable>()->Attributes().binding_point
: binding_info->placeholder_binding_point;
bp_pair.sampler_binding_point =
- sampler_var ? *sampler_var->As<sem::GlobalVariable>()->BindingPoint()
+ sampler_var ? *sampler_var->As<sem::GlobalVariable>()->Attributes().binding_point
: binding_info->placeholder_binding_point;
auto it = binding_info->binding_map.find(bp_pair);
if (it != binding_info->binding_map.end()) {
@@ -232,7 +232,7 @@
if (tint::IsAnyOf<core::type::Texture, core::type::Sampler>(type) &&
!type->Is<core::type::StorageTexture>()) {
ctx.Remove(ctx.src->AST().GlobalDeclarations(), global);
- } else if (auto binding_point = global_sem->BindingPoint()) {
+ } else if (auto binding_point = global_sem->Attributes().binding_point) {
if (binding_point->group == 0 && binding_point->binding == 0) {
auto* attribute =
ctx.dst->Disable(ast::DisabledValidation::kBindingPointCollision);
diff --git a/src/tint/lang/glsl/writer/ast_raise/texture_builtins_from_uniform.cc b/src/tint/lang/glsl/writer/ast_raise/texture_builtins_from_uniform.cc
index 67eb338..bc40549 100644
--- a/src/tint/lang/glsl/writer/ast_raise/texture_builtins_from_uniform.cc
+++ b/src/tint/lang/glsl/writer/ast_raise/texture_builtins_from_uniform.cc
@@ -366,7 +366,7 @@
auto* global_sem = sem.Get<sem::GlobalVariable>(var);
// The original binding point
- BindingPoint binding_point = *global_sem->BindingPoint();
+ BindingPoint binding_point = *global_sem->Attributes().binding_point;
if (binding_point == cfg->ubo_binding) {
// This ubo_binding struct already exists.
@@ -423,7 +423,7 @@
/// @returns binding of the global variable.
BindingPoint GetAndRecordGlobalBinding(const sem::GlobalVariable* global,
TextureBuiltinsFromUniformOptions::Field field) {
- auto binding = global->BindingPoint().value();
+ auto binding = global->Attributes().binding_point.value();
auto iter = bindpoint_to_data.find(binding);
if (iter == bindpoint_to_data.end()) {
// First visit, recording the binding.
diff --git a/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc
index b23c19f..6ee9b5a 100644
--- a/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc
@@ -3331,7 +3331,7 @@
}
bool ASTPrinter::EmitUniformVariable(const ast::Var* var, const sem::Variable* sem) {
- auto binding_point = *sem->As<sem::GlobalVariable>()->BindingPoint();
+ auto binding_point = *sem->As<sem::GlobalVariable>()->Attributes().binding_point;
auto* type = sem->Type()->UnwrapRef();
auto name = var->name->symbol.Name();
Line() << "cbuffer cbuffer_" << name << RegisterAndSpace('b', binding_point) << " {";
@@ -3360,7 +3360,7 @@
auto* global_sem = sem->As<sem::GlobalVariable>();
out << RegisterAndSpace(sem->Access() == core::Access::kRead ? 't' : 'u',
- *global_sem->BindingPoint())
+ *global_sem->Attributes().binding_point)
<< ";";
return true;
@@ -3389,7 +3389,7 @@
}
if (register_space) {
- auto bp = sem->As<sem::GlobalVariable>()->BindingPoint();
+ auto bp = sem->As<sem::GlobalVariable>()->Attributes().binding_point;
out << " : register(" << register_space << bp->binding;
// Omit the space if it's 0, as it's the default.
// SM 5.0 doesn't support spaces, so we don't emit them if group is 0 for better
diff --git a/src/tint/lang/hlsl/writer/ast_raise/num_workgroups_from_uniform.cc b/src/tint/lang/hlsl/writer/ast_raise/num_workgroups_from_uniform.cc
index 31590d9..22a8ff3 100644
--- a/src/tint/lang/hlsl/writer/ast_raise/num_workgroups_from_uniform.cc
+++ b/src/tint/lang/hlsl/writer/ast_raise/num_workgroups_from_uniform.cc
@@ -165,7 +165,7 @@
for (auto* global : src.AST().GlobalVariables()) {
auto* global_sem = src.Sem().Get<sem::GlobalVariable>(global);
- if (auto bp = global_sem->BindingPoint()) {
+ if (auto bp = global_sem->Attributes().binding_point) {
if (bp->group >= group) {
group = bp->group + 1;
}
diff --git a/src/tint/lang/msl/writer/ast_printer/ast_printer.cc b/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
index aed7504..6ef2020 100644
--- a/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
@@ -1970,10 +1970,9 @@
return kInvalidBindingIndex;
}
auto* param_sem = builder_.Sem().Get<sem::Parameter>(param);
- auto bp = param_sem->BindingPoint();
+ auto bp = param_sem->Attributes().binding_point;
if (TINT_UNLIKELY(bp->group != 0)) {
- TINT_ICE() << "encountered non-zero resource group index (use "
- "BindingRemapper to fix)";
+ TINT_ICE() << "encountered non-zero resource group index (use BindingRemapper to fix)";
return kInvalidBindingIndex;
}
return bp->binding;
diff --git a/src/tint/lang/msl/writer/writer_bench.cc b/src/tint/lang/msl/writer/writer_bench.cc
index 2705e93..0af1f7b 100644
--- a/src/tint/lang/msl/writer/writer_bench.cc
+++ b/src/tint/lang/msl/writer/writer_bench.cc
@@ -65,7 +65,7 @@
uint32_t next_binding_point = 0;
for (auto* var : program.AST().GlobalVariables()) {
if (auto* var_sem = program.Sem().Get(var)->As<sem::GlobalVariable>()) {
- if (auto bp = var_sem->BindingPoint()) {
+ if (auto bp = var_sem->Attributes().binding_point) {
gen_options.binding_remapper_options.binding_points[*bp] = BindingPoint{
0, // group
next_binding_point++, // binding
diff --git a/src/tint/lang/spirv/writer/ast_printer/builder.cc b/src/tint/lang/spirv/writer/ast_printer/builder.cc
index 734c380..a75d703 100644
--- a/src/tint/lang/spirv/writer/ast_printer/builder.cc
+++ b/src/tint/lang/spirv/writer/ast_printer/builder.cc
@@ -806,13 +806,13 @@
[&](const ast::LocationAttribute*) {
module_.PushAnnot(spv::Op::OpDecorate,
{Operand(var_id), U32Operand(SpvDecorationLocation),
- Operand(sem->Location().value())});
+ Operand(sem->Attributes().location.value())});
return true;
},
[&](const ast::IndexAttribute*) {
module_.PushAnnot(spv::Op::OpDecorate,
{Operand(var_id), U32Operand(SpvDecorationIndex),
- Operand(sem->Index().value())});
+ Operand(sem->Attributes().index.value())});
return true;
},
[&](const ast::InterpolateAttribute* interpolate) {
@@ -837,14 +837,14 @@
return true;
},
[&](const ast::BindingAttribute*) {
- auto bp = sem->BindingPoint();
+ auto bp = sem->Attributes().binding_point;
module_.PushAnnot(
spv::Op::OpDecorate,
{Operand(var_id), U32Operand(SpvDecorationBinding), Operand(bp->binding)});
return true;
},
[&](const ast::GroupAttribute*) {
- auto bp = sem->BindingPoint();
+ auto bp = sem->Attributes().binding_point;
module_.PushAnnot(
spv::Op::OpDecorate,
{Operand(var_id), U32Operand(SpvDecorationDescriptorSet), Operand(bp->group)});
diff --git a/src/tint/lang/spirv/writer/helpers/generate_bindings.cc b/src/tint/lang/spirv/writer/helpers/generate_bindings.cc
index 21ef88b..076a594 100644
--- a/src/tint/lang/spirv/writer/helpers/generate_bindings.cc
+++ b/src/tint/lang/spirv/writer/helpers/generate_bindings.cc
@@ -55,7 +55,7 @@
Vector<tint::BindingPoint, 4> ext_tex_bps;
for (auto* var : program.AST().GlobalVariables()) {
if (auto* sem_var = program.Sem().Get(var)->As<sem::GlobalVariable>()) {
- if (auto bp = sem_var->BindingPoint()) {
+ if (auto bp = sem_var->Attributes().binding_point) {
if (auto val = group_to_next_binding_number.Find(bp->group)) {
*val = std::max(*val, bp->binding + 1);
} else {
diff --git a/src/tint/lang/wgsl/ast/transform/array_length_from_uniform.cc b/src/tint/lang/wgsl/ast/transform/array_length_from_uniform.cc
index 2f617c1..d98068d 100644
--- a/src/tint/lang/wgsl/ast/transform/array_length_from_uniform.cc
+++ b/src/tint/lang/wgsl/ast/transform/array_length_from_uniform.cc
@@ -100,7 +100,7 @@
IterateArrayLengthOnStorageVar(
[&](const CallExpression*, const sem::VariableUser*, const sem::GlobalVariable* var) {
- if (auto binding = var->BindingPoint()) {
+ if (auto binding = var->Attributes().binding_point) {
auto idx_itr = cfg->bindpoint_to_size_index.find(*binding);
if (idx_itr == cfg->bindpoint_to_size_index.end()) {
return;
@@ -138,7 +138,7 @@
IterateArrayLengthOnStorageVar([&](const CallExpression* call_expr,
const sem::VariableUser* storage_buffer_sem,
const sem::GlobalVariable* var) {
- auto binding = var->BindingPoint();
+ auto binding = var->Attributes().binding_point;
if (!binding) {
return;
}
diff --git a/src/tint/lang/wgsl/ast/transform/binding_remapper.cc b/src/tint/lang/wgsl/ast/transform/binding_remapper.cc
index 3ff5e0a..b2ec92a 100644
--- a/src/tint/lang/wgsl/ast/transform/binding_remapper.cc
+++ b/src/tint/lang/wgsl/ast/transform/binding_remapper.cc
@@ -89,7 +89,7 @@
auto* func = src.Sem().Get(func_ast);
std::unordered_map<BindingPoint, int> binding_point_counts;
for (auto* global : func->TransitivelyReferencedGlobals()) {
- if (auto from = global->BindingPoint()) {
+ if (auto from = global->Attributes().binding_point) {
auto bp_it = remappings->binding_points.find(*from);
if (bp_it != remappings->binding_points.end()) {
// Remapped
@@ -113,7 +113,7 @@
auto* global_sem = src.Sem().Get<sem::GlobalVariable>(var);
// The original binding point
- BindingPoint from = *global_sem->BindingPoint();
+ BindingPoint from = *global_sem->Attributes().binding_point;
// The binding point after remapping
BindingPoint bp = from;
diff --git a/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc b/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
index 4643176..45c270c 100644
--- a/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
@@ -428,7 +428,8 @@
}
auto name = param->Declaration()->name->symbol.Name();
- auto* input_expr = AddInput(name, param->Type(), param->Location(), std::move(attributes));
+ auto* input_expr =
+ AddInput(name, param->Type(), param->Attributes().location, std::move(attributes));
inner_call_parameters.Push(input_expr);
}
diff --git a/src/tint/lang/wgsl/ast/transform/multiplanar_external_texture.cc b/src/tint/lang/wgsl/ast/transform/multiplanar_external_texture.cc
index c463dbc..0a5f85e 100644
--- a/src/tint/lang/wgsl/ast/transform/multiplanar_external_texture.cc
+++ b/src/tint/lang/wgsl/ast/transform/multiplanar_external_texture.cc
@@ -131,7 +131,7 @@
// The binding points for the newly introduced bindings must have been provided to this
// transform. We fetch the new binding points by providing the original texture_external
// binding points into the passed map.
- BindingPoint bp = *sem_var->BindingPoint();
+ BindingPoint bp = *sem_var->Attributes().binding_point;
BindingsMap::const_iterator it = new_binding_points->bindings_map.find(bp);
if (it == new_binding_points->bindings_map.end()) {
diff --git a/src/tint/lang/wgsl/ast/transform/robustness.cc b/src/tint/lang/wgsl/ast/transform/robustness.cc
index c984b29..0bc1575 100644
--- a/src/tint/lang/wgsl/ast/transform/robustness.cc
+++ b/src/tint/lang/wgsl/ast/transform/robustness.cc
@@ -699,11 +699,11 @@
if (globalVariable == nullptr) {
return false;
}
- if (!globalVariable->BindingPoint().has_value()) {
+ auto binding_point = globalVariable->Attributes().binding_point;
+ if (!binding_point.has_value()) {
return false;
}
- BindingPoint bindingPoint = *globalVariable->BindingPoint();
- return cfg.bindings_ignored.find(bindingPoint) != cfg.bindings_ignored.cend();
+ return cfg.bindings_ignored.find(*binding_point) != cfg.bindings_ignored.cend();
}
/// @returns true if expr is an IndexAccessorExpression whose object is a runtime-sized array.
diff --git a/src/tint/lang/wgsl/ast/transform/single_entry_point.cc b/src/tint/lang/wgsl/ast/transform/single_entry_point.cc
index daae6f8..3311ce4 100644
--- a/src/tint/lang/wgsl/ast/transform/single_entry_point.cc
+++ b/src/tint/lang/wgsl/ast/transform/single_entry_point.cc
@@ -105,7 +105,7 @@
// so that its allocated ID so that it won't be affected by other
// stripped away overrides
auto* global = sem.Get(override);
- const auto* id = b.Id(global->OverrideId());
+ const auto* id = b.Id(global->Attributes().override_id.value());
ctx.InsertFront(override->attributes, id);
}
b.AST().AddGlobalVariable(ctx.Clone(override));
diff --git a/src/tint/lang/wgsl/ast/transform/substitute_override.cc b/src/tint/lang/wgsl/ast/transform/substitute_override.cc
index 75dd9df..a36bc65 100644
--- a/src/tint/lang/wgsl/ast/transform/substitute_override.cc
+++ b/src/tint/lang/wgsl/ast/transform/substitute_override.cc
@@ -87,7 +87,7 @@
Type ty = w->type ? ctx.Clone(w->type) : Type{};
// No replacement provided, just clone the override node as a const.
- auto iter = data->map.find(sem->OverrideId());
+ auto iter = data->map.find(sem->Attributes().override_id.value());
if (iter == data->map.end()) {
if (!w->initializer) {
b.Diagnostics().add_error(
diff --git a/src/tint/lang/wgsl/ast/transform/vertex_pulling.cc b/src/tint/lang/wgsl/ast/transform/vertex_pulling.cc
index 145d053..0ebf6fa 100644
--- a/src/tint/lang/wgsl/ast/transform/vertex_pulling.cc
+++ b/src/tint/lang/wgsl/ast/transform/vertex_pulling.cc
@@ -796,11 +796,11 @@
auto* sem = src.Sem().Get<sem::Parameter>(param);
info.type = sem->Type();
- if (TINT_UNLIKELY(!sem->Location().has_value())) {
+ if (TINT_UNLIKELY(!sem->Attributes().location.has_value())) {
TINT_ICE() << "Location missing value";
return;
}
- location_info[sem->Location().value()] = info;
+ location_info[sem->Attributes().location.value()] = info;
} else {
auto* builtin_attr = GetAttribute<BuiltinAttribute>(param->attributes);
if (TINT_UNLIKELY(!builtin_attr)) {
diff --git a/src/tint/lang/wgsl/helpers/flatten_bindings_test.cc b/src/tint/lang/wgsl/helpers/flatten_bindings_test.cc
index b395664..003ef72 100644
--- a/src/tint/lang/wgsl/helpers/flatten_bindings_test.cc
+++ b/src/tint/lang/wgsl/helpers/flatten_bindings_test.cc
@@ -81,18 +81,18 @@
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[0]);
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(sem->BindingPoint()->group, 0u);
- EXPECT_EQ(sem->BindingPoint()->binding, 0u);
+ EXPECT_EQ(sem->Attributes().binding_point->group, 0u);
+ EXPECT_EQ(sem->Attributes().binding_point->binding, 0u);
sem = flattened->Sem().Get<sem::GlobalVariable>(vars[1]);
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(sem->BindingPoint()->group, 0u);
- EXPECT_EQ(sem->BindingPoint()->binding, 1u);
+ EXPECT_EQ(sem->Attributes().binding_point->group, 0u);
+ EXPECT_EQ(sem->Attributes().binding_point->binding, 1u);
sem = flattened->Sem().Get<sem::GlobalVariable>(vars[2]);
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(sem->BindingPoint()->group, 0u);
- EXPECT_EQ(sem->BindingPoint()->binding, 2u);
+ EXPECT_EQ(sem->Attributes().binding_point->group, 0u);
+ EXPECT_EQ(sem->Attributes().binding_point->binding, 2u);
}
TEST_F(FlattenBindingsTest, NotFlat_MultipleNamespaces) {
@@ -144,20 +144,20 @@
for (size_t i = 0; i < num_buffers; ++i) {
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[i]);
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(sem->BindingPoint()->group, 0u);
- EXPECT_EQ(sem->BindingPoint()->binding, i);
+ EXPECT_EQ(sem->Attributes().binding_point->group, 0u);
+ EXPECT_EQ(sem->Attributes().binding_point->binding, i);
}
for (size_t i = 0; i < num_samplers; ++i) {
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[i + num_buffers]);
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(sem->BindingPoint()->group, 0u);
- EXPECT_EQ(sem->BindingPoint()->binding, i);
+ EXPECT_EQ(sem->Attributes().binding_point->group, 0u);
+ EXPECT_EQ(sem->Attributes().binding_point->binding, i);
}
for (size_t i = 0; i < num_textures; ++i) {
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[i + num_buffers + num_samplers]);
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(sem->BindingPoint()->group, 0u);
- EXPECT_EQ(sem->BindingPoint()->binding, i);
+ EXPECT_EQ(sem->Attributes().binding_point->group, 0u);
+ EXPECT_EQ(sem->Attributes().binding_point->binding, i);
}
}
diff --git a/src/tint/lang/wgsl/inspector/inspector.cc b/src/tint/lang/wgsl/inspector/inspector.cc
index 278773a..7f49f66 100644
--- a/src/tint/lang/wgsl/inspector/inspector.cc
+++ b/src/tint/lang/wgsl/inspector/inspector.cc
@@ -177,7 +177,7 @@
for (auto* param : sem->Parameters()) {
AddEntryPointInOutVariables(param->Declaration()->name->symbol.Name(),
param->Declaration()->name->symbol.Name(), param->Type(),
- param->Declaration()->attributes, param->Location(),
+ param->Declaration()->attributes, param->Attributes().location,
entry_point.input_variables);
entry_point.input_position_used |= ContainsBuiltin(
@@ -212,10 +212,10 @@
auto name = decl->name->symbol.Name();
auto* global = var->As<sem::GlobalVariable>();
- if (global && global->Declaration()->Is<ast::Override>()) {
+ if (auto override_id = global->Attributes().override_id) {
Override override;
override.name = name;
- override.id = global->OverrideId();
+ override.id = override_id.value();
auto* type = var->Type();
TINT_ASSERT(type->Is<core::type::Scalar>());
if (type->is_bool_scalar_or_vector()) {
@@ -279,7 +279,7 @@
// WGSL, so the resolver should catch it. Thus here the inspector just
// assumes all definitions of the override id are the same, so only needs
// to find the first reference to override id.
- OverrideId override_id = global->OverrideId();
+ auto override_id = global->Attributes().override_id.value();
if (result.find(override_id) != result.end()) {
continue;
}
@@ -311,9 +311,9 @@
std::map<std::string, OverrideId> result;
for (auto* var : program_.AST().GlobalVariables()) {
auto* global = program_.Sem().Get<sem::GlobalVariable>(var);
- if (global && global->Declaration()->Is<ast::Override>()) {
+ if (auto override_id = global->Attributes().override_id) {
auto name = var->name->symbol.Name();
- result[name] = global->OverrideId();
+ result[name] = override_id.value();
}
}
return result;
@@ -527,8 +527,9 @@
auto* texture = pair.first->As<sem::GlobalVariable>();
auto* sampler = pair.second ? pair.second->As<sem::GlobalVariable>() : nullptr;
SamplerTexturePair new_pair;
- new_pair.sampler_binding_point = sampler ? *sampler->BindingPoint() : placeholder;
- new_pair.texture_binding_point = *texture->BindingPoint();
+ new_pair.sampler_binding_point =
+ sampler ? *sampler->Attributes().binding_point : placeholder;
+ new_pair.texture_binding_point = *texture->Attributes().binding_point;
new_pairs.push_back(new_pair);
}
return new_pairs;
@@ -818,18 +819,18 @@
auto* t = c->args[static_cast<size_t>(texture_index)];
auto* s = c->args[static_cast<size_t>(sampler_index)];
- GetOriginatingResources(std::array<const ast::Expression*, 2>{t, s},
- [&](std::array<const sem::GlobalVariable*, 2> globals) {
- auto texture_binding_point = *globals[0]->BindingPoint();
- auto sampler_binding_point = *globals[1]->BindingPoint();
+ GetOriginatingResources(
+ std::array<const ast::Expression*, 2>{t, s},
+ [&](std::array<const sem::GlobalVariable*, 2> globals) {
+ auto texture_binding_point = *globals[0]->Attributes().binding_point;
+ auto sampler_binding_point = *globals[1]->Attributes().binding_point;
- for (auto* entry_point : entry_points) {
- const auto& ep_name =
- entry_point->Declaration()->name->symbol.Name();
- (*sampler_targets_)[ep_name].Add(
- {sampler_binding_point, texture_binding_point});
- }
- });
+ for (auto* entry_point : entry_points) {
+ const auto& ep_name = entry_point->Declaration()->name->symbol.Name();
+ (*sampler_targets_)[ep_name].Add(
+ {sampler_binding_point, texture_binding_point});
+ }
+ });
}
}
diff --git a/src/tint/lang/wgsl/inspector/inspector_test.cc b/src/tint/lang/wgsl/inspector/inspector_test.cc
index 052c464..0eb5c8e 100644
--- a/src/tint/lang/wgsl/inspector/inspector_test.cc
+++ b/src/tint/lang/wgsl/inspector/inspector_test.cc
@@ -1879,15 +1879,15 @@
ASSERT_TRUE(result.count("a"));
ASSERT_TRUE(program_->Sem().Get(a));
- EXPECT_EQ(result["a"], program_->Sem().Get(a)->OverrideId());
+ EXPECT_EQ(result["a"], program_->Sem().Get(a)->Attributes().override_id);
ASSERT_TRUE(result.count("b"));
ASSERT_TRUE(program_->Sem().Get(b));
- EXPECT_EQ(result["b"], program_->Sem().Get(b)->OverrideId());
+ EXPECT_EQ(result["b"], program_->Sem().Get(b)->Attributes().override_id);
ASSERT_TRUE(result.count("c"));
ASSERT_TRUE(program_->Sem().Get(c));
- EXPECT_EQ(result["c"], program_->Sem().Get(c)->OverrideId());
+ EXPECT_EQ(result["c"], program_->Sem().Get(c)->Attributes().override_id);
}
TEST_F(InspectorGetResourceBindingsTest, Empty) {
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
index a0c10a8..5e99225 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
@@ -456,12 +456,8 @@
}
});
- if (param_sem->Location().has_value()) {
- param->SetLocation(param_sem->Location().value(), interpolation);
- }
- if (param_sem->BindingPoint().has_value()) {
- param->SetBindingPoint(param_sem->BindingPoint()->group,
- param_sem->BindingPoint()->binding);
+ if (param_sem->Attributes().location.has_value()) {
+ param->SetLocation(param_sem->Attributes().location.value(), interpolation);
}
}
@@ -1324,8 +1320,8 @@
current_block_->Append(val);
if (auto* gv = sem->As<sem::GlobalVariable>(); gv && var->HasBindingPoint()) {
- val->SetBindingPoint(gv->BindingPoint().value().group,
- gv->BindingPoint().value().binding);
+ val->SetBindingPoint(gv->Attributes().binding_point->group,
+ gv->Attributes().binding_point->binding);
}
// Store the declaration so we can get the instruction to store too
diff --git a/src/tint/lang/wgsl/resolver/override_test.cc b/src/tint/lang/wgsl/resolver/override_test.cc
index 6bd7223..3077e79 100644
--- a/src/tint/lang/wgsl/resolver/override_test.cc
+++ b/src/tint/lang/wgsl/resolver/override_test.cc
@@ -46,7 +46,7 @@
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Declaration(), var);
EXPECT_TRUE(sem->Declaration()->Is<ast::Override>());
- EXPECT_EQ(sem->OverrideId().value, id);
+ EXPECT_EQ(sem->Attributes().override_id->value, id);
EXPECT_FALSE(sem->ConstantValue());
}
};
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index c3d2f53..d5a0e93 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -389,7 +389,7 @@
}
auto o = OverrideId{static_cast<decltype(OverrideId::value)>(value)};
- sem->SetOverrideId(o);
+ sem->Attributes().override_id = o;
// Track the constant IDs that are specified in the shader.
override_ids_.Add(o, sem);
@@ -626,7 +626,7 @@
if (!value) {
return kErrored;
}
- global->SetLocation(value.Get());
+ global->Attributes().location = value.Get();
return kSuccess;
},
[&](const ast::IndexAttribute* attr) {
@@ -637,7 +637,7 @@
if (!value) {
return kErrored;
}
- global->SetIndex(value.Get());
+ global->Attributes().index = value.Get();
return kSuccess;
},
[&](const ast::BuiltinAttribute* attr) {
@@ -675,7 +675,7 @@
}
if (group && binding) {
- global->SetBindingPoint(BindingPoint{group.value(), binding.value()});
+ global->Attributes().binding_point = BindingPoint{group.value(), binding.value()};
}
} else {
@@ -720,7 +720,7 @@
if (TINT_UNLIKELY(!value)) {
return false;
}
- sem->SetLocation(value.Get());
+ sem->Attributes().location = value.Get();
return true;
},
[&](const ast::BuiltinAttribute* attr) -> bool { return BuiltinAttribute(attr); },
@@ -766,7 +766,7 @@
}
}
if (group && binding) {
- sem->SetBindingPoint(BindingPoint{group.value(), binding.value()});
+ sem->Attributes().binding_point = BindingPoint{group.value(), binding.value()};
}
} else {
for (auto* attribute : param->attributes) {
@@ -862,8 +862,8 @@
auto* sem = sem_.Get(override);
OverrideId id;
- if (ast::HasAttribute<ast::IdAttribute>(override->attributes)) {
- id = sem->OverrideId();
+ if (auto sem_id = sem->Attributes().override_id) {
+ id = *sem_id;
} else {
// No ID was specified, so allocate the next available ID.
while (!ids_exhausted && override_ids_.Contains(next_id)) {
@@ -879,7 +879,7 @@
increment_next_id();
}
- const_cast<sem::GlobalVariable*>(sem)->SetOverrideId(id);
+ const_cast<sem::GlobalVariable*>(sem)->Attributes().override_id = id;
}
return true;
}
diff --git a/src/tint/lang/wgsl/resolver/resolver_test.cc b/src/tint/lang/wgsl/resolver/resolver_test.cc
index 9b3c171..f78bdc3 100644
--- a/src/tint/lang/wgsl/resolver/resolver_test.cc
+++ b/src/tint/lang/wgsl/resolver/resolver_test.cc
@@ -896,9 +896,9 @@
auto* func_sem = Sem().Get(func);
ASSERT_NE(func_sem, nullptr);
EXPECT_EQ(func_sem->Parameters().Length(), 3u);
- EXPECT_EQ(3u, func_sem->Parameters()[0]->Location());
- EXPECT_FALSE(func_sem->Parameters()[1]->Location().has_value());
- EXPECT_EQ(1u, func_sem->Parameters()[2]->Location());
+ EXPECT_EQ(3u, func_sem->Parameters()[0]->Attributes().location);
+ EXPECT_FALSE(func_sem->Parameters()[1]->Attributes().location.has_value());
+ EXPECT_EQ(1u, func_sem->Parameters()[2]->Attributes().location);
}
TEST_F(ResolverTest, Function_GlobalVariable_Location) {
@@ -910,7 +910,7 @@
auto* sem = Sem().Get<sem::GlobalVariable>(var);
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(3u, sem->Location());
+ EXPECT_EQ(3u, sem->Attributes().location);
}
TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
@@ -1931,8 +1931,10 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
- EXPECT_EQ(Sem().Get<sem::GlobalVariable>(s1)->BindingPoint(), (BindingPoint{1u, 2u}));
- EXPECT_EQ(Sem().Get<sem::GlobalVariable>(s2)->BindingPoint(), (BindingPoint{3u, 4u}));
+ EXPECT_EQ(Sem().Get<sem::GlobalVariable>(s1)->Attributes().binding_point,
+ (BindingPoint{1u, 2u}));
+ EXPECT_EQ(Sem().Get<sem::GlobalVariable>(s2)->Attributes().binding_point,
+ (BindingPoint{3u, 4u}));
}
TEST_F(ResolverTest, Function_EntryPoints_StageAttribute) {
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index 929a508..7c8e2c9 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -767,17 +767,14 @@
return false;
}
- for (auto* attr : decl->attributes) {
- if (attr->Is<ast::IdAttribute>()) {
- auto id = v->OverrideId();
- if (auto var = override_ids.Find(id); var && *var != v) {
- AddError("@id values must be unique", attr->source);
- AddNote(
- "a override with an ID of " + std::to_string(id.value) +
+ if (auto id = v->Attributes().override_id) {
+ if (auto var = override_ids.Find(*id); var && *var != v) {
+ auto* attr = ast::GetAttribute<ast::IdAttribute>(v->Declaration()->attributes);
+ AddError("@id values must be unique", attr->source);
+ AddNote("a override with an ID of " + std::to_string(id->value) +
" was previously declared here:",
ast::GetAttribute<ast::IdAttribute>((*var)->Declaration()->attributes)->source);
- return false;
- }
+ return false;
}
}
@@ -1335,7 +1332,8 @@
auto* param_decl = param->Declaration();
if (!validate_entry_point_attributes(param_decl->attributes, param->Type(),
param_decl->source, ParamOrRetType::kParameter,
- param->Location(), std::nullopt)) {
+ param->Attributes().location,
+ param->Attributes().index)) {
return false;
}
}
@@ -1389,7 +1387,7 @@
if (!var_decl) {
continue;
}
- auto bp = global->BindingPoint();
+ auto bp = global->Attributes().binding_point;
if (!bp) {
continue;
}
diff --git a/src/tint/lang/wgsl/sem/function.cc b/src/tint/lang/wgsl/sem/function.cc
index 4d1d3c9..9a56376 100644
--- a/src/tint/lang/wgsl/sem/function.cc
+++ b/src/tint/lang/wgsl/sem/function.cc
@@ -81,7 +81,7 @@
continue;
}
- if (auto bp = global->BindingPoint()) {
+ if (auto bp = global->Attributes().binding_point) {
ret.push_back({global, *bp});
}
}
@@ -96,7 +96,7 @@
continue;
}
- if (auto bp = global->BindingPoint()) {
+ if (auto bp = global->Attributes().binding_point) {
ret.push_back({global, *bp});
}
}
@@ -140,7 +140,7 @@
for (auto* global : TransitivelyReferencedGlobals()) {
auto* unwrapped_type = global->Type()->UnwrapRef();
if (unwrapped_type->TypeInfo().Is(type)) {
- if (auto bp = global->BindingPoint()) {
+ if (auto bp = global->Attributes().binding_point) {
ret.push_back({global, *bp});
}
}
@@ -168,7 +168,7 @@
continue;
}
- if (auto bp = global->BindingPoint()) {
+ if (auto bp = global->Attributes().binding_point) {
ret.push_back({global, *bp});
}
}
@@ -193,7 +193,7 @@
continue;
}
- if (auto bp = global->BindingPoint()) {
+ if (auto bp = global->Attributes().binding_point) {
ret.push_back({global, *bp});
}
}
diff --git a/src/tint/lang/wgsl/sem/variable.h b/src/tint/lang/wgsl/sem/variable.h
index bca5d1b..3ee24f3 100644
--- a/src/tint/lang/wgsl/sem/variable.h
+++ b/src/tint/lang/wgsl/sem/variable.h
@@ -151,6 +151,22 @@
const CastableBase* shadows_ = nullptr;
};
+/// Attributes that can be applied to global variables
+struct GlobalVariableAttributes {
+ /// the pipeline constant ID associated with the variable
+ std::optional<tint::OverrideId> override_id;
+ /// the resource binding point for the variable, if set.
+ std::optional<tint::BindingPoint> binding_point;
+ /// The `location` attribute value for the variable, if set
+ /// @note a GlobalVariable generally doesn't have a `location` in WGSL, as it isn't allowed by
+ /// the spec. The location maybe attached by transforms such as CanonicalizeEntryPointIO.
+ std::optional<uint32_t> location;
+ /// The `index` attribute value for the variable, if set
+ /// @note a GlobalVariable generally doesn't have a `index` in WGSL, as it isn't allowed by
+ /// the spec. The location maybe attached by transforms such as CanonicalizeEntryPointIO.
+ std::optional<uint32_t> index;
+};
+
/// GlobalVariable is a module-scope variable
class GlobalVariable final : public Castable<GlobalVariable, Variable> {
public:
@@ -161,34 +177,6 @@
/// Destructor
~GlobalVariable() override;
- /// @param binding_point the resource binding point for the parameter
- void SetBindingPoint(std::optional<tint::BindingPoint> binding_point) {
- binding_point_ = binding_point;
- }
-
- /// @returns the resource binding point for the variable
- std::optional<tint::BindingPoint> BindingPoint() const { return binding_point_; }
-
- /// @param id the constant identifier to assign to this variable
- void SetOverrideId(OverrideId id) { override_id_ = id; }
-
- /// @returns the pipeline constant ID associated with the variable
- tint::OverrideId OverrideId() const { return override_id_; }
-
- /// @param location the location value for the parameter, if set
- /// @note a GlobalVariable generally doesn't have a `location` in WGSL, as it isn't allowed by
- /// the spec. The location maybe attached by transforms such as CanonicalizeEntryPointIO.
- void SetLocation(std::optional<uint32_t> location) { location_ = location; }
-
- /// @returns the location value for the parameter, if set
- std::optional<uint32_t> Location() const { return location_; }
-
- /// @param index the index value for the parameter, if set
- void SetIndex(std::optional<uint32_t> index) { index_ = index; }
-
- /// @returns the index value for the parameter, if set
- std::optional<uint32_t> Index() const { return index_; }
-
/// Records that this variable (transitively) references the given override variable.
/// @param var the module-scope override variable
void AddTransitivelyReferencedOverride(const GlobalVariable* var);
@@ -198,12 +186,30 @@
return transitively_referenced_overrides_;
}
+ /// @return the mutable attributes for the variable
+ GlobalVariableAttributes& Attributes() { return attributes_; }
+
+ /// @return the immutable attributes for the variable
+ const GlobalVariableAttributes& Attributes() const { return attributes_; }
+
private:
std::optional<tint::BindingPoint> binding_point_;
tint::OverrideId override_id_;
- std::optional<uint32_t> location_;
- std::optional<uint32_t> index_;
UniqueVector<const GlobalVariable*, 4> transitively_referenced_overrides_;
+ GlobalVariableAttributes attributes_;
+};
+
+/// Attributes that can be applied to parameters
+struct ParameterAttributes {
+ /// the resource binding point for the variable, if set.
+ /// @note a Parameter generally doesn't have a `group` or `binding` attribute in WGSL, as it
+ /// isn't allowed by the spec. The binding point maybe attached by transforms such as
+ /// CanonicalizeEntryPointIO.
+ std::optional<tint::BindingPoint> binding_point;
+ /// The `location` attribute value for the variable, if set
+ std::optional<uint32_t> location;
+ /// The `index` attribute value for the variable, if set
+ std::optional<uint32_t> index;
};
/// Parameter is a function parameter
@@ -227,9 +233,6 @@
return static_cast<const ast::Parameter*>(Variable::Declaration());
}
- /// @param index the index value for the parameter, if set
- void SetIndex(uint32_t index) { index_ = index; }
-
/// @return the index of the parameter in the function
uint32_t Index() const { return index_; }
@@ -252,27 +255,18 @@
/// @returns the Type, Function or Variable that this local variable shadows
const CastableBase* Shadows() const { return shadows_; }
- /// @param binding_point the resource binding point for the parameter
- void SetBindingPoint(std::optional<tint::BindingPoint> binding_point) {
- binding_point_ = binding_point;
- }
+ /// @return the mutable attributes for the parameter
+ ParameterAttributes& Attributes() { return attributes_; }
- /// @returns the resource binding point for the parameter
- std::optional<tint::BindingPoint> BindingPoint() const { return binding_point_; }
-
- /// @param location the location value for the parameter, if set
- void SetLocation(std::optional<uint32_t> location) { location_ = location; }
-
- /// @returns the location value for the parameter, if set
- std::optional<uint32_t> Location() const { return location_; }
+ /// @return the immutable attributes for the parameter
+ const ParameterAttributes& Attributes() const { return attributes_; }
private:
- uint32_t index_ = 0;
+ const uint32_t index_ = 0;
core::ParameterUsage usage_ = core::ParameterUsage::kNone;
CallTarget const* owner_ = nullptr;
const CastableBase* shadows_ = nullptr;
- std::optional<tint::BindingPoint> binding_point_;
- std::optional<uint32_t> location_;
+ ParameterAttributes attributes_;
};
/// VariableUser holds the semantic information for an identifier expression