tint: Unkeyword 'var' template args
Change the address space and access mode in ast::Var from enums
to Expressions. Have the resolver resolve these, like we do for
other template arguments.
As the AST nodes now have identifier expressions, the tint-internal
'in' and 'out' address spaces have been prefixed with underscores to
prevent input code from using this.
Change-Id: Ie8abf371ee6a7031613709b83b575d2723418fcf
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/120405
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index dd679c7..fbed83a 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -1646,7 +1646,6 @@
"reader/wgsl/classify_template_args_test.cc",
"reader/wgsl/lexer_test.cc",
"reader/wgsl/parser_impl_additive_expression_test.cc",
- "reader/wgsl/parser_impl_address_space_test.cc",
"reader/wgsl/parser_impl_argument_expression_list_test.cc",
"reader/wgsl/parser_impl_assignment_stmt_test.cc",
"reader/wgsl/parser_impl_bitwise_expression_test.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 67ca5e9..4b87d7b 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -1092,7 +1092,6 @@
reader/wgsl/parser_impl_singular_expression_test.cc
reader/wgsl/parser_impl_statement_test.cc
reader/wgsl/parser_impl_statements_test.cc
- reader/wgsl/parser_impl_address_space_test.cc
reader/wgsl/parser_impl_struct_body_decl_test.cc
reader/wgsl/parser_impl_struct_decl_test.cc
reader/wgsl/parser_impl_struct_attribute_decl_test.cc
diff --git a/src/tint/ast/var.cc b/src/tint/ast/var.cc
index b748381..bccdbcc 100644
--- a/src/tint/ast/var.cc
+++ b/src/tint/ast/var.cc
@@ -25,8 +25,8 @@
const Source& src,
const Identifier* n,
Type ty,
- type::AddressSpace address_space,
- type::Access access,
+ const Expression* address_space,
+ const Expression* access,
const Expression* init,
utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src, n, ty, init, std::move(attrs)),
@@ -45,10 +45,11 @@
auto src = ctx->Clone(source);
auto* n = ctx->Clone(name);
auto ty = ctx->Clone(type);
+ auto* address_space = ctx->Clone(declared_address_space);
+ auto* access = ctx->Clone(declared_access);
auto* init = ctx->Clone(initializer);
auto attrs = ctx->Clone(attributes);
- return ctx->dst->create<Var>(src, n, ty, declared_address_space, declared_access, init,
- std::move(attrs));
+ return ctx->dst->create<Var>(src, n, ty, address_space, access, init, std::move(attrs));
}
} // namespace tint::ast
diff --git a/src/tint/ast/var.h b/src/tint/ast/var.h
index e3537d1..006d8de 100644
--- a/src/tint/ast/var.h
+++ b/src/tint/ast/var.h
@@ -56,8 +56,8 @@
const Source& source,
const Identifier* name,
Type type,
- type::AddressSpace declared_address_space,
- type::Access declared_access,
+ const Expression* declared_address_space,
+ const Expression* declared_access,
const Expression* initializer,
utils::VectorRef<const Attribute*> attributes);
@@ -77,10 +77,10 @@
const Var* Clone(CloneContext* ctx) const override;
/// The declared address space
- const type::AddressSpace declared_address_space;
+ const Expression* const declared_address_space = nullptr;
/// The declared access control
- const type::Access declared_access;
+ const Expression* const declared_access = nullptr;
};
/// A list of `var` declarations
diff --git a/src/tint/ast/variable_test.cc b/src/tint/ast/variable_test.cc
index 88bcdc4..dcbf1e5 100644
--- a/src/tint/ast/variable_test.cc
+++ b/src/tint/ast/variable_test.cc
@@ -28,7 +28,8 @@
auto* v = Var("my_var", ty.i32(), type::AddressSpace::kFunction);
CheckIdentifier(Symbols(), v->name, "my_var");
- EXPECT_EQ(v->declared_address_space, type::AddressSpace::kFunction);
+ CheckIdentifier(Symbols(), v->declared_address_space, "function");
+ EXPECT_EQ(v->declared_access, nullptr);
CheckIdentifier(Symbols(), v->type, "i32");
EXPECT_EQ(v->source.range.begin.line, 0u);
EXPECT_EQ(v->source.range.begin.column, 0u);
@@ -41,7 +42,7 @@
ty.f32(), type::AddressSpace::kPrivate, utils::Empty);
CheckIdentifier(Symbols(), v->name, "i");
- EXPECT_EQ(v->declared_address_space, type::AddressSpace::kPrivate);
+ CheckIdentifier(Symbols(), v->declared_address_space, "private");
CheckIdentifier(Symbols(), v->type, "f32");
EXPECT_EQ(v->source.range.begin.line, 27u);
EXPECT_EQ(v->source.range.begin.column, 4u);
@@ -54,7 +55,7 @@
ty.i32(), type::AddressSpace::kWorkgroup, utils::Empty);
CheckIdentifier(Symbols(), v->name, "a_var");
- EXPECT_EQ(v->declared_address_space, type::AddressSpace::kWorkgroup);
+ CheckIdentifier(Symbols(), v->declared_address_space, "workgroup");
CheckIdentifier(Symbols(), v->type, "i32");
EXPECT_EQ(v->source.range.begin.line, 27u);
EXPECT_EQ(v->source.range.begin.column, 4u);
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index ee28010..f55b12c 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -80,9 +80,9 @@
uniform
storage
push_constant
+ __in
+ __out
@internal handle
- @internal in
- @internal out
}
// https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index 1c04faf..f89a30b 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -219,24 +219,34 @@
/// constructing an ast::Var.
struct VarOptions {
template <typename... ARGS>
- explicit VarOptions(ARGS&&... args) {
- (Set(std::forward<ARGS>(args)), ...);
+ explicit VarOptions(ProgramBuilder& b, ARGS&&... args) {
+ (Set(b, std::forward<ARGS>(args)), ...);
}
~VarOptions();
ast::Type type;
- type::AddressSpace address_space = type::AddressSpace::kUndefined;
- type::Access access = type::Access::kUndefined;
+ const ast::Expression* address_space = nullptr;
+ const ast::Expression* access = nullptr;
const ast::Expression* initializer = nullptr;
utils::Vector<const ast::Attribute*, 4> attributes;
private:
- void Set(ast::Type t) { type = t; }
- void Set(type::AddressSpace addr_space) { address_space = addr_space; }
- void Set(type::Access ac) { access = ac; }
- void Set(const ast::Expression* c) { initializer = c; }
- void Set(utils::VectorRef<const ast::Attribute*> l) { attributes = std::move(l); }
- void Set(const ast::Attribute* a) { attributes.Push(a); }
+ void Set(ProgramBuilder&, ast::Type t) { type = t; }
+ void Set(ProgramBuilder& b, type::AddressSpace addr_space) {
+ if (addr_space != type::AddressSpace::kUndefined) {
+ address_space = b.Expr(addr_space);
+ }
+ }
+ void Set(ProgramBuilder& b, type::Access ac) {
+ if (ac != type::Access::kUndefined) {
+ access = b.Expr(ac);
+ }
+ }
+ void Set(ProgramBuilder&, const ast::Expression* c) { initializer = c; }
+ void Set(ProgramBuilder&, utils::VectorRef<const ast::Attribute*> l) {
+ attributes = std::move(l);
+ }
+ void Set(ProgramBuilder&, const ast::Attribute* a) { attributes.Push(a); }
};
/// LetOptions is a helper for accepting an arbitrary number of order independent options for
@@ -2055,9 +2065,9 @@
/// @param name the variable name
/// @param options the extra options passed to the ast::Var initializer
/// Can be any of the following, in any order:
- /// * ast::Type* - specifies the variable type
- /// * type::AddressSpace - specifies the variable address space
- /// * type::Access - specifies the variable's access control
+ /// * ast::Type - specifies the variable's type
+ /// * type::AddressSpace - specifies the variable's address space
+ /// * type::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
@@ -2072,16 +2082,16 @@
/// @param name the variable name
/// @param options the extra options passed to the ast::Var initializer
/// Can be any of the following, in any order:
- /// * ast::Type* - specifies the variable type
- /// * type::AddressSpace - specifies the variable address space
- /// * type::Access - specifies the variable's access control
+ /// * ast::Type - specifies the variable's type
+ /// * type::AddressSpace - specifies the variable's address space
+ /// * type::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
/// @returns a `ast::Var` with the given name, address_space and type
template <typename NAME, typename... OPTIONS>
const ast::Var* Var(const Source& source, NAME&& name, OPTIONS&&... options) {
- VarOptions opts(std::forward<OPTIONS>(options)...);
+ VarOptions opts(*this, std::forward<OPTIONS>(options)...);
return create<ast::Var>(source, Ident(std::forward<NAME>(name)), opts.type,
opts.address_space, opts.access, opts.initializer,
std::move(opts.attributes));
@@ -2091,8 +2101,7 @@
/// @param options the extra options passed to the ast::Var initializer
/// Can be any of the following, in any order:
/// * ast::Expression* - specifies the variable's initializer expression (required)
- /// * ast::Identifier* - specifies the variable type
- /// * ast::Type* - specifies the variable type
+ /// * ast::Type - specifies the variable's type
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
/// @returns an `ast::Const` with the given name, type and additional options
@@ -2106,8 +2115,8 @@
/// @param options the extra options passed to the ast::Var initializer
/// Can be any of the following, in any order:
/// * ast::Expression* - specifies the variable's initializer expression (required)
- /// * ast::Identifier* - specifies the variable type
- /// * ast::Type* - specifies the variable type
+ /// * ast::Identifier* - specifies the variable's type
+ /// * ast::Type - specifies the variable's type
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
/// @returns an `ast::Const` with the given name, type and additional options
@@ -2122,7 +2131,7 @@
/// @param options the extra options passed to the ast::Var initializer
/// Can be any of the following, in any order:
/// * ast::Expression* - specifies the variable's initializer expression (required)
- /// * ast::Type* - specifies the variable type
+ /// * ast::Type - specifies the variable's type
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
/// @returns an `ast::Let` with the given name, type and additional options
@@ -2136,7 +2145,7 @@
/// @param options the extra options passed to the ast::Var initializer
/// Can be any of the following, in any order:
/// * ast::Expression* - specifies the variable's initializer expression (required)
- /// * ast::Type* - specifies the variable type
+ /// * ast::Type - specifies the variable's type
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
/// @returns an `ast::Let` with the given name, type and additional options
@@ -2175,7 +2184,7 @@
/// @param name the variable name
/// @param options the extra options passed to the ast::Var initializer
/// Can be any of the following, in any order:
- /// * ast::Type* - specifies the variable type
+ /// * ast::Type - specifies the variable's type
/// * type::AddressSpace - specifies the variable address space
/// * type::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression
@@ -2192,7 +2201,7 @@
/// @param name the variable name
/// @param options the extra options passed to the ast::Var initializer
/// Can be any of the following, in any order:
- /// * ast::Type* - specifies the variable type
+ /// * ast::Type - specifies the variable's type
/// * type::AddressSpace - specifies the variable address space
/// * type::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression
@@ -2211,7 +2220,7 @@
/// @param options the extra options passed to the ast::Const initializer
/// Can be any of the following, in any order:
/// * ast::Expression* - specifies the variable's initializer expression (required)
- /// * ast::Type* - specifies the variable type
+ /// * ast::Type - specifies the variable's type
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
/// @returns an `ast::Const` with the given name, type and additional options, which is
@@ -2226,7 +2235,7 @@
/// @param options the extra options passed to the ast::Const initializer
/// Can be any of the following, in any order:
/// * ast::Expression* - specifies the variable's initializer expression (required)
- /// * ast::Type* - specifies the variable type
+ /// * ast::Type - specifies the variable's type
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
/// @returns an `ast::Const` with the given name, type and additional options, which is
@@ -2242,7 +2251,7 @@
/// @param options the extra options passed to the ast::Override initializer
/// Can be any of the following, in any order:
/// * ast::Expression* - specifies the variable's initializer expression (required)
- /// * ast::Type* - specifies the variable type
+ /// * ast::Type - specifies the variable's type
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
/// @returns an `ast::Override` with the given name, type and additional options, which is
@@ -2257,7 +2266,7 @@
/// @param options the extra options passed to the ast::Override initializer
/// Can be any of the following, in any order:
/// * ast::Expression* - specifies the variable's initializer expression (required)
- /// * ast::Type* - specifies the variable type
+ /// * ast::Type - specifies the variable's type
/// * ast::Attribute* - specifies the variable's attributes (repeatable, or vector)
/// Note that non-repeatable arguments of the same type will use the last argument's value.
/// @returns an `ast::Override` with the given name, type and additional options, which is
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index 046780f..513b7f3 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -2522,7 +2522,8 @@
}
}
auto* var = parser_impl_.MakeVar(inst.result_id(), type::AddressSpace::kUndefined,
- var_store_type, initializer, AttributeList{});
+ type::Access::kUndefined, var_store_type, initializer,
+ AttributeList{});
auto* var_decl_stmt = create<ast::VariableDeclStatement>(Source{}, var);
AddStatement(var_decl_stmt);
auto* var_type = ty_.Reference(var_store_type, type::AddressSpace::kUndefined);
@@ -3367,8 +3368,9 @@
// no need to remap pointer properties.
auto* store_type = parser_impl_.ConvertType(def_inst->type_id());
AddStatement(create<ast::VariableDeclStatement>(
- Source{}, parser_impl_.MakeVar(id, type::AddressSpace::kUndefined, store_type, nullptr,
- AttributeList{})));
+ Source{},
+ parser_impl_.MakeVar(id, type::AddressSpace::kUndefined, type::Access::kUndefined,
+ store_type, nullptr, AttributeList{})));
auto* type = ty_.Reference(store_type, type::AddressSpace::kUndefined);
identifier_types_.emplace(id, type);
}
@@ -4835,9 +4837,8 @@
// either variables or function parameters.
switch (opcode(inst)) {
case spv::Op::OpVariable: {
- if (const auto* module_var = parser_impl_.GetModuleVariable(id)) {
- return DefInfo::Pointer{module_var->declared_address_space,
- module_var->declared_access};
+ if (auto v = parser_impl_.GetModuleVariable(id); v.var) {
+ return DefInfo::Pointer{v.address_space, v.access};
}
// Local variables are always Function storage class, with default
// access mode.
diff --git a/src/tint/reader/spirv/parser_impl.cc b/src/tint/reader/spirv/parser_impl.cc
index 5707bf1..443b28f 100644
--- a/src/tint/reader/spirv/parser_impl.cc
+++ b/src/tint/reader/spirv/parser_impl.cc
@@ -1504,12 +1504,15 @@
// here.)
ast_initializer = MakeConstantExpression(var.GetSingleWordInOperand(1)).expr;
}
- auto* ast_var = MakeVar(var.result_id(), ast_address_space, ast_store_type, ast_initializer,
- utils::Empty);
+ auto ast_access = VarAccess(ast_store_type, ast_address_space);
+ auto* ast_var = MakeVar(var.result_id(), ast_address_space, ast_access, ast_store_type,
+ ast_initializer, utils::Empty);
// TODO(dneto): initializers (a.k.a. initializer expression)
if (ast_var) {
builder_.AST().AddGlobalVariable(ast_var);
- module_variable_.GetOrCreate(var.result_id(), [ast_var] { return ast_var; });
+ module_variable_.GetOrCreate(var.result_id(), [&] {
+ return ModuleVariable{ast_var, ast_address_space, ast_access};
+ });
}
}
@@ -1536,14 +1539,16 @@
<< init->PrettyPrint();
}
}
- auto* ast_var =
- MakeVar(builtin_position_.per_vertex_var_id,
- enum_converter_.ToAddressSpace(builtin_position_.storage_class),
- ConvertType(builtin_position_.position_member_type_id), ast_initializer, {});
+ auto storage_type = ConvertType(builtin_position_.position_member_type_id);
+ auto ast_address_space = enum_converter_.ToAddressSpace(builtin_position_.storage_class);
+ auto ast_access = VarAccess(storage_type, ast_address_space);
+ auto* ast_var = MakeVar(builtin_position_.per_vertex_var_id, ast_address_space, ast_access,
+ storage_type, ast_initializer, {});
builder_.AST().AddGlobalVariable(ast_var);
- module_variable_.GetOrCreate(builtin_position_.per_vertex_var_id,
- [ast_var] { return ast_var; });
+ module_variable_.GetOrCreate(builtin_position_.per_vertex_var_id, [&] {
+ return ModuleVariable{ast_var, ast_address_space};
+ });
}
return success_;
}
@@ -1571,8 +1576,23 @@
return size->AsIntConstant();
}
+type::Access ParserImpl::VarAccess(const Type* storage_type, type::AddressSpace address_space) {
+ if (address_space != type::AddressSpace::kStorage) {
+ return type::Access::kUndefined;
+ }
+
+ bool read_only = false;
+ if (auto* tn = storage_type->As<Named>()) {
+ read_only = read_only_struct_types_.count(tn->name) > 0;
+ }
+
+ // Apply the access(read) or access(read_write) modifier.
+ return read_only ? type::Access::kRead : type::Access::kReadWrite;
+}
+
const ast::Var* ParserImpl::MakeVar(uint32_t id,
type::AddressSpace address_space,
+ type::Access access,
const Type* storage_type,
const ast::Expression* initializer,
AttributeList decorations) {
@@ -1581,17 +1601,6 @@
return nullptr;
}
- type::Access access = type::Access::kUndefined;
- if (address_space == type::AddressSpace::kStorage) {
- bool read_only = false;
- if (auto* tn = storage_type->As<Named>()) {
- read_only = read_only_struct_types_.count(tn->name) > 0;
- }
-
- // Apply the access(read) or access(read_write) modifier.
- access = read_only ? type::Access::kRead : type::Access::kReadWrite;
- }
-
// Handle variables (textures and samplers) are always in the handle
// address space, so we don't mention the address space.
if (address_space == type::AddressSpace::kHandle) {
diff --git a/src/tint/reader/spirv/parser_impl.h b/src/tint/reader/spirv/parser_impl.h
index 5d6daa4..0c77a02 100644
--- a/src/tint/reader/spirv/parser_impl.h
+++ b/src/tint/reader/spirv/parser_impl.h
@@ -420,10 +420,17 @@
/// @returns a list of SPIR-V decorations.
DecorationList GetMemberPipelineDecorations(const Struct& struct_type, int member_index);
+ /// @param storage_type the 'var' storage type
+ /// @param address_space the 'var' address space
+ /// @returns the access mode for a 'var' declaration with the given storage type and address
+ /// space.
+ type::Access VarAccess(const Type* storage_type, type::AddressSpace address_space);
+
/// Creates an AST 'var' node for a SPIR-V ID, including any attached decorations, unless it's
/// an ignorable builtin variable.
/// @param id the SPIR-V result ID
/// @param address_space the address space, which cannot be type::AddressSpace::kUndefined
+ /// @param access the access
/// @param storage_type the storage type of the variable
/// @param initializer the variable initializer
/// @param decorations the variable decorations
@@ -431,6 +438,7 @@
/// in the error case
const ast::Var* MakeVar(uint32_t id,
type::AddressSpace address_space,
+ type::Access access,
const Type* storage_type,
const ast::Expression* initializer,
AttributeList decorations);
@@ -659,13 +667,23 @@
/// error
const Type* GetHandleTypeForSpirvHandle(const spvtools::opt::Instruction& obj);
+ /// ModuleVariable describes a module scope variable
+ struct ModuleVariable {
+ /// The AST variable node.
+ const ast::Var* var = nullptr;
+ /// The address space of the var
+ type::AddressSpace address_space = type::AddressSpace::kUndefined;
+ /// The access mode of the var
+ type::Access access = type::Access::kUndefined;
+ };
+
/// Returns the AST variable for the SPIR-V ID of a module-scope variable,
/// or null if there isn't one.
/// @param id a SPIR-V ID
/// @returns the AST variable or null.
- const ast::Var* GetModuleVariable(uint32_t id) {
+ ModuleVariable GetModuleVariable(uint32_t id) {
auto entry = module_variable_.Find(id);
- return entry ? *entry : nullptr;
+ return entry ? *entry : ModuleVariable{};
}
/// Returns the channel component type corresponding to the given image
@@ -885,7 +903,7 @@
std::unordered_map<const spvtools::opt::Instruction*, const Type*> handle_type_;
/// Maps the SPIR-V ID of a module-scope variable to its AST variable.
- utils::Hashmap<uint32_t, const ast::Var*, 16> module_variable_;
+ utils::Hashmap<uint32_t, ModuleVariable, 16> module_variable_;
// Set of symbols of declared type that have been added, used to avoid
// adding duplicates.
diff --git a/src/tint/reader/wgsl/classify_template_args.cc b/src/tint/reader/wgsl/classify_template_args.cc
index 0ccef95..79d39d2 100644
--- a/src/tint/reader/wgsl/classify_template_args.cc
+++ b/src/tint/reader/wgsl/classify_template_args.cc
@@ -70,8 +70,8 @@
for (size_t i = 0; i < count - 1; i++) {
switch (tokens[i].type()) {
- // <identifier> + all type / builtin keywords that will become identifiers.
case Token::Type::kIdentifier:
+ case Token::Type::kVar:
case Token::Type::kBitcast: {
auto& next = tokens[i + 1];
if (next.type() == Token::Type::kLessThan) {
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index c503353..c9a8576 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -204,23 +204,6 @@
ParserImpl::FunctionHeader& ParserImpl::FunctionHeader::operator=(const FunctionHeader& rhs) =
default;
-ParserImpl::VarDeclInfo::VarDeclInfo() = default;
-
-ParserImpl::VarDeclInfo::VarDeclInfo(const VarDeclInfo&) = default;
-
-ParserImpl::VarDeclInfo::VarDeclInfo(Source source_in,
- std::string name_in,
- type::AddressSpace address_space_in,
- type::Access access_in,
- ast::Type type_in)
- : source(std::move(source_in)),
- name(std::move(name_in)),
- address_space(address_space_in),
- access(access_in),
- type(type_in) {}
-
-ParserImpl::VarDeclInfo::~VarDeclInfo() = default;
-
ParserImpl::ParserImpl(Source::File const* file) : file_(file) {}
ParserImpl::~ParserImpl() = default;
@@ -614,13 +597,13 @@
TINT_DEFER(attrs.Clear());
- return builder_.Var(decl->source, // source
- decl->name, // symbol
- decl->type, // type
- decl->address_space, // address space
- decl->access, // access control
- initializer, // initializer
- std::move(attrs)); // attributes
+ return builder_.create<ast::Var>(decl->source, // source
+ builder_.Ident(decl->name), // symbol
+ decl->type, // type
+ decl->address_space, // address space
+ decl->access, // access control
+ initializer, // initializer
+ std::move(attrs)); // attributes
}
// global_constant_decl :
@@ -756,37 +739,28 @@
return expect_ident_with_optional_type_specifier(use, /* allow_inferred */ false);
}
-// access_mode
-// : 'read'
-// | 'write'
-// | 'read_write'
-Expect<type::Access> ParserImpl::expect_access_mode(std::string_view use) {
- return expect_enum("access control", type::ParseAccess, type::kAccessStrings, use);
-}
-
// variable_qualifier
-// : LESS_THAN address_spaces (COMMA access_mode)? GREATER_THAN
+// : _template_args_start expression (COMMA expression)? _template_args_end
Maybe<ParserImpl::VariableQualifier> ParserImpl::variable_qualifier() {
- if (!peek_is(Token::Type::kLessThan)) {
+ if (!peek_is(Token::Type::kTemplateArgsLeft) && !peek_is(Token::Type::kLessThan)) {
+ // Note: kLessThan will give a sensible error at expect_template_arg_block()
return Failure::kNoMatch;
}
auto* use = "variable declaration";
- auto vq = expect_lt_gt_block(use, [&]() -> Expect<VariableQualifier> {
- auto source = make_source_range();
- auto sc = expect_address_space(use);
- if (sc.errored) {
+ auto vq = expect_template_arg_block(use, [&]() -> Expect<VariableQualifier> {
+ auto address_space = expect_expression("'var' address space");
+ if (address_space.errored) {
return Failure::kErrored;
}
if (match(Token::Type::kComma)) {
- auto ac = expect_access_mode(use);
- if (ac.errored) {
+ auto access = expect_expression("'var' access mode");
+ if (access.errored) {
return Failure::kErrored;
}
- return VariableQualifier{sc.value, ac.value};
+ return VariableQualifier{address_space.value, access.value};
}
- return Expect<VariableQualifier>{VariableQualifier{sc.value, type::Access::kUndefined},
- source};
+ return VariableQualifier{address_space.value};
});
if (vq.errored) {
@@ -900,18 +874,6 @@
return type.value;
}
-// address_space
-// : 'function'
-// | 'private'
-// | 'workgroup'
-// | 'uniform'
-// | 'storage'
-//
-// Note, we also parse `push_constant` from the experimental extension
-Expect<type::AddressSpace> ParserImpl::expect_address_space(std::string_view use) {
- return expect_enum("address space", type::ParseAddressSpace, type::kAddressSpaceStrings, use);
-}
-
// struct_decl
// : STRUCT IDENT struct_body_decl
Maybe<const ast::Struct*> ParserImpl::struct_decl() {
@@ -1519,12 +1481,13 @@
initializer = initializer_expr.value;
}
- auto* var = builder_.Var(decl_source, // source
- decl->name, // symbol
- decl->type, // type
- decl->address_space, // address space
- decl->access, // access control
- initializer); // initializer
+ auto* var = builder_.create<ast::Var>(decl_source, // source
+ builder_.Ident(decl->name), // symbol
+ decl->type, // type
+ decl->address_space, // address space
+ decl->access, // access control
+ initializer, // initializer
+ utils::Empty); // attributes
return create<ast::VariableDeclStatement>(var->source, var);
}
@@ -2520,7 +2483,7 @@
return create<ast::BinaryExpression>(tok_op.source(), op, lhs, rhs.value);
}
-Expect<const ast::Expression*> ParserImpl::expect_expression() {
+Expect<const ast::Expression*> ParserImpl::expect_expression(std::string_view use) {
auto& t = peek();
auto expr = expression();
if (expr.errored) {
@@ -2529,7 +2492,7 @@
if (expr.matched) {
return expr.value;
}
- return add_error(t, "expected expression");
+ return add_error(t, "expected expression for " + std::string(use));
}
Expect<utils::Vector<const ast::Expression*, 3>> ParserImpl::expect_expression_list(
@@ -2537,7 +2500,7 @@
Token::Type terminator) {
utils::Vector<const ast::Expression*, 3> exprs;
while (continue_parsing()) {
- auto expr = expect_expression();
+ auto expr = expect_expression(use);
if (expr.errored) {
return Failure::kErrored;
}
diff --git a/src/tint/reader/wgsl/parser_impl.h b/src/tint/reader/wgsl/parser_impl.h
index f692d77..64618b3 100644
--- a/src/tint/reader/wgsl/parser_impl.h
+++ b/src/tint/reader/wgsl/parser_impl.h
@@ -148,10 +148,9 @@
/// Constructor for a successful parse.
/// @param val the result value of the parse
- /// @param s the optional source of the value
template <typename U>
- inline Maybe(U&& val, const Source& s = {}) // NOLINT
- : value(std::forward<U>(val)), source(s), matched(true) {}
+ inline Maybe(U&& val) // NOLINT
+ : value(std::forward<U>(val)), matched(true) {}
/// Constructor for parse error state.
inline Maybe(Failure::Errored) : errored(true) {} // NOLINT
@@ -163,16 +162,13 @@
/// @param e the Expect to copy this Maybe from
template <typename U>
inline Maybe(const Expect<U>& e) // NOLINT
- : value(e.value), source(e.value), errored(e.errored), matched(!e.errored) {}
+ : value(e.value), errored(e.errored), matched(!e.errored) {}
/// Move from an Expect.
/// @param e the Expect to move this Maybe from
template <typename U>
inline Maybe(Expect<U>&& e) // NOLINT
- : value(std::move(e.value)),
- source(std::move(e.source)),
- errored(e.errored),
- matched(!e.errored) {}
+ : value(std::move(e.value)), errored(e.errored), matched(!e.errored) {}
/// Copy constructor
inline Maybe(const Maybe&) = default;
@@ -197,8 +193,6 @@
/// The value of a successful parse.
/// Zero-initialized when there was a parse error.
T value{};
- /// Optional source of the value.
- Source source;
/// True if there was a error parsing.
bool errored = false;
/// True if there was a error parsing.
@@ -268,33 +262,14 @@
/// VarDeclInfo contains the parsed information for variable declaration.
struct VarDeclInfo {
- /// Constructor
- VarDeclInfo();
- /// Copy constructor
- /// @param other the VarDeclInfo to copy
- VarDeclInfo(const VarDeclInfo& other);
- /// Constructor
- /// @param source_in variable declaration source
- /// @param name_in variable name
- /// @param address_space_in variable address space
- /// @param access_in variable access control
- /// @param type_in variable type
- VarDeclInfo(Source source_in,
- std::string name_in,
- type::AddressSpace address_space_in,
- type::Access access_in,
- ast::Type type_in);
- /// Destructor
- ~VarDeclInfo();
-
/// Variable declaration source
Source source;
/// Variable name
std::string name;
/// Variable address space
- type::AddressSpace address_space = type::AddressSpace::kUndefined;
+ const ast::Expression* address_space = nullptr;
/// Variable access control
- type::Access access = type::Access::kUndefined;
+ const ast::Expression* access = nullptr;
/// Variable type
ast::Type type;
};
@@ -302,9 +277,9 @@
/// VariableQualifier contains the parsed information for a variable qualifier
struct VariableQualifier {
/// The variable's address space
- type::AddressSpace address_space = type::AddressSpace::kUndefined;
+ const ast::Expression* address_space = nullptr;
/// The variable's access control
- type::Access access = type::Access::kUndefined;
+ const ast::Expression* access = nullptr;
};
/// MatrixDimensions contains the column and row information for a matrix
@@ -447,10 +422,6 @@
/// Parses a `type_specifier` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<ast::Type> type_specifier();
- /// Parses an `address_space` grammar element, erroring on parse failure.
- /// @param use a description of what was being parsed if an error was raised.
- /// @returns the address space or type::AddressSpace::kUndefined if none matched
- Expect<type::AddressSpace> expect_address_space(std::string_view use);
/// Parses a `struct_decl` grammar element.
/// @returns the struct type or nullptr on error
Maybe<const ast::Struct*> struct_decl();
@@ -482,11 +453,6 @@
/// not match a stage name.
/// @returns the pipeline stage.
Expect<ast::PipelineStage> expect_pipeline_stage();
- /// Parses an access control identifier, erroring if the next token does not
- /// match a valid access control.
- /// @param use a description of what was being parsed if an error was raised
- /// @returns the parsed access control.
- Expect<type::Access> expect_access_mode(std::string_view use);
/// Parses an interpolation sample name identifier, erroring if the next token does not match a
/// valid sample name.
/// @returns the parsed sample name.
@@ -597,8 +563,9 @@
/// @returns the parsed expression or nullptr
Maybe<const ast::Expression*> expression();
/// Parses the `expression` grammar rule
+ /// @param use the use of the expression
/// @returns the parsed expression or error
- Expect<const ast::Expression*> expect_expression();
+ Expect<const ast::Expression*> expect_expression(std::string_view use);
/// Parses a comma separated expression list
/// @param use the use of the expression list
/// @param terminator the terminating token for the list
diff --git a/src/tint/reader/wgsl/parser_impl_address_space_test.cc b/src/tint/reader/wgsl/parser_impl_address_space_test.cc
deleted file mode 100644
index 32c3c47..0000000
--- a/src/tint/reader/wgsl/parser_impl_address_space_test.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
-
-namespace tint::reader::wgsl {
-namespace {
-
-struct AddressSpaceData {
- const char* input;
- type::AddressSpace result;
-};
-inline std::ostream& operator<<(std::ostream& out, AddressSpaceData data) {
- out << std::string(data.input);
- return out;
-}
-
-class ParserAddressSpaceTest : public ParserImplTestWithParam<AddressSpaceData> {};
-
-TEST_P(ParserAddressSpaceTest, Parses) {
- auto params = GetParam();
- auto p = parser(params.input);
-
- auto sc = p->expect_address_space("test");
- EXPECT_FALSE(sc.errored);
- EXPECT_FALSE(p->has_error());
- EXPECT_EQ(sc.value, params.result);
-
- auto& t = p->next();
- EXPECT_TRUE(t.IsEof());
-}
-INSTANTIATE_TEST_SUITE_P(
- ParserImplTest,
- ParserAddressSpaceTest,
- testing::Values(AddressSpaceData{"uniform", type::AddressSpace::kUniform},
- AddressSpaceData{"workgroup", type::AddressSpace::kWorkgroup},
- AddressSpaceData{"storage", type::AddressSpace::kStorage},
- AddressSpaceData{"private", type::AddressSpace::kPrivate},
- AddressSpaceData{"function", type::AddressSpace::kFunction}));
-
-TEST_F(ParserImplTest, AddressSpace_NoMatch) {
- auto p = parser("not-a-address-space");
- auto sc = p->expect_address_space("test");
- EXPECT_EQ(sc.errored, true);
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), R"(1:1: expected address space for test
-Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
-}
-
-} // namespace
-} // namespace tint::reader::wgsl
diff --git a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
index d40898a..18b40be 100644
--- a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
@@ -799,7 +799,7 @@
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingSubtype) {
EXPECT("var x : texture_storage_2d<>;",
- R"(test.wgsl:1:28 error: expected expression
+ R"(test.wgsl:1:28 error: expected expression for type template argument list
var x : texture_storage_2d<>;
^
)");
@@ -1123,20 +1123,11 @@
)");
}
-TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclInvalidClass) {
- EXPECT("var<fish> i : i32",
- R"(test.wgsl:1:5 error: expected address space for variable declaration
-Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup'
-var<fish> i : i32
- ^^^^
-)");
-}
-
TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclMissingGThan) {
EXPECT("var<private i : i32",
- R"(test.wgsl:1:13 error: expected '>' for variable declaration
+ R"(test.wgsl:1:4 error: missing closing '>' for variable declaration
var<private i : i32
- ^
+ ^
)");
}
diff --git a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
index 92272cc..daf978e 100644
--- a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
@@ -31,10 +31,8 @@
ASSERT_NE(var, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), var->name, "a");
-
ast::CheckIdentifier(p->builder().Symbols(), var->type, "f32");
-
- EXPECT_EQ(var->declared_address_space, type::AddressSpace::kPrivate);
+ ast::CheckIdentifier(p->builder().Symbols(), var->declared_address_space, "private");
EXPECT_EQ(var->source.range.begin.line, 1u);
EXPECT_EQ(var->source.range.begin.column, 14u);
@@ -58,8 +56,7 @@
ast::CheckIdentifier(p->builder().Symbols(), var->name, "a");
ast::CheckIdentifier(p->builder().Symbols(), var->type, "f32");
-
- EXPECT_EQ(var->declared_address_space, type::AddressSpace::kPrivate);
+ ast::CheckIdentifier(p->builder().Symbols(), var->declared_address_space, "private");
EXPECT_EQ(var->source.range.begin.line, 1u);
EXPECT_EQ(var->source.range.begin.column, 14u);
@@ -83,11 +80,8 @@
ASSERT_NE(var, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), var->name, "a");
- ASSERT_NE(var->type, nullptr);
-
ast::CheckIdentifier(p->builder().Symbols(), var->type, "f32");
-
- EXPECT_EQ(var->declared_address_space, type::AddressSpace::kUniform);
+ ast::CheckIdentifier(p->builder().Symbols(), var->declared_address_space, "uniform");
EXPECT_EQ(var->source.range.begin.line, 1u);
EXPECT_EQ(var->source.range.begin.column, 36u);
@@ -116,10 +110,8 @@
ASSERT_NE(var, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), var->name, "a");
- ASSERT_NE(var->type, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), var->type, "f32");
-
- EXPECT_EQ(var->declared_address_space, type::AddressSpace::kUniform);
+ ast::CheckIdentifier(p->builder().Symbols(), var->declared_address_space, "uniform");
EXPECT_EQ(var->source.range.begin.line, 1u);
EXPECT_EQ(var->source.range.begin.column, 36u);
@@ -162,19 +154,5 @@
EXPECT_EQ(p->error(), "1:24: missing initializer for 'var' declaration");
}
-TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
- auto p = parser("var<invalid> a : f32;");
- auto attrs = p->attribute_list();
- EXPECT_FALSE(attrs.errored);
- EXPECT_FALSE(attrs.matched);
- auto e = p->global_variable_decl(attrs.value);
- EXPECT_TRUE(p->has_error());
- EXPECT_TRUE(e.errored);
- EXPECT_FALSE(e.matched);
- EXPECT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), R"(1:5: expected address space for variable declaration
-Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
-}
-
} // namespace
} // namespace tint::reader::wgsl
diff --git a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
index b40d887..25e60e0 100644
--- a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
@@ -137,7 +137,7 @@
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
- ASSERT_EQ(p->error(), "1:6: expected expression");
+ ASSERT_EQ(p->error(), "1:6: expected expression for type template argument list");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
VecMissingType,
@@ -211,7 +211,7 @@
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
- ASSERT_EQ(p->error(), R"(1:5: expected expression)");
+ ASSERT_EQ(p->error(), R"(1:5: expected expression for type template argument list)");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) {
@@ -221,7 +221,7 @@
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
- ASSERT_EQ(p->error(), R"(1:5: expected expression)");
+ ASSERT_EQ(p->error(), R"(1:5: expected expression for type template argument list)");
}
TEST_F(ParserImplTest, TypeDecl_Atomic) {
@@ -256,7 +256,7 @@
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
- ASSERT_EQ(p->error(), "1:8: expected expression");
+ ASSERT_EQ(p->error(), "1:8: expected expression for type template argument list");
}
TEST_F(ParserImplTest, TypeDecl_Array_AbstractIntLiteralSize) {
@@ -431,7 +431,7 @@
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
- ASSERT_EQ(p->error(), "1:8: expected expression");
+ ASSERT_EQ(p->error(), "1:8: expected expression for type template argument list");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
MatrixMissingType,
diff --git a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
index 9138d55..993ecb0 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
@@ -84,8 +84,7 @@
EXPECT_EQ(v->name, "my_var");
ast::CheckIdentifier(p->builder().Symbols(), v->type, "f32");
-
- EXPECT_EQ(v->address_space, type::AddressSpace::kPrivate);
+ ast::CheckIdentifier(p->builder().Symbols(), v->address_space, "private");
EXPECT_EQ(v->source.range.begin.line, 1u);
EXPECT_EQ(v->source.range.begin.column, 14u);
@@ -102,20 +101,7 @@
EXPECT_EQ(v->name, "my_var");
ast::CheckIdentifier(p->builder().Symbols(), v->type, "f32");
-
- EXPECT_EQ(v->address_space, type::AddressSpace::kPushConstant);
-}
-
-TEST_F(ParserImplTest, VariableDecl_InvalidAddressSpace) {
- auto p = parser("var<unknown> my_var : f32");
- auto v = p->variable_decl();
- EXPECT_FALSE(v.matched);
- EXPECT_TRUE(v.errored);
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(),
- R"(1:5: expected address space for variable declaration
-Did you mean 'uniform'?
-Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
+ ast::CheckIdentifier(p->builder().Symbols(), v->address_space, "push_constant");
}
} // namespace
diff --git a/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc b/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc
index 111f207..9a8b936 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
@@ -31,14 +32,23 @@
TEST_P(VariableQualifierTest, ParsesAddressSpace) {
auto params = GetParam();
- auto p = parser(std::string("<") + params.input + ">");
+ auto p = parser(std::string("var<") + params.input + "> name");
- auto sc = p->variable_qualifier();
+ auto sc = p->variable_decl();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(sc.errored);
EXPECT_TRUE(sc.matched);
- EXPECT_EQ(sc->address_space, params.address_space);
- EXPECT_EQ(sc->access, params.access);
+ if (params.address_space != type::AddressSpace::kUndefined) {
+ ast::CheckIdentifier(p->builder().Symbols(), sc->address_space,
+ utils::ToString(params.address_space));
+ } else {
+ EXPECT_EQ(sc->address_space, nullptr);
+ }
+ if (params.access != type::Access::kUndefined) {
+ ast::CheckIdentifier(p->builder().Symbols(), sc->access, utils::ToString(params.access));
+ } else {
+ EXPECT_EQ(sc->access, nullptr);
+ }
auto& t = p->next();
EXPECT_TRUE(t.IsEof());
@@ -57,24 +67,13 @@
VariableStorageData{"storage, read_write", type::AddressSpace::kStorage,
type::Access::kReadWrite}));
-TEST_F(ParserImplTest, VariableQualifier_NoMatch) {
- auto p = parser("<not-a-storage-class>");
- auto sc = p->variable_qualifier();
- EXPECT_TRUE(p->has_error());
- EXPECT_TRUE(sc.errored);
- EXPECT_FALSE(sc.matched);
- EXPECT_EQ(p->error(), R"(1:2: expected address space for variable declaration
-Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
-}
-
TEST_F(ParserImplTest, VariableQualifier_Empty) {
- auto p = parser("<>");
- auto sc = p->variable_qualifier();
+ auto p = parser("var<> name");
+ auto sc = p->variable_decl();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(sc.errored);
EXPECT_FALSE(sc.matched);
- EXPECT_EQ(p->error(), R"(1:2: expected address space for variable declaration
-Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
+ EXPECT_EQ(p->error(), R"(1:5: expected expression for 'var' address space)");
}
TEST_F(ParserImplTest, VariableQualifier_MissingLessThan) {
@@ -105,7 +104,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(sc.errored);
EXPECT_FALSE(sc.matched);
- EXPECT_EQ(p->error(), "1:9: expected '>' for variable declaration");
+ EXPECT_EQ(p->error(), "1:1: missing closing '>' for variable declaration");
}
} // namespace
diff --git a/src/tint/resolver/address_space_validation_test.cc b/src/tint/resolver/address_space_validation_test.cc
index 2c879de..95301c7 100644
--- a/src/tint/resolver/address_space_validation_test.cc
+++ b/src/tint/resolver/address_space_validation_test.cc
@@ -32,8 +32,9 @@
GlobalVar(Source{{12, 34}}, "g", ty.f32());
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: module-scope 'var' declaration must have a address space");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: module-scope 'var' declarations that are not of texture or sampler types must provide an address space)");
}
TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_NoAddressSpace_Fail) {
@@ -469,7 +470,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: only variables in <storage> address space may declare an access mode)");
+ R"(12:34 error: only variables in <storage> address space may specify an access mode)");
}
TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_NotStorage_AccessMode) {
@@ -481,7 +482,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: only pointers in <storage> address space may declare an access mode)");
+ R"(12:34 error: only pointers in <storage> address space may specify an access mode)");
}
TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_ReadAccessMode) {
diff --git a/src/tint/resolver/dependency_graph.cc b/src/tint/resolver/dependency_graph.cc
index 16a3f8e..75e377f 100644
--- a/src/tint/resolver/dependency_graph.cc
+++ b/src/tint/resolver/dependency_graph.cc
@@ -183,13 +183,9 @@
Declare(func->name->symbol, func);
TraverseFunction(func);
},
- [&](const ast::Variable* var) {
- Declare(var->name->symbol, var);
- TraverseTypeExpression(var->type);
- TraverseAttributes(var->attributes);
- if (var->initializer) {
- TraverseValueExpression(var->initializer);
- }
+ [&](const ast::Variable* v) {
+ Declare(v->name->symbol, v);
+ TraverseVariable(v);
},
[&](const ast::DiagnosticDirective*) {
// Diagnostic directives do not affect the dependency graph.
@@ -204,8 +200,18 @@
}
private:
- /// Traverses the function, performing symbol resolution and determining
- /// global dependencies.
+ /// Traverses the variable, performing symbol resolution.
+ void TraverseVariable(const ast::Variable* v) {
+ if (auto* var = v->As<ast::Var>()) {
+ TraverseAddressSpaceExpression(var->declared_address_space);
+ TraverseAccessExpression(var->declared_access);
+ }
+ TraverseTypeExpression(v->type);
+ TraverseAttributes(v->attributes);
+ TraverseValueExpression(v->initializer);
+ }
+
+ /// Traverses the function, performing symbol resolution and determining global dependencies.
void TraverseFunction(const ast::Function* func) {
TraverseAttributes(func->attributes);
TraverseAttributes(func->return_type_attributes);
@@ -301,8 +307,7 @@
if (auto* shadows = scope_stack_.Get(v->variable->name->symbol)) {
graph_.shadows.Add(v->variable, shadows);
}
- TraverseTypeExpression(v->variable->type);
- TraverseValueExpression(v->variable->initializer);
+ TraverseVariable(v->variable);
Declare(v->variable->name->symbol, v->variable);
},
[&](const ast::WhileStatement* w) {
@@ -345,6 +350,18 @@
TraverseExpression(root, "type", "references");
}
+ /// Traverses the expression @p root_expr for the intended use as an address space, performing
+ /// symbol resolution and determining global dependencies.
+ void TraverseAddressSpaceExpression(const ast::Expression* root) {
+ TraverseExpression(root, "address space", "references");
+ }
+
+ /// Traverses the expression @p root_expr for the intended use as an access, performing symbol
+ /// resolution and determining global dependencies.
+ void TraverseAccessExpression(const ast::Expression* root) {
+ TraverseExpression(root, "access", "references");
+ }
+
/// Traverses the expression @p root_expr for the intended use as a call target, performing
/// symbol resolution and determining global dependencies.
void TraverseCallableExpression(const ast::Expression* root) {
diff --git a/src/tint/resolver/dependency_graph_test.cc b/src/tint/resolver/dependency_graph_test.cc
index 31e484e..a316ad0 100644
--- a/src/tint/resolver/dependency_graph_test.cc
+++ b/src/tint/resolver/dependency_graph_test.cc
@@ -1437,13 +1437,13 @@
<< resolved->String(Symbols(), Diagnostics());
}
-TEST_P(ResolverDependencyGraphResolveToAddressSpace, ShadowedByGlobalVar) {
+TEST_P(ResolverDependencyGraphResolveToAddressSpace, ShadowedByGlobalConst) {
const auto use = std::get<0>(GetParam());
const auto builtin = std::get<1>(GetParam());
const auto symbol = Symbols().New(utils::ToString(builtin));
SymbolTestHelper helper(this);
- auto* decl = helper.Add(SymbolDeclKind::GlobalVar, symbol);
+ auto* decl = helper.Add(SymbolDeclKind::GlobalConst, symbol);
auto* ident = helper.Add(use, symbol);
helper.Build();
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index b04831e..1062958 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -1088,15 +1088,14 @@
param.expectation == Expectation::kPassWithFullPtrParameterExtension) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
} else {
- std::stringstream ss;
- ss << param.address_space;
EXPECT_FALSE(r()->Resolve());
if (param.expectation == Expectation::kInvalid) {
- EXPECT_EQ(r()->error(), "12:34 error: unknown identifier: '" + ss.str() + "'");
+ EXPECT_EQ(r()->error(), "12:34 error: unknown identifier: '" +
+ utils::ToString(param.address_space) + "'");
} else {
EXPECT_EQ(r()->error(),
- "12:34 error: function parameter of pointer type cannot be in '" + ss.str() +
- "' address space");
+ "12:34 error: function parameter of pointer type cannot be in '" +
+ utils::ToString(param.address_space) + "' address space");
}
}
}
@@ -1105,8 +1104,8 @@
ResolverFunctionParameterValidationTest,
testing::Values(
TestParams{type::AddressSpace::kUndefined, Expectation::kInvalid},
- TestParams{type::AddressSpace::kIn, Expectation::kInvalid},
- TestParams{type::AddressSpace::kOut, Expectation::kInvalid},
+ TestParams{type::AddressSpace::kIn, Expectation::kAlwaysFail},
+ TestParams{type::AddressSpace::kOut, Expectation::kAlwaysFail},
TestParams{type::AddressSpace::kUniform, Expectation::kPassWithFullPtrParameterExtension},
TestParams{type::AddressSpace::kWorkgroup, Expectation::kPassWithFullPtrParameterExtension},
TestParams{type::AddressSpace::kHandle, Expectation::kInvalid},
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index b87852f..8336765 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -473,8 +473,14 @@
return nullptr;
}
- auto address_space = var->declared_address_space;
- if (address_space == type::AddressSpace::kUndefined) {
+ auto address_space = type::AddressSpace::kUndefined;
+ if (var->declared_address_space) {
+ auto expr = AddressSpaceExpression(var->declared_address_space);
+ if (!expr) {
+ return nullptr;
+ }
+ address_space = expr->Value();
+ } else {
// No declared address space. Infer from usage / type.
if (!is_global) {
address_space = type::AddressSpace::kFunction;
@@ -494,8 +500,14 @@
return nullptr;
}
- auto access = var->declared_access;
- if (access == type::Access::kUndefined) {
+ auto access = type::Access::kUndefined;
+ if (var->declared_access) {
+ auto expr = AccessExpression(var->declared_access);
+ if (!expr) {
+ return nullptr;
+ }
+ access = expr->Value();
+ } else {
access = DefaultAccessForAddressSpace(address_space);
}
diff --git a/src/tint/resolver/validation_test.cc b/src/tint/resolver/validation_test.cc
index 73fa9b8..8ee795c 100644
--- a/src/tint/resolver/validation_test.cc
+++ b/src/tint/resolver/validation_test.cc
@@ -295,22 +295,23 @@
TEST_F(ResolverValidationTest, AddressSpace_SamplerExplicitAddressSpace) {
auto t = ty.sampler(type::SamplerKind::kSampler);
- GlobalVar(Source{{12, 34}}, "var", t, type::AddressSpace::kHandle, Binding(0_a), Group(0_a));
+ GlobalVar(Source{{12, 34}}, "var", t, type::AddressSpace::kPrivate, Binding(0_a), Group(0_a));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: variables of type 'sampler' must not have a address space)");
+ R"(12:34 error: variables of type 'sampler' must not specifiy an address space)");
}
TEST_F(ResolverValidationTest, AddressSpace_TextureExplicitAddressSpace) {
auto t = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
- GlobalVar(Source{{12, 34}}, "var", t, type::AddressSpace::kHandle, Binding(0_a), Group(0_a));
+ GlobalVar(Source{{12, 34}}, "var", t, type::AddressSpace::kFunction, Binding(0_a), Group(0_a));
EXPECT_FALSE(r()->Resolve()) << r()->error();
- EXPECT_EQ(r()->error(),
- R"(12:34 error: variables of type 'texture_1d<f32>' must not have a address space)");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: variables of type 'texture_1d<f32>' must not specifiy an address space)");
}
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index 5b399cf..2935c70 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -299,7 +299,7 @@
// * For the storage address space, the access mode is optional, and defaults to read.
// * For other address spaces, the access mode must not be written.
if (s->AddressSpace() != type::AddressSpace::kStorage) {
- AddError("only pointers in <storage> address space may declare an access mode",
+ AddError("only pointers in <storage> address space may specify an access mode",
a->source);
return false;
}
@@ -604,7 +604,7 @@
}
bool ok = Switch(
decl, //
- [&](const ast::Var*) {
+ [&](const ast::Var* var) {
if (auto* init = global->Initializer();
init && init->Stage() > sem::EvaluationStage::kOverride) {
AddError("module-scope 'var' initializer must be a constant or override-expression",
@@ -612,8 +612,11 @@
return false;
}
- if (global->AddressSpace() == type::AddressSpace::kUndefined) {
- AddError("module-scope 'var' declaration must have a address space", decl->source);
+ if (!var->declared_address_space && !global->Type()->UnwrapRef()->is_handle()) {
+ AddError(
+ "module-scope 'var' declarations that are not of texture or sampler types must "
+ "provide an address space",
+ decl->source);
return false;
}
@@ -696,25 +699,23 @@
return false;
}
- if (store_ty->is_handle()) {
- if (var->declared_address_space != type::AddressSpace::kUndefined) {
- // https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
- // If the store type is a texture type or a sampler type, then the variable declaration
- // must not have a address space attribute. The address space will always be handle.
- AddError("variables of type '" + sem_.TypeNameOf(store_ty) +
- "' must not have a address space",
- var->source);
- return false;
- }
+ if (store_ty->is_handle() && var->declared_address_space) {
+ // https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
+ // If the store type is a texture type or a sampler type, then the variable declaration must
+ // not have a address space attribute. The address space will always be handle.
+ AddError("variables of type '" + sem_.TypeNameOf(store_ty) +
+ "' must not specifiy an address space",
+ var->source);
+ return false;
}
- if (var->declared_access != type::Access::kUndefined) {
+ if (var->declared_access) {
// https://www.w3.org/TR/WGSL/#access-mode-defaults
// When writing a variable declaration or a pointer type in WGSL source:
// * For the storage address space, the access mode is optional, and defaults to read.
// * For other address spaces, the access mode must not be written.
- if (var->declared_address_space != type::AddressSpace::kStorage) {
- AddError("only variables in <storage> address space may declare an access mode",
+ if (v->AddressSpace() != type::AddressSpace::kStorage) {
+ AddError("only variables in <storage> address space may specify an access mode",
var->source);
return false;
}
@@ -726,8 +727,8 @@
}
if (IsValidationEnabled(var->attributes, ast::DisabledValidation::kIgnoreAddressSpace) &&
- (var->declared_address_space == type::AddressSpace::kIn ||
- var->declared_address_space == type::AddressSpace::kOut)) {
+ (v->AddressSpace() == type::AddressSpace::kIn ||
+ v->AddressSpace() == type::AddressSpace::kOut)) {
AddError("invalid use of input/output address space", var->source);
return false;
}
diff --git a/src/tint/transform/binding_remapper.cc b/src/tint/transform/binding_remapper.cc
index b657980..192b2c9 100644
--- a/src/tint/transform/binding_remapper.cc
+++ b/src/tint/transform/binding_remapper.cc
@@ -122,11 +122,12 @@
// Replace any access controls.
auto ac_it = remappings->access_controls.find(from);
if (ac_it != remappings->access_controls.end()) {
- type::Access ac = ac_it->second;
- if (ac == type::Access::kUndefined) {
- b.Diagnostics().add_error(
- diag::System::Transform,
- "invalid access mode (" + std::to_string(static_cast<uint32_t>(ac)) + ")");
+ type::Access access = ac_it->second;
+ if (access == type::Access::kUndefined) {
+ b.Diagnostics().add_error(diag::System::Transform,
+ "invalid access mode (" +
+ std::to_string(static_cast<uint32_t>(access)) +
+ ")");
return Program(std::move(b));
}
auto* sem = src->Sem().Get(var);
@@ -139,9 +140,14 @@
}
auto* ty = sem->Type()->UnwrapRef();
auto inner_ty = CreateASTTypeFor(ctx, ty);
- auto* new_var = b.Var(ctx.Clone(var->source), ctx.Clone(var->name->symbol),
- inner_ty, var->declared_address_space, ac,
- ctx.Clone(var->initializer), ctx.Clone(var->attributes));
+ auto* new_var =
+ b.create<ast::Var>(ctx.Clone(var->source), // source
+ b.Ident(ctx.Clone(var->name->symbol)), // name
+ inner_ty, // type
+ ctx.Clone(var->declared_address_space), // address space
+ b.Expr(access), // access
+ ctx.Clone(var->initializer), // initializer
+ ctx.Clone(var->attributes)); // attributes
ctx.Replace(var, new_var);
}
diff --git a/src/tint/transform/canonicalize_entry_point_io_test.cc b/src/tint/transform/canonicalize_entry_point_io_test.cc
index 5af8a14..f0ce8c3 100644
--- a/src/tint/transform/canonicalize_entry_point_io_test.cc
+++ b/src/tint/transform/canonicalize_entry_point_io_test.cc
@@ -67,11 +67,11 @@
)";
auto* expect = R"(
-@location(1) @internal(disable_validation__ignore_address_space) var<in> loc1_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> loc1_1 : f32;
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> loc2_1 : vec4<u32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> loc2_1 : vec4<u32>;
-@builtin(position) @internal(disable_validation__ignore_address_space) var<in> coord_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__in> coord_1 : vec4<f32>;
fn frag_main_inner(loc1 : f32, loc2 : vec4<u32>, coord : vec4<f32>) {
var col : f32 = (coord.x * loc1);
@@ -251,13 +251,13 @@
)";
auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<in> loc0_1 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> loc0_1 : f32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> loc1_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> loc1_1 : f32;
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> loc2_1 : vec4<u32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> loc2_1 : vec4<u32>;
-@builtin(position) @internal(disable_validation__ignore_address_space) var<in> coord_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__in> coord_1 : vec4<f32>;
struct FragBuiltins {
coord : vec4<f32>,
@@ -304,13 +304,13 @@
)";
auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<in> loc0_1 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> loc0_1 : f32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> loc1_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> loc1_1 : f32;
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> loc2_1 : vec4<u32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> loc2_1 : vec4<u32>;
-@builtin(position) @internal(disable_validation__ignore_address_space) var<in> coord_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__in> coord_1 : vec4<f32>;
fn frag_main_inner(loc0 : f32, locations : FragLocations, builtins : FragBuiltins) {
var col : f32 = ((builtins.coord.x * locations.loc1) + loc0);
@@ -567,7 +567,7 @@
)";
auto* expect = R"(
-@builtin(frag_depth) @internal(disable_validation__ignore_address_space) var<out> value : f32;
+@builtin(frag_depth) @internal(disable_validation__ignore_address_space) var<__out> value : f32;
fn frag_main_inner() -> f32 {
return 1.0;
@@ -674,11 +674,11 @@
)";
auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<out> color_1 : vec4<f32>;
+@location(0) @internal(disable_validation__ignore_address_space) var<__out> color_1 : vec4<f32>;
-@builtin(frag_depth) @internal(disable_validation__ignore_address_space) var<out> depth_1 : f32;
+@builtin(frag_depth) @internal(disable_validation__ignore_address_space) var<__out> depth_1 : f32;
-@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<out> mask_1 : array<u32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<__out> mask_1 : array<u32, 1u>;
struct FragOutput {
color : vec4<f32>,
@@ -729,11 +729,11 @@
)";
auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<out> color_1 : vec4<f32>;
+@location(0) @internal(disable_validation__ignore_address_space) var<__out> color_1 : vec4<f32>;
-@builtin(frag_depth) @internal(disable_validation__ignore_address_space) var<out> depth_1 : f32;
+@builtin(frag_depth) @internal(disable_validation__ignore_address_space) var<__out> depth_1 : f32;
-@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<out> mask_1 : array<u32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<__out> mask_1 : array<u32, 1u>;
fn frag_main_inner() -> FragOutput {
var output : FragOutput;
@@ -1028,13 +1028,13 @@
)";
auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<in> value_1 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> value_1 : f32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> mul_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> mul_1 : f32;
-@location(0) @internal(disable_validation__ignore_address_space) var<in> value_2 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> value_2 : f32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> mul_2 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> mul_2 : f32;
struct FragmentInput {
value : f32,
@@ -1094,13 +1094,13 @@
)";
auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<in> value_1 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> value_1 : f32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> mul_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> mul_1 : f32;
-@location(0) @internal(disable_validation__ignore_address_space) var<in> value_2 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> value_2 : f32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> mul_2 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> mul_2 : f32;
fn frag_main1_inner(inputs : FragmentInput) {
var x : f32 = foo(inputs);
@@ -1952,39 +1952,39 @@
auto* expect =
R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<in> i_1 : i32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> i_1 : i32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> u_1 : u32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> u_1 : u32;
-@location(2) @internal(disable_validation__ignore_address_space) var<in> vi_1 : vec4<i32>;
+@location(2) @internal(disable_validation__ignore_address_space) var<__in> vi_1 : vec4<i32>;
-@location(3) @internal(disable_validation__ignore_address_space) var<in> vu_1 : vec4<u32>;
+@location(3) @internal(disable_validation__ignore_address_space) var<__in> vu_1 : vec4<u32>;
-@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> i_2 : i32;
+@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__out> i_2 : i32;
-@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> u_2 : u32;
+@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__out> u_2 : u32;
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> vi_2 : vec4<i32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__out> vi_2 : vec4<i32>;
-@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> vu_2 : vec4<u32>;
+@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__out> vu_2 : vec4<u32>;
-@builtin(position) @internal(disable_validation__ignore_address_space) var<out> pos_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__out> pos_1 : vec4<f32>;
-@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> i_3 : i32;
+@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> i_3 : i32;
-@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> u_3 : u32;
+@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> u_3 : u32;
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> vi_3 : vec4<i32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> vi_3 : vec4<i32>;
-@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> vu_3 : vec4<u32>;
+@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> vu_3 : vec4<u32>;
-@location(0) @internal(disable_validation__ignore_address_space) var<out> i_4 : i32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__out> i_4 : i32;
-@location(1) @internal(disable_validation__ignore_address_space) var<out> u_4 : u32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__out> u_4 : u32;
-@location(2) @internal(disable_validation__ignore_address_space) var<out> vi_4 : vec4<i32>;
+@location(2) @internal(disable_validation__ignore_address_space) var<__out> vi_4 : vec4<i32>;
-@location(3) @internal(disable_validation__ignore_address_space) var<out> vu_4 : vec4<u32>;
+@location(3) @internal(disable_validation__ignore_address_space) var<__out> vu_4 : vec4<u32>;
struct VertexIn {
i : i32,
@@ -2082,39 +2082,39 @@
auto* expect =
R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<in> i_1 : i32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> i_1 : i32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> u_1 : u32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> u_1 : u32;
-@location(2) @internal(disable_validation__ignore_address_space) var<in> vi_1 : vec4<i32>;
+@location(2) @internal(disable_validation__ignore_address_space) var<__in> vi_1 : vec4<i32>;
-@location(3) @internal(disable_validation__ignore_address_space) var<in> vu_1 : vec4<u32>;
+@location(3) @internal(disable_validation__ignore_address_space) var<__in> vu_1 : vec4<u32>;
-@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> i_2 : i32;
+@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__out> i_2 : i32;
-@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> u_2 : u32;
+@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__out> u_2 : u32;
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> vi_2 : vec4<i32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__out> vi_2 : vec4<i32>;
-@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> vu_2 : vec4<u32>;
+@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__out> vu_2 : vec4<u32>;
-@builtin(position) @internal(disable_validation__ignore_address_space) var<out> pos_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__out> pos_1 : vec4<f32>;
-@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> i_3 : i32;
+@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> i_3 : i32;
-@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> u_3 : u32;
+@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> u_3 : u32;
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> vi_3 : vec4<i32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> vi_3 : vec4<i32>;
-@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> vu_3 : vec4<u32>;
+@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> vu_3 : vec4<u32>;
-@location(0) @internal(disable_validation__ignore_address_space) var<out> i_4 : i32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__out> i_4 : i32;
-@location(1) @internal(disable_validation__ignore_address_space) var<out> u_4 : u32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__out> u_4 : u32;
-@location(2) @internal(disable_validation__ignore_address_space) var<out> vi_4 : vec4<i32>;
+@location(2) @internal(disable_validation__ignore_address_space) var<__out> vi_4 : vec4<i32>;
-@location(3) @internal(disable_validation__ignore_address_space) var<out> vu_4 : vec4<u32>;
+@location(3) @internal(disable_validation__ignore_address_space) var<__out> vu_4 : vec4<u32>;
fn vert_main_inner(in : VertexIn) -> VertexOut {
return VertexOut(in.i, in.u, in.vi, in.vu, vec4<f32>());
@@ -3161,9 +3161,9 @@
)";
auto* expect = R"(
-@builtin(position) @internal(disable_validation__ignore_address_space) var<out> value : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__out> value : vec4<f32>;
-@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<__out> vertex_point_size : f32;
fn vert_main_inner() -> vec4<f32> {
return vec4<f32>();
@@ -3236,9 +3236,9 @@
)";
auto* expect = R"(
-@builtin(position) @internal(disable_validation__ignore_address_space) var<out> pos_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__out> pos_1 : vec4<f32>;
-@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<__out> vertex_point_size : f32;
struct VertOut {
pos : vec4<f32>,
@@ -3277,9 +3277,9 @@
)";
auto* expect = R"(
-@builtin(position) @internal(disable_validation__ignore_address_space) var<out> pos_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__out> pos_1 : vec4<f32>;
-@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<__out> vertex_point_size : f32;
fn vert_main_inner() -> VertOut {
return VertOut();
@@ -3424,15 +3424,15 @@
)";
auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<in> collide_2 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> collide_2 : f32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> collide_3 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> collide_3 : f32;
-@location(0) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_3 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__out> vertex_point_size_3 : f32;
-@builtin(position) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_1_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__out> vertex_point_size_1_1 : vec4<f32>;
-@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_4 : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<__out> vertex_point_size_4 : f32;
var<private> vertex_point_size : f32;
@@ -3502,15 +3502,15 @@
)";
auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_address_space) var<in> collide_2 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__in> collide_2 : f32;
-@location(1) @internal(disable_validation__ignore_address_space) var<in> collide_3 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<__in> collide_3 : f32;
-@location(0) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_3 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<__out> vertex_point_size_3 : f32;
-@builtin(position) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_1_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__out> vertex_point_size_1_1 : vec4<f32>;
-@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_4 : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<__out> vertex_point_size_4 : f32;
fn vert_main_inner(collide : VertIn1, collide_1 : VertIn2) -> VertOut {
let x = (collide.collide + collide_1.collide);
@@ -3868,11 +3868,11 @@
)";
auto* expect = R"(
-@builtin(sample_index) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> sample_index_1 : u32;
+@builtin(sample_index) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> sample_index_1 : u32;
-@builtin(sample_mask) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> mask_in_1 : array<u32, 1u>;
+@builtin(sample_mask) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<__in> mask_in_1 : array<u32, 1u>;
-@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<out> value : array<u32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<__out> value : array<u32, 1u>;
fn main_inner(sample_index : u32, mask_in : u32) -> u32 {
return mask_in;
@@ -3903,11 +3903,11 @@
)";
auto* expect = R"(
-@builtin(sample_index) @internal(disable_validation__ignore_address_space) var<in> gl_SampleID : i32;
+@builtin(sample_index) @internal(disable_validation__ignore_address_space) var<__in> gl_SampleID : i32;
-@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<in> gl_SampleMaskIn : array<i32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<__in> gl_SampleMaskIn : array<i32, 1u>;
-@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<out> gl_SampleMask : array<i32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<__out> gl_SampleMask : array<i32, 1u>;
fn fragment_main(sample_index : u32, mask_in : u32) -> u32 {
return mask_in;
@@ -3938,11 +3938,11 @@
)";
auto* expect = R"(
-@builtin(vertex_index) @internal(disable_validation__ignore_address_space) var<in> gl_VertexID : i32;
+@builtin(vertex_index) @internal(disable_validation__ignore_address_space) var<__in> gl_VertexID : i32;
-@builtin(instance_index) @internal(disable_validation__ignore_address_space) var<in> gl_InstanceID : i32;
+@builtin(instance_index) @internal(disable_validation__ignore_address_space) var<__in> gl_InstanceID : i32;
-@builtin(position) @internal(disable_validation__ignore_address_space) var<out> gl_Position : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<__out> gl_Position : vec4<f32>;
fn vertex_main(vertexID : u32, instanceID : u32) -> vec4<f32> {
return vec4<f32>((f32(vertexID) + f32(instanceID)));
diff --git a/src/tint/transform/clamp_frag_depth.cc b/src/tint/transform/clamp_frag_depth.cc
index 57d9a40..8d84ed3 100644
--- a/src/tint/transform/clamp_frag_depth.cc
+++ b/src/tint/transform/clamp_frag_depth.cc
@@ -88,10 +88,11 @@
// Abort on any use of push constants in the module.
for (auto* global : src->AST().GlobalVariables()) {
if (auto* var = global->As<ast::Var>()) {
- if (TINT_UNLIKELY(var->declared_address_space == type::AddressSpace::kPushConstant)) {
+ auto* v = src->Sem().Get(var);
+ if (TINT_UNLIKELY(v->AddressSpace() == type::AddressSpace::kPushConstant)) {
TINT_ICE(Transform, b.Diagnostics())
<< "ClampFragDepth doesn't know how to handle module that already use push "
- "constants.";
+ "constants";
return Program(std::move(b));
}
}
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.cc b/src/tint/transform/module_scope_var_to_entry_point_param.cc
index ff65fec..47356e9 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param.cc
+++ b/src/tint/transform/module_scope_var_to_entry_point_param.cc
@@ -117,7 +117,6 @@
WorkgroupParameterMemberList& workgroup_parameter_members,
bool& is_pointer,
bool& is_wrapped) {
- auto* var_ast = var->Declaration()->As<ast::Var>();
auto* ty = var->Type()->UnwrapRef();
// Helper to create an AST node for the store type of the variable.
@@ -160,7 +159,9 @@
is_wrapped = true;
}
- param_type = ctx.dst->ty.pointer(param_type, sc, var_ast->declared_access);
+ param_type = sc == type::AddressSpace::kStorage
+ ? ctx.dst->ty.pointer(param_type, sc, var->Access())
+ : ctx.dst->ty.pointer(param_type, sc);
auto* param = ctx.dst->Param(new_var_symbol, param_type, attributes);
ctx.InsertFront(func->params, param);
is_pointer = true;
@@ -228,7 +229,6 @@
const sem::Variable* var,
Symbol new_var_symbol,
bool& is_pointer) {
- auto* var_ast = var->Declaration()->As<ast::Var>();
auto* ty = var->Type()->UnwrapRef();
auto param_type = CreateASTTypeFor(ctx, ty);
auto sc = var->AddressSpace();
@@ -254,7 +254,9 @@
// Use a pointer for non-handle types.
utils::Vector<const ast::Attribute*, 2> attributes;
if (!ty->is_handle()) {
- param_type = ctx.dst->ty.pointer(param_type, sc, var_ast->declared_access);
+ param_type = sc == type::AddressSpace::kStorage
+ ? ctx.dst->ty.pointer(param_type, sc, var->Access())
+ : ctx.dst->ty.pointer(param_type, sc);
is_pointer = true;
// Disable validation of the parameter's address space and of arguments passed to it.
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param_test.cc b/src/tint/transform/module_scope_var_to_entry_point_param_test.cc
index 999761d..0f4c5b9 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param_test.cc
+++ b/src/tint/transform/module_scope_var_to_entry_point_param_test.cc
@@ -435,7 +435,7 @@
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, S>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, S, read>) {
_ = *(tint_symbol);
_ = *(tint_symbol_1);
}
@@ -465,7 +465,7 @@
auto* expect = R"(
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, S>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, S, read>) {
_ = *(tint_symbol);
_ = *(tint_symbol_1);
}
@@ -497,7 +497,7 @@
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1, read>) {
_ = (*(tint_symbol)).arr[0];
}
)";
@@ -524,7 +524,7 @@
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1, read>) {
_ = (*(tint_symbol)).arr[0];
}
)";
@@ -554,12 +554,12 @@
arr : array<f32>,
}
-fn foo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<storage, array<f32>>) {
+fn foo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<storage, array<f32>, read>) {
_ = (*(tint_symbol))[0];
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, tint_symbol_2>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, tint_symbol_2, read>) {
foo(&((*(tint_symbol_1)).arr));
}
)";
@@ -589,11 +589,11 @@
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, tint_symbol_2>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, tint_symbol_2, read>) {
foo(&((*(tint_symbol_1)).arr));
}
-fn foo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<storage, array<f32>>) {
+fn foo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<storage, array<f32>, read>) {
_ = (*(tint_symbol))[0];
}
)";
@@ -624,7 +624,7 @@
alias myarray = array<f32>;
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1, read>) {
_ = (*(tint_symbol)).arr[0];
}
)";
@@ -652,7 +652,7 @@
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1, read>) {
_ = (*(tint_symbol)).arr[0];
}
@@ -689,7 +689,7 @@
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1, read>) {
_ = (*(tint_symbol)).arr[0];
}
)";
@@ -723,7 +723,7 @@
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1, read>) {
_ = (*(tint_symbol)).arr[0];
}
)";
@@ -773,12 +773,12 @@
fn no_uses() {
}
-fn bar(a : f32, b : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<storage, S>) {
+fn bar(a : f32, b : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<storage, S, read>) {
_ = *(tint_symbol);
_ = *(tint_symbol_1);
}
-fn foo(a : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<storage, S>) {
+fn foo(a : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<storage, S, read>) {
let b : f32 = 2.0;
_ = *(tint_symbol_2);
bar(a, b, tint_symbol_2, tint_symbol_3);
@@ -786,7 +786,7 @@
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_4 : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_5 : ptr<storage, S>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_4 : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_5 : ptr<storage, S, read>) {
foo(1.0, tint_symbol_4, tint_symbol_5);
}
)";
@@ -830,11 +830,11 @@
auto* expect = R"(
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_4 : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_5 : ptr<storage, S>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_4 : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_5 : ptr<storage, S, read>) {
foo(1.0, tint_symbol_4, tint_symbol_5);
}
-fn foo(a : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<storage, S>) {
+fn foo(a : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<storage, S, read>) {
let b : f32 = 2.0;
_ = *(tint_symbol_2);
bar(a, b, tint_symbol_2, tint_symbol_3);
@@ -844,7 +844,7 @@
fn no_uses() {
}
-fn bar(a : f32, b : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<storage, S>) {
+fn bar(a : f32, b : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<storage, S, read>) {
_ = *(tint_symbol);
_ = *(tint_symbol_1);
}
diff --git a/src/tint/transform/renamer_test.cc b/src/tint/transform/renamer_test.cc
index c233267..2d13436 100644
--- a/src/tint/transform/renamer_test.cc
+++ b/src/tint/transform/renamer_test.cc
@@ -1927,7 +1927,9 @@
out.push_back(ident);
}
for (auto* ident : type::kAddressSpaceStrings) {
- out.push_back(ident);
+ if (!utils::HasPrefix(ident, "_")) {
+ out.push_back(ident);
+ }
}
for (auto* ident : type::kTexelFormatStrings) {
out.push_back(ident);
@@ -1940,24 +1942,24 @@
using RenamerBuiltinIdentifierTest = TransformTestWithParam<const char*>;
-TEST_P(RenamerBuiltinIdentifierTest, GlobalVarName) {
+TEST_P(RenamerBuiltinIdentifierTest, GlobalConstName) {
auto expand = [&](const char* source) {
return utils::ReplaceAll(source, "$name", GetParam());
};
auto src = expand(R"(
-var<private> $name = 42;
+const $name = 42;
fn f() {
- var v = $name;
+ const v = $name;
}
)");
auto expect = expand(R"(
-var<private> tint_symbol = 42;
+const tint_symbol = 42;
fn tint_symbol_1() {
- var tint_symbol_2 = tint_symbol;
+ const tint_symbol_2 = tint_symbol;
}
)");
diff --git a/src/tint/transform/std140.cc b/src/tint/transform/std140.cc
index 4c487d0..a19d78f 100644
--- a/src/tint/transform/std140.cc
+++ b/src/tint/transform/std140.cc
@@ -350,8 +350,8 @@
void ReplaceUniformVarTypes() {
for (auto* global : src->AST().GlobalVariables()) {
if (auto* var = global->As<ast::Var>()) {
- if (var->declared_address_space == type::AddressSpace::kUniform) {
- auto* v = sem.Get(var);
+ auto* v = sem.Get(var);
+ if (v->AddressSpace() == type::AddressSpace::kUniform) {
if (auto std140_ty = Std140Type(v->Type()->UnwrapRef())) {
ctx.Replace(global->type.expr, b.Expr(std140_ty));
std140_uniforms.Add(v);
diff --git a/src/tint/transform/zero_init_workgroup_memory.cc b/src/tint/transform/zero_init_workgroup_memory.cc
index 49d96d9..015a25b 100644
--- a/src/tint/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/transform/zero_init_workgroup_memory.cc
@@ -36,7 +36,8 @@
bool ShouldRun(const Program* program) {
for (auto* global : program->AST().GlobalVariables()) {
if (auto* var = global->As<ast::Var>()) {
- if (var->declared_address_space == type::AddressSpace::kWorkgroup) {
+ auto* v = program->Sem().Get(var);
+ if (v->AddressSpace() == type::AddressSpace::kWorkgroup) {
return true;
}
}
diff --git a/src/tint/type/address_space.cc b/src/tint/type/address_space.cc
index 68f2c71..c3cfcc6 100644
--- a/src/tint/type/address_space.cc
+++ b/src/tint/type/address_space.cc
@@ -28,6 +28,12 @@
/// @param str the string to parse
/// @returns the parsed enum, or AddressSpace::kUndefined if the string could not be parsed.
AddressSpace ParseAddressSpace(std::string_view str) {
+ if (str == "__in") {
+ return AddressSpace::kIn;
+ }
+ if (str == "__out") {
+ return AddressSpace::kOut;
+ }
if (str == "function") {
return AddressSpace::kFunction;
}
@@ -53,14 +59,14 @@
switch (value) {
case AddressSpace::kUndefined:
return out << "undefined";
+ case AddressSpace::kIn:
+ return out << "__in";
+ case AddressSpace::kOut:
+ return out << "__out";
case AddressSpace::kFunction:
return out << "function";
case AddressSpace::kHandle:
return out << "handle";
- case AddressSpace::kIn:
- return out << "in";
- case AddressSpace::kOut:
- return out << "out";
case AddressSpace::kPrivate:
return out << "private";
case AddressSpace::kPushConstant:
diff --git a/src/tint/type/address_space.h b/src/tint/type/address_space.h
index 5b3855c..f0b0224 100644
--- a/src/tint/type/address_space.h
+++ b/src/tint/type/address_space.h
@@ -30,10 +30,10 @@
/// Address space of a given pointer.
enum class AddressSpace {
kUndefined,
+ kIn,
+ kOut,
kFunction,
kHandle, // Tint-internal enum entry - not parsed
- kIn, // Tint-internal enum entry - not parsed
- kOut, // Tint-internal enum entry - not parsed
kPrivate,
kPushConstant,
kStorage,
@@ -52,7 +52,7 @@
AddressSpace ParseAddressSpace(std::string_view str);
constexpr const char* kAddressSpaceStrings[] = {
- "function", "private", "push_constant", "storage", "uniform", "workgroup",
+ "__in", "__out", "function", "private", "push_constant", "storage", "uniform", "workgroup",
};
/// @returns true if the AddressSpace is host-shareable
diff --git a/src/tint/type/address_space_bench.cc b/src/tint/type/address_space_bench.cc
index ecd3ccf..6f33497 100644
--- a/src/tint/type/address_space_bench.cc
+++ b/src/tint/type/address_space_bench.cc
@@ -31,15 +31,62 @@
void AddressSpaceParser(::benchmark::State& state) {
const char* kStrings[] = {
- "fccnctin", "ucti3", "functVon", "function", "1unction",
- "unJtqqon", "llun77tion", "ppqqivtHH", "prcv", "bivaGe",
- "private", "priviive", "8WWivate", "pxxvate", "pXh_cggnstant",
- "pX_Vonstanu", "push_consta3t", "push_constant", "push_constanE", "push_TTPnstant",
- "puxxdh_constan", "s44orage", "stSSraVVe", "RtoR22e", "storage",
- "sFra9e", "stoage", "VOORRHge", "unfoym", "llnnrrf77rm",
- "unif4r00", "uniform", "nfoom", "zzform", "uiiippo1",
- "workgrouXX", "wor55gro99nII", "wrrrkgroSSaHH", "workgroup", "kkrHoup",
- "jgkrouRR", "wokroub",
+ "ccin",
+ "3",
+ "_Vin",
+ "__in",
+ "1_in",
+ "_qiJ",
+ "_lli77",
+ "__qHupp",
+ "vt",
+ "G_bt",
+ "__out",
+ "__viut",
+ "__8WWt",
+ "Mxxou",
+ "fuXggton",
+ "fuXtou",
+ "funct3on",
+ "function",
+ "funEtion",
+ "PPncTTion",
+ "xxuncddon",
+ "p44ivate",
+ "prSSvaVVe",
+ "RriR22e",
+ "private",
+ "pFva9e",
+ "priate",
+ "VOORRHte",
+ "push_constyn",
+ "punnh_crr77stallt",
+ "pu4h_cons00ant",
+ "push_constant",
+ "puoo_costan",
+ "ushzzcnstant",
+ "push_coii11apt",
+ "storaXXe",
+ "9II5tnnrage",
+ "stoaSSrHHYe",
+ "storage",
+ "stkke",
+ "jtogRa",
+ "sbrag",
+ "unifojm",
+ "niform",
+ "qform",
+ "uniform",
+ "uniNNrm",
+ "nifrvv",
+ "QQiform",
+ "workrorf",
+ "workjroup",
+ "wNNorkrou2",
+ "workgroup",
+ "workgrop",
+ "rrorkgroup",
+ "workgroGp",
};
for (auto _ : state) {
for (auto* str : kStrings) {
diff --git a/src/tint/type/address_space_test.cc b/src/tint/type/address_space_test.cc
index 8b2af5c..7909f0e 100644
--- a/src/tint/type/address_space_test.cc
+++ b/src/tint/type/address_space_test.cc
@@ -42,6 +42,8 @@
}
static constexpr Case kValidCases[] = {
+ {"__in", AddressSpace::kIn},
+ {"__out", AddressSpace::kOut},
{"function", AddressSpace::kFunction},
{"private", AddressSpace::kPrivate},
{"push_constant", AddressSpace::kPushConstant},
@@ -51,15 +53,18 @@
};
static constexpr Case kInvalidCases[] = {
- {"fccnctin", AddressSpace::kUndefined}, {"ucti3", AddressSpace::kUndefined},
- {"functVon", AddressSpace::kUndefined}, {"priv1te", AddressSpace::kUndefined},
- {"pqiJate", AddressSpace::kUndefined}, {"privat7ll", AddressSpace::kUndefined},
- {"pqqsh_pponstHnt", AddressSpace::kUndefined}, {"pus_cnstat", AddressSpace::kUndefined},
- {"bus_Gonstant", AddressSpace::kUndefined}, {"storiive", AddressSpace::kUndefined},
- {"8WWorage", AddressSpace::kUndefined}, {"sxxrage", AddressSpace::kUndefined},
- {"uXforgg", AddressSpace::kUndefined}, {"nfoXm", AddressSpace::kUndefined},
- {"unif3rm", AddressSpace::kUndefined}, {"workgroEp", AddressSpace::kUndefined},
- {"woTTPkroup", AddressSpace::kUndefined}, {"ddorkroxxp", AddressSpace::kUndefined},
+ {"ccin", AddressSpace::kUndefined}, {"3", AddressSpace::kUndefined},
+ {"_Vin", AddressSpace::kUndefined}, {"__ou1", AddressSpace::kUndefined},
+ {"qq_Jt", AddressSpace::kUndefined}, {"__oll7t", AddressSpace::kUndefined},
+ {"qquntppHon", AddressSpace::kUndefined}, {"cnciv", AddressSpace::kUndefined},
+ {"funGion", AddressSpace::kUndefined}, {"priviive", AddressSpace::kUndefined},
+ {"8WWivate", AddressSpace::kUndefined}, {"pxxvate", AddressSpace::kUndefined},
+ {"pXh_cggnstant", AddressSpace::kUndefined}, {"pX_Vonstanu", AddressSpace::kUndefined},
+ {"push_consta3t", AddressSpace::kUndefined}, {"Etorage", AddressSpace::kUndefined},
+ {"sPTTrage", AddressSpace::kUndefined}, {"storadxx", AddressSpace::kUndefined},
+ {"u44iform", AddressSpace::kUndefined}, {"unSSfoVVm", AddressSpace::kUndefined},
+ {"RniR22m", AddressSpace::kUndefined}, {"w9rFroup", AddressSpace::kUndefined},
+ {"workgoup", AddressSpace::kUndefined}, {"woVROOrHup", AddressSpace::kUndefined},
};
using AddressSpaceParseTest = testing::TestWithParam<Case>;
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc
index ae34abb..c92e51a 100644
--- a/src/tint/writer/wgsl/generator_impl.cc
+++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -34,8 +34,6 @@
#include "src/tint/ast/workgroup_attribute.h"
#include "src/tint/sem/struct.h"
#include "src/tint/sem/switch_statement.h"
-#include "src/tint/type/access.h"
-#include "src/tint/type/texture_dimension.h"
#include "src/tint/utils/math.h"
#include "src/tint/utils/scoped_assignment.h"
#include "src/tint/writer/float_to_string.h"
@@ -376,24 +374,6 @@
return true;
}
-bool GeneratorImpl::EmitAccess(std::ostream& out, const type::Access access) {
- switch (access) {
- case type::Access::kRead:
- out << "read";
- return true;
- case type::Access::kWrite:
- out << "write";
- return true;
- case type::Access::kReadWrite:
- out << "read_write";
- return true;
- default:
- break;
- }
- diagnostics_.add_error(diag::System::Writer, "unknown access");
- return false;
-}
-
bool GeneratorImpl::EmitStructType(const ast::Struct* str) {
if (str->attributes.Length()) {
if (!EmitAttributes(line(), str->attributes)) {
@@ -473,17 +453,18 @@
v, //
[&](const ast::Var* var) {
out << "var";
- auto address_space = var->declared_address_space;
- auto ac = var->declared_access;
- if (address_space != type::AddressSpace::kUndefined || ac != type::Access::kUndefined) {
- out << "<" << address_space;
- if (ac != type::Access::kUndefined) {
+ if (var->declared_address_space || var->declared_access) {
+ out << "<";
+ TINT_DEFER(out << ">");
+ if (!EmitExpression(out, var->declared_address_space)) {
+ return false;
+ }
+ if (var->declared_access) {
out << ", ";
- if (!EmitAccess(out, ac)) {
+ if (!EmitExpression(out, var->declared_access)) {
return false;
}
}
- out << ">";
}
return true;
},
diff --git a/src/tint/writer/wgsl/generator_impl.h b/src/tint/writer/wgsl/generator_impl.h
index 56c0dfb..746ce0f 100644
--- a/src/tint/writer/wgsl/generator_impl.h
+++ b/src/tint/writer/wgsl/generator_impl.h
@@ -35,7 +35,6 @@
#include "src/tint/ast/unary_op_expression.h"
#include "src/tint/program.h"
#include "src/tint/sem/struct.h"
-#include "src/tint/type/storage_texture.h"
#include "src/tint/writer/text_generator.h"
namespace tint::writer::wgsl {
@@ -209,11 +208,6 @@
/// @param fmt the format to generate
/// @returns true if the format is emitted
bool EmitImageFormat(std::ostream& out, const type::TexelFormat fmt);
- /// Handles emitting an access control
- /// @param out the output stream
- /// @param access the access to generate
- /// @returns true if the access is emitted
- bool EmitAccess(std::ostream& out, const type::Access access);
/// Handles a unary op expression
/// @param out the output stream
/// @param expr the expression to emit