Rename 'decoration' to 'attribute'

This matches (mostly) the term used in the WGSL spec.

Change-Id: Ie148a1ca8498698e91fdbb60e1aeb0d509b80630
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/78786
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2022-02-02 23:07:11 +00:00
parent d4d7153bad
commit a996ffbd1f
228 changed files with 5609 additions and 5642 deletions

View File

@ -94,7 +94,7 @@ Each `ast::Node` represents a **single** part of the program's source, and so
`ast::Node`s are not shared. `ast::Node`s are not shared.
The AST does not perform any verification of its content. For example, the The AST does not perform any verification of its content. For example, the
`ast::StrideDecoration` node has numeric stride parameter, which is a count of `ast::StrideAttribute` node has numeric stride parameter, which is a count of
the number of bytes from the start of one array element to the start of the the number of bytes from the start of one array element to the start of the
next. The AST node itself does not constrain the set of stride values that you next. The AST node itself does not constrain the set of stride values that you
can set, aside from storing it as an unsigned integer. can set, aside from storing it as an unsigned integer.

View File

@ -186,8 +186,8 @@ libtint_source_set("libtint_core_all_src") {
"ast/atomic.h", "ast/atomic.h",
"ast/binary_expression.cc", "ast/binary_expression.cc",
"ast/binary_expression.h", "ast/binary_expression.h",
"ast/binding_decoration.cc", "ast/binding_attribute.cc",
"ast/binding_decoration.h", "ast/binding_attribute.h",
"ast/bitcast_expression.cc", "ast/bitcast_expression.cc",
"ast/bitcast_expression.h", "ast/bitcast_expression.h",
"ast/block_statement.cc", "ast/block_statement.cc",
@ -200,8 +200,8 @@ libtint_source_set("libtint_core_all_src") {
"ast/break_statement.h", "ast/break_statement.h",
"ast/builtin.cc", "ast/builtin.cc",
"ast/builtin.h", "ast/builtin.h",
"ast/builtin_decoration.cc", "ast/builtin_attribute.cc",
"ast/builtin_decoration.h", "ast/builtin_attribute.h",
"ast/call_expression.cc", "ast/call_expression.cc",
"ast/call_expression.h", "ast/call_expression.h",
"ast/call_statement.cc", "ast/call_statement.cc",
@ -210,14 +210,14 @@ libtint_source_set("libtint_core_all_src") {
"ast/case_statement.h", "ast/case_statement.h",
"ast/continue_statement.cc", "ast/continue_statement.cc",
"ast/continue_statement.h", "ast/continue_statement.h",
"ast/decoration.cc", "ast/attribute.cc",
"ast/decoration.h", "ast/attribute.h",
"ast/depth_multisampled_texture.cc", "ast/depth_multisampled_texture.cc",
"ast/depth_multisampled_texture.h", "ast/depth_multisampled_texture.h",
"ast/depth_texture.cc", "ast/depth_texture.cc",
"ast/depth_texture.h", "ast/depth_texture.h",
"ast/disable_validation_decoration.cc", "ast/disable_validation_attribute.cc",
"ast/disable_validation_decoration.h", "ast/disable_validation_attribute.h",
"ast/discard_statement.cc", "ast/discard_statement.cc",
"ast/discard_statement.h", "ast/discard_statement.h",
"ast/else_statement.cc", "ast/else_statement.cc",
@ -236,8 +236,8 @@ libtint_source_set("libtint_core_all_src") {
"ast/for_loop_statement.h", "ast/for_loop_statement.h",
"ast/function.cc", "ast/function.cc",
"ast/function.h", "ast/function.h",
"ast/group_decoration.cc", "ast/group_attribute.cc",
"ast/group_decoration.h", "ast/group_attribute.h",
"ast/i32.cc", "ast/i32.cc",
"ast/i32.h", "ast/i32.h",
"ast/identifier_expression.cc", "ast/identifier_expression.cc",
@ -248,16 +248,16 @@ libtint_source_set("libtint_core_all_src") {
"ast/index_accessor_expression.h", "ast/index_accessor_expression.h",
"ast/int_literal_expression.cc", "ast/int_literal_expression.cc",
"ast/int_literal_expression.h", "ast/int_literal_expression.h",
"ast/internal_decoration.cc", "ast/internal_attribute.cc",
"ast/internal_decoration.h", "ast/internal_attribute.h",
"ast/interpolate_decoration.cc", "ast/interpolate_attribute.cc",
"ast/interpolate_decoration.h", "ast/interpolate_attribute.h",
"ast/invariant_decoration.cc", "ast/invariant_attribute.cc",
"ast/invariant_decoration.h", "ast/invariant_attribute.h",
"ast/literal_expression.cc", "ast/literal_expression.cc",
"ast/literal_expression.h", "ast/literal_expression.h",
"ast/location_decoration.cc", "ast/location_attribute.cc",
"ast/location_decoration.h", "ast/location_attribute.h",
"ast/loop_statement.cc", "ast/loop_statement.cc",
"ast/loop_statement.h", "ast/loop_statement.h",
"ast/matrix.cc", "ast/matrix.cc",
@ -270,8 +270,8 @@ libtint_source_set("libtint_core_all_src") {
"ast/multisampled_texture.h", "ast/multisampled_texture.h",
"ast/node.cc", "ast/node.cc",
"ast/node.h", "ast/node.h",
"ast/override_decoration.cc", "ast/override_attribute.cc",
"ast/override_decoration.h", "ast/override_attribute.h",
"ast/phony_expression.cc", "ast/phony_expression.cc",
"ast/phony_expression.h", "ast/phony_expression.h",
"ast/pipeline_stage.cc", "ast/pipeline_stage.cc",
@ -286,28 +286,28 @@ libtint_source_set("libtint_core_all_src") {
"ast/sampler.h", "ast/sampler.h",
"ast/sint_literal_expression.cc", "ast/sint_literal_expression.cc",
"ast/sint_literal_expression.h", "ast/sint_literal_expression.h",
"ast/stage_decoration.cc", "ast/stage_attribute.cc",
"ast/stage_decoration.h", "ast/stage_attribute.h",
"ast/statement.cc", "ast/statement.cc",
"ast/statement.h", "ast/statement.h",
"ast/storage_class.cc", "ast/storage_class.cc",
"ast/storage_class.h", "ast/storage_class.h",
"ast/storage_texture.cc", "ast/storage_texture.cc",
"ast/storage_texture.h", "ast/storage_texture.h",
"ast/stride_decoration.cc", "ast/stride_attribute.cc",
"ast/stride_decoration.h", "ast/stride_attribute.h",
"ast/struct.cc", "ast/struct.cc",
"ast/struct.h", "ast/struct.h",
"ast/struct_block_decoration.cc", "ast/struct_block_attribute.cc",
"ast/struct_block_decoration.h", "ast/struct_block_attribute.h",
"ast/struct_member.cc", "ast/struct_member.cc",
"ast/struct_member.h", "ast/struct_member.h",
"ast/struct_member_align_decoration.cc", "ast/struct_member_align_attribute.cc",
"ast/struct_member_align_decoration.h", "ast/struct_member_align_attribute.h",
"ast/struct_member_offset_decoration.cc", "ast/struct_member_offset_attribute.cc",
"ast/struct_member_offset_decoration.h", "ast/struct_member_offset_attribute.h",
"ast/struct_member_size_decoration.cc", "ast/struct_member_size_attribute.cc",
"ast/struct_member_size_decoration.h", "ast/struct_member_size_attribute.h",
"ast/switch_statement.cc", "ast/switch_statement.cc",
"ast/switch_statement.h", "ast/switch_statement.h",
"ast/texture.cc", "ast/texture.cc",
@ -334,8 +334,8 @@ libtint_source_set("libtint_core_all_src") {
"ast/vector.h", "ast/vector.h",
"ast/void.cc", "ast/void.cc",
"ast/void.h", "ast/void.h",
"ast/workgroup_decoration.cc", "ast/workgroup_attribute.cc",
"ast/workgroup_decoration.h", "ast/workgroup_attribute.h",
"block_allocator.h", "block_allocator.h",
"castable.cc", "castable.cc",
"castable.h", "castable.h",
@ -427,8 +427,8 @@ libtint_source_set("libtint_core_all_src") {
"traits.h", "traits.h",
"transform/add_empty_entry_point.cc", "transform/add_empty_entry_point.cc",
"transform/add_empty_entry_point.h", "transform/add_empty_entry_point.h",
"transform/add_spirv_block_decoration.cc", "transform/add_spirv_block_attribute.cc",
"transform/add_spirv_block_decoration.h", "transform/add_spirv_block_attribute.h",
"transform/array_length_from_uniform.cc", "transform/array_length_from_uniform.cc",
"transform/array_length_from_uniform.h", "transform/array_length_from_uniform.h",
"transform/binding_remapper.cc", "transform/binding_remapper.cc",

View File

@ -55,6 +55,8 @@ set(TINT_LIB_SRCS
../include/tint/tint.h ../include/tint/tint.h
ast/access.cc ast/access.cc
ast/access.h ast/access.h
ast/attribute.cc
ast/attribute.h
ast/alias.cc ast/alias.cc
ast/alias.h ast/alias.h
ast/index_accessor_expression.cc ast/index_accessor_expression.cc
@ -67,8 +69,8 @@ set(TINT_LIB_SRCS
ast/atomic.h ast/atomic.h
ast/binary_expression.cc ast/binary_expression.cc
ast/binary_expression.h ast/binary_expression.h
ast/binding_decoration.cc ast/binding_attribute.cc
ast/binding_decoration.h ast/binding_attribute.h
ast/bitcast_expression.cc ast/bitcast_expression.cc
ast/bitcast_expression.h ast/bitcast_expression.h
ast/block_statement.cc ast/block_statement.cc
@ -79,8 +81,8 @@ set(TINT_LIB_SRCS
ast/bool.h ast/bool.h
ast/break_statement.cc ast/break_statement.cc
ast/break_statement.h ast/break_statement.h
ast/builtin_decoration.cc ast/builtin_attribute.cc
ast/builtin_decoration.h ast/builtin_attribute.h
ast/builtin.cc ast/builtin.cc
ast/builtin.h ast/builtin.h
ast/call_expression.cc ast/call_expression.cc
@ -91,12 +93,10 @@ set(TINT_LIB_SRCS
ast/case_statement.h ast/case_statement.h
ast/continue_statement.cc ast/continue_statement.cc
ast/continue_statement.h ast/continue_statement.h
ast/decoration.cc
ast/decoration.h
ast/depth_multisampled_texture.cc ast/depth_multisampled_texture.cc
ast/depth_multisampled_texture.h ast/depth_multisampled_texture.h
ast/disable_validation_decoration.cc ast/disable_validation_attribute.cc
ast/disable_validation_decoration.h ast/disable_validation_attribute.h
ast/depth_texture.cc ast/depth_texture.cc
ast/depth_texture.h ast/depth_texture.h
ast/discard_statement.cc ast/discard_statement.cc
@ -117,8 +117,8 @@ set(TINT_LIB_SRCS
ast/for_loop_statement.h ast/for_loop_statement.h
ast/function.cc ast/function.cc
ast/function.h ast/function.h
ast/group_decoration.cc ast/group_attribute.cc
ast/group_decoration.h ast/group_attribute.h
ast/i32.cc ast/i32.cc
ast/i32.h ast/i32.h
ast/identifier_expression.cc ast/identifier_expression.cc
@ -127,16 +127,16 @@ set(TINT_LIB_SRCS
ast/if_statement.h ast/if_statement.h
ast/int_literal_expression.cc ast/int_literal_expression.cc
ast/int_literal_expression.h ast/int_literal_expression.h
ast/internal_decoration.cc ast/internal_attribute.cc
ast/internal_decoration.h ast/internal_attribute.h
ast/interpolate_decoration.cc ast/interpolate_attribute.cc
ast/interpolate_decoration.h ast/interpolate_attribute.h
ast/invariant_decoration.cc ast/invariant_attribute.cc
ast/invariant_decoration.h ast/invariant_attribute.h
ast/literal_expression.cc ast/literal_expression.cc
ast/literal_expression.h ast/literal_expression.h
ast/location_decoration.cc ast/location_attribute.cc
ast/location_decoration.h ast/location_attribute.h
ast/loop_statement.cc ast/loop_statement.cc
ast/loop_statement.h ast/loop_statement.h
ast/matrix.cc ast/matrix.cc
@ -149,8 +149,8 @@ set(TINT_LIB_SRCS
ast/multisampled_texture.h ast/multisampled_texture.h
ast/node.cc ast/node.cc
ast/node.h ast/node.h
ast/override_decoration.cc ast/override_attribute.cc
ast/override_decoration.h ast/override_attribute.h
ast/phony_expression.cc ast/phony_expression.cc
ast/phony_expression.h ast/phony_expression.h
ast/pipeline_stage.cc ast/pipeline_stage.cc
@ -165,24 +165,24 @@ set(TINT_LIB_SRCS
ast/sampler.h ast/sampler.h
ast/sint_literal_expression.cc ast/sint_literal_expression.cc
ast/sint_literal_expression.h ast/sint_literal_expression.h
ast/stage_decoration.cc ast/stage_attribute.cc
ast/stage_decoration.h ast/stage_attribute.h
ast/statement.cc ast/statement.cc
ast/statement.h ast/statement.h
ast/storage_class.cc ast/storage_class.cc
ast/storage_class.h ast/storage_class.h
ast/storage_texture.cc ast/storage_texture.cc
ast/storage_texture.h ast/storage_texture.h
ast/stride_decoration.cc ast/stride_attribute.cc
ast/stride_decoration.h ast/stride_attribute.h
ast/struct_block_decoration.cc ast/struct_block_attribute.cc
ast/struct_block_decoration.h ast/struct_block_attribute.h
ast/struct_member_align_decoration.cc ast/struct_member_align_attribute.cc
ast/struct_member_align_decoration.h ast/struct_member_align_attribute.h
ast/struct_member_offset_decoration.cc ast/struct_member_offset_attribute.cc
ast/struct_member_offset_decoration.h ast/struct_member_offset_attribute.h
ast/struct_member_size_decoration.cc ast/struct_member_size_attribute.cc
ast/struct_member_size_decoration.h ast/struct_member_size_attribute.h
ast/struct_member.cc ast/struct_member.cc
ast/struct_member.h ast/struct_member.h
ast/struct.cc ast/struct.cc
@ -216,8 +216,8 @@ set(TINT_LIB_SRCS
ast/vector.h ast/vector.h
ast/void.cc ast/void.cc
ast/void.h ast/void.h
ast/workgroup_decoration.cc ast/workgroup_attribute.cc
ast/workgroup_decoration.h ast/workgroup_attribute.h
block_allocator.h block_allocator.h
castable.cc castable.cc
castable.h castable.h
@ -295,8 +295,8 @@ set(TINT_LIB_SRCS
traits.h traits.h
transform/add_empty_entry_point.cc transform/add_empty_entry_point.cc
transform/add_empty_entry_point.h transform/add_empty_entry_point.h
transform/add_spirv_block_decoration.cc transform/add_spirv_block_attribute.cc
transform/add_spirv_block_decoration.h transform/add_spirv_block_attribute.h
transform/array_length_from_uniform.cc transform/array_length_from_uniform.cc
transform/array_length_from_uniform.h transform/array_length_from_uniform.h
transform/binding_remapper.cc transform/binding_remapper.cc
@ -617,13 +617,13 @@ if(TINT_BUILD_TESTS)
ast/assignment_statement_test.cc ast/assignment_statement_test.cc
ast/atomic_test.cc ast/atomic_test.cc
ast/binary_expression_test.cc ast/binary_expression_test.cc
ast/binding_decoration_test.cc ast/binding_attribute_test.cc
ast/bitcast_expression_test.cc ast/bitcast_expression_test.cc
ast/block_statement_test.cc ast/block_statement_test.cc
ast/bool_literal_expression_test.cc ast/bool_literal_expression_test.cc
ast/bool_test.cc ast/bool_test.cc
ast/break_statement_test.cc ast/break_statement_test.cc
ast/builtin_decoration_test.cc ast/builtin_attribute_test.cc
ast/call_expression_test.cc ast/call_expression_test.cc
ast/call_statement_test.cc ast/call_statement_test.cc
ast/case_statement_test.cc ast/case_statement_test.cc
@ -638,36 +638,36 @@ if(TINT_BUILD_TESTS)
ast/float_literal_expression_test.cc ast/float_literal_expression_test.cc
ast/for_loop_statement_test.cc ast/for_loop_statement_test.cc
ast/function_test.cc ast/function_test.cc
ast/group_decoration_test.cc ast/group_attribute_test.cc
ast/i32_test.cc ast/i32_test.cc
ast/identifier_expression_test.cc ast/identifier_expression_test.cc
ast/if_statement_test.cc ast/if_statement_test.cc
ast/index_accessor_expression_test.cc ast/index_accessor_expression_test.cc
ast/int_literal_expression_test.cc ast/int_literal_expression_test.cc
ast/interpolate_decoration_test.cc ast/interpolate_attribute_test.cc
ast/intrinsic_texture_helper_test.cc ast/intrinsic_texture_helper_test.cc
ast/intrinsic_texture_helper_test.h ast/intrinsic_texture_helper_test.h
ast/invariant_decoration_test.cc ast/invariant_attribute_test.cc
ast/location_decoration_test.cc ast/location_attribute_test.cc
ast/loop_statement_test.cc ast/loop_statement_test.cc
ast/matrix_test.cc ast/matrix_test.cc
ast/member_accessor_expression_test.cc ast/member_accessor_expression_test.cc
ast/module_clone_test.cc ast/module_clone_test.cc
ast/module_test.cc ast/module_test.cc
ast/multisampled_texture_test.cc ast/multisampled_texture_test.cc
ast/override_decoration_test.cc ast/override_attribute_test.cc
ast/phony_expression_test.cc ast/phony_expression_test.cc
ast/pointer_test.cc ast/pointer_test.cc
ast/return_statement_test.cc ast/return_statement_test.cc
ast/sampled_texture_test.cc ast/sampled_texture_test.cc
ast/sampler_test.cc ast/sampler_test.cc
ast/sint_literal_expression_test.cc ast/sint_literal_expression_test.cc
ast/stage_decoration_test.cc ast/stage_attribute_test.cc
ast/storage_texture_test.cc ast/storage_texture_test.cc
ast/stride_decoration_test.cc ast/stride_attribute_test.cc
ast/struct_member_align_decoration_test.cc ast/struct_member_align_attribute_test.cc
ast/struct_member_offset_decoration_test.cc ast/struct_member_offset_attribute_test.cc
ast/struct_member_size_decoration_test.cc ast/struct_member_size_attribute_test.cc
ast/struct_member_test.cc ast/struct_member_test.cc
ast/struct_test.cc ast/struct_test.cc
ast/switch_statement_test.cc ast/switch_statement_test.cc
@ -680,7 +680,7 @@ if(TINT_BUILD_TESTS)
ast/variable_decl_statement_test.cc ast/variable_decl_statement_test.cc
ast/variable_test.cc ast/variable_test.cc
ast/vector_test.cc ast/vector_test.cc
ast/workgroup_decoration_test.cc ast/workgroup_attribute_test.cc
block_allocator_test.cc block_allocator_test.cc
castable_test.cc castable_test.cc
clone_context_test.cc clone_context_test.cc
@ -701,7 +701,7 @@ if(TINT_BUILD_TESTS)
resolver/call_validation_test.cc resolver/call_validation_test.cc
resolver/compound_statement_test.cc resolver/compound_statement_test.cc
resolver/control_block_validation_test.cc resolver/control_block_validation_test.cc
resolver/decoration_validation_test.cc resolver/attribute_validation_test.cc
resolver/dependency_graph_test.cc resolver/dependency_graph_test.cc
resolver/entry_point_validation_test.cc resolver/entry_point_validation_test.cc
resolver/function_validation_test.cc resolver/function_validation_test.cc
@ -850,8 +850,8 @@ if(TINT_BUILD_TESTS)
reader/wgsl/parser_impl_exclusive_or_expression_test.cc reader/wgsl/parser_impl_exclusive_or_expression_test.cc
reader/wgsl/parser_impl_for_stmt_test.cc reader/wgsl/parser_impl_for_stmt_test.cc
reader/wgsl/parser_impl_function_decl_test.cc reader/wgsl/parser_impl_function_decl_test.cc
reader/wgsl/parser_impl_function_decoration_list_test.cc reader/wgsl/parser_impl_function_attribute_list_test.cc
reader/wgsl/parser_impl_function_decoration_test.cc reader/wgsl/parser_impl_function_attribute_test.cc
reader/wgsl/parser_impl_function_header_test.cc reader/wgsl/parser_impl_function_header_test.cc
reader/wgsl/parser_impl_global_constant_decl_test.cc reader/wgsl/parser_impl_global_constant_decl_test.cc
reader/wgsl/parser_impl_global_decl_test.cc reader/wgsl/parser_impl_global_decl_test.cc
@ -878,10 +878,10 @@ if(TINT_BUILD_TESTS)
reader/wgsl/parser_impl_storage_texture_type_test.cc reader/wgsl/parser_impl_storage_texture_type_test.cc
reader/wgsl/parser_impl_struct_body_decl_test.cc reader/wgsl/parser_impl_struct_body_decl_test.cc
reader/wgsl/parser_impl_struct_decl_test.cc reader/wgsl/parser_impl_struct_decl_test.cc
reader/wgsl/parser_impl_struct_decoration_decl_test.cc reader/wgsl/parser_impl_struct_attribute_decl_test.cc
reader/wgsl/parser_impl_struct_decoration_test.cc reader/wgsl/parser_impl_struct_attribute_test.cc
reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc reader/wgsl/parser_impl_struct_member_attribute_decl_test.cc
reader/wgsl/parser_impl_struct_member_decoration_test.cc reader/wgsl/parser_impl_struct_member_attribute_test.cc
reader/wgsl/parser_impl_struct_member_test.cc reader/wgsl/parser_impl_struct_member_test.cc
reader/wgsl/parser_impl_switch_body_test.cc reader/wgsl/parser_impl_switch_body_test.cc
reader/wgsl/parser_impl_switch_stmt_test.cc reader/wgsl/parser_impl_switch_stmt_test.cc
@ -894,8 +894,8 @@ if(TINT_BUILD_TESTS)
reader/wgsl/parser_impl_type_decl_test.cc reader/wgsl/parser_impl_type_decl_test.cc
reader/wgsl/parser_impl_unary_expression_test.cc reader/wgsl/parser_impl_unary_expression_test.cc
reader/wgsl/parser_impl_variable_decl_test.cc reader/wgsl/parser_impl_variable_decl_test.cc
reader/wgsl/parser_impl_variable_decoration_list_test.cc reader/wgsl/parser_impl_variable_attribute_list_test.cc
reader/wgsl/parser_impl_variable_decoration_test.cc reader/wgsl/parser_impl_variable_attribute_test.cc
reader/wgsl/parser_impl_variable_ident_decl_test.cc reader/wgsl/parser_impl_variable_ident_decl_test.cc
reader/wgsl/parser_impl_variable_stmt_test.cc reader/wgsl/parser_impl_variable_stmt_test.cc
reader/wgsl/parser_impl_variable_qualifier_test.cc reader/wgsl/parser_impl_variable_qualifier_test.cc
@ -916,7 +916,7 @@ if(TINT_BUILD_TESTS)
writer/spirv/builder_discard_test.cc writer/spirv/builder_discard_test.cc
writer/spirv/builder_entry_point_test.cc writer/spirv/builder_entry_point_test.cc
writer/spirv/builder_format_conversion_test.cc writer/spirv/builder_format_conversion_test.cc
writer/spirv/builder_function_decoration_test.cc writer/spirv/builder_function_attribute_test.cc
writer/spirv/builder_function_test.cc writer/spirv/builder_function_test.cc
writer/spirv/builder_function_variable_test.cc writer/spirv/builder_function_variable_test.cc
writer/spirv/builder_global_variable_test.cc writer/spirv/builder_global_variable_test.cc
@ -977,7 +977,7 @@ if(TINT_BUILD_TESTS)
if(${TINT_BUILD_WGSL_READER} AND ${TINT_BUILD_WGSL_WRITER}) if(${TINT_BUILD_WGSL_READER} AND ${TINT_BUILD_WGSL_WRITER})
list(APPEND TINT_TEST_SRCS list(APPEND TINT_TEST_SRCS
transform/add_empty_entry_point_test.cc transform/add_empty_entry_point_test.cc
transform/add_spirv_block_decoration_test.cc transform/add_spirv_block_attribute_test.cc
transform/array_length_from_uniform_test.cc transform/array_length_from_uniform_test.cc
transform/binding_remapper_test.cc transform/binding_remapper_test.cc
transform/calculate_array_length_test.cc transform/calculate_array_length_test.cc

View File

@ -43,8 +43,8 @@ Array::Array(ProgramID pid,
const Source& src, const Source& src,
const Type* subtype, const Type* subtype,
const Expression* cnt, const Expression* cnt,
DecorationList decos) AttributeList attrs)
: Base(pid, src), type(subtype), count(cnt), decorations(decos) {} : Base(pid, src), type(subtype), count(cnt), attributes(attrs) {}
Array::Array(Array&&) = default; Array::Array(Array&&) = default;
@ -52,8 +52,8 @@ Array::~Array() = default;
std::string Array::FriendlyName(const SymbolTable& symbols) const { std::string Array::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out; std::ostringstream out;
for (auto* deco : decorations) { for (auto* attr : attributes) {
if (auto* stride = deco->As<ast::StrideDecoration>()) { if (auto* stride = attr->As<ast::StrideAttribute>()) {
out << "@stride(" << stride->stride << ") "; out << "@stride(" << stride->stride << ") ";
} }
} }
@ -70,8 +70,8 @@ const Array* Array::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type); auto* ty = ctx->Clone(type);
auto* cnt = ctx->Clone(count); auto* cnt = ctx->Clone(count);
auto decos = ctx->Clone(decorations); auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Array>(src, ty, cnt, decos); return ctx->dst->create<Array>(src, ty, cnt, attrs);
} }
} // namespace ast } // namespace ast

View File

@ -17,7 +17,7 @@
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
#include "src/ast/type.h" #include "src/ast/type.h"
namespace tint { namespace tint {
@ -35,12 +35,12 @@ class Array : public Castable<Array, Type> {
/// @param subtype the type of the array elements /// @param subtype the type of the array elements
/// @param count the number of elements in the array. nullptr represents a /// @param count the number of elements in the array. nullptr represents a
/// runtime-sized array. /// runtime-sized array.
/// @param decorations the array decorations /// @param attributes the array attributes
Array(ProgramID pid, Array(ProgramID pid,
const Source& src, const Source& src,
const Type* subtype, const Type* subtype,
const Expression* count, const Expression* count,
DecorationList decorations); AttributeList attributes);
/// Move constructor /// Move constructor
Array(Array&&); Array(Array&&);
~Array() override; ~Array() override;
@ -65,8 +65,8 @@ class Array : public Castable<Array, Type> {
/// the array size in elements, or nullptr for a runtime array /// the array size in elements, or nullptr for a runtime array
const Expression* const count; const Expression* const count;
/// the array decorations /// the array attributes
const DecorationList decorations; const AttributeList attributes;
}; };
} // namespace ast } // namespace ast

View File

@ -25,7 +25,7 @@ using AstArrayTest = TestHelper;
TEST_F(AstArrayTest, CreateSizedArray) { TEST_F(AstArrayTest, CreateSizedArray) {
auto* u32 = create<U32>(); auto* u32 = create<U32>();
auto* count = Expr(3); auto* count = Expr(3);
auto* arr = create<Array>(u32, count, DecorationList{}); auto* arr = create<Array>(u32, count, AttributeList{});
EXPECT_EQ(arr->type, u32); EXPECT_EQ(arr->type, u32);
EXPECT_EQ(arr->count, count); EXPECT_EQ(arr->count, count);
EXPECT_TRUE(arr->Is<Array>()); EXPECT_TRUE(arr->Is<Array>());
@ -34,7 +34,7 @@ TEST_F(AstArrayTest, CreateSizedArray) {
TEST_F(AstArrayTest, CreateRuntimeArray) { TEST_F(AstArrayTest, CreateRuntimeArray) {
auto* u32 = create<U32>(); auto* u32 = create<U32>();
auto* arr = create<Array>(u32, nullptr, DecorationList{}); auto* arr = create<Array>(u32, nullptr, AttributeList{});
EXPECT_EQ(arr->type, u32); EXPECT_EQ(arr->type, u32);
EXPECT_EQ(arr->count, nullptr); EXPECT_EQ(arr->count, nullptr);
EXPECT_TRUE(arr->Is<Array>()); EXPECT_TRUE(arr->Is<Array>());
@ -43,26 +43,26 @@ TEST_F(AstArrayTest, CreateRuntimeArray) {
TEST_F(AstArrayTest, FriendlyName_RuntimeSized) { TEST_F(AstArrayTest, FriendlyName_RuntimeSized) {
auto* i32 = create<I32>(); auto* i32 = create<I32>();
auto* arr = create<Array>(i32, nullptr, DecorationList{}); auto* arr = create<Array>(i32, nullptr, AttributeList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>"); EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
} }
TEST_F(AstArrayTest, FriendlyName_LiteralSized) { TEST_F(AstArrayTest, FriendlyName_LiteralSized) {
auto* i32 = create<I32>(); auto* i32 = create<I32>();
auto* arr = create<Array>(i32, Expr(5), DecorationList{}); auto* arr = create<Array>(i32, Expr(5), AttributeList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>"); EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
} }
TEST_F(AstArrayTest, FriendlyName_ConstantSized) { TEST_F(AstArrayTest, FriendlyName_ConstantSized) {
auto* i32 = create<I32>(); auto* i32 = create<I32>();
auto* arr = create<Array>(i32, Expr("size"), DecorationList{}); auto* arr = create<Array>(i32, Expr("size"), AttributeList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, size>"); EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, size>");
} }
TEST_F(AstArrayTest, FriendlyName_WithStride) { TEST_F(AstArrayTest, FriendlyName_WithStride) {
auto* i32 = create<I32>(); auto* i32 = create<I32>();
auto* arr = auto* arr =
create<Array>(i32, Expr(5), DecorationList{create<StrideDecoration>(32)}); create<Array>(i32, Expr(5), AttributeList{create<StrideAttribute>(32)});
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>"); EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>");
} }

View File

@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Decoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::Attribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
Decoration::~Decoration() = default; Attribute::~Attribute() = default;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_DECORATION_H_ #ifndef SRC_AST_ATTRIBUTE_H_
#define SRC_AST_DECORATION_H_ #define SRC_AST_ATTRIBUTE_H_
#include <string> #include <string>
#include <vector> #include <vector>
@ -23,43 +23,43 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
/// The base class for all decorations /// The base class for all attributes
class Decoration : public Castable<Decoration, Node> { class Attribute : public Castable<Attribute, Node> {
public: public:
~Decoration() override; ~Attribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
virtual std::string Name() const = 0; virtual std::string Name() const = 0;
protected: protected:
/// Constructor /// Constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
Decoration(ProgramID pid, const Source& src) : Base(pid, src) {} Attribute(ProgramID pid, const Source& src) : Base(pid, src) {}
}; };
/// A list of decorations /// A list of attributes
using DecorationList = std::vector<const Decoration*>; using AttributeList = std::vector<const Attribute*>;
/// @param decorations the list of decorations to search /// @param attributes the list of attributes to search
/// @returns true if `decorations` includes a decoration of type `T` /// @returns true if `attributes` includes a attribute of type `T`
template <typename T> template <typename T>
bool HasDecoration(const DecorationList& decorations) { bool HasAttribute(const AttributeList& attributes) {
for (auto* deco : decorations) { for (auto* attr : attributes) {
if (deco->Is<T>()) { if (attr->Is<T>()) {
return true; return true;
} }
} }
return false; return false;
} }
/// @param decorations the list of decorations to search /// @param attributes the list of attributes to search
/// @returns a pointer to `T` from `decorations` if found, otherwise nullptr. /// @returns a pointer to `T` from `attributes` if found, otherwise nullptr.
template <typename T> template <typename T>
const T* GetDecoration(const DecorationList& decorations) { const T* GetAttribute(const AttributeList& attributes) {
for (auto* deco : decorations) { for (auto* attr : attributes) {
if (deco->Is<T>()) { if (attr->Is<T>()) {
return deco->As<T>(); return attr->As<T>();
} }
} }
return nullptr; return nullptr;
@ -68,4 +68,4 @@ const T* GetDecoration(const DecorationList& decorations) {
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_DECORATION_H_ #endif // SRC_AST_ATTRIBUTE_H_

View File

@ -12,32 +12,32 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/location_decoration.h" #include "src/ast/binding_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::LocationDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::BindingAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
LocationDecoration::LocationDecoration(ProgramID pid, BindingAttribute::BindingAttribute(ProgramID pid,
const Source& src, const Source& src,
uint32_t val) uint32_t val)
: Base(pid, src), value(val) {} : Base(pid, src), value(val) {}
LocationDecoration::~LocationDecoration() = default; BindingAttribute::~BindingAttribute() = default;
std::string LocationDecoration::Name() const { std::string BindingAttribute::Name() const {
return "location"; return "binding";
} }
const LocationDecoration* LocationDecoration::Clone(CloneContext* ctx) const { const BindingAttribute* BindingAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<LocationDecoration>(src, value); return ctx->dst->create<BindingAttribute>(src, value);
} }
} // namespace ast } // namespace ast

View File

@ -12,34 +12,34 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_BINDING_DECORATION_H_ #ifndef SRC_AST_BINDING_ATTRIBUTE_H_
#define SRC_AST_BINDING_DECORATION_H_ #define SRC_AST_BINDING_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A binding decoration /// A binding attribute
class BindingDecoration : public Castable<BindingDecoration, Decoration> { class BindingAttribute : public Castable<BindingAttribute, Attribute> {
public: public:
/// constructor /// Constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param value the binding value /// @param value the binding value
BindingDecoration(ProgramID pid, const Source& src, uint32_t value); BindingAttribute(ProgramID pid, const Source& src, uint32_t value);
~BindingDecoration() override; ~BindingAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const BindingDecoration* Clone(CloneContext* ctx) const override; const BindingAttribute* Clone(CloneContext* ctx) const override;
/// the binding value /// the binding value
const uint32_t value; const uint32_t value;
@ -48,4 +48,4 @@ class BindingDecoration : public Castable<BindingDecoration, Decoration> {
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_BINDING_DECORATION_H_ #endif // SRC_AST_BINDING_ATTRIBUTE_H_

View File

@ -12,17 +12,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/override_decoration.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using GroupDecorationTest = TestHelper; using BindingAttributeTest = TestHelper;
TEST_F(GroupDecorationTest, Creation) { TEST_F(BindingAttributeTest, Creation) {
auto* d = create<GroupDecoration>(2); auto* d = create<BindingAttribute>(2);
EXPECT_EQ(2u, d->value); EXPECT_EQ(2u, d->value);
} }

View File

@ -12,32 +12,30 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/builtin_decoration.h" #include "src/ast/builtin_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
BuiltinDecoration::BuiltinDecoration(ProgramID pid, BuiltinAttribute::BuiltinAttribute(ProgramID pid, const Source& src, Builtin b)
const Source& src,
Builtin b)
: Base(pid, src), builtin(b) {} : Base(pid, src), builtin(b) {}
BuiltinDecoration::~BuiltinDecoration() = default; BuiltinAttribute::~BuiltinAttribute() = default;
std::string BuiltinDecoration::Name() const { std::string BuiltinAttribute::Name() const {
return "builtin"; return "builtin";
} }
const BuiltinDecoration* BuiltinDecoration::Clone(CloneContext* ctx) const { const BuiltinAttribute* BuiltinAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<BuiltinDecoration>(src, builtin); return ctx->dst->create<BuiltinAttribute>(src, builtin);
} }
} // namespace ast } // namespace ast

View File

@ -12,35 +12,35 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_BUILTIN_DECORATION_H_ #ifndef SRC_AST_BUILTIN_ATTRIBUTE_H_
#define SRC_AST_BUILTIN_DECORATION_H_ #define SRC_AST_BUILTIN_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/attribute.h"
#include "src/ast/builtin.h" #include "src/ast/builtin.h"
#include "src/ast/decoration.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A builtin decoration /// A builtin attribute
class BuiltinDecoration : public Castable<BuiltinDecoration, Decoration> { class BuiltinAttribute : public Castable<BuiltinAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param builtin the builtin value /// @param builtin the builtin value
BuiltinDecoration(ProgramID pid, const Source& src, Builtin builtin); BuiltinAttribute(ProgramID pid, const Source& src, Builtin builtin);
~BuiltinDecoration() override; ~BuiltinAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const BuiltinDecoration* Clone(CloneContext* ctx) const override; const BuiltinAttribute* Clone(CloneContext* ctx) const override;
/// The builtin value /// The builtin value
const Builtin builtin; const Builtin builtin;
@ -49,4 +49,4 @@ class BuiltinDecoration : public Castable<BuiltinDecoration, Decoration> {
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_BUILTIN_DECORATION_H_ #endif // SRC_AST_BUILTIN_ATTRIBUTE_H_

View File

@ -12,17 +12,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/override_decoration.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using BuiltinDecorationTest = TestHelper; using BuiltinAttributeTest = TestHelper;
TEST_F(BuiltinDecorationTest, Creation) { TEST_F(BuiltinAttributeTest, Creation) {
auto* d = create<BuiltinDecoration>(Builtin::kFragDepth); auto* d = create<BuiltinAttribute>(Builtin::kFragDepth);
EXPECT_EQ(Builtin::kFragDepth, d->builtin); EXPECT_EQ(Builtin::kFragDepth, d->builtin);
} }

View File

@ -12,22 +12,22 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/disable_validation_decoration.h" #include "src/ast/disable_validation_attribute.h"
#include "src/clone_context.h" #include "src/clone_context.h"
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::DisableValidationDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::DisableValidationAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
DisableValidationDecoration::DisableValidationDecoration(ProgramID pid, DisableValidationAttribute::DisableValidationAttribute(ProgramID pid,
DisabledValidation val) DisabledValidation val)
: Base(pid), validation(val) {} : Base(pid), validation(val) {}
DisableValidationDecoration::~DisableValidationDecoration() = default; DisableValidationAttribute::~DisableValidationAttribute() = default;
std::string DisableValidationDecoration::InternalName() const { std::string DisableValidationAttribute::InternalName() const {
switch (validation) { switch (validation) {
case DisabledValidation::kFunctionHasNoBody: case DisabledValidation::kFunctionHasNoBody:
return "disable_validation__function_has_no_body"; return "disable_validation__function_has_no_body";
@ -39,7 +39,7 @@ std::string DisableValidationDecoration::InternalName() const {
return "disable_validation__entry_point_parameter"; return "disable_validation__entry_point_parameter";
case DisabledValidation::kIgnoreConstructibleFunctionParameter: case DisabledValidation::kIgnoreConstructibleFunctionParameter:
return "disable_validation__ignore_constructible_function_parameter"; return "disable_validation__ignore_constructible_function_parameter";
case DisabledValidation::kIgnoreStrideDecoration: case DisabledValidation::kIgnoreStrideAttribute:
return "disable_validation__ignore_stride"; return "disable_validation__ignore_stride";
case DisabledValidation::kIgnoreInvalidPointerArgument: case DisabledValidation::kIgnoreInvalidPointerArgument:
return "disable_validation__ignore_invalid_pointer_argument"; return "disable_validation__ignore_invalid_pointer_argument";
@ -47,10 +47,10 @@ std::string DisableValidationDecoration::InternalName() const {
return "<invalid>"; return "<invalid>";
} }
const DisableValidationDecoration* DisableValidationDecoration::Clone( const DisableValidationAttribute* DisableValidationAttribute::Clone(
CloneContext* ctx) const { CloneContext* ctx) const {
return ctx->dst->ASTNodes().Create<DisableValidationDecoration>( return ctx->dst->ASTNodes().Create<DisableValidationAttribute>(ctx->dst->ID(),
ctx->dst->ID(), validation); validation);
} }
} // namespace ast } // namespace ast

View File

@ -12,18 +12,18 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_DISABLE_VALIDATION_DECORATION_H_ #ifndef SRC_AST_DISABLE_VALIDATION_ATTRIBUTE_H_
#define SRC_AST_DISABLE_VALIDATION_DECORATION_H_ #define SRC_AST_DISABLE_VALIDATION_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/internal_decoration.h" #include "src/ast/internal_attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// Enumerator of validation features that can be disabled with a /// Enumerator of validation features that can be disabled with a
/// DisableValidationDecoration decoration. /// DisableValidationAttribute attribute.
enum class DisabledValidation { enum class DisabledValidation {
/// When applied to a function, the validator will not complain there is no /// When applied to a function, the validator will not complain there is no
/// body to a function. /// body to a function.
@ -35,49 +35,49 @@ enum class DisabledValidation {
/// declared storage class. /// declared storage class.
kIgnoreStorageClass, kIgnoreStorageClass,
/// When applied to an entry-point function parameter, the validator will not /// When applied to an entry-point function parameter, the validator will not
/// check for entry IO decorations. /// check for entry IO attributes.
kEntryPointParameter, kEntryPointParameter,
/// When applied to a function parameter, the validator will not /// When applied to a function parameter, the validator will not
/// check if parameter type is constructible /// check if parameter type is constructible
kIgnoreConstructibleFunctionParameter, kIgnoreConstructibleFunctionParameter,
/// When applied to a member decoration, a stride decoration may be applied to /// When applied to a member attribute, a stride attribute may be applied to
/// non-array types. /// non-array types.
kIgnoreStrideDecoration, kIgnoreStrideAttribute,
/// When applied to a pointer function parameter, the validator will not /// When applied to a pointer function parameter, the validator will not
/// require a function call argument passed for that parameter to have a /// require a function call argument passed for that parameter to have a
/// certain form. /// certain form.
kIgnoreInvalidPointerArgument, kIgnoreInvalidPointerArgument,
}; };
/// An internal decoration used to tell the validator to ignore specific /// An internal attribute used to tell the validator to ignore specific
/// violations. Typically generated by transforms that need to produce ASTs that /// violations. Typically generated by transforms that need to produce ASTs that
/// would otherwise cause validation errors. /// would otherwise cause validation errors.
class DisableValidationDecoration class DisableValidationAttribute
: public Castable<DisableValidationDecoration, InternalDecoration> { : public Castable<DisableValidationAttribute, InternalAttribute> {
public: public:
/// Constructor /// Constructor
/// @param program_id the identifier of the program that owns this node /// @param program_id the identifier of the program that owns this node
/// @param validation the validation to disable /// @param validation the validation to disable
explicit DisableValidationDecoration(ProgramID program_id, explicit DisableValidationAttribute(ProgramID program_id,
DisabledValidation validation); DisabledValidation validation);
/// Destructor /// Destructor
~DisableValidationDecoration() override; ~DisableValidationAttribute() override;
/// @return a short description of the internal decoration which will be /// @return a short description of the internal attribute which will be
/// displayed in WGSL as `@internal(<name>)` (but is not parsable). /// displayed in WGSL as `@internal(<name>)` (but is not parsable).
std::string InternalName() const override; std::string InternalName() const override;
/// Performs a deep clone of this object using the CloneContext `ctx`. /// Performs a deep clone of this object using the CloneContext `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned object /// @return the newly cloned object
const DisableValidationDecoration* Clone(CloneContext* ctx) const override; const DisableValidationAttribute* Clone(CloneContext* ctx) const override;
/// The validation that this decoration disables /// The validation that this attribute disables
const DisabledValidation validation; const DisabledValidation validation;
}; };
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_DISABLE_VALIDATION_DECORATION_H_ #endif // SRC_AST_DISABLE_VALIDATION_ATTRIBUTE_H_

View File

@ -14,8 +14,8 @@
#include "src/ast/function.h" #include "src/ast/function.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Function); TINT_INSTANTIATE_TYPEINFO(tint::ast::Function);
@ -29,15 +29,15 @@ Function::Function(ProgramID pid,
VariableList parameters, VariableList parameters,
const Type* return_ty, const Type* return_ty,
const BlockStatement* b, const BlockStatement* b,
DecorationList decos, AttributeList attrs,
DecorationList return_type_decos) AttributeList return_type_attrs)
: Base(pid, src), : Base(pid, src),
symbol(sym), symbol(sym),
params(std::move(parameters)), params(std::move(parameters)),
return_type(return_ty), return_type(return_ty),
body(b), body(b),
decorations(std::move(decos)), attributes(std::move(attrs)),
return_type_decorations(std::move(return_type_decos)) { return_type_attributes(std::move(return_type_attrs)) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
for (auto* param : params) { for (auto* param : params) {
@ -46,11 +46,11 @@ Function::Function(ProgramID pid,
} }
TINT_ASSERT(AST, symbol.IsValid()); TINT_ASSERT(AST, symbol.IsValid());
TINT_ASSERT(AST, return_type); TINT_ASSERT(AST, return_type);
for (auto* deco : decorations) { for (auto* attr : attributes) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
} }
for (auto* deco : return_type_decorations) { for (auto* attr : return_type_attributes) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
} }
} }
@ -59,7 +59,7 @@ Function::Function(Function&&) = default;
Function::~Function() = default; Function::~Function() = default;
PipelineStage Function::PipelineStage() const { PipelineStage Function::PipelineStage() const {
if (auto* stage = GetDecoration<StageDecoration>(decorations)) { if (auto* stage = GetAttribute<StageAttribute>(attributes)) {
return stage->stage; return stage->stage;
} }
return PipelineStage::kNone; return PipelineStage::kNone;
@ -72,9 +72,9 @@ const Function* Function::Clone(CloneContext* ctx) const {
auto p = ctx->Clone(params); auto p = ctx->Clone(params);
auto* ret = ctx->Clone(return_type); auto* ret = ctx->Clone(return_type);
auto* b = ctx->Clone(body); auto* b = ctx->Clone(body);
auto decos = ctx->Clone(decorations); auto attrs = ctx->Clone(attributes);
auto ret_decos = ctx->Clone(return_type_decorations); auto ret_attrs = ctx->Clone(return_type_attributes);
return ctx->dst->create<Function>(src, sym, p, ret, b, decos, ret_decos); return ctx->dst->create<Function>(src, sym, p, ret, b, attrs, ret_attrs);
} }
const Function* FunctionList::Find(Symbol sym) const { const Function* FunctionList::Find(Symbol sym) const {

View File

@ -20,12 +20,12 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "src/ast/binding_decoration.h" #include "src/ast/attribute.h"
#include "src/ast/binding_attribute.h"
#include "src/ast/block_statement.h" #include "src/ast/block_statement.h"
#include "src/ast/builtin_decoration.h" #include "src/ast/builtin_attribute.h"
#include "src/ast/decoration.h" #include "src/ast/group_attribute.h"
#include "src/ast/group_decoration.h" #include "src/ast/location_attribute.h"
#include "src/ast/location_decoration.h"
#include "src/ast/pipeline_stage.h" #include "src/ast/pipeline_stage.h"
#include "src/ast/variable.h" #include "src/ast/variable.h"
@ -42,16 +42,16 @@ class Function : public Castable<Function, Node> {
/// @param params the function parameters /// @param params the function parameters
/// @param return_type the return type /// @param return_type the return type
/// @param body the function body /// @param body the function body
/// @param decorations the function decorations /// @param attributes the function attributes
/// @param return_type_decorations the return type decorations /// @param return_type_attributes the return type attributes
Function(ProgramID program_id, Function(ProgramID program_id,
const Source& source, const Source& source,
Symbol symbol, Symbol symbol,
VariableList params, VariableList params,
const Type* return_type, const Type* return_type,
const BlockStatement* body, const BlockStatement* body,
DecorationList decorations, AttributeList attributes,
DecorationList return_type_decorations); AttributeList return_type_attributes);
/// Move constructor /// Move constructor
Function(Function&&); Function(Function&&);
@ -81,11 +81,11 @@ class Function : public Castable<Function, Node> {
/// The function body /// The function body
const BlockStatement* const body; const BlockStatement* const body;
/// The decorations attached to this function /// The attributes attached to this function
const DecorationList decorations; const AttributeList attributes;
/// The decorations attached to the function return type. /// The attributes attached to the function return type.
const DecorationList return_type_decorations; const AttributeList return_type_attributes;
}; };
/// A list of functions /// A list of functions

View File

@ -14,9 +14,9 @@
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
#include "src/ast/discard_statement.h" #include "src/ast/discard_statement.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -29,7 +29,7 @@ TEST_F(FunctionTest, Creation) {
params.push_back(Param("var", ty.i32())); params.push_back(Param("var", ty.i32()));
auto* var = params[0]; auto* var = params[0];
auto* f = Func("func", params, ty.void_(), StatementList{}, DecorationList{}); auto* f = Func("func", params, ty.void_(), StatementList{}, AttributeList{});
EXPECT_EQ(f->symbol, Symbols().Get("func")); EXPECT_EQ(f->symbol, Symbols().Get("func"));
ASSERT_EQ(f->params.size(), 1u); ASSERT_EQ(f->params.size(), 1u);
EXPECT_TRUE(f->return_type->Is<ast::Void>()); EXPECT_TRUE(f->return_type->Is<ast::Void>());
@ -41,7 +41,7 @@ TEST_F(FunctionTest, Creation_WithSource) {
params.push_back(Param("var", ty.i32())); params.push_back(Param("var", ty.i32()));
auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(), auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(),
StatementList{}, DecorationList{}); StatementList{}, AttributeList{});
auto src = f->source; auto src = f->source;
EXPECT_EQ(src.range.begin.line, 20u); EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u); EXPECT_EQ(src.range.begin.column, 2u);
@ -52,7 +52,7 @@ TEST_F(FunctionTest, Assert_InvalidName) {
{ {
ProgramBuilder b; ProgramBuilder b;
b.Func("", VariableList{}, b.ty.void_(), StatementList{}, b.Func("", VariableList{}, b.ty.void_(), StatementList{},
DecorationList{}); AttributeList{});
}, },
"internal compiler error"); "internal compiler error");
} }
@ -61,7 +61,7 @@ TEST_F(FunctionTest, Assert_Null_ReturnType) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
ProgramBuilder b; ProgramBuilder b;
b.Func("f", VariableList{}, nullptr, StatementList{}, DecorationList{}); b.Func("f", VariableList{}, nullptr, StatementList{}, AttributeList{});
}, },
"internal compiler error"); "internal compiler error");
} }
@ -74,7 +74,7 @@ TEST_F(FunctionTest, Assert_Null_Param) {
params.push_back(b.Param("var", b.ty.i32())); params.push_back(b.Param("var", b.ty.i32()));
params.push_back(nullptr); params.push_back(nullptr);
b.Func("f", params, b.ty.void_(), StatementList{}, DecorationList{}); b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
}, },
"internal compiler error"); "internal compiler error");
} }
@ -100,27 +100,27 @@ TEST_F(FunctionTest, Assert_DifferentProgramID_Param) {
"internal compiler error"); "internal compiler error");
} }
TEST_F(FunctionTest, Assert_DifferentProgramID_Deco) { TEST_F(FunctionTest, Assert_DifferentProgramID_Attr) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
ProgramBuilder b1; ProgramBuilder b1;
ProgramBuilder b2; ProgramBuilder b2;
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{}, b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
DecorationList{ AttributeList{
b2.WorkgroupSize(2, 4, 6), b2.WorkgroupSize(2, 4, 6),
}); });
}, },
"internal compiler error"); "internal compiler error");
} }
TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnDeco) { TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnAttr) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
ProgramBuilder b1; ProgramBuilder b1;
ProgramBuilder b2; ProgramBuilder b2;
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{}, b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
DecorationList{}, AttributeList{},
DecorationList{ AttributeList{
b2.WorkgroupSize(2, 4, 6), b2.WorkgroupSize(2, 4, 6),
}); });
}, },
@ -134,7 +134,7 @@ TEST_F(FunctionTest, Assert_NonConstParam) {
VariableList params; VariableList params;
params.push_back(b.Var("var", b.ty.i32(), ast::StorageClass::kNone)); params.push_back(b.Var("var", b.ty.i32(), ast::StorageClass::kNone));
b.Func("f", params, b.ty.void_(), StatementList{}, DecorationList{}); b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
}, },
"internal compiler error"); "internal compiler error");
} }
@ -143,7 +143,7 @@ using FunctionListTest = TestHelper;
TEST_F(FunctionListTest, FindSymbol) { TEST_F(FunctionListTest, FindSymbol) {
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{}, auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
ast::DecorationList{}); ast::AttributeList{});
FunctionList list; FunctionList list;
list.Add(func); list.Add(func);
EXPECT_EQ(func, list.Find(Symbols().Register("main"))); EXPECT_EQ(func, list.Find(Symbols().Register("main")));
@ -156,11 +156,11 @@ TEST_F(FunctionListTest, FindSymbolMissing) {
TEST_F(FunctionListTest, FindSymbolStage) { TEST_F(FunctionListTest, FindSymbolStage) {
auto* fs = Func("main", VariableList{}, ty.f32(), StatementList{}, auto* fs = Func("main", VariableList{}, ty.f32(), StatementList{},
ast::DecorationList{ ast::AttributeList{
Stage(PipelineStage::kFragment), Stage(PipelineStage::kFragment),
}); });
auto* vs = Func("main", VariableList{}, ty.f32(), StatementList{}, auto* vs = Func("main", VariableList{}, ty.f32(), StatementList{},
ast::DecorationList{ ast::AttributeList{
Stage(PipelineStage::kVertex), Stage(PipelineStage::kVertex),
}); });
FunctionList list; FunctionList list;
@ -174,7 +174,7 @@ TEST_F(FunctionListTest, FindSymbolStage) {
TEST_F(FunctionListTest, FindSymbolStageMissing) { TEST_F(FunctionListTest, FindSymbolStageMissing) {
FunctionList list; FunctionList list;
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{}, list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
ast::DecorationList{ ast::AttributeList{
Stage(PipelineStage::kFragment), Stage(PipelineStage::kFragment),
})); }));
EXPECT_EQ(nullptr, EXPECT_EQ(nullptr,
@ -184,7 +184,7 @@ TEST_F(FunctionListTest, FindSymbolStageMissing) {
TEST_F(FunctionListTest, HasStage) { TEST_F(FunctionListTest, HasStage) {
FunctionList list; FunctionList list;
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{}, list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
ast::DecorationList{ ast::AttributeList{
Stage(PipelineStage::kFragment), Stage(PipelineStage::kFragment),
})); }));
EXPECT_TRUE(list.HasStage(PipelineStage::kFragment)); EXPECT_TRUE(list.HasStage(PipelineStage::kFragment));

View File

@ -12,30 +12,30 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/group_decoration.h" #include "src/ast/group_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::GroupDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::GroupAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
GroupDecoration::GroupDecoration(ProgramID pid, const Source& src, uint32_t val) GroupAttribute::GroupAttribute(ProgramID pid, const Source& src, uint32_t val)
: Base(pid, src), value(val) {} : Base(pid, src), value(val) {}
GroupDecoration::~GroupDecoration() = default; GroupAttribute::~GroupAttribute() = default;
std::string GroupDecoration::Name() const { std::string GroupAttribute::Name() const {
return "group"; return "group";
} }
const GroupDecoration* GroupDecoration::Clone(CloneContext* ctx) const { const GroupAttribute* GroupAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<GroupDecoration>(src, value); return ctx->dst->create<GroupAttribute>(src, value);
} }
} // namespace ast } // namespace ast

View File

@ -12,34 +12,34 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_GROUP_DECORATION_H_ #ifndef SRC_AST_GROUP_ATTRIBUTE_H_
#define SRC_AST_GROUP_DECORATION_H_ #define SRC_AST_GROUP_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A group decoration /// A group attribute
class GroupDecoration : public Castable<GroupDecoration, Decoration> { class GroupAttribute : public Castable<GroupAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param value the group value /// @param value the group value
GroupDecoration(ProgramID pid, const Source& src, uint32_t value); GroupAttribute(ProgramID pid, const Source& src, uint32_t value);
~GroupDecoration() override; ~GroupAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const GroupDecoration* Clone(CloneContext* ctx) const override; const GroupAttribute* Clone(CloneContext* ctx) const override;
/// The group value /// The group value
const uint32_t value; const uint32_t value;
@ -48,4 +48,4 @@ class GroupDecoration : public Castable<GroupDecoration, Decoration> {
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_GROUP_DECORATION_H_ #endif // SRC_AST_GROUP_ATTRIBUTE_H_

View File

@ -12,17 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using BindingDecorationTest = TestHelper; using GroupAttributeTest = TestHelper;
TEST_F(BindingDecorationTest, Creation) { TEST_F(GroupAttributeTest, Creation) {
auto* d = create<BindingDecoration>(2); auto* d = create<GroupAttribute>(2);
EXPECT_EQ(2u, d->value); EXPECT_EQ(2u, d->value);
} }

View File

@ -12,18 +12,18 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/internal_decoration.h" #include "src/ast/internal_attribute.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::InternalDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::InternalAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
InternalDecoration::InternalDecoration(ProgramID pid) : Base(pid, Source{}) {} InternalAttribute::InternalAttribute(ProgramID pid) : Base(pid, Source{}) {}
InternalDecoration::~InternalDecoration() = default; InternalAttribute::~InternalAttribute() = default;
std::string InternalDecoration::Name() const { std::string InternalAttribute::Name() const {
return "internal"; return "internal";
} }

View File

@ -12,37 +12,37 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_INTERNAL_DECORATION_H_ #ifndef SRC_AST_INTERNAL_ATTRIBUTE_H_
#define SRC_AST_INTERNAL_DECORATION_H_ #define SRC_AST_INTERNAL_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A decoration used to indicate that a function is tint-internal. /// An attribute used to indicate that a function is tint-internal.
/// These decorations are not produced by generators, but instead are usually /// These attributes are not produced by generators, but instead are usually
/// created by transforms for consumption by a particular backend. /// created by transforms for consumption by a particular backend.
class InternalDecoration : public Castable<InternalDecoration, Decoration> { class InternalAttribute : public Castable<InternalAttribute, Attribute> {
public: public:
/// Constructor /// Constructor
/// @param program_id the identifier of the program that owns this node /// @param program_id the identifier of the program that owns this node
explicit InternalDecoration(ProgramID program_id); explicit InternalAttribute(ProgramID program_id);
/// Destructor /// Destructor
~InternalDecoration() override; ~InternalAttribute() override;
/// @return a short description of the internal decoration which will be /// @return a short description of the internal attribute which will be
/// displayed in WGSL as `@internal(<name>)` (but is not parsable). /// displayed in WGSL as `@internal(<name>)` (but is not parsable).
virtual std::string InternalName() const = 0; virtual std::string InternalName() const = 0;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
}; };
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_INTERNAL_DECORATION_H_ #endif // SRC_AST_INTERNAL_ATTRIBUTE_H_

View File

@ -12,34 +12,34 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/interpolate_decoration.h" #include "src/ast/interpolate_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::InterpolateDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::InterpolateAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
InterpolateDecoration::InterpolateDecoration(ProgramID pid, InterpolateAttribute::InterpolateAttribute(ProgramID pid,
const Source& src, const Source& src,
InterpolationType ty, InterpolationType ty,
InterpolationSampling smpl) InterpolationSampling smpl)
: Base(pid, src), type(ty), sampling(smpl) {} : Base(pid, src), type(ty), sampling(smpl) {}
InterpolateDecoration::~InterpolateDecoration() = default; InterpolateAttribute::~InterpolateAttribute() = default;
std::string InterpolateDecoration::Name() const { std::string InterpolateAttribute::Name() const {
return "interpolate"; return "interpolate";
} }
const InterpolateDecoration* InterpolateDecoration::Clone( const InterpolateAttribute* InterpolateAttribute::Clone(
CloneContext* ctx) const { CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<InterpolateDecoration>(src, type, sampling); return ctx->dst->create<InterpolateAttribute>(src, type, sampling);
} }
std::ostream& operator<<(std::ostream& out, InterpolationType type) { std::ostream& operator<<(std::ostream& out, InterpolationType type) {

View File

@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_INTERPOLATE_DECORATION_H_ #ifndef SRC_AST_INTERPOLATE_ATTRIBUTE_H_
#define SRC_AST_INTERPOLATE_DECORATION_H_ #define SRC_AST_INTERPOLATE_ATTRIBUTE_H_
#include <ostream> #include <ostream>
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -29,29 +29,28 @@ enum class InterpolationType { kPerspective, kLinear, kFlat };
/// The interpolation sampling. /// The interpolation sampling.
enum class InterpolationSampling { kNone = -1, kCenter, kCentroid, kSample }; enum class InterpolationSampling { kNone = -1, kCenter, kCentroid, kSample };
/// An interpolate decoration /// An interpolate attribute
class InterpolateDecoration class InterpolateAttribute : public Castable<InterpolateAttribute, Attribute> {
: public Castable<InterpolateDecoration, Decoration> {
public: public:
/// Create an interpolate decoration. /// Create an interpolate attribute.
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param type the interpolation type /// @param type the interpolation type
/// @param sampling the interpolation sampling /// @param sampling the interpolation sampling
InterpolateDecoration(ProgramID pid, InterpolateAttribute(ProgramID pid,
const Source& src, const Source& src,
InterpolationType type, InterpolationType type,
InterpolationSampling sampling); InterpolationSampling sampling);
~InterpolateDecoration() override; ~InterpolateAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const InterpolateDecoration* Clone(CloneContext* ctx) const override; const InterpolateAttribute* Clone(CloneContext* ctx) const override;
/// The interpolation type /// The interpolation type
const InterpolationType type; const InterpolationType type;
@ -73,4 +72,4 @@ std::ostream& operator<<(std::ostream& out, InterpolationSampling sampling);
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_INTERPOLATE_DECORATION_H_ #endif // SRC_AST_INTERPOLATE_ATTRIBUTE_H_

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/interpolate_decoration.h" #include "src/ast/interpolate_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
@ -20,11 +20,11 @@ namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using InterpolateDecorationTest = TestHelper; using InterpolateAttributeTest = TestHelper;
TEST_F(InterpolateDecorationTest, Creation) { TEST_F(InterpolateAttributeTest, Creation) {
auto* d = create<InterpolateDecoration>(InterpolationType::kLinear, auto* d = create<InterpolateAttribute>(InterpolationType::kLinear,
InterpolationSampling::kCenter); InterpolationSampling::kCenter);
EXPECT_EQ(InterpolationType::kLinear, d->type); EXPECT_EQ(InterpolationType::kLinear, d->type);
EXPECT_EQ(InterpolationSampling::kCenter, d->sampling); EXPECT_EQ(InterpolationSampling::kCenter, d->sampling);
} }

View File

@ -151,36 +151,36 @@ const ast::Type* TextureOverloadCase::BuildResultVectorComponentType(
const ast::Variable* TextureOverloadCase::BuildTextureVariable( const ast::Variable* TextureOverloadCase::BuildTextureVariable(
ProgramBuilder* b) const { ProgramBuilder* b) const {
DecorationList decos = { AttributeList attrs = {
b->create<ast::GroupDecoration>(0), b->create<ast::GroupAttribute>(0),
b->create<ast::BindingDecoration>(0), b->create<ast::BindingAttribute>(0),
}; };
switch (texture_kind) { switch (texture_kind) {
case ast::intrinsic::test::TextureKind::kRegular: case ast::intrinsic::test::TextureKind::kRegular:
return b->Global("texture", return b->Global("texture",
b->ty.sampled_texture(texture_dimension, b->ty.sampled_texture(texture_dimension,
BuildResultVectorComponentType(b)), BuildResultVectorComponentType(b)),
decos); attrs);
case ast::intrinsic::test::TextureKind::kDepth: case ast::intrinsic::test::TextureKind::kDepth:
return b->Global("texture", b->ty.depth_texture(texture_dimension), return b->Global("texture", b->ty.depth_texture(texture_dimension),
decos); attrs);
case ast::intrinsic::test::TextureKind::kDepthMultisampled: case ast::intrinsic::test::TextureKind::kDepthMultisampled:
return b->Global("texture", return b->Global("texture",
b->ty.depth_multisampled_texture(texture_dimension), b->ty.depth_multisampled_texture(texture_dimension),
decos); attrs);
case ast::intrinsic::test::TextureKind::kMultisampled: case ast::intrinsic::test::TextureKind::kMultisampled:
return b->Global( return b->Global(
"texture", "texture",
b->ty.multisampled_texture(texture_dimension, b->ty.multisampled_texture(texture_dimension,
BuildResultVectorComponentType(b)), BuildResultVectorComponentType(b)),
decos); attrs);
case ast::intrinsic::test::TextureKind::kStorage: { case ast::intrinsic::test::TextureKind::kStorage: {
auto* st = b->ty.storage_texture(texture_dimension, texel_format, access); auto* st = b->ty.storage_texture(texture_dimension, texel_format, access);
return b->Global("texture", st, decos); return b->Global("texture", st, attrs);
} }
} }
@ -190,11 +190,11 @@ const ast::Variable* TextureOverloadCase::BuildTextureVariable(
const ast::Variable* TextureOverloadCase::BuildSamplerVariable( const ast::Variable* TextureOverloadCase::BuildSamplerVariable(
ProgramBuilder* b) const { ProgramBuilder* b) const {
DecorationList decos = { AttributeList attrs = {
b->create<ast::GroupDecoration>(0), b->create<ast::GroupAttribute>(0),
b->create<ast::BindingDecoration>(1), b->create<ast::BindingAttribute>(1),
}; };
return b->Global("sampler", b->ty.sampler(sampler_kind), decos); return b->Global("sampler", b->ty.sampler(sampler_kind), attrs);
} }
std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() { std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {

View File

@ -12,28 +12,28 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/invariant_decoration.h" #include "src/ast/invariant_attribute.h"
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::InvariantDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::InvariantAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
InvariantDecoration::InvariantDecoration(ProgramID pid, const Source& src) InvariantAttribute::InvariantAttribute(ProgramID pid, const Source& src)
: Base(pid, src) {} : Base(pid, src) {}
InvariantDecoration::~InvariantDecoration() = default; InvariantAttribute::~InvariantAttribute() = default;
std::string InvariantDecoration::Name() const { std::string InvariantAttribute::Name() const {
return "invariant"; return "invariant";
} }
const InvariantDecoration* InvariantDecoration::Clone(CloneContext* ctx) const { const InvariantAttribute* InvariantAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<InvariantDecoration>(src); return ctx->dst->create<InvariantAttribute>(src);
} }
} // namespace ast } // namespace ast

View File

@ -12,36 +12,36 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_INVARIANT_DECORATION_H_ #ifndef SRC_AST_INVARIANT_ATTRIBUTE_H_
#define SRC_AST_INVARIANT_DECORATION_H_ #define SRC_AST_INVARIANT_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// The invariant attribute /// The invariant attribute
class InvariantDecoration : public Castable<InvariantDecoration, Decoration> { class InvariantAttribute : public Castable<InvariantAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
InvariantDecoration(ProgramID pid, const Source& src); InvariantAttribute(ProgramID pid, const Source& src);
~InvariantDecoration() override; ~InvariantAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const InvariantDecoration* Clone(CloneContext* ctx) const override; const InvariantAttribute* Clone(CloneContext* ctx) const override;
}; };
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_INVARIANT_DECORATION_H_ #endif // SRC_AST_INVARIANT_ATTRIBUTE_H_

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/invariant_decoration.h" #include "src/ast/invariant_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
@ -20,7 +20,7 @@ namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using InvariantDecorationTest = TestHelper; using InvariantAttributeTest = TestHelper;
} // namespace } // namespace
} // namespace ast } // namespace ast

View File

@ -12,32 +12,32 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/binding_decoration.h" #include "src/ast/location_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::BindingDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::LocationAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
BindingDecoration::BindingDecoration(ProgramID pid, LocationAttribute::LocationAttribute(ProgramID pid,
const Source& src, const Source& src,
uint32_t val) uint32_t val)
: Base(pid, src), value(val) {} : Base(pid, src), value(val) {}
BindingDecoration::~BindingDecoration() = default; LocationAttribute::~LocationAttribute() = default;
std::string BindingDecoration::Name() const { std::string LocationAttribute::Name() const {
return "binding"; return "location";
} }
const BindingDecoration* BindingDecoration::Clone(CloneContext* ctx) const { const LocationAttribute* LocationAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<BindingDecoration>(src, value); return ctx->dst->create<LocationAttribute>(src, value);
} }
} // namespace ast } // namespace ast

View File

@ -12,34 +12,34 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_LOCATION_DECORATION_H_ #ifndef SRC_AST_LOCATION_ATTRIBUTE_H_
#define SRC_AST_LOCATION_DECORATION_H_ #define SRC_AST_LOCATION_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A location decoration /// A location attribute
class LocationDecoration : public Castable<LocationDecoration, Decoration> { class LocationAttribute : public Castable<LocationAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param value the location value /// @param value the location value
LocationDecoration(ProgramID pid, const Source& src, uint32_t value); LocationAttribute(ProgramID pid, const Source& src, uint32_t value);
~LocationDecoration() override; ~LocationAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const LocationDecoration* Clone(CloneContext* ctx) const override; const LocationAttribute* Clone(CloneContext* ctx) const override;
/// The location value /// The location value
const uint32_t value; const uint32_t value;
@ -48,4 +48,4 @@ class LocationDecoration : public Castable<LocationDecoration, Decoration> {
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_LOCATION_DECORATION_H_ #endif // SRC_AST_LOCATION_ATTRIBUTE_H_

View File

@ -12,17 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using LocationDecorationTest = TestHelper; using LocationAttributeTest = TestHelper;
TEST_F(LocationDecorationTest, Creation) { TEST_F(LocationAttributeTest, Creation) {
auto* d = create<LocationDecoration>(2); auto* d = create<LocationAttribute>(2);
EXPECT_EQ(2u, d->value); EXPECT_EQ(2u, d->value);
} }

View File

@ -28,7 +28,7 @@ TEST_F(ModuleTest, Creation) {
TEST_F(ModuleTest, LookupFunction) { TEST_F(ModuleTest, LookupFunction) {
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{}, auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
ast::DecorationList{}); ast::AttributeList{});
Program program(std::move(*this)); Program program(std::move(*this));
EXPECT_EQ(func, EXPECT_EQ(func,
@ -66,7 +66,7 @@ TEST_F(ModuleTest, Assert_DifferentProgramID_Function) {
ProgramBuilder b2; ProgramBuilder b2;
b1.AST().AddFunction(b2.create<ast::Function>( b1.AST().AddFunction(b2.create<ast::Function>(
b2.Symbols().Register("func"), VariableList{}, b2.ty.f32(), b2.Symbols().Register("func"), VariableList{}, b2.ty.f32(),
b2.Block(), DecorationList{}, DecorationList{})); b2.Block(), AttributeList{}, AttributeList{}));
}, },
"internal compiler error"); "internal compiler error");
} }

View File

@ -12,38 +12,38 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::OverrideDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::OverrideAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
OverrideDecoration::OverrideDecoration(ProgramID pid, const Source& src) OverrideAttribute::OverrideAttribute(ProgramID pid, const Source& src)
: Base(pid, src), has_value(false), value(0) {} : Base(pid, src), has_value(false), value(0) {}
OverrideDecoration::OverrideDecoration(ProgramID pid, OverrideAttribute::OverrideAttribute(ProgramID pid,
const Source& src, const Source& src,
uint32_t val) uint32_t val)
: Base(pid, src), has_value(true), value(val) {} : Base(pid, src), has_value(true), value(val) {}
OverrideDecoration::~OverrideDecoration() = default; OverrideAttribute::~OverrideAttribute() = default;
std::string OverrideDecoration::Name() const { std::string OverrideAttribute::Name() const {
return "override"; return "override";
} }
const OverrideDecoration* OverrideDecoration::Clone(CloneContext* ctx) const { const OverrideAttribute* OverrideAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
if (has_value) { if (has_value) {
return ctx->dst->create<OverrideDecoration>(src, value); return ctx->dst->create<OverrideAttribute>(src, value);
} else { } else {
return ctx->dst->create<OverrideDecoration>(src); return ctx->dst->create<OverrideAttribute>(src);
} }
} }

View File

@ -12,38 +12,38 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_OVERRIDE_DECORATION_H_ #ifndef SRC_AST_OVERRIDE_ATTRIBUTE_H_
#define SRC_AST_OVERRIDE_DECORATION_H_ #define SRC_AST_OVERRIDE_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// An override decoration /// An override attribute
class OverrideDecoration : public Castable<OverrideDecoration, Decoration> { class OverrideAttribute : public Castable<OverrideAttribute, Attribute> {
public: public:
/// Create an override decoration with no specified id. /// Create an override attribute with no specified id.
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
OverrideDecoration(ProgramID pid, const Source& src); OverrideAttribute(ProgramID pid, const Source& src);
/// Create an override decoration with a specific id value. /// Create an override attribute with a specific id value.
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param val the override value /// @param val the override value
OverrideDecoration(ProgramID pid, const Source& src, uint32_t val); OverrideAttribute(ProgramID pid, const Source& src, uint32_t val);
~OverrideDecoration() override; ~OverrideAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const OverrideDecoration* Clone(CloneContext* ctx) const override; const OverrideAttribute* Clone(CloneContext* ctx) const override;
/// True if an override id was specified /// True if an override id was specified
const bool has_value; const bool has_value;
@ -55,4 +55,4 @@ class OverrideDecoration : public Castable<OverrideDecoration, Decoration> {
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_OVERRIDE_DECORATION_H_ #endif // SRC_AST_OVERRIDE_ATTRIBUTE_H_

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
@ -20,16 +20,16 @@ namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using OverrideDecorationTest = TestHelper; using OverrideAttributeTest = TestHelper;
TEST_F(OverrideDecorationTest, Creation_WithValue) { TEST_F(OverrideAttributeTest, Creation_WithValue) {
auto* d = create<OverrideDecoration>(12); auto* d = create<OverrideAttribute>(12);
EXPECT_TRUE(d->has_value); EXPECT_TRUE(d->has_value);
EXPECT_EQ(12u, d->value); EXPECT_EQ(12u, d->value);
} }
TEST_F(OverrideDecorationTest, Creation_WithoutValue) { TEST_F(OverrideAttributeTest, Creation_WithoutValue) {
auto* d = create<OverrideDecoration>(); auto* d = create<OverrideAttribute>();
EXPECT_FALSE(d->has_value); EXPECT_FALSE(d->has_value);
} }

View File

@ -12,32 +12,32 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StageDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::StageAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
StageDecoration::StageDecoration(ProgramID pid, StageAttribute::StageAttribute(ProgramID pid,
const Source& src, const Source& src,
PipelineStage s) PipelineStage s)
: Base(pid, src), stage(s) {} : Base(pid, src), stage(s) {}
StageDecoration::~StageDecoration() = default; StageAttribute::~StageAttribute() = default;
std::string StageDecoration::Name() const { std::string StageAttribute::Name() const {
return "stage"; return "stage";
} }
const StageDecoration* StageDecoration::Clone(CloneContext* ctx) const { const StageAttribute* StageAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<StageDecoration>(src, stage); return ctx->dst->create<StageAttribute>(src, stage);
} }
} // namespace ast } // namespace ast

View File

@ -12,37 +12,37 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_STAGE_DECORATION_H_ #ifndef SRC_AST_STAGE_ATTRIBUTE_H_
#define SRC_AST_STAGE_DECORATION_H_ #define SRC_AST_STAGE_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
#include "src/ast/pipeline_stage.h" #include "src/ast/pipeline_stage.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A workgroup decoration /// A workgroup attribute
class StageDecoration : public Castable<StageDecoration, Decoration> { class StageAttribute : public Castable<StageAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param program_id the identifier of the program that owns this node /// @param program_id the identifier of the program that owns this node
/// @param stage the pipeline stage /// @param stage the pipeline stage
/// @param source the source of this decoration /// @param source the source of this attribute
StageDecoration(ProgramID program_id, StageAttribute(ProgramID program_id,
const Source& source, const Source& source,
PipelineStage stage); PipelineStage stage);
~StageDecoration() override; ~StageAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const StageDecoration* Clone(CloneContext* ctx) const override; const StageAttribute* Clone(CloneContext* ctx) const override;
/// The pipeline stage /// The pipeline stage
const PipelineStage stage; const PipelineStage stage;
@ -51,4 +51,4 @@ class StageDecoration : public Castable<StageDecoration, Decoration> {
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_STAGE_DECORATION_H_ #endif // SRC_AST_STAGE_ATTRIBUTE_H_

View File

@ -12,19 +12,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using StageDecorationTest = TestHelper; using StageAttributeTest = TestHelper;
TEST_F(StageDecorationTest, Creation_1param) { TEST_F(StageAttributeTest, Creation_1param) {
auto* d = create<StageDecoration>(PipelineStage::kFragment); auto* d = create<StageAttribute>(PipelineStage::kFragment);
EXPECT_EQ(d->stage, PipelineStage::kFragment); EXPECT_EQ(d->stage, PipelineStage::kFragment);
} }

View File

@ -12,30 +12,30 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/stride_decoration.h" #include "src/ast/stride_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StrideDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::StrideAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
StrideDecoration::StrideDecoration(ProgramID pid, const Source& src, uint32_t s) StrideAttribute::StrideAttribute(ProgramID pid, const Source& src, uint32_t s)
: Base(pid, src), stride(s) {} : Base(pid, src), stride(s) {}
StrideDecoration::~StrideDecoration() = default; StrideAttribute::~StrideAttribute() = default;
std::string StrideDecoration::Name() const { std::string StrideAttribute::Name() const {
return "stride"; return "stride";
} }
const StrideDecoration* StrideDecoration::Clone(CloneContext* ctx) const { const StrideAttribute* StrideAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<StrideDecoration>(src, stride); return ctx->dst->create<StrideAttribute>(src, stride);
} }
} // namespace ast } // namespace ast

View File

@ -12,34 +12,34 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_STRIDE_DECORATION_H_ #ifndef SRC_AST_STRIDE_ATTRIBUTE_H_
#define SRC_AST_STRIDE_DECORATION_H_ #define SRC_AST_STRIDE_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A stride decoration /// A stride attribute
class StrideDecoration : public Castable<StrideDecoration, Decoration> { class StrideAttribute : public Castable<StrideAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param stride the stride value /// @param stride the stride value
StrideDecoration(ProgramID pid, const Source& src, uint32_t stride); StrideAttribute(ProgramID pid, const Source& src, uint32_t stride);
~StrideDecoration() override; ~StrideAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const StrideDecoration* Clone(CloneContext* ctx) const override; const StrideAttribute* Clone(CloneContext* ctx) const override;
/// The stride value /// The stride value
const uint32_t stride; const uint32_t stride;
@ -48,4 +48,4 @@ class StrideDecoration : public Castable<StrideDecoration, Decoration> {
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_STRIDE_DECORATION_H_ #endif // SRC_AST_STRIDE_ATTRIBUTE_H_

View File

@ -18,15 +18,15 @@ namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using StrideDecorationTest = TestHelper; using StrideAttributeTest = TestHelper;
TEST_F(StrideDecorationTest, Creation) { TEST_F(StrideAttributeTest, Creation) {
auto* d = create<StrideDecoration>(2); auto* d = create<StrideAttribute>(2);
EXPECT_EQ(2u, d->stride); EXPECT_EQ(2u, d->stride);
} }
TEST_F(StrideDecorationTest, Source) { TEST_F(StrideAttributeTest, Source) {
auto* d = create<StrideDecoration>( auto* d = create<StrideAttribute>(
Source{Source::Range{Source::Location{1, 2}, Source::Location{3, 4}}}, 2); Source{Source::Range{Source::Location{1, 2}, Source::Location{3, 4}}}, 2);
EXPECT_EQ(d->source.range.begin.line, 1u); EXPECT_EQ(d->source.range.begin.line, 1u);
EXPECT_EQ(d->source.range.begin.column, 2u); EXPECT_EQ(d->source.range.begin.column, 2u);

View File

@ -16,7 +16,7 @@
#include <string> #include <string>
#include "src/ast/struct_block_decoration.h" #include "src/ast/struct_block_attribute.h"
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Struct); TINT_INSTANTIATE_TYPEINFO(tint::ast::Struct);
@ -28,15 +28,15 @@ Struct::Struct(ProgramID pid,
const Source& src, const Source& src,
Symbol n, Symbol n,
StructMemberList m, StructMemberList m,
DecorationList decos) AttributeList attrs)
: Base(pid, src, n), members(std::move(m)), decorations(std::move(decos)) { : Base(pid, src, n), members(std::move(m)), attributes(std::move(attrs)) {
for (auto* mem : members) { for (auto* mem : members) {
TINT_ASSERT(AST, mem); TINT_ASSERT(AST, mem);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, mem, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, mem, program_id);
} }
for (auto* deco : decorations) { for (auto* attr : attributes) {
TINT_ASSERT(AST, deco); TINT_ASSERT(AST, attr);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
} }
} }
@ -49,8 +49,8 @@ const Struct* Struct::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto n = ctx->Clone(name); auto n = ctx->Clone(name);
auto mem = ctx->Clone(members); auto mem = ctx->Clone(members);
auto decos = ctx->Clone(decorations); auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Struct>(src, n, mem, decos); return ctx->dst->create<Struct>(src, n, mem, attrs);
} }
} // namespace ast } // namespace ast

View File

@ -18,7 +18,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
#include "src/ast/struct_member.h" #include "src/ast/struct_member.h"
#include "src/ast/type_decl.h" #include "src/ast/type_decl.h"
@ -33,12 +33,12 @@ class Struct : public Castable<Struct, TypeDecl> {
/// @param src the source of this node for the import statement /// @param src the source of this node for the import statement
/// @param name The name of the structure /// @param name The name of the structure
/// @param members The struct members /// @param members The struct members
/// @param decorations The struct decorations /// @param attributes The struct attributes
Struct(ProgramID pid, Struct(ProgramID pid,
const Source& src, const Source& src,
Symbol name, Symbol name,
StructMemberList members, StructMemberList members,
DecorationList decorations); AttributeList attributes);
/// Move constructor /// Move constructor
Struct(Struct&&); Struct(Struct&&);
@ -53,8 +53,8 @@ class Struct : public Castable<Struct, TypeDecl> {
/// The members /// The members
const StructMemberList members; const StructMemberList members;
/// The struct decorations /// The struct attributes
const DecorationList decorations; const AttributeList attributes;
}; };
} // namespace ast } // namespace ast

View File

@ -12,31 +12,31 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/struct_block_decoration.h" #include "src/ast/struct_block_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructBlockDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::StructBlockAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
StructBlockDecoration::StructBlockDecoration(ProgramID pid, const Source& src) StructBlockAttribute::StructBlockAttribute(ProgramID pid, const Source& src)
: Base(pid, src) {} : Base(pid, src) {}
StructBlockDecoration::~StructBlockDecoration() = default; StructBlockAttribute::~StructBlockAttribute() = default;
std::string StructBlockDecoration::Name() const { std::string StructBlockAttribute::Name() const {
return "block"; return "block";
} }
const StructBlockDecoration* StructBlockDecoration::Clone( const StructBlockAttribute* StructBlockAttribute::Clone(
CloneContext* ctx) const { CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<StructBlockDecoration>(src); return ctx->dst->create<StructBlockAttribute>(src);
} }
} // namespace ast } // namespace ast

View File

@ -12,38 +12,37 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_STRUCT_BLOCK_DECORATION_H_ #ifndef SRC_AST_STRUCT_BLOCK_ATTRIBUTE_H_
#define SRC_AST_STRUCT_BLOCK_DECORATION_H_ #define SRC_AST_STRUCT_BLOCK_ATTRIBUTE_H_
#include <string> #include <string>
#include <vector> #include <vector>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// The struct decorations /// The struct block attribute
class StructBlockDecoration class StructBlockAttribute : public Castable<StructBlockAttribute, Attribute> {
: public Castable<StructBlockDecoration, Decoration> {
public: public:
/// constructor /// Constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
StructBlockDecoration(ProgramID pid, const Source& src); StructBlockAttribute(ProgramID pid, const Source& src);
~StructBlockDecoration() override; ~StructBlockAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const StructBlockDecoration* Clone(CloneContext* ctx) const override; const StructBlockAttribute* Clone(CloneContext* ctx) const override;
}; };
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_STRUCT_BLOCK_DECORATION_H_ #endif // SRC_AST_STRUCT_BLOCK_ATTRIBUTE_H_

View File

@ -25,14 +25,14 @@ StructMember::StructMember(ProgramID pid,
const Source& src, const Source& src,
const Symbol& sym, const Symbol& sym,
const ast::Type* ty, const ast::Type* ty,
DecorationList decos) AttributeList attrs)
: Base(pid, src), symbol(sym), type(ty), decorations(std::move(decos)) { : Base(pid, src), symbol(sym), type(ty), attributes(std::move(attrs)) {
TINT_ASSERT(AST, type); TINT_ASSERT(AST, type);
TINT_ASSERT(AST, symbol.IsValid()); TINT_ASSERT(AST, symbol.IsValid());
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
for (auto* deco : decorations) { for (auto* attr : attributes) {
TINT_ASSERT(AST, deco); TINT_ASSERT(AST, attr);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
} }
} }
@ -45,8 +45,8 @@ const StructMember* StructMember::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto sym = ctx->Clone(symbol); auto sym = ctx->Clone(symbol);
auto* ty = ctx->Clone(type); auto* ty = ctx->Clone(type);
auto decos = ctx->Clone(decorations); auto attrs = ctx->Clone(attributes);
return ctx->dst->create<StructMember>(src, sym, ty, decos); return ctx->dst->create<StructMember>(src, sym, ty, attrs);
} }
} // namespace ast } // namespace ast

View File

@ -18,7 +18,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -34,12 +34,12 @@ class StructMember : public Castable<StructMember, Node> {
/// @param src the source of this node for the struct member statement /// @param src the source of this node for the struct member statement
/// @param sym The struct member symbol /// @param sym The struct member symbol
/// @param type The struct member type /// @param type The struct member type
/// @param decorations The struct member decorations /// @param attributes The struct member attributes
StructMember(ProgramID pid, StructMember(ProgramID pid,
const Source& src, const Source& src,
const Symbol& sym, const Symbol& sym,
const ast::Type* type, const ast::Type* type,
DecorationList decorations); AttributeList attributes);
/// Move constructor /// Move constructor
StructMember(StructMember&&); StructMember(StructMember&&);
@ -57,8 +57,8 @@ class StructMember : public Castable<StructMember, Node> {
/// The type /// The type
const ast::Type* const type; const ast::Type* const type;
/// The decorations /// The attributes
const DecorationList decorations; const AttributeList attributes;
}; };
/// A list of struct members /// A list of struct members

View File

@ -12,34 +12,34 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/struct_member_size_decoration.h" #include "src/ast/struct_member_align_attribute.h"
#include <string> #include <string>
#include "src/clone_context.h" #include "src/clone_context.h"
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberSizeDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberAlignAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
StructMemberSizeDecoration::StructMemberSizeDecoration(ProgramID pid, StructMemberAlignAttribute::StructMemberAlignAttribute(ProgramID pid,
const Source& src, const Source& src,
uint32_t sz) uint32_t a)
: Base(pid, src), size(sz) {} : Base(pid, src), align(a) {}
StructMemberSizeDecoration::~StructMemberSizeDecoration() = default; StructMemberAlignAttribute::~StructMemberAlignAttribute() = default;
std::string StructMemberSizeDecoration::Name() const { std::string StructMemberAlignAttribute::Name() const {
return "size"; return "align";
} }
const StructMemberSizeDecoration* StructMemberSizeDecoration::Clone( const StructMemberAlignAttribute* StructMemberAlignAttribute::Clone(
CloneContext* ctx) const { CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<StructMemberSizeDecoration>(src, size); return ctx->dst->create<StructMemberAlignAttribute>(src, align);
} }
} // namespace ast } // namespace ast

View File

@ -12,36 +12,36 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_ #ifndef SRC_AST_STRUCT_MEMBER_ALIGN_ATTRIBUTE_H_
#define SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_ #define SRC_AST_STRUCT_MEMBER_ALIGN_ATTRIBUTE_H_
#include <stddef.h> #include <stddef.h>
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A struct member align decoration /// A struct member align attribute
class StructMemberAlignDecoration class StructMemberAlignAttribute
: public Castable<StructMemberAlignDecoration, Decoration> { : public Castable<StructMemberAlignAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param align the align value /// @param align the align value
StructMemberAlignDecoration(ProgramID pid, const Source& src, uint32_t align); StructMemberAlignAttribute(ProgramID pid, const Source& src, uint32_t align);
~StructMemberAlignDecoration() override; ~StructMemberAlignAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const StructMemberAlignDecoration* Clone(CloneContext* ctx) const override; const StructMemberAlignAttribute* Clone(CloneContext* ctx) const override;
/// The align value /// The align value
const uint32_t align; const uint32_t align;
@ -50,4 +50,4 @@ class StructMemberAlignDecoration
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_ #endif // SRC_AST_STRUCT_MEMBER_ALIGN_ATTRIBUTE_H_

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/struct_member_align_decoration.h" #include "src/ast/struct_member_align_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
@ -20,10 +20,10 @@ namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using StructMemberAlignDecorationTest = TestHelper; using StructMemberAlignAttributeTest = TestHelper;
TEST_F(StructMemberAlignDecorationTest, Creation) { TEST_F(StructMemberAlignAttributeTest, Creation) {
auto* d = create<StructMemberAlignDecoration>(2); auto* d = create<StructMemberAlignAttribute>(2);
EXPECT_EQ(2u, d->align); EXPECT_EQ(2u, d->align);
} }

View File

@ -1,4 +1,4 @@
// Copyright 2021 The Tint Authors. // Copyright 2020 The Tint Authors.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,34 +12,33 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/struct_member_align_decoration.h" #include "src/ast/struct_member_offset_attribute.h"
#include <string> #include <string>
#include "src/clone_context.h"
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberAlignDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberOffsetAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
StructMemberAlignDecoration::StructMemberAlignDecoration(ProgramID pid, StructMemberOffsetAttribute::StructMemberOffsetAttribute(ProgramID pid,
const Source& src, const Source& src,
uint32_t a) uint32_t o)
: Base(pid, src), align(a) {} : Base(pid, src), offset(o) {}
StructMemberAlignDecoration::~StructMemberAlignDecoration() = default; StructMemberOffsetAttribute::~StructMemberOffsetAttribute() = default;
std::string StructMemberAlignDecoration::Name() const { std::string StructMemberOffsetAttribute::Name() const {
return "align"; return "offset";
} }
const StructMemberAlignDecoration* StructMemberAlignDecoration::Clone( const StructMemberOffsetAttribute* StructMemberOffsetAttribute::Clone(
CloneContext* ctx) const { CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<StructMemberAlignDecoration>(src, align); return ctx->dst->create<StructMemberOffsetAttribute>(src, offset);
} }
} // namespace ast } // namespace ast

View File

@ -12,46 +12,46 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_ #ifndef SRC_AST_STRUCT_MEMBER_OFFSET_ATTRIBUTE_H_
#define SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_ #define SRC_AST_STRUCT_MEMBER_OFFSET_ATTRIBUTE_H_
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A struct member offset decoration /// A struct member offset attribute
/// @note The WGSL spec removed the `@offset(n)` decoration for `@size(n)` /// @note The WGSL spec removed the `@offset(n)` attribute for `@size(n)`
/// and `@align(n)` in https://github.com/gpuweb/gpuweb/pull/1447. However /// and `@align(n)` in https://github.com/gpuweb/gpuweb/pull/1447. However
/// this decoration is kept because the SPIR-V reader has to deal with absolute /// this attribute is kept because the SPIR-V reader has to deal with absolute
/// offsets, and transforming these to size / align is complex and can be done /// offsets, and transforming these to size / align is complex and can be done
/// in a number of ways. The Resolver is responsible for consuming the size and /// in a number of ways. The Resolver is responsible for consuming the size and
/// align decorations and transforming these into absolute offsets. It is /// align attributes and transforming these into absolute offsets. It is
/// trivial for the Resolver to handle `@offset(n)` or `@size(n)` / /// trivial for the Resolver to handle `@offset(n)` or `@size(n)` /
/// `@align(n)` decorations, so this is what we do, keeping all the layout /// `@align(n)` attributes, so this is what we do, keeping all the layout
/// logic in one place. /// logic in one place.
class StructMemberOffsetDecoration class StructMemberOffsetAttribute
: public Castable<StructMemberOffsetDecoration, Decoration> { : public Castable<StructMemberOffsetAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param offset the offset value /// @param offset the offset value
StructMemberOffsetDecoration(ProgramID pid, StructMemberOffsetAttribute(ProgramID pid,
const Source& src, const Source& src,
uint32_t offset); uint32_t offset);
~StructMemberOffsetDecoration() override; ~StructMemberOffsetAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const StructMemberOffsetDecoration* Clone(CloneContext* ctx) const override; const StructMemberOffsetAttribute* Clone(CloneContext* ctx) const override;
/// The offset value /// The offset value
const uint32_t offset; const uint32_t offset;
@ -60,4 +60,4 @@ class StructMemberOffsetDecoration
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_ #endif // SRC_AST_STRUCT_MEMBER_OFFSET_ATTRIBUTE_H_

View File

@ -18,10 +18,10 @@ namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using StructMemberOffsetDecorationTest = TestHelper; using StructMemberOffsetAttributeTest = TestHelper;
TEST_F(StructMemberOffsetDecorationTest, Creation) { TEST_F(StructMemberOffsetAttributeTest, Creation) {
auto* d = create<StructMemberOffsetDecoration>(2); auto* d = create<StructMemberOffsetAttribute>(2);
EXPECT_EQ(2u, d->offset); EXPECT_EQ(2u, d->offset);
} }

View File

@ -1,4 +1,4 @@
// Copyright 2020 The Tint Authors. // Copyright 2021 The Tint Authors.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,33 +12,34 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/struct_member_offset_decoration.h" #include "src/ast/struct_member_size_attribute.h"
#include <string> #include <string>
#include "src/clone_context.h"
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberOffsetDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberSizeAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
StructMemberOffsetDecoration::StructMemberOffsetDecoration(ProgramID pid, StructMemberSizeAttribute::StructMemberSizeAttribute(ProgramID pid,
const Source& src, const Source& src,
uint32_t o) uint32_t sz)
: Base(pid, src), offset(o) {} : Base(pid, src), size(sz) {}
StructMemberOffsetDecoration::~StructMemberOffsetDecoration() = default; StructMemberSizeAttribute::~StructMemberSizeAttribute() = default;
std::string StructMemberOffsetDecoration::Name() const { std::string StructMemberSizeAttribute::Name() const {
return "offset"; return "size";
} }
const StructMemberOffsetDecoration* StructMemberOffsetDecoration::Clone( const StructMemberSizeAttribute* StructMemberSizeAttribute::Clone(
CloneContext* ctx) const { CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
return ctx->dst->create<StructMemberOffsetDecoration>(src, offset); return ctx->dst->create<StructMemberSizeAttribute>(src, size);
} }
} // namespace ast } // namespace ast

View File

@ -12,36 +12,36 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_ #ifndef SRC_AST_STRUCT_MEMBER_SIZE_ATTRIBUTE_H_
#define SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_ #define SRC_AST_STRUCT_MEMBER_SIZE_ATTRIBUTE_H_
#include <stddef.h> #include <stddef.h>
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// A struct member size decoration /// A struct member size attribute
class StructMemberSizeDecoration class StructMemberSizeAttribute
: public Castable<StructMemberSizeDecoration, Decoration> { : public Castable<StructMemberSizeAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param src the source of this node /// @param src the source of this node
/// @param size the size value /// @param size the size value
StructMemberSizeDecoration(ProgramID pid, const Source& src, uint32_t size); StructMemberSizeAttribute(ProgramID pid, const Source& src, uint32_t size);
~StructMemberSizeDecoration() override; ~StructMemberSizeAttribute() override;
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const StructMemberSizeDecoration* Clone(CloneContext* ctx) const override; const StructMemberSizeAttribute* Clone(CloneContext* ctx) const override;
/// The size value /// The size value
const uint32_t size; const uint32_t size;
@ -50,4 +50,4 @@ class StructMemberSizeDecoration
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_ #endif // SRC_AST_STRUCT_MEMBER_SIZE_ATTRIBUTE_H_

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/struct_member_size_decoration.h" #include "src/ast/struct_member_size_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
@ -20,10 +20,10 @@ namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using StructMemberOffsetDecorationTest = TestHelper; using StructMemberSizeAttributeTest = TestHelper;
TEST_F(StructMemberOffsetDecorationTest, Creation) { TEST_F(StructMemberSizeAttributeTest, Creation) {
auto* d = create<StructMemberSizeDecoration>(2); auto* d = create<StructMemberSizeAttribute>(2);
EXPECT_EQ(2u, d->size); EXPECT_EQ(2u, d->size);
} }

View File

@ -25,8 +25,8 @@ TEST_F(StructMemberTest, Creation) {
auto* st = Member("a", ty.i32(), {MemberSize(4)}); auto* st = Member("a", ty.i32(), {MemberSize(4)});
EXPECT_EQ(st->symbol, Symbol(1, ID())); EXPECT_EQ(st->symbol, Symbol(1, ID()));
EXPECT_TRUE(st->type->Is<ast::I32>()); EXPECT_TRUE(st->type->Is<ast::I32>());
EXPECT_EQ(st->decorations.size(), 1u); EXPECT_EQ(st->attributes.size(), 1u);
EXPECT_TRUE(st->decorations[0]->Is<StructMemberSizeDecoration>()); EXPECT_TRUE(st->attributes[0]->Is<StructMemberSizeAttribute>());
EXPECT_EQ(st->source.range.begin.line, 0u); EXPECT_EQ(st->source.range.begin.line, 0u);
EXPECT_EQ(st->source.range.begin.column, 0u); EXPECT_EQ(st->source.range.begin.column, 0u);
EXPECT_EQ(st->source.range.end.line, 0u); EXPECT_EQ(st->source.range.end.line, 0u);
@ -39,7 +39,7 @@ TEST_F(StructMemberTest, CreationWithSource) {
"a", ty.i32()); "a", ty.i32());
EXPECT_EQ(st->symbol, Symbol(1, ID())); EXPECT_EQ(st->symbol, Symbol(1, ID()));
EXPECT_TRUE(st->type->Is<ast::I32>()); EXPECT_TRUE(st->type->Is<ast::I32>());
EXPECT_EQ(st->decorations.size(), 0u); EXPECT_EQ(st->attributes.size(), 0u);
EXPECT_EQ(st->source.range.begin.line, 27u); EXPECT_EQ(st->source.range.begin.line, 27u);
EXPECT_EQ(st->source.range.begin.column, 4u); EXPECT_EQ(st->source.range.begin.column, 4u);
EXPECT_EQ(st->source.range.end.line, 27u); EXPECT_EQ(st->source.range.end.line, 27u);
@ -64,7 +64,7 @@ TEST_F(StructMemberTest, Assert_Null_Type) {
"internal compiler error"); "internal compiler error");
} }
TEST_F(StructMemberTest, Assert_Null_Decoration) { TEST_F(StructMemberTest, Assert_Null_Attribute) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
ProgramBuilder b; ProgramBuilder b;
@ -83,7 +83,7 @@ TEST_F(StructMemberTest, Assert_DifferentProgramID_Symbol) {
"internal compiler error"); "internal compiler error");
} }
TEST_F(StructMemberTest, Assert_DifferentProgramID_Decoration) { TEST_F(StructMemberTest, Assert_DifferentProgramID_Attribute) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
ProgramBuilder b1; ProgramBuilder b1;

View File

@ -22,7 +22,7 @@
#include "src/ast/matrix.h" #include "src/ast/matrix.h"
#include "src/ast/pointer.h" #include "src/ast/pointer.h"
#include "src/ast/sampler.h" #include "src/ast/sampler.h"
#include "src/ast/struct_block_decoration.h" #include "src/ast/struct_block_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h" #include "src/ast/texture.h"
#include "src/ast/u32.h" #include "src/ast/u32.h"
@ -37,43 +37,43 @@ using AstStructTest = TestHelper;
TEST_F(AstStructTest, Creation) { TEST_F(AstStructTest, Creation) {
auto name = Sym("s"); auto name = Sym("s");
auto* s = create<Struct>(name, StructMemberList{Member("a", ty.i32())}, auto* s = create<Struct>(name, StructMemberList{Member("a", ty.i32())},
DecorationList{}); AttributeList{});
EXPECT_EQ(s->name, name); EXPECT_EQ(s->name, name);
EXPECT_EQ(s->members.size(), 1u); EXPECT_EQ(s->members.size(), 1u);
EXPECT_TRUE(s->decorations.empty()); EXPECT_TRUE(s->attributes.empty());
EXPECT_EQ(s->source.range.begin.line, 0u); EXPECT_EQ(s->source.range.begin.line, 0u);
EXPECT_EQ(s->source.range.begin.column, 0u); EXPECT_EQ(s->source.range.begin.column, 0u);
EXPECT_EQ(s->source.range.end.line, 0u); EXPECT_EQ(s->source.range.end.line, 0u);
EXPECT_EQ(s->source.range.end.column, 0u); EXPECT_EQ(s->source.range.end.column, 0u);
} }
TEST_F(AstStructTest, Creation_WithDecorations) { TEST_F(AstStructTest, Creation_WithAttributes) {
auto name = Sym("s"); auto name = Sym("s");
DecorationList decos; AttributeList attrs;
decos.push_back(create<StructBlockDecoration>()); attrs.push_back(create<StructBlockAttribute>());
auto* s = auto* s =
create<Struct>(name, StructMemberList{Member("a", ty.i32())}, decos); create<Struct>(name, StructMemberList{Member("a", ty.i32())}, attrs);
EXPECT_EQ(s->name, name); EXPECT_EQ(s->name, name);
EXPECT_EQ(s->members.size(), 1u); EXPECT_EQ(s->members.size(), 1u);
ASSERT_EQ(s->decorations.size(), 1u); ASSERT_EQ(s->attributes.size(), 1u);
EXPECT_TRUE(s->decorations[0]->Is<StructBlockDecoration>()); EXPECT_TRUE(s->attributes[0]->Is<StructBlockAttribute>());
EXPECT_EQ(s->source.range.begin.line, 0u); EXPECT_EQ(s->source.range.begin.line, 0u);
EXPECT_EQ(s->source.range.begin.column, 0u); EXPECT_EQ(s->source.range.begin.column, 0u);
EXPECT_EQ(s->source.range.end.line, 0u); EXPECT_EQ(s->source.range.end.line, 0u);
EXPECT_EQ(s->source.range.end.column, 0u); EXPECT_EQ(s->source.range.end.column, 0u);
} }
TEST_F(AstStructTest, CreationWithSourceAndDecorations) { TEST_F(AstStructTest, CreationWithSourceAndAttributes) {
auto name = Sym("s"); auto name = Sym("s");
auto* s = create<Struct>( auto* s = create<Struct>(
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}}, Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
name, StructMemberList{Member("a", ty.i32())}, name, StructMemberList{Member("a", ty.i32())},
DecorationList{create<StructBlockDecoration>()}); AttributeList{create<StructBlockAttribute>()});
EXPECT_EQ(s->name, name); EXPECT_EQ(s->name, name);
EXPECT_EQ(s->members.size(), 1u); EXPECT_EQ(s->members.size(), 1u);
ASSERT_EQ(s->decorations.size(), 1u); ASSERT_EQ(s->attributes.size(), 1u);
EXPECT_TRUE(s->decorations[0]->Is<StructBlockDecoration>()); EXPECT_TRUE(s->attributes[0]->Is<StructBlockAttribute>());
EXPECT_EQ(s->source.range.begin.line, 27u); EXPECT_EQ(s->source.range.begin.line, 27u);
EXPECT_EQ(s->source.range.begin.column, 4u); EXPECT_EQ(s->source.range.begin.column, 4u);
EXPECT_EQ(s->source.range.end.line, 27u); EXPECT_EQ(s->source.range.end.line, 27u);
@ -86,18 +86,18 @@ TEST_F(AstStructTest, Assert_Null_StructMember) {
ProgramBuilder b; ProgramBuilder b;
b.create<Struct>(b.Sym("S"), b.create<Struct>(b.Sym("S"),
StructMemberList{b.Member("a", b.ty.i32()), nullptr}, StructMemberList{b.Member("a", b.ty.i32()), nullptr},
DecorationList{}); AttributeList{});
}, },
"internal compiler error"); "internal compiler error");
} }
TEST_F(AstStructTest, Assert_Null_Decoration) { TEST_F(AstStructTest, Assert_Null_Attribute) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
ProgramBuilder b; ProgramBuilder b;
b.create<Struct>(b.Sym("S"), b.create<Struct>(b.Sym("S"),
StructMemberList{b.Member("a", b.ty.i32())}, StructMemberList{b.Member("a", b.ty.i32())},
DecorationList{nullptr}); AttributeList{nullptr});
}, },
"internal compiler error"); "internal compiler error");
} }
@ -109,19 +109,19 @@ TEST_F(AstStructTest, Assert_DifferentProgramID_StructMember) {
ProgramBuilder b2; ProgramBuilder b2;
b1.create<Struct>(b1.Sym("S"), b1.create<Struct>(b1.Sym("S"),
StructMemberList{b2.Member("a", b2.ty.i32())}, StructMemberList{b2.Member("a", b2.ty.i32())},
DecorationList{}); AttributeList{});
}, },
"internal compiler error"); "internal compiler error");
} }
TEST_F(AstStructTest, Assert_DifferentProgramID_Decoration) { TEST_F(AstStructTest, Assert_DifferentProgramID_Attribute) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
ProgramBuilder b1; ProgramBuilder b1;
ProgramBuilder b2; ProgramBuilder b2;
b1.create<Struct>(b1.Sym("S"), b1.create<Struct>(b1.Sym("S"),
StructMemberList{b1.Member("a", b1.ty.i32())}, StructMemberList{b1.Member("a", b1.ty.i32())},
DecorationList{b2.create<StructBlockDecoration>()}); AttributeList{b2.create<StructBlockAttribute>()});
}, },
"internal compiler error"); "internal compiler error");
} }

View File

@ -14,7 +14,7 @@
#include "src/ast/variable.h" #include "src/ast/variable.h"
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/program_builder.h" #include "src/program_builder.h"
#include "src/sem/variable.h" #include "src/sem/variable.h"
@ -31,13 +31,13 @@ Variable::Variable(ProgramID pid,
const ast::Type* ty, const ast::Type* ty,
bool constant, bool constant,
const Expression* ctor, const Expression* ctor,
DecorationList decos) AttributeList attrs)
: Base(pid, src), : Base(pid, src),
symbol(sym), symbol(sym),
type(ty), type(ty),
is_const(constant), is_const(constant),
constructor(ctor), constructor(ctor),
decorations(std::move(decos)), attributes(std::move(attrs)),
declared_storage_class(dsc), declared_storage_class(dsc),
declared_access(da) { declared_access(da) {
TINT_ASSERT(AST, symbol.IsValid()); TINT_ASSERT(AST, symbol.IsValid());
@ -50,12 +50,12 @@ Variable::Variable(Variable&&) = default;
Variable::~Variable() = default; Variable::~Variable() = default;
VariableBindingPoint Variable::BindingPoint() const { VariableBindingPoint Variable::BindingPoint() const {
const GroupDecoration* group = nullptr; const GroupAttribute* group = nullptr;
const BindingDecoration* binding = nullptr; const BindingAttribute* binding = nullptr;
for (auto* deco : decorations) { for (auto* attr : attributes) {
if (auto* g = deco->As<GroupDecoration>()) { if (auto* g = attr->As<GroupAttribute>()) {
group = g; group = g;
} else if (auto* b = deco->As<BindingDecoration>()) { } else if (auto* b = attr->As<BindingAttribute>()) {
binding = b; binding = b;
} }
} }
@ -67,9 +67,9 @@ const Variable* Variable::Clone(CloneContext* ctx) const {
auto sym = ctx->Clone(symbol); auto sym = ctx->Clone(symbol);
auto* ty = ctx->Clone(type); auto* ty = ctx->Clone(type);
auto* ctor = ctx->Clone(constructor); auto* ctor = ctx->Clone(constructor);
auto decos = ctx->Clone(decorations); auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Variable>(src, sym, declared_storage_class, return ctx->dst->create<Variable>(src, sym, declared_storage_class,
declared_access, ty, is_const, ctor, decos); declared_access, ty, is_const, ctor, attrs);
} }
} // namespace ast } // namespace ast

View File

@ -19,7 +19,7 @@
#include <vector> #include <vector>
#include "src/ast/access.h" #include "src/ast/access.h"
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
#include "src/ast/expression.h" #include "src/ast/expression.h"
#include "src/ast/storage_class.h" #include "src/ast/storage_class.h"
@ -27,20 +27,20 @@ namespace tint {
namespace ast { namespace ast {
// Forward declarations // Forward declarations
class BindingDecoration; class BindingAttribute;
class GroupDecoration; class GroupAttribute;
class LocationDecoration; class LocationAttribute;
class Type; class Type;
/// VariableBindingPoint holds a group and binding decoration. /// VariableBindingPoint holds a group and binding attribute.
struct VariableBindingPoint { struct VariableBindingPoint {
/// The `[[group]]` part of the binding point /// The `@group` part of the binding point
const GroupDecoration* group = nullptr; const GroupAttribute* group = nullptr;
/// The `[[binding]]` part of the binding point /// The `@binding` part of the binding point
const BindingDecoration* binding = nullptr; const BindingAttribute* binding = nullptr;
/// @returns true if the BindingPoint has a valid group and binding /// @returns true if the BindingPoint has a valid group and binding
/// decoration. /// attribute.
inline operator bool() const { return group && binding; } inline operator bool() const { return group && binding; }
}; };
@ -108,7 +108,7 @@ class Variable : public Castable<Variable, Node> {
/// @param type the declared variable type /// @param type the declared variable type
/// @param is_const true if the variable is const /// @param is_const true if the variable is const
/// @param constructor the constructor expression /// @param constructor the constructor expression
/// @param decorations the variable decorations /// @param attributes the variable attributes
Variable(ProgramID program_id, Variable(ProgramID program_id,
const Source& source, const Source& source,
const Symbol& sym, const Symbol& sym,
@ -117,7 +117,7 @@ class Variable : public Castable<Variable, Node> {
const ast::Type* type, const ast::Type* type,
bool is_const, bool is_const,
const Expression* constructor, const Expression* constructor,
DecorationList decorations); AttributeList attributes);
/// Move constructor /// Move constructor
Variable(Variable&&); Variable(Variable&&);
@ -146,8 +146,8 @@ class Variable : public Castable<Variable, Node> {
/// The constructor expression or nullptr if none set /// The constructor expression or nullptr if none set
const Expression* const constructor; const Expression* const constructor;
/// The decorations attached to this variable /// The attributes attached to this variable
const DecorationList decorations; const AttributeList attributes;
/// The declared storage class /// The declared storage class
const StorageClass declared_storage_class; const StorageClass declared_storage_class;

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
namespace tint { namespace tint {
@ -37,7 +37,7 @@ TEST_F(VariableTest, Creation) {
TEST_F(VariableTest, CreationWithSource) { TEST_F(VariableTest, CreationWithSource) {
auto* v = Var( auto* v = Var(
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}}, Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}},
"i", ty.f32(), StorageClass::kPrivate, nullptr, DecorationList{}); "i", ty.f32(), StorageClass::kPrivate, nullptr, AttributeList{});
EXPECT_EQ(v->symbol, Symbol(1, ID())); EXPECT_EQ(v->symbol, Symbol(1, ID()));
EXPECT_EQ(v->declared_storage_class, StorageClass::kPrivate); EXPECT_EQ(v->declared_storage_class, StorageClass::kPrivate);
@ -51,7 +51,7 @@ TEST_F(VariableTest, CreationWithSource) {
TEST_F(VariableTest, CreationEmpty) { TEST_F(VariableTest, CreationEmpty) {
auto* v = Var( auto* v = Var(
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}}, Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}},
"a_var", ty.i32(), StorageClass::kWorkgroup, nullptr, DecorationList{}); "a_var", ty.i32(), StorageClass::kWorkgroup, nullptr, AttributeList{});
EXPECT_EQ(v->symbol, Symbol(1, ID())); EXPECT_EQ(v->symbol, Symbol(1, ID()));
EXPECT_EQ(v->declared_storage_class, StorageClass::kWorkgroup); EXPECT_EQ(v->declared_storage_class, StorageClass::kWorkgroup);
@ -91,29 +91,29 @@ TEST_F(VariableTest, Assert_DifferentProgramID_Constructor) {
"internal compiler error"); "internal compiler error");
} }
TEST_F(VariableTest, WithDecorations) { TEST_F(VariableTest, WithAttributes) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr, auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{ AttributeList{
create<LocationDecoration>(1), create<LocationAttribute>(1),
create<BuiltinDecoration>(Builtin::kPosition), create<BuiltinAttribute>(Builtin::kPosition),
create<OverrideDecoration>(1200), create<OverrideAttribute>(1200),
}); });
auto& decorations = var->decorations; auto& attributes = var->attributes;
EXPECT_TRUE(ast::HasDecoration<ast::LocationDecoration>(decorations)); EXPECT_TRUE(ast::HasAttribute<ast::LocationAttribute>(attributes));
EXPECT_TRUE(ast::HasDecoration<ast::BuiltinDecoration>(decorations)); EXPECT_TRUE(ast::HasAttribute<ast::BuiltinAttribute>(attributes));
EXPECT_TRUE(ast::HasDecoration<ast::OverrideDecoration>(decorations)); EXPECT_TRUE(ast::HasAttribute<ast::OverrideAttribute>(attributes));
auto* location = ast::GetDecoration<ast::LocationDecoration>(decorations); auto* location = ast::GetAttribute<ast::LocationAttribute>(attributes);
ASSERT_NE(nullptr, location); ASSERT_NE(nullptr, location);
EXPECT_EQ(1u, location->value); EXPECT_EQ(1u, location->value);
} }
TEST_F(VariableTest, BindingPoint) { TEST_F(VariableTest, BindingPoint) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr, auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{ AttributeList{
create<BindingDecoration>(2), create<BindingAttribute>(2),
create<GroupDecoration>(1), create<GroupAttribute>(1),
}); });
EXPECT_TRUE(var->BindingPoint()); EXPECT_TRUE(var->BindingPoint());
ASSERT_NE(var->BindingPoint().binding, nullptr); ASSERT_NE(var->BindingPoint().binding, nullptr);
@ -122,18 +122,18 @@ TEST_F(VariableTest, BindingPoint) {
EXPECT_EQ(var->BindingPoint().group->value, 1u); EXPECT_EQ(var->BindingPoint().group->value, 1u);
} }
TEST_F(VariableTest, BindingPointoDecorations) { TEST_F(VariableTest, BindingPointAttributes) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr, auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{}); AttributeList{});
EXPECT_FALSE(var->BindingPoint()); EXPECT_FALSE(var->BindingPoint());
EXPECT_EQ(var->BindingPoint().group, nullptr); EXPECT_EQ(var->BindingPoint().group, nullptr);
EXPECT_EQ(var->BindingPoint().binding, nullptr); EXPECT_EQ(var->BindingPoint().binding, nullptr);
} }
TEST_F(VariableTest, BindingPointMissingGroupDecoration) { TEST_F(VariableTest, BindingPointMissingGroupAttribute) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr, auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{ AttributeList{
create<BindingDecoration>(2), create<BindingAttribute>(2),
}); });
EXPECT_FALSE(var->BindingPoint()); EXPECT_FALSE(var->BindingPoint());
ASSERT_NE(var->BindingPoint().binding, nullptr); ASSERT_NE(var->BindingPoint().binding, nullptr);
@ -141,9 +141,9 @@ TEST_F(VariableTest, BindingPointMissingGroupDecoration) {
EXPECT_EQ(var->BindingPoint().group, nullptr); EXPECT_EQ(var->BindingPoint().group, nullptr);
} }
TEST_F(VariableTest, BindingPointMissingBindingDecoration) { TEST_F(VariableTest, BindingPointMissingBindingAttribute) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr, auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{create<GroupDecoration>(1)}); AttributeList{create<GroupAttribute>(1)});
EXPECT_FALSE(var->BindingPoint()); EXPECT_FALSE(var->BindingPoint());
ASSERT_NE(var->BindingPoint().group, nullptr); ASSERT_NE(var->BindingPoint().group, nullptr);
EXPECT_EQ(var->BindingPoint().group->value, 1u); EXPECT_EQ(var->BindingPoint().group->value, 1u);

View File

@ -12,37 +12,37 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
#include <string> #include <string>
#include "src/program_builder.h" #include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::WorkgroupDecoration); TINT_INSTANTIATE_TYPEINFO(tint::ast::WorkgroupAttribute);
namespace tint { namespace tint {
namespace ast { namespace ast {
WorkgroupDecoration::WorkgroupDecoration(ProgramID pid, WorkgroupAttribute::WorkgroupAttribute(ProgramID pid,
const Source& src, const Source& src,
const ast::Expression* x_, const ast::Expression* x_,
const ast::Expression* y_, const ast::Expression* y_,
const ast::Expression* z_) const ast::Expression* z_)
: Base(pid, src), x(x_), y(y_), z(z_) {} : Base(pid, src), x(x_), y(y_), z(z_) {}
WorkgroupDecoration::~WorkgroupDecoration() = default; WorkgroupAttribute::~WorkgroupAttribute() = default;
std::string WorkgroupDecoration::Name() const { std::string WorkgroupAttribute::Name() const {
return "workgroup_size"; return "workgroup_size";
} }
const WorkgroupDecoration* WorkgroupDecoration::Clone(CloneContext* ctx) const { const WorkgroupAttribute* WorkgroupAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto* x_ = ctx->Clone(x); auto* x_ = ctx->Clone(x);
auto* y_ = ctx->Clone(y); auto* y_ = ctx->Clone(y);
auto* z_ = ctx->Clone(z); auto* z_ = ctx->Clone(z);
return ctx->dst->create<WorkgroupDecoration>(src, x_, y_, z_); return ctx->dst->create<WorkgroupAttribute>(src, x_, y_, z_);
} }
} // namespace ast } // namespace ast

View File

@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_AST_WORKGROUP_DECORATION_H_ #ifndef SRC_AST_WORKGROUP_ATTRIBUTE_H_
#define SRC_AST_WORKGROUP_DECORATION_H_ #define SRC_AST_WORKGROUP_ATTRIBUTE_H_
#include <array> #include <array>
#include <string> #include <string>
#include "src/ast/decoration.h" #include "src/ast/attribute.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -26,8 +26,8 @@ namespace ast {
// Forward declaration // Forward declaration
class Expression; class Expression;
/// A workgroup decoration /// A workgroup attribute
class WorkgroupDecoration : public Castable<WorkgroupDecoration, Decoration> { class WorkgroupAttribute : public Castable<WorkgroupAttribute, Attribute> {
public: public:
/// constructor /// constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
@ -35,25 +35,25 @@ class WorkgroupDecoration : public Castable<WorkgroupDecoration, Decoration> {
/// @param x the workgroup x dimension expression /// @param x the workgroup x dimension expression
/// @param y the optional workgroup y dimension expression /// @param y the optional workgroup y dimension expression
/// @param z the optional workgroup z dimension expression /// @param z the optional workgroup z dimension expression
WorkgroupDecoration(ProgramID pid, WorkgroupAttribute(ProgramID pid,
const Source& src, const Source& src,
const ast::Expression* x, const ast::Expression* x,
const ast::Expression* y = nullptr, const ast::Expression* y = nullptr,
const ast::Expression* z = nullptr); const ast::Expression* z = nullptr);
~WorkgroupDecoration() override; ~WorkgroupAttribute() override;
/// @returns the workgroup dimensions /// @returns the workgroup dimensions
std::array<const ast::Expression*, 3> Values() const { return {x, y, z}; } std::array<const ast::Expression*, 3> Values() const { return {x, y, z}; }
/// @returns the WGSL name for the decoration /// @returns the WGSL name for the attribute
std::string Name() const override; std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext` /// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`. /// `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const WorkgroupDecoration* Clone(CloneContext* ctx) const override; const WorkgroupAttribute* Clone(CloneContext* ctx) const override;
/// The workgroup x dimension. /// The workgroup x dimension.
const ast::Expression* const x; const ast::Expression* const x;
@ -66,4 +66,4 @@ class WorkgroupDecoration : public Castable<WorkgroupDecoration, Decoration> {
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint
#endif // SRC_AST_WORKGROUP_DECORATION_H_ #endif // SRC_AST_WORKGROUP_ATTRIBUTE_H_

View File

@ -12,18 +12,18 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
namespace { namespace {
using WorkgroupDecorationTest = TestHelper; using WorkgroupAttributeTest = TestHelper;
TEST_F(WorkgroupDecorationTest, Creation_1param) { TEST_F(WorkgroupAttributeTest, Creation_1param) {
auto* d = WorkgroupSize(2); auto* d = WorkgroupSize(2);
auto values = d->Values(); auto values = d->Values();
@ -33,7 +33,7 @@ TEST_F(WorkgroupDecorationTest, Creation_1param) {
EXPECT_EQ(values[1], nullptr); EXPECT_EQ(values[1], nullptr);
EXPECT_EQ(values[2], nullptr); EXPECT_EQ(values[2], nullptr);
} }
TEST_F(WorkgroupDecorationTest, Creation_2param) { TEST_F(WorkgroupAttributeTest, Creation_2param) {
auto* d = WorkgroupSize(2, 4); auto* d = WorkgroupSize(2, 4);
auto values = d->Values(); auto values = d->Values();
@ -46,7 +46,7 @@ TEST_F(WorkgroupDecorationTest, Creation_2param) {
EXPECT_EQ(values[2], nullptr); EXPECT_EQ(values[2], nullptr);
} }
TEST_F(WorkgroupDecorationTest, Creation_3param) { TEST_F(WorkgroupAttributeTest, Creation_3param) {
auto* d = WorkgroupSize(2, 4, 6); auto* d = WorkgroupSize(2, 4, 6);
auto values = d->Values(); auto values = d->Values();
@ -60,7 +60,7 @@ TEST_F(WorkgroupDecorationTest, Creation_3param) {
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u); EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
} }
TEST_F(WorkgroupDecorationTest, Creation_WithIdentifier) { TEST_F(WorkgroupAttributeTest, Creation_WithIdentifier) {
auto* d = WorkgroupSize(2, 4, "depth"); auto* d = WorkgroupSize(2, 4, "depth");
auto values = d->Values(); auto values = d->Values();

View File

@ -17,6 +17,10 @@
namespace tint { namespace tint {
namespace inspector { namespace inspector {
StageVariable::StageVariable() = default;
StageVariable::StageVariable(const StageVariable&) = default;
StageVariable::~StageVariable() = default;
EntryPoint::EntryPoint() = default; EntryPoint::EntryPoint() = default;
EntryPoint::EntryPoint(EntryPoint&) = default; EntryPoint::EntryPoint(EntryPoint&) = default;
EntryPoint::EntryPoint(EntryPoint&&) = default; EntryPoint::EntryPoint(EntryPoint&&) = default;

View File

@ -19,7 +19,7 @@
#include <tuple> #include <tuple>
#include <vector> #include <vector>
#include "src/ast/interpolate_decoration.h" #include "src/ast/interpolate_attribute.h"
#include "src/ast/pipeline_stage.h" #include "src/ast/pipeline_stage.h"
namespace tint { namespace tint {
@ -56,13 +56,27 @@ enum class InterpolationSampling {
/// Reflection data about an entry point input or output. /// Reflection data about an entry point input or output.
struct StageVariable { struct StageVariable {
/// Constructor
StageVariable();
/// Copy constructor
StageVariable(const StageVariable&);
/// Destructor
~StageVariable();
/// Name of the variable in the shader. /// Name of the variable in the shader.
std::string name; std::string name;
/// Is Location Decoration present /// Is location attribute present
bool has_location_decoration = false; bool has_location_attribute = false;
/// Value of Location Decoration, only valid if |has_location_decoration| is /// Value of the location attribute, only valid if #has_location_attribute is
/// true. /// true.
uint32_t location_decoration; uint32_t location_attribute;
/// Is Location attribute present
/// [DEPRECATED]: Use #has_location_attribute
bool& has_location_decoration = has_location_attribute;
/// Value of Location Decoration, only valid if #has_location_decoration is
/// true.
/// [DEPRECATED]: Use #location_attribute
uint32_t& location_decoration = location_attribute;
/// Scalar type that the variable is composed of. /// Scalar type that the variable is composed of.
ComponentType component_type = ComponentType::kUnknown; ComponentType component_type = ComponentType::kUnknown;
/// How the scalars are composed for the variable. /// How the scalars are composed for the variable.

View File

@ -20,10 +20,10 @@
#include "src/ast/bool_literal_expression.h" #include "src/ast/bool_literal_expression.h"
#include "src/ast/call_expression.h" #include "src/ast/call_expression.h"
#include "src/ast/float_literal_expression.h" #include "src/ast/float_literal_expression.h"
#include "src/ast/interpolate_decoration.h" #include "src/ast/interpolate_attribute.h"
#include "src/ast/location_decoration.h" #include "src/ast/location_attribute.h"
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/sint_literal_expression.h" #include "src/ast/sint_literal_expression.h"
#include "src/ast/uint_literal_expression.h" #include "src/ast/uint_literal_expression.h"
#include "src/sem/array.h" #include "src/sem/array.h"
@ -102,19 +102,19 @@ std::tuple<ComponentType, CompositionType> CalculateComponentAndComposition(
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData( std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
const sem::Type* type, const sem::Type* type,
const ast::DecorationList& decorations) { const ast::AttributeList& attributes) {
auto* interpolation_decoration = auto* interpolation_attribute =
ast::GetDecoration<ast::InterpolateDecoration>(decorations); ast::GetAttribute<ast::InterpolateAttribute>(attributes);
if (type->is_integer_scalar_or_vector()) { if (type->is_integer_scalar_or_vector()) {
return {InterpolationType::kFlat, InterpolationSampling::kNone}; return {InterpolationType::kFlat, InterpolationSampling::kNone};
} }
if (!interpolation_decoration) { if (!interpolation_attribute) {
return {InterpolationType::kPerspective, InterpolationSampling::kCenter}; return {InterpolationType::kPerspective, InterpolationSampling::kCenter};
} }
auto interpolation_type = interpolation_decoration->type; auto interpolation_type = interpolation_attribute->type;
auto sampling = interpolation_decoration->sampling; auto sampling = interpolation_attribute->sampling;
if (interpolation_type != ast::InterpolationType::kFlat && if (interpolation_type != ast::InterpolationType::kFlat &&
sampling == ast::InterpolationSampling::kNone) { sampling == ast::InterpolationSampling::kNone) {
sampling = ast::InterpolationSampling::kCenter; sampling = ast::InterpolationSampling::kCenter;
@ -157,34 +157,34 @@ std::vector<EntryPoint> Inspector::GetEntryPoints() {
for (auto* param : sem->Parameters()) { for (auto* param : sem->Parameters()) {
AddEntryPointInOutVariables( AddEntryPointInOutVariables(
program_->Symbols().NameFor(param->Declaration()->symbol), program_->Symbols().NameFor(param->Declaration()->symbol),
param->Type(), param->Declaration()->decorations, param->Type(), param->Declaration()->attributes,
entry_point.input_variables); entry_point.input_variables);
entry_point.input_position_used |= entry_point.input_position_used |=
ContainsBuiltin(ast::Builtin::kPosition, param->Type(), ContainsBuiltin(ast::Builtin::kPosition, param->Type(),
param->Declaration()->decorations); param->Declaration()->attributes);
entry_point.front_facing_used |= entry_point.front_facing_used |=
ContainsBuiltin(ast::Builtin::kFrontFacing, param->Type(), ContainsBuiltin(ast::Builtin::kFrontFacing, param->Type(),
param->Declaration()->decorations); param->Declaration()->attributes);
entry_point.sample_index_used |= entry_point.sample_index_used |=
ContainsBuiltin(ast::Builtin::kSampleIndex, param->Type(), ContainsBuiltin(ast::Builtin::kSampleIndex, param->Type(),
param->Declaration()->decorations); param->Declaration()->attributes);
entry_point.input_sample_mask_used |= entry_point.input_sample_mask_used |=
ContainsBuiltin(ast::Builtin::kSampleMask, param->Type(), ContainsBuiltin(ast::Builtin::kSampleMask, param->Type(),
param->Declaration()->decorations); param->Declaration()->attributes);
entry_point.num_workgroups_used |= entry_point.num_workgroups_used |=
ContainsBuiltin(ast::Builtin::kNumWorkgroups, param->Type(), ContainsBuiltin(ast::Builtin::kNumWorkgroups, param->Type(),
param->Declaration()->decorations); param->Declaration()->attributes);
} }
if (!sem->ReturnType()->Is<sem::Void>()) { if (!sem->ReturnType()->Is<sem::Void>()) {
AddEntryPointInOutVariables("<retval>", sem->ReturnType(), AddEntryPointInOutVariables("<retval>", sem->ReturnType(),
func->return_type_decorations, func->return_type_attributes,
entry_point.output_variables); entry_point.output_variables);
entry_point.output_sample_mask_used = entry_point.output_sample_mask_used =
ContainsBuiltin(ast::Builtin::kSampleMask, sem->ReturnType(), ContainsBuiltin(ast::Builtin::kSampleMask, sem->ReturnType(),
func->return_type_decorations); func->return_type_attributes);
} }
for (auto* var : sem->TransitivelyReferencedGlobals()) { for (auto* var : sem->TransitivelyReferencedGlobals()) {
@ -213,10 +213,10 @@ std::vector<EntryPoint> Inspector::GetEntryPoints() {
overridable_constant.is_initialized = overridable_constant.is_initialized =
global->Declaration()->constructor; global->Declaration()->constructor;
auto* override_deco = ast::GetDecoration<ast::OverrideDecoration>( auto* override_attr = ast::GetAttribute<ast::OverrideAttribute>(
global->Declaration()->decorations); global->Declaration()->attributes);
overridable_constant.is_numeric_id_specified = overridable_constant.is_numeric_id_specified =
override_deco ? override_deco->has_value : false; override_attr ? override_attr->has_value : false;
entry_point.overridable_constants.push_back(overridable_constant); entry_point.overridable_constants.push_back(overridable_constant);
} }
@ -579,10 +579,10 @@ const ast::Function* Inspector::FindEntryPointByName(const std::string& name) {
void Inspector::AddEntryPointInOutVariables( void Inspector::AddEntryPointInOutVariables(
std::string name, std::string name,
const sem::Type* type, const sem::Type* type,
const ast::DecorationList& decorations, const ast::AttributeList& attributes,
std::vector<StageVariable>& variables) const { std::vector<StageVariable>& variables) const {
// Skip builtins. // Skip builtins.
if (ast::HasDecoration<ast::BuiltinDecoration>(decorations)) { if (ast::HasAttribute<ast::BuiltinAttribute>(attributes)) {
return; return;
} }
@ -594,7 +594,7 @@ void Inspector::AddEntryPointInOutVariables(
AddEntryPointInOutVariables( AddEntryPointInOutVariables(
name + "." + name + "." +
program_->Symbols().NameFor(member->Declaration()->symbol), program_->Symbols().NameFor(member->Declaration()->symbol),
member->Type(), member->Declaration()->decorations, variables); member->Type(), member->Declaration()->attributes, variables);
} }
return; return;
} }
@ -606,28 +606,28 @@ void Inspector::AddEntryPointInOutVariables(
std::tie(stage_variable.component_type, stage_variable.composition_type) = std::tie(stage_variable.component_type, stage_variable.composition_type) =
CalculateComponentAndComposition(type); CalculateComponentAndComposition(type);
auto* location = ast::GetDecoration<ast::LocationDecoration>(decorations); auto* location = ast::GetAttribute<ast::LocationAttribute>(attributes);
TINT_ASSERT(Inspector, location != nullptr); TINT_ASSERT(Inspector, location != nullptr);
stage_variable.has_location_decoration = true; stage_variable.has_location_attribute = true;
stage_variable.location_decoration = location->value; stage_variable.location_attribute = location->value;
std::tie(stage_variable.interpolation_type, std::tie(stage_variable.interpolation_type,
stage_variable.interpolation_sampling) = stage_variable.interpolation_sampling) =
CalculateInterpolationData(type, decorations); CalculateInterpolationData(type, attributes);
variables.push_back(stage_variable); variables.push_back(stage_variable);
} }
bool Inspector::ContainsBuiltin(ast::Builtin builtin, bool Inspector::ContainsBuiltin(ast::Builtin builtin,
const sem::Type* type, const sem::Type* type,
const ast::DecorationList& decorations) const { const ast::AttributeList& attributes) const {
auto* unwrapped_type = type->UnwrapRef(); auto* unwrapped_type = type->UnwrapRef();
if (auto* struct_ty = unwrapped_type->As<sem::Struct>()) { if (auto* struct_ty = unwrapped_type->As<sem::Struct>()) {
// Recurse into members. // Recurse into members.
for (auto* member : struct_ty->Members()) { for (auto* member : struct_ty->Members()) {
if (ContainsBuiltin(builtin, member->Type(), if (ContainsBuiltin(builtin, member->Type(),
member->Declaration()->decorations)) { member->Declaration()->attributes)) {
return true; return true;
} }
} }
@ -636,7 +636,7 @@ bool Inspector::ContainsBuiltin(ast::Builtin builtin,
// Base case: check for builtin // Base case: check for builtin
auto* builtin_declaration = auto* builtin_declaration =
ast::GetDecoration<ast::BuiltinDecoration>(decorations); ast::GetAttribute<ast::BuiltinAttribute>(attributes);
if (!builtin_declaration || builtin_declaration->builtin != builtin) { if (!builtin_declaration || builtin_declaration->builtin != builtin) {
return false; return false;
} }

View File

@ -158,19 +158,19 @@ class Inspector {
/// Otherwise, add the variable unless it is a builtin. /// Otherwise, add the variable unless it is a builtin.
/// @param name the name of the variable being added /// @param name the name of the variable being added
/// @param type the type of the variable /// @param type the type of the variable
/// @param decorations the variable decorations /// @param attributes the variable attributes
/// @param variables the list to add the variables to /// @param variables the list to add the variables to
void AddEntryPointInOutVariables(std::string name, void AddEntryPointInOutVariables(std::string name,
const sem::Type* type, const sem::Type* type,
const ast::DecorationList& decorations, const ast::AttributeList& attributes,
std::vector<StageVariable>& variables) const; std::vector<StageVariable>& variables) const;
/// Recursively determine if the type contains builtin. /// Recursively determine if the type contains builtin.
/// If `type` is a struct, recurse into members to check for the decoration. /// If `type` is a struct, recurse into members to check for the attribute.
/// Otherwise, check `decorations` for the decoration. /// Otherwise, check `attributes` for the attribute.
bool ContainsBuiltin(ast::Builtin builtin, bool ContainsBuiltin(ast::Builtin builtin,
const sem::Type* type, const sem::Type* type,
const ast::DecorationList& decorations) const; const ast::AttributeList& attributes) const;
/// Gathers all the texture resource bindings of the given type for the given /// Gathers all the texture resource bindings of the given type for the given
/// entry point. /// entry point.

View File

@ -14,11 +14,11 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/ast/call_statement.h" #include "src/ast/call_statement.h"
#include "src/ast/disable_validation_decoration.h" #include "src/ast/disable_validation_attribute.h"
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include "src/ast/struct_block_decoration.h" #include "src/ast/struct_block_attribute.h"
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
#include "src/inspector/test_inspector_builder.h" #include "src/inspector/test_inspector_builder.h"
#include "src/inspector/test_inspector_runner.h" #include "src/inspector/test_inspector_runner.h"
#include "src/program_builder.h" #include "src/program_builder.h"
@ -172,7 +172,7 @@ TEST_F(InspectorGetEntryPointTest, NoEntryPoints) {
} }
TEST_F(InspectorGetEntryPointTest, OneEntryPoint) { TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
MakeEmptyBodyFunction("foo", ast::DecorationList{ MakeEmptyBodyFunction("foo", ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -190,13 +190,13 @@ TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
} }
TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) { TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
MakeEmptyBodyFunction("foo", ast::DecorationList{ MakeEmptyBodyFunction("foo", ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
MakeEmptyBodyFunction("bar", MakeEmptyBodyFunction("bar",
ast::DecorationList{Stage(ast::PipelineStage::kCompute), ast::AttributeList{Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1)}); WorkgroupSize(1)});
// TODO(dsinclair): Update to run the namer transform when available. // TODO(dsinclair): Update to run the namer transform when available.
@ -217,13 +217,12 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) { TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
MakeEmptyBodyFunction("func", {}); MakeEmptyBodyFunction("func", {});
MakeCallerBodyFunction( MakeCallerBodyFunction("foo", {"func"},
"foo", {"func"}, ast::AttributeList{Stage(ast::PipelineStage::kCompute),
ast::DecorationList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
WorkgroupSize(1)});
MakeCallerBodyFunction("bar", {"func"}, MakeCallerBodyFunction("bar", {"func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -245,8 +244,8 @@ TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) { TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
MakeEmptyBodyFunction("foo", MakeEmptyBodyFunction("foo",
ast::DecorationList{Stage(ast::PipelineStage::kCompute), ast::AttributeList{Stage(ast::PipelineStage::kCompute),
WorkgroupSize(8, 2, 1)}); WorkgroupSize(8, 2, 1)});
Inspector& inspector = Build(); Inspector& inspector = Build();
@ -282,7 +281,7 @@ TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
MakeEmptyBodyFunction("func", {}); MakeEmptyBodyFunction("func", {});
MakeCallerBodyFunction("foo", {"func"}, MakeCallerBodyFunction("foo", {"func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -315,14 +314,14 @@ TEST_P(InspectorGetEntryPointComponentAndCompositionTest, Test) {
ASSERT_EQ(1u, result[0].input_variables.size()); ASSERT_EQ(1u, result[0].input_variables.size());
EXPECT_EQ("in_var", result[0].input_variables[0].name); EXPECT_EQ("in_var", result[0].input_variables[0].name);
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration); EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration); EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
EXPECT_EQ(component, result[0].input_variables[0].component_type); EXPECT_EQ(component, result[0].input_variables[0].component_type);
ASSERT_EQ(1u, result[0].output_variables.size()); ASSERT_EQ(1u, result[0].output_variables.size());
EXPECT_EQ("<retval>", result[0].output_variables[0].name); EXPECT_EQ("<retval>", result[0].output_variables[0].name);
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration); EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration); EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
EXPECT_EQ(component, result[0].output_variables[0].component_type); EXPECT_EQ(component, result[0].output_variables[0].component_type);
} }
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
@ -351,28 +350,28 @@ TEST_F(InspectorGetEntryPointTest, MultipleInOutVariables) {
ASSERT_EQ(3u, result[0].input_variables.size()); ASSERT_EQ(3u, result[0].input_variables.size());
EXPECT_EQ("in_var0", result[0].input_variables[0].name); EXPECT_EQ("in_var0", result[0].input_variables[0].name);
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration); EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration); EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
EXPECT_EQ(InterpolationType::kFlat, EXPECT_EQ(InterpolationType::kFlat,
result[0].input_variables[0].interpolation_type); result[0].input_variables[0].interpolation_type);
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
EXPECT_EQ("in_var1", result[0].input_variables[1].name); EXPECT_EQ("in_var1", result[0].input_variables[1].name);
EXPECT_TRUE(result[0].input_variables[1].has_location_decoration); EXPECT_TRUE(result[0].input_variables[1].has_location_attribute);
EXPECT_EQ(1u, result[0].input_variables[1].location_decoration); EXPECT_EQ(1u, result[0].input_variables[1].location_attribute);
EXPECT_EQ(InterpolationType::kFlat, EXPECT_EQ(InterpolationType::kFlat,
result[0].input_variables[1].interpolation_type); result[0].input_variables[1].interpolation_type);
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
EXPECT_EQ("in_var4", result[0].input_variables[2].name); EXPECT_EQ("in_var4", result[0].input_variables[2].name);
EXPECT_TRUE(result[0].input_variables[2].has_location_decoration); EXPECT_TRUE(result[0].input_variables[2].has_location_attribute);
EXPECT_EQ(4u, result[0].input_variables[2].location_decoration); EXPECT_EQ(4u, result[0].input_variables[2].location_attribute);
EXPECT_EQ(InterpolationType::kFlat, EXPECT_EQ(InterpolationType::kFlat,
result[0].input_variables[2].interpolation_type); result[0].input_variables[2].interpolation_type);
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type);
ASSERT_EQ(1u, result[0].output_variables.size()); ASSERT_EQ(1u, result[0].output_variables.size());
EXPECT_EQ("<retval>", result[0].output_variables[0].name); EXPECT_EQ("<retval>", result[0].output_variables[0].name);
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration); EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration); EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
} }
@ -394,30 +393,30 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutVariables) {
ASSERT_EQ(1u, result[0].input_variables.size()); ASSERT_EQ(1u, result[0].input_variables.size());
EXPECT_EQ("in_var_foo", result[0].input_variables[0].name); EXPECT_EQ("in_var_foo", result[0].input_variables[0].name);
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration); EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration); EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
EXPECT_EQ(InterpolationType::kFlat, EXPECT_EQ(InterpolationType::kFlat,
result[0].input_variables[0].interpolation_type); result[0].input_variables[0].interpolation_type);
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
ASSERT_EQ(1u, result[0].output_variables.size()); ASSERT_EQ(1u, result[0].output_variables.size());
EXPECT_EQ("<retval>", result[0].output_variables[0].name); EXPECT_EQ("<retval>", result[0].output_variables[0].name);
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration); EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration); EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
ASSERT_EQ(1u, result[1].input_variables.size()); ASSERT_EQ(1u, result[1].input_variables.size());
EXPECT_EQ("in_var_bar", result[1].input_variables[0].name); EXPECT_EQ("in_var_bar", result[1].input_variables[0].name);
EXPECT_TRUE(result[1].input_variables[0].has_location_decoration); EXPECT_TRUE(result[1].input_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[1].input_variables[0].location_decoration); EXPECT_EQ(0u, result[1].input_variables[0].location_attribute);
EXPECT_EQ(InterpolationType::kFlat, EXPECT_EQ(InterpolationType::kFlat,
result[1].input_variables[0].interpolation_type); result[1].input_variables[0].interpolation_type);
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type);
ASSERT_EQ(1u, result[1].output_variables.size()); ASSERT_EQ(1u, result[1].output_variables.size());
EXPECT_EQ("<retval>", result[1].output_variables[0].name); EXPECT_EQ("<retval>", result[1].output_variables[0].name);
EXPECT_TRUE(result[1].output_variables[0].has_location_decoration); EXPECT_TRUE(result[1].output_variables[0].has_location_attribute);
EXPECT_EQ(1u, result[1].output_variables[0].location_decoration); EXPECT_EQ(1u, result[1].output_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[1].output_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[1].output_variables[0].component_type);
} }
@ -437,8 +436,8 @@ TEST_F(InspectorGetEntryPointTest, BuiltInsNotStageVariables) {
ASSERT_EQ(1u, result[0].input_variables.size()); ASSERT_EQ(1u, result[0].input_variables.size());
EXPECT_EQ("in_var1", result[0].input_variables[0].name); EXPECT_EQ("in_var1", result[0].input_variables[0].name);
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration); EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration); EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[0].component_type); EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[0].component_type);
ASSERT_EQ(0u, result[0].output_variables.size()); ASSERT_EQ(0u, result[0].output_variables.size());
@ -457,22 +456,22 @@ TEST_F(InspectorGetEntryPointTest, InOutStruct) {
ASSERT_EQ(2u, result[0].input_variables.size()); ASSERT_EQ(2u, result[0].input_variables.size());
EXPECT_EQ("param.a", result[0].input_variables[0].name); EXPECT_EQ("param.a", result[0].input_variables[0].name);
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration); EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration); EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
EXPECT_EQ("param.b", result[0].input_variables[1].name); EXPECT_EQ("param.b", result[0].input_variables[1].name);
EXPECT_TRUE(result[0].input_variables[1].has_location_decoration); EXPECT_TRUE(result[0].input_variables[1].has_location_attribute);
EXPECT_EQ(1u, result[0].input_variables[1].location_decoration); EXPECT_EQ(1u, result[0].input_variables[1].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
ASSERT_EQ(2u, result[0].output_variables.size()); ASSERT_EQ(2u, result[0].output_variables.size());
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name); EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration); EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration); EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name); EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
EXPECT_TRUE(result[0].output_variables[1].has_location_decoration); EXPECT_TRUE(result[0].output_variables[1].has_location_attribute);
EXPECT_EQ(1u, result[0].output_variables[1].location_decoration); EXPECT_EQ(1u, result[0].output_variables[1].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
} }
@ -493,22 +492,22 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutSharedStruct) {
ASSERT_EQ(2u, result[0].output_variables.size()); ASSERT_EQ(2u, result[0].output_variables.size());
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name); EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration); EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration); EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name); EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
EXPECT_TRUE(result[0].output_variables[1].has_location_decoration); EXPECT_TRUE(result[0].output_variables[1].has_location_attribute);
EXPECT_EQ(1u, result[0].output_variables[1].location_decoration); EXPECT_EQ(1u, result[0].output_variables[1].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
ASSERT_EQ(2u, result[1].input_variables.size()); ASSERT_EQ(2u, result[1].input_variables.size());
EXPECT_EQ("param.a", result[1].input_variables[0].name); EXPECT_EQ("param.a", result[1].input_variables[0].name);
EXPECT_TRUE(result[1].input_variables[0].has_location_decoration); EXPECT_TRUE(result[1].input_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[1].input_variables[0].location_decoration); EXPECT_EQ(0u, result[1].input_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type);
EXPECT_EQ("param.b", result[1].input_variables[1].name); EXPECT_EQ("param.b", result[1].input_variables[1].name);
EXPECT_TRUE(result[1].input_variables[1].has_location_decoration); EXPECT_TRUE(result[1].input_variables[1].has_location_attribute);
EXPECT_EQ(1u, result[1].input_variables[1].location_decoration); EXPECT_EQ(1u, result[1].input_variables[1].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[1].component_type); EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[1].component_type);
ASSERT_EQ(0u, result[1].output_variables.size()); ASSERT_EQ(0u, result[1].output_variables.size());
@ -532,34 +531,34 @@ TEST_F(InspectorGetEntryPointTest, MixInOutVariablesAndStruct) {
ASSERT_EQ(5u, result[0].input_variables.size()); ASSERT_EQ(5u, result[0].input_variables.size());
EXPECT_EQ("param_a.a", result[0].input_variables[0].name); EXPECT_EQ("param_a.a", result[0].input_variables[0].name);
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration); EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration); EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
EXPECT_EQ("param_a.b", result[0].input_variables[1].name); EXPECT_EQ("param_a.b", result[0].input_variables[1].name);
EXPECT_TRUE(result[0].input_variables[1].has_location_decoration); EXPECT_TRUE(result[0].input_variables[1].has_location_attribute);
EXPECT_EQ(1u, result[0].input_variables[1].location_decoration); EXPECT_EQ(1u, result[0].input_variables[1].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
EXPECT_EQ("param_b.a", result[0].input_variables[2].name); EXPECT_EQ("param_b.a", result[0].input_variables[2].name);
EXPECT_TRUE(result[0].input_variables[2].has_location_decoration); EXPECT_TRUE(result[0].input_variables[2].has_location_attribute);
EXPECT_EQ(2u, result[0].input_variables[2].location_decoration); EXPECT_EQ(2u, result[0].input_variables[2].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type);
EXPECT_EQ("param_c", result[0].input_variables[3].name); EXPECT_EQ("param_c", result[0].input_variables[3].name);
EXPECT_TRUE(result[0].input_variables[3].has_location_decoration); EXPECT_TRUE(result[0].input_variables[3].has_location_attribute);
EXPECT_EQ(3u, result[0].input_variables[3].location_decoration); EXPECT_EQ(3u, result[0].input_variables[3].location_attribute);
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[3].component_type); EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[3].component_type);
EXPECT_EQ("param_d", result[0].input_variables[4].name); EXPECT_EQ("param_d", result[0].input_variables[4].name);
EXPECT_TRUE(result[0].input_variables[4].has_location_decoration); EXPECT_TRUE(result[0].input_variables[4].has_location_attribute);
EXPECT_EQ(4u, result[0].input_variables[4].location_decoration); EXPECT_EQ(4u, result[0].input_variables[4].location_attribute);
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[4].component_type); EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[4].component_type);
ASSERT_EQ(2u, result[0].output_variables.size()); ASSERT_EQ(2u, result[0].output_variables.size());
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name); EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration); EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration); EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name); EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
EXPECT_TRUE(result[0].output_variables[1].has_location_decoration); EXPECT_TRUE(result[0].output_variables[1].has_location_attribute);
EXPECT_EQ(1u, result[0].output_variables[1].location_decoration); EXPECT_EQ(1u, result[0].output_variables[1].location_attribute);
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type); EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
} }
@ -1050,7 +1049,7 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_NoEntryPoints) {
// TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass // TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass
// through // through
TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) { TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
MakeEmptyBodyFunction("foo", ast::DecorationList{ MakeEmptyBodyFunction("foo", ast::AttributeList{
Stage(ast::PipelineStage::kVertex), Stage(ast::PipelineStage::kVertex),
}); });
@ -1069,7 +1068,7 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
// through // through
TEST_F(InspectorGetRemappedNameForEntryPointTest, TEST_F(InspectorGetRemappedNameForEntryPointTest,
DISABLED_MultipleEntryPoints) { DISABLED_MultipleEntryPoints) {
MakeEmptyBodyFunction("foo", ast::DecorationList{ MakeEmptyBodyFunction("foo", ast::AttributeList{
Stage(ast::PipelineStage::kVertex), Stage(ast::PipelineStage::kVertex),
}); });
@ -1077,8 +1076,8 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest,
// available. // available.
MakeEmptyBodyFunction("bar", MakeEmptyBodyFunction("bar",
ast::DecorationList{Stage(ast::PipelineStage::kCompute), ast::AttributeList{Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1)}); WorkgroupSize(1)});
Inspector& inspector = Build(); Inspector& inspector = Build();
@ -1222,8 +1221,8 @@ TEST_F(InspectorGetConstantNameToIdMapTest, WithAndWithoutIds) {
TEST_F(InspectorGetStorageSizeTest, Empty) { TEST_F(InspectorGetStorageSizeTest, Empty) {
MakeEmptyBodyFunction("ep_func", MakeEmptyBodyFunction("ep_func",
ast::DecorationList{Stage(ast::PipelineStage::kCompute), ast::AttributeList{Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1)}); WorkgroupSize(1)});
Inspector& inspector = Build(); Inspector& inspector = Build();
EXPECT_EQ(0u, inspector.GetStorageSize("ep_func")); EXPECT_EQ(0u, inspector.GetStorageSize("ep_func"));
} }
@ -1260,7 +1259,7 @@ TEST_F(InspectorGetStorageSizeTest, Simple_Struct) {
{{0, ty.i32()}}); {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"ub_func", "sb_func", "rosb_func"}, MakeCallerBodyFunction("ep_func", {"ub_func", "sb_func", "rosb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kCompute), Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1), WorkgroupSize(1),
}); });
@ -1299,7 +1298,7 @@ TEST_F(InspectorGetStorageSizeTest, StructVec3) {
TEST_F(InspectorGetResourceBindingsTest, Empty) { TEST_F(InspectorGetResourceBindingsTest, Empty) {
MakeCallerBodyFunction("ep_func", {}, MakeCallerBodyFunction("ep_func", {},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1353,7 +1352,7 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
MakeCallerBodyFunction("ep_func", MakeCallerBodyFunction("ep_func",
{"ub_func", "sb_func", "rosb_func", "s_func", {"ub_func", "sb_func", "rosb_func", "s_func",
"cs_func", "depth_ms_func", "st_func"}, "cs_func", "depth_ms_func", "st_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1424,7 +1423,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonEntryPointFunc) {
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"ub_func"}, MakeCallerBodyFunction("ep_func", {"ub_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1440,7 +1439,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple_NonStruct) {
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.i32(), {}); MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.i32(), {});
MakeCallerBodyFunction("ep_func", {"ub_func"}, MakeCallerBodyFunction("ep_func", {"ub_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1465,7 +1464,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple_Struct) {
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"ub_func"}, MakeCallerBodyFunction("ep_func", {"ub_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1492,7 +1491,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleMembers) {
"ub_func", "foo_ub", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}}); "ub_func", "foo_ub", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
MakeCallerBodyFunction("ep_func", {"ub_func"}, MakeCallerBodyFunction("ep_func", {"ub_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1518,7 +1517,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingPadding) {
{{0, ty.vec3<f32>()}}); {{0, ty.vec3<f32>()}});
MakeCallerBodyFunction("ep_func", {"ub_func"}, MakeCallerBodyFunction("ep_func", {"ub_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1541,7 +1540,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonStructVec3) {
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {}); MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
MakeCallerBodyFunction("ep_func", {"ub_func"}, MakeCallerBodyFunction("ep_func", {"ub_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1582,7 +1581,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) {
Func("ep_func", ast::VariableList(), ty.void_(), Func("ep_func", ast::VariableList(), ty.void_(),
ast::StatementList{FuncCall("ub_foo_func"), FuncCall("ub_bar_func"), ast::StatementList{FuncCall("ub_foo_func"), FuncCall("ub_bar_func"),
FuncCall("ub_baz_func"), Return()}, FuncCall("ub_baz_func"), Return()},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1621,14 +1620,14 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingArray) {
"foo_type", "foo_type",
{Member("0i32", ty.i32()), {Member("0i32", ty.i32()),
Member("b", ty.array(ty.u32(), 4, /*stride*/ 16), {MemberAlign(16)})}, Member("b", ty.array(ty.u32(), 4, /*stride*/ 16), {MemberAlign(16)})},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockAttribute>()});
AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0); AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"ub_func"}, MakeCallerBodyFunction("ep_func", {"ub_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1651,7 +1650,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple_NonStruct) {
MakePlainGlobalReferenceBodyFunction("sb_func", "foo_sb", ty.i32(), {}); MakePlainGlobalReferenceBodyFunction("sb_func", "foo_sb", ty.i32(), {});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1676,7 +1675,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple_Struct) {
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1706,7 +1705,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) {
"sb_func", "foo_sb", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}}); "sb_func", "foo_sb", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1754,7 +1753,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
FuncCall("sb_baz_func"), FuncCall("sb_baz_func"),
Return(), Return(),
}, },
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1794,7 +1793,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1822,7 +1821,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1848,7 +1847,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) {
{{0, ty.vec3<f32>()}}); {{0, ty.vec3<f32>()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1871,7 +1870,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, NonStructVec3) {
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {}); MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
MakeCallerBodyFunction("ep_func", {"ub_func"}, MakeCallerBodyFunction("ep_func", {"ub_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1896,7 +1895,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1914,7 +1913,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -1963,7 +1962,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
FuncCall("sb_baz_func"), FuncCall("sb_baz_func"),
Return(), Return(),
}, },
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2006,7 +2005,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2035,7 +2034,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2060,7 +2059,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
MakeCallerBodyFunction("ep_func", {"sb_func"}, MakeCallerBodyFunction("ep_func", {"sb_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2080,7 +2079,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
"foo_coords", ty.f32(), "foo_coords", ty.f32(),
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2096,7 +2095,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) { TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
MakeEmptyBodyFunction("ep_func", ast::DecorationList{ MakeEmptyBodyFunction("ep_func", ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2119,7 +2118,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
"foo_coords", ty.f32(), {}); "foo_coords", ty.f32(), {});
MakeCallerBodyFunction("ep_func", {"foo_func"}, MakeCallerBodyFunction("ep_func", {"foo_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2143,7 +2142,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
"foo_coords", ty.f32(), "foo_coords", ty.f32(),
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2162,7 +2161,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
MakeComparisonSamplerReferenceBodyFunction( MakeComparisonSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(), "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2183,7 +2182,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
MakeComparisonSamplerReferenceBodyFunction( MakeComparisonSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(), "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2200,7 +2199,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) { TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
MakeEmptyBodyFunction("ep_func", ast::DecorationList{ MakeEmptyBodyFunction("ep_func", ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2224,7 +2223,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
"foo_depth", ty.f32(), {}); "foo_depth", ty.f32(), {});
MakeCallerBodyFunction("ep_func", {"foo_func"}, MakeCallerBodyFunction("ep_func", {"foo_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2249,7 +2248,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
MakeComparisonSamplerReferenceBodyFunction( MakeComparisonSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(), "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2268,7 +2267,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
"foo_coords", ty.f32(), "foo_coords", ty.f32(),
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2281,7 +2280,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
} }
TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) { TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
MakeEmptyBodyFunction("foo", ast::DecorationList{ MakeEmptyBodyFunction("foo", ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2304,7 +2303,7 @@ TEST_P(InspectorGetSampledTextureResourceBindingsTestWithParam, textureSample) {
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
"foo_coords", "foo_coords",
GetBaseType(GetParam().sampled_kind), GetBaseType(GetParam().sampled_kind),
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2363,7 +2362,7 @@ TEST_P(InspectorGetSampledArrayTextureResourceBindingsTestWithParam,
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
"foo_coords", "foo_array_index", "foo_coords", "foo_array_index",
GetBaseType(GetParam().sampled_kind), GetBaseType(GetParam().sampled_kind),
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2408,7 +2407,7 @@ TEST_P(InspectorGetMultisampledTextureResourceBindingsTestWithParam,
CallStmt(Call("textureLoad", "foo_texture", "foo_coords", CallStmt(Call("textureLoad", "foo_texture", "foo_coords",
"foo_sample_index")), "foo_sample_index")),
}, },
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2451,7 +2450,7 @@ INSTANTIATE_TEST_SUITE_P(
inspector::ResourceBinding::SampledKind::kUInt})); inspector::ResourceBinding::SampledKind::kUInt}));
TEST_F(InspectorGetMultisampledArrayTextureResourceBindingsTest, Empty) { TEST_F(InspectorGetMultisampledArrayTextureResourceBindingsTest, Empty) {
MakeEmptyBodyFunction("foo", ast::DecorationList{ MakeEmptyBodyFunction("foo", ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2476,7 +2475,7 @@ TEST_P(InspectorGetMultisampledArrayTextureResourceBindingsTestWithParam,
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
"foo_coords", "foo_array_index", "foo_coords", "foo_array_index",
GetBaseType(GetParam().sampled_kind), GetBaseType(GetParam().sampled_kind),
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2512,7 +2511,7 @@ INSTANTIATE_TEST_SUITE_P(
inspector::ResourceBinding::SampledKind::kUInt})); inspector::ResourceBinding::SampledKind::kUInt}));
TEST_F(InspectorGetStorageTextureResourceBindingsTest, Empty) { TEST_F(InspectorGetStorageTextureResourceBindingsTest, Empty) {
MakeEmptyBodyFunction("ep", ast::DecorationList{ MakeEmptyBodyFunction("ep", ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2560,7 +2559,7 @@ TEST_P(InspectorGetStorageTextureResourceBindingsTestWithParam, Simple) {
MakeStorageTextureBodyFunction( MakeStorageTextureBodyFunction(
"ep", "st_var", dim_type, "ep", "st_var", dim_type,
ast::DecorationList{Stage(ast::PipelineStage::kFragment)}); ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
Inspector& inspector = Build(); Inspector& inspector = Build();
@ -2649,7 +2648,7 @@ TEST_P(InspectorGetDepthTextureResourceBindingsTestWithParam,
ast::StatementList{ ast::StatementList{
CallStmt(Call("textureDimensions", "dt")), CallStmt(Call("textureDimensions", "dt")),
}, },
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2693,7 +2692,7 @@ TEST_F(InspectorGetDepthMultisampledTextureResourceBindingsTest,
ast::StatementList{ ast::StatementList{
CallStmt(Call("textureDimensions", "tex")), CallStmt(Call("textureDimensions", "tex")),
}, },
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2718,7 +2717,7 @@ TEST_F(InspectorGetExternalTextureResourceBindingsTest, Simple) {
ast::StatementList{ ast::StatementList{
CallStmt(Call("textureDimensions", "et")), CallStmt(Call("textureDimensions", "et")),
}, },
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kFragment), Stage(ast::PipelineStage::kFragment),
}); });
@ -2996,8 +2995,8 @@ fn direct(@location(0) fragUV: vec2<f32>,
TEST_F(InspectorGetWorkgroupStorageSizeTest, Empty) { TEST_F(InspectorGetWorkgroupStorageSizeTest, Empty) {
MakeEmptyBodyFunction("ep_func", MakeEmptyBodyFunction("ep_func",
ast::DecorationList{Stage(ast::PipelineStage::kCompute), ast::AttributeList{Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1)}); WorkgroupSize(1)});
Inspector& inspector = Build(); Inspector& inspector = Build();
EXPECT_EQ(0u, inspector.GetWorkgroupStorageSize("ep_func")); EXPECT_EQ(0u, inspector.GetWorkgroupStorageSize("ep_func"));
} }
@ -3007,7 +3006,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, Simple) {
MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {}); MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
MakeCallerBodyFunction("ep_func", {"f32_func"}, MakeCallerBodyFunction("ep_func", {"f32_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kCompute), Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1), WorkgroupSize(1),
}); });
@ -3031,7 +3030,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, CompoundTypes) {
MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {}); MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
MakeCallerBodyFunction("ep_func", {"wg_struct_func", "f32_func"}, MakeCallerBodyFunction("ep_func", {"wg_struct_func", "f32_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kCompute), Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1), WorkgroupSize(1),
}); });
@ -3048,7 +3047,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, AlignmentPadding) {
{}); {});
MakeCallerBodyFunction("ep_func", {"wg_func"}, MakeCallerBodyFunction("ep_func", {"wg_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kCompute), Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1), WorkgroupSize(1),
}); });
@ -3064,7 +3063,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, StructAlignment) {
const auto* wg_struct_type = MakeStructTypeFromMembers( const auto* wg_struct_type = MakeStructTypeFromMembers(
"WgStruct", "WgStruct",
{MakeStructMember(0, ty.f32(), {MakeStructMember(0, ty.f32(),
{create<ast::StructMemberAlignDecoration>(1024)})}, {create<ast::StructMemberAlignAttribute>(1024)})},
/*is_block=*/false); /*is_block=*/false);
AddWorkgroupStorage("wg_struct_var", ty.Of(wg_struct_type)); AddWorkgroupStorage("wg_struct_var", ty.Of(wg_struct_type));
@ -3072,7 +3071,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, StructAlignment) {
{{0, ty.f32()}}); {{0, ty.f32()}});
MakeCallerBodyFunction("ep_func", {"wg_struct_func"}, MakeCallerBodyFunction("ep_func", {"wg_struct_func"},
ast::DecorationList{ ast::AttributeList{
Stage(ast::PipelineStage::kCompute), Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1), WorkgroupSize(1),
}); });

View File

@ -29,14 +29,14 @@ InspectorBuilder::InspectorBuilder() = default;
InspectorBuilder::~InspectorBuilder() = default; InspectorBuilder::~InspectorBuilder() = default;
void InspectorBuilder::MakeEmptyBodyFunction(std::string name, void InspectorBuilder::MakeEmptyBodyFunction(std::string name,
ast::DecorationList decorations) { ast::AttributeList attributes) {
Func(name, ast::VariableList(), ty.void_(), ast::StatementList{Return()}, Func(name, ast::VariableList(), ty.void_(), ast::StatementList{Return()},
decorations); attributes);
} }
void InspectorBuilder::MakeCallerBodyFunction(std::string caller, void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
std::vector<std::string> callees, std::vector<std::string> callees,
ast::DecorationList decorations) { ast::AttributeList attributes) {
ast::StatementList body; ast::StatementList body;
body.reserve(callees.size() + 1); body.reserve(callees.size() + 1);
for (auto callee : callees) { for (auto callee : callees) {
@ -44,7 +44,7 @@ void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
} }
body.push_back(Return()); body.push_back(Return());
Func(caller, ast::VariableList(), ty.void_(), body, decorations); Func(caller, ast::VariableList(), ty.void_(), body, attributes);
} }
const ast::Struct* InspectorBuilder::MakeInOutStruct( const ast::Struct* InspectorBuilder::MakeInOutStruct(
@ -65,13 +65,13 @@ const ast::Function* InspectorBuilder::MakePlainGlobalReferenceBodyFunction(
std::string func, std::string func,
std::string var, std::string var,
const ast::Type* type, const ast::Type* type,
ast::DecorationList decorations) { ast::AttributeList attributes) {
ast::StatementList stmts; ast::StatementList stmts;
stmts.emplace_back(Decl(Var("local_" + var, type))); stmts.emplace_back(Decl(Var("local_" + var, type)));
stmts.emplace_back(Assign("local_" + var, var)); stmts.emplace_back(Assign("local_" + var, var));
stmts.emplace_back(Return()); stmts.emplace_back(Return());
return Func(func, ast::VariableList(), ty.void_(), stmts, decorations); return Func(func, ast::VariableList(), ty.void_(), stmts, attributes);
} }
bool InspectorBuilder::ContainsName(const std::vector<StageVariable>& vec, bool InspectorBuilder::ContainsName(const std::vector<StageVariable>& vec,
@ -104,18 +104,18 @@ const ast::Struct* InspectorBuilder::MakeStructTypeFromMembers(
const std::string& name, const std::string& name,
ast::StructMemberList members, ast::StructMemberList members,
bool is_block) { bool is_block) {
ast::DecorationList decos; ast::AttributeList attrs;
if (is_block) { if (is_block) {
decos.push_back(create<ast::StructBlockDecoration>()); attrs.push_back(create<ast::StructBlockAttribute>());
} }
return Structure(name, std::move(members), decos); return Structure(name, std::move(members), attrs);
} }
const ast::StructMember* InspectorBuilder::MakeStructMember( const ast::StructMember* InspectorBuilder::MakeStructMember(
size_t index, size_t index,
const ast::Type* type, const ast::Type* type,
ast::DecorationList decorations) { ast::AttributeList attributes) {
return Member(StructMemberName(index, type), type, std::move(decorations)); return Member(StructMemberName(index, type), type, std::move(attributes));
} }
const ast::Struct* InspectorBuilder::MakeUniformBufferType( const ast::Struct* InspectorBuilder::MakeUniformBufferType(
@ -136,9 +136,9 @@ void InspectorBuilder::AddUniformBuffer(const std::string& name,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
Global(name, type, ast::StorageClass::kUniform, Global(name, type, ast::StorageClass::kUniform,
ast::DecorationList{ ast::AttributeList{
create<ast::BindingDecoration>(binding), create<ast::BindingAttribute>(binding),
create<ast::GroupDecoration>(group), create<ast::GroupAttribute>(group),
}); });
} }
@ -153,9 +153,9 @@ void InspectorBuilder::AddStorageBuffer(const std::string& name,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
Global(name, type, ast::StorageClass::kStorage, access, Global(name, type, ast::StorageClass::kStorage, access,
ast::DecorationList{ ast::AttributeList{
create<ast::BindingDecoration>(binding), create<ast::BindingAttribute>(binding),
create<ast::GroupDecoration>(group), create<ast::GroupAttribute>(group),
}); });
} }
@ -185,17 +185,16 @@ void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
stmts.emplace_back(Return()); stmts.emplace_back(Return());
Func(func_name, ast::VariableList(), ty.void_(), stmts, Func(func_name, ast::VariableList(), ty.void_(), stmts, ast::AttributeList{});
ast::DecorationList{});
} }
void InspectorBuilder::AddSampler(const std::string& name, void InspectorBuilder::AddSampler(const std::string& name,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
Global(name, sampler_type(), Global(name, sampler_type(),
ast::DecorationList{ ast::AttributeList{
create<ast::BindingDecoration>(binding), create<ast::BindingAttribute>(binding),
create<ast::GroupDecoration>(group), create<ast::GroupAttribute>(group),
}); });
} }
@ -203,9 +202,9 @@ void InspectorBuilder::AddComparisonSampler(const std::string& name,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
Global(name, comparison_sampler_type(), Global(name, comparison_sampler_type(),
ast::DecorationList{ ast::AttributeList{
create<ast::BindingDecoration>(binding), create<ast::BindingAttribute>(binding),
create<ast::GroupDecoration>(group), create<ast::GroupAttribute>(group),
}); });
} }
@ -214,9 +213,9 @@ void InspectorBuilder::AddResource(const std::string& name,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
Global(name, type, Global(name, type,
ast::DecorationList{ ast::AttributeList{
create<ast::BindingDecoration>(binding), create<ast::BindingAttribute>(binding),
create<ast::GroupDecoration>(group), create<ast::GroupAttribute>(group),
}); });
} }
@ -231,7 +230,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
const std::string& sampler_name, const std::string& sampler_name,
const std::string& coords_name, const std::string& coords_name,
const ast::Type* base_type, const ast::Type* base_type,
ast::DecorationList decorations) { ast::AttributeList attributes) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
ast::StatementList stmts; ast::StatementList stmts;
@ -241,7 +240,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
sampler_name, coords_name))); sampler_name, coords_name)));
stmts.emplace_back(Return()); stmts.emplace_back(Return());
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations); return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
} }
const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction( const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
@ -251,7 +250,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
const std::string& coords_name, const std::string& coords_name,
const std::string& array_index, const std::string& array_index,
const ast::Type* base_type, const ast::Type* base_type,
ast::DecorationList decorations) { ast::AttributeList attributes) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
ast::StatementList stmts; ast::StatementList stmts;
@ -263,7 +262,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
coords_name, array_index))); coords_name, array_index)));
stmts.emplace_back(Return()); stmts.emplace_back(Return());
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations); return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
} }
const ast::Function* const ast::Function*
@ -274,7 +273,7 @@ InspectorBuilder::MakeComparisonSamplerReferenceBodyFunction(
const std::string& coords_name, const std::string& coords_name,
const std::string& depth_name, const std::string& depth_name,
const ast::Type* base_type, const ast::Type* base_type,
ast::DecorationList decorations) { ast::AttributeList attributes) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
ast::StatementList stmts; ast::StatementList stmts;
@ -285,7 +284,7 @@ InspectorBuilder::MakeComparisonSamplerReferenceBodyFunction(
sampler_name, coords_name, depth_name))); sampler_name, coords_name, depth_name)));
stmts.emplace_back(Return()); stmts.emplace_back(Return());
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations); return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
} }
const ast::Type* InspectorBuilder::GetBaseType( const ast::Type* InspectorBuilder::GetBaseType(
@ -331,9 +330,9 @@ void InspectorBuilder::AddStorageTexture(const std::string& name,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
Global(name, type, Global(name, type,
ast::DecorationList{ ast::AttributeList{
create<ast::BindingDecoration>(binding), create<ast::BindingAttribute>(binding),
create<ast::GroupDecoration>(group), create<ast::GroupAttribute>(group),
}); });
} }
@ -341,14 +340,14 @@ const ast::Function* InspectorBuilder::MakeStorageTextureBodyFunction(
const std::string& func_name, const std::string& func_name,
const std::string& st_name, const std::string& st_name,
const ast::Type* dim_type, const ast::Type* dim_type,
ast::DecorationList decorations) { ast::AttributeList attributes) {
ast::StatementList stmts; ast::StatementList stmts;
stmts.emplace_back(Decl(Var("dim", dim_type))); stmts.emplace_back(Decl(Var("dim", dim_type)));
stmts.emplace_back(Assign("dim", Call("textureDimensions", st_name))); stmts.emplace_back(Assign("dim", Call("textureDimensions", st_name)));
stmts.emplace_back(Return()); stmts.emplace_back(Return());
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations); return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
} }
std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction( std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction(

View File

@ -21,11 +21,11 @@
#include <vector> #include <vector>
#include "src/ast/call_statement.h" #include "src/ast/call_statement.h"
#include "src/ast/disable_validation_decoration.h" #include "src/ast/disable_validation_attribute.h"
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include "src/ast/struct_block_decoration.h" #include "src/ast/struct_block_attribute.h"
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
#include "src/program_builder.h" #include "src/program_builder.h"
#include "src/sem/depth_texture_type.h" #include "src/sem/depth_texture_type.h"
#include "src/sem/external_texture_type.h" #include "src/sem/external_texture_type.h"
@ -45,16 +45,16 @@ class InspectorBuilder : public ProgramBuilder {
/// Generates an empty function /// Generates an empty function
/// @param name name of the function created /// @param name name of the function created
/// @param decorations the function decorations /// @param attributes the function attributes
void MakeEmptyBodyFunction(std::string name, ast::DecorationList decorations); void MakeEmptyBodyFunction(std::string name, ast::AttributeList attributes);
/// Generates a function that calls other functions /// Generates a function that calls other functions
/// @param caller name of the function created /// @param caller name of the function created
/// @param callees names of the functions to be called /// @param callees names of the functions to be called
/// @param decorations the function decorations /// @param attributes the function attributes
void MakeCallerBodyFunction(std::string caller, void MakeCallerBodyFunction(std::string caller,
std::vector<std::string> callees, std::vector<std::string> callees,
ast::DecorationList decorations); ast::AttributeList attributes);
/// Generates a struct that contains user-defined IO members /// Generates a struct that contains user-defined IO members
/// @param name the name of the generated struct /// @param name the name of the generated struct
@ -76,11 +76,11 @@ class InspectorBuilder : public ProgramBuilder {
/// @param name name of the function created /// @param name name of the function created
/// @param inout_vars tuples of {in, out} that will be converted into out = in /// @param inout_vars tuples of {in, out} that will be converted into out = in
/// calls in the function body /// calls in the function body
/// @param decorations the function decorations /// @param attributes the function attributes
void MakeInOutVariableBodyFunction( void MakeInOutVariableBodyFunction(
std::string name, std::string name,
std::vector<std::tuple<std::string, std::string>> inout_vars, std::vector<std::tuple<std::string, std::string>> inout_vars,
ast::DecorationList decorations); ast::AttributeList attributes);
// TODO(crbug.com/tint/697): Remove this. // TODO(crbug.com/tint/697): Remove this.
/// Generates a function that references in/out variables and calls another /// Generates a function that references in/out variables and calls another
@ -89,13 +89,13 @@ class InspectorBuilder : public ProgramBuilder {
/// @param callee name of the function to be called /// @param callee name of the function to be called
/// @param inout_vars tuples of {in, out} that will be converted into out = in /// @param inout_vars tuples of {in, out} that will be converted into out = in
/// calls in the function body /// calls in the function body
/// @param decorations the function decorations /// @param attributes the function attributes
/// @returns a function object /// @returns a function object
const ast::Function* MakeInOutVariableCallerBodyFunction( const ast::Function* MakeInOutVariableCallerBodyFunction(
std::string caller, std::string caller,
std::string callee, std::string callee,
std::vector<std::tuple<std::string, std::string>> inout_vars, std::vector<std::tuple<std::string, std::string>> inout_vars,
ast::DecorationList decorations); ast::AttributeList attributes);
/// Add a pipeline constant to the global variables, with a specific ID. /// Add a pipeline constant to the global variables, with a specific ID.
/// @param name name of the variable to add /// @param name name of the variable to add
@ -110,7 +110,7 @@ class InspectorBuilder : public ProgramBuilder {
const ast::Type* type, const ast::Type* type,
const ast::Expression* constructor) { const ast::Expression* constructor) {
return GlobalConst(name, type, constructor, return GlobalConst(name, type, constructor,
ast::DecorationList{ ast::AttributeList{
Override(id), Override(id),
}); });
} }
@ -126,7 +126,7 @@ class InspectorBuilder : public ProgramBuilder {
const ast::Type* type, const ast::Type* type,
const ast::Expression* constructor) { const ast::Expression* constructor) {
return GlobalConst(name, type, constructor, return GlobalConst(name, type, constructor,
ast::DecorationList{ ast::AttributeList{
Override(), Override(),
}); });
} }
@ -136,13 +136,13 @@ class InspectorBuilder : public ProgramBuilder {
/// @param func name of the function created /// @param func name of the function created
/// @param var name of the constant to be reference /// @param var name of the constant to be reference
/// @param type type of the const being referenced /// @param type type of the const being referenced
/// @param decorations the function decorations /// @param attributes the function attributes
/// @returns a function object /// @returns a function object
const ast::Function* MakePlainGlobalReferenceBodyFunction( const ast::Function* MakePlainGlobalReferenceBodyFunction(
std::string func, std::string func,
std::string var, std::string var,
const ast::Type* type, const ast::Type* type,
ast::DecorationList decorations); ast::AttributeList attributes);
/// @param vec Vector of StageVariable to be searched /// @param vec Vector of StageVariable to be searched
/// @param name Name to be searching for /// @param name Name to be searching for
@ -177,11 +177,11 @@ class InspectorBuilder : public ProgramBuilder {
/// Generates a struct member with a specified index and type. /// Generates a struct member with a specified index and type.
/// @param index index of the field within the struct /// @param index index of the field within the struct
/// @param type the type of the member field /// @param type the type of the member field
/// @param decorations a list of decorations to apply to the member field /// @param attributes a list of attributes to apply to the member field
/// @returns a struct member /// @returns a struct member
const ast::StructMember* MakeStructMember(size_t index, const ast::StructMember* MakeStructMember(size_t index,
const ast::Type* type, const ast::Type* type,
ast::DecorationList decorations); ast::AttributeList attributes);
/// Generates types appropriate for using in an uniform buffer /// Generates types appropriate for using in an uniform buffer
/// @param name name for the type /// @param name name for the type
@ -270,7 +270,7 @@ class InspectorBuilder : public ProgramBuilder {
/// @param sampler_name name of the sampler to use /// @param sampler_name name of the sampler to use
/// @param coords_name name of the coords variable to use /// @param coords_name name of the coords variable to use
/// @param base_type sampler base type /// @param base_type sampler base type
/// @param decorations the function decorations /// @param attributes the function attributes
/// @returns a function that references all of the values specified /// @returns a function that references all of the values specified
const ast::Function* MakeSamplerReferenceBodyFunction( const ast::Function* MakeSamplerReferenceBodyFunction(
const std::string& func_name, const std::string& func_name,
@ -278,7 +278,7 @@ class InspectorBuilder : public ProgramBuilder {
const std::string& sampler_name, const std::string& sampler_name,
const std::string& coords_name, const std::string& coords_name,
const ast::Type* base_type, const ast::Type* base_type,
ast::DecorationList decorations); ast::AttributeList attributes);
/// Generates a function that references a specific sampler variable /// Generates a function that references a specific sampler variable
/// @param func_name name of the function created /// @param func_name name of the function created
@ -287,7 +287,7 @@ class InspectorBuilder : public ProgramBuilder {
/// @param coords_name name of the coords variable to use /// @param coords_name name of the coords variable to use
/// @param array_index name of the array index variable to use /// @param array_index name of the array index variable to use
/// @param base_type sampler base type /// @param base_type sampler base type
/// @param decorations the function decorations /// @param attributes the function attributes
/// @returns a function that references all of the values specified /// @returns a function that references all of the values specified
const ast::Function* MakeSamplerReferenceBodyFunction( const ast::Function* MakeSamplerReferenceBodyFunction(
const std::string& func_name, const std::string& func_name,
@ -296,7 +296,7 @@ class InspectorBuilder : public ProgramBuilder {
const std::string& coords_name, const std::string& coords_name,
const std::string& array_index, const std::string& array_index,
const ast::Type* base_type, const ast::Type* base_type,
ast::DecorationList decorations); ast::AttributeList attributes);
/// Generates a function that references a specific comparison sampler /// Generates a function that references a specific comparison sampler
/// variable. /// variable.
@ -306,7 +306,7 @@ class InspectorBuilder : public ProgramBuilder {
/// @param coords_name name of the coords variable to use /// @param coords_name name of the coords variable to use
/// @param depth_name name of the depth reference to use /// @param depth_name name of the depth reference to use
/// @param base_type sampler base type /// @param base_type sampler base type
/// @param decorations the function decorations /// @param attributes the function attributes
/// @returns a function that references all of the values specified /// @returns a function that references all of the values specified
const ast::Function* MakeComparisonSamplerReferenceBodyFunction( const ast::Function* MakeComparisonSamplerReferenceBodyFunction(
const std::string& func_name, const std::string& func_name,
@ -315,7 +315,7 @@ class InspectorBuilder : public ProgramBuilder {
const std::string& coords_name, const std::string& coords_name,
const std::string& depth_name, const std::string& depth_name,
const ast::Type* base_type, const ast::Type* base_type,
ast::DecorationList decorations); ast::AttributeList attributes);
/// Gets an appropriate type for the data in a given texture type. /// Gets an appropriate type for the data in a given texture type.
/// @param sampled_kind type of in the texture /// @param sampled_kind type of in the texture
@ -351,13 +351,13 @@ class InspectorBuilder : public ProgramBuilder {
/// @param func_name name of the function created /// @param func_name name of the function created
/// @param st_name name of the storage texture to use /// @param st_name name of the storage texture to use
/// @param dim_type type expected by textureDimensons to return /// @param dim_type type expected by textureDimensons to return
/// @param decorations the function decorations /// @param attributes the function attributes
/// @returns a function that references all of the values specified /// @returns a function that references all of the values specified
const ast::Function* MakeStorageTextureBodyFunction( const ast::Function* MakeStorageTextureBodyFunction(
const std::string& func_name, const std::string& func_name,
const std::string& st_name, const std::string& st_name,
const ast::Type* dim_type, const ast::Type* dim_type,
ast::DecorationList decorations); ast::AttributeList attributes);
/// Get a generator function that returns a type appropriate for a stage /// Get a generator function that returns a type appropriate for a stage
/// variable with the given combination of component and composition type. /// variable with the given combination of component and composition type.

View File

@ -131,7 +131,7 @@ const ast::Statement* ProgramBuilder::WrapInStatement(
const ast::Function* ProgramBuilder::WrapInFunction( const ast::Function* ProgramBuilder::WrapInFunction(
const ast::StatementList stmts) { const ast::StatementList stmts) {
return Func("test_function", {}, ty.void_(), std::move(stmts), return Func("test_function", {}, ty.void_(), std::move(stmts),
{create<ast::StageDecoration>(ast::PipelineStage::kCompute), {create<ast::StageAttribute>(ast::PipelineStage::kCompute),
WorkgroupSize(1, 1, 1)}); WorkgroupSize(1, 1, 1)});
} }

View File

@ -24,7 +24,7 @@
#include "src/ast/assignment_statement.h" #include "src/ast/assignment_statement.h"
#include "src/ast/atomic.h" #include "src/ast/atomic.h"
#include "src/ast/binary_expression.h" #include "src/ast/binary_expression.h"
#include "src/ast/binding_decoration.h" #include "src/ast/binding_attribute.h"
#include "src/ast/bitcast_expression.h" #include "src/ast/bitcast_expression.h"
#include "src/ast/bool.h" #include "src/ast/bool.h"
#include "src/ast/bool_literal_expression.h" #include "src/ast/bool_literal_expression.h"
@ -35,7 +35,7 @@
#include "src/ast/continue_statement.h" #include "src/ast/continue_statement.h"
#include "src/ast/depth_multisampled_texture.h" #include "src/ast/depth_multisampled_texture.h"
#include "src/ast/depth_texture.h" #include "src/ast/depth_texture.h"
#include "src/ast/disable_validation_decoration.h" #include "src/ast/disable_validation_attribute.h"
#include "src/ast/discard_statement.h" #include "src/ast/discard_statement.h"
#include "src/ast/external_texture.h" #include "src/ast/external_texture.h"
#include "src/ast/f32.h" #include "src/ast/f32.h"
@ -45,27 +45,27 @@
#include "src/ast/i32.h" #include "src/ast/i32.h"
#include "src/ast/if_statement.h" #include "src/ast/if_statement.h"
#include "src/ast/index_accessor_expression.h" #include "src/ast/index_accessor_expression.h"
#include "src/ast/interpolate_decoration.h" #include "src/ast/interpolate_attribute.h"
#include "src/ast/invariant_decoration.h" #include "src/ast/invariant_attribute.h"
#include "src/ast/loop_statement.h" #include "src/ast/loop_statement.h"
#include "src/ast/matrix.h" #include "src/ast/matrix.h"
#include "src/ast/member_accessor_expression.h" #include "src/ast/member_accessor_expression.h"
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/ast/multisampled_texture.h" #include "src/ast/multisampled_texture.h"
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/phony_expression.h" #include "src/ast/phony_expression.h"
#include "src/ast/pointer.h" #include "src/ast/pointer.h"
#include "src/ast/return_statement.h" #include "src/ast/return_statement.h"
#include "src/ast/sampled_texture.h" #include "src/ast/sampled_texture.h"
#include "src/ast/sampler.h" #include "src/ast/sampler.h"
#include "src/ast/sint_literal_expression.h" #include "src/ast/sint_literal_expression.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include "src/ast/storage_texture.h" #include "src/ast/storage_texture.h"
#include "src/ast/stride_decoration.h" #include "src/ast/stride_attribute.h"
#include "src/ast/struct_block_decoration.h" #include "src/ast/struct_block_attribute.h"
#include "src/ast/struct_member_align_decoration.h" #include "src/ast/struct_member_align_attribute.h"
#include "src/ast/struct_member_offset_decoration.h" #include "src/ast/struct_member_offset_attribute.h"
#include "src/ast/struct_member_size_decoration.h" #include "src/ast/struct_member_size_attribute.h"
#include "src/ast/switch_statement.h" #include "src/ast/switch_statement.h"
#include "src/ast/type_name.h" #include "src/ast/type_name.h"
#include "src/ast/u32.h" #include "src/ast/u32.h"
@ -74,7 +74,7 @@
#include "src/ast/variable_decl_statement.h" #include "src/ast/variable_decl_statement.h"
#include "src/ast/vector.h" #include "src/ast/vector.h"
#include "src/ast/void.h" #include "src/ast/void.h"
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
#include "src/program.h" #include "src/program.h"
#include "src/program_id.h" #include "src/program_id.h"
#include "src/sem/array.h" #include "src/sem/array.h"
@ -131,13 +131,13 @@ class ProgramBuilder {
ast::StorageClass storage = ast::StorageClass::kNone; ast::StorageClass storage = ast::StorageClass::kNone;
ast::Access access = ast::Access::kUndefined; ast::Access access = ast::Access::kUndefined;
const ast::Expression* constructor = nullptr; const ast::Expression* constructor = nullptr;
ast::DecorationList decorations = {}; ast::AttributeList attributes = {};
private: private:
void Set(ast::StorageClass sc) { storage = sc; } void Set(ast::StorageClass sc) { storage = sc; }
void Set(ast::Access ac) { access = ac; } void Set(ast::Access ac) { access = ac; }
void Set(const ast::Expression* c) { constructor = c; } void Set(const ast::Expression* c) { constructor = c; }
void Set(const ast::DecorationList& l) { decorations = l; } void Set(const ast::AttributeList& l) { attributes = l; }
template <typename FIRST, typename... ARGS> template <typename FIRST, typename... ARGS>
void Apply(FIRST&& first, ARGS&&... args) { void Apply(FIRST&& first, ARGS&&... args) {
@ -640,28 +640,28 @@ class ProgramBuilder {
/// @param subtype the array element type /// @param subtype the array element type
/// @param n the array size. nullptr represents a runtime-array /// @param n the array size. nullptr represents a runtime-array
/// @param decos the optional decorations for the array /// @param attrs the optional attributes for the array
/// @return the tint AST type for a array of size `n` of type `T` /// @return the tint AST type for a array of size `n` of type `T`
template <typename EXPR = ast::Expression*> template <typename EXPR = ast::Expression*>
const ast::Array* array(const ast::Type* subtype, const ast::Array* array(const ast::Type* subtype,
EXPR&& n = nullptr, EXPR&& n = nullptr,
ast::DecorationList decos = {}) const { ast::AttributeList attrs = {}) const {
return builder->create<ast::Array>( return builder->create<ast::Array>(
subtype, builder->Expr(std::forward<EXPR>(n)), decos); subtype, builder->Expr(std::forward<EXPR>(n)), attrs);
} }
/// @param source the Source of the node /// @param source the Source of the node
/// @param subtype the array element type /// @param subtype the array element type
/// @param n the array size. nullptr represents a runtime-array /// @param n the array size. nullptr represents a runtime-array
/// @param decos the optional decorations for the array /// @param attrs the optional attributes for the array
/// @return the tint AST type for a array of size `n` of type `T` /// @return the tint AST type for a array of size `n` of type `T`
template <typename EXPR = ast::Expression*> template <typename EXPR = ast::Expression*>
const ast::Array* array(const Source& source, const ast::Array* array(const Source& source,
const ast::Type* subtype, const ast::Type* subtype,
EXPR&& n = nullptr, EXPR&& n = nullptr,
ast::DecorationList decos = {}) const { ast::AttributeList attrs = {}) const {
return builder->create<ast::Array>( return builder->create<ast::Array>(
source, subtype, builder->Expr(std::forward<EXPR>(n)), decos); source, subtype, builder->Expr(std::forward<EXPR>(n)), attrs);
} }
/// @param subtype the array element type /// @param subtype the array element type
@ -672,11 +672,11 @@ class ProgramBuilder {
const ast::Array* array(const ast::Type* subtype, const ast::Array* array(const ast::Type* subtype,
EXPR&& n, EXPR&& n,
uint32_t stride) const { uint32_t stride) const {
ast::DecorationList decos; ast::AttributeList attrs;
if (stride) { if (stride) {
decos.emplace_back(builder->create<ast::StrideDecoration>(stride)); attrs.emplace_back(builder->create<ast::StrideAttribute>(stride));
} }
return array(subtype, std::forward<EXPR>(n), std::move(decos)); return array(subtype, std::forward<EXPR>(n), std::move(attrs));
} }
/// @param source the Source of the node /// @param source the Source of the node
@ -689,11 +689,11 @@ class ProgramBuilder {
const ast::Type* subtype, const ast::Type* subtype,
EXPR&& n, EXPR&& n,
uint32_t stride) const { uint32_t stride) const {
ast::DecorationList decos; ast::AttributeList attrs;
if (stride) { if (stride) {
decos.emplace_back(builder->create<ast::StrideDecoration>(stride)); attrs.emplace_back(builder->create<ast::StrideAttribute>(stride));
} }
return array(source, subtype, std::forward<EXPR>(n), std::move(decos)); return array(source, subtype, std::forward<EXPR>(n), std::move(attrs));
} }
/// @return the tint AST type for a runtime-sized array of type `T` /// @return the tint AST type for a runtime-sized array of type `T`
@ -1322,7 +1322,7 @@ class ProgramBuilder {
/// * ast::StorageClass - specifies the variable storage class /// * ast::StorageClass - specifies the variable storage class
/// * ast::Access - specifies the variable's access control /// * ast::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression /// * ast::Expression* - specifies the variable's initializer expression
/// * ast::DecorationList - specifies the variable's decorations /// * ast::AttributeList - specifies the variable's attributes
/// Note that repeated arguments of the same type will use the last argument's /// Note that repeated arguments of the same type will use the last argument's
/// value. /// value.
/// @returns a `ast::Variable` with the given name, type and additional /// @returns a `ast::Variable` with the given name, type and additional
@ -1334,7 +1334,7 @@ class ProgramBuilder {
VarOptionals opts(std::forward<OPTIONAL>(optional)...); VarOptionals opts(std::forward<OPTIONAL>(optional)...);
return create<ast::Variable>(Sym(std::forward<NAME>(name)), opts.storage, return create<ast::Variable>(Sym(std::forward<NAME>(name)), opts.storage,
opts.access, type, false, opts.constructor, opts.access, type, false, opts.constructor,
std::move(opts.decorations)); std::move(opts.attributes));
} }
/// @param source the variable source /// @param source the variable source
@ -1345,7 +1345,7 @@ class ProgramBuilder {
/// * ast::StorageClass - specifies the variable storage class /// * ast::StorageClass - specifies the variable storage class
/// * ast::Access - specifies the variable's access control /// * ast::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression /// * ast::Expression* - specifies the variable's initializer expression
/// * ast::DecorationList - specifies the variable's decorations /// * ast::AttributeList - specifies the variable's attributes
/// Note that repeated arguments of the same type will use the last argument's /// Note that repeated arguments of the same type will use the last argument's
/// value. /// value.
/// @returns a `ast::Variable` with the given name, storage and type /// @returns a `ast::Variable` with the given name, storage and type
@ -1357,67 +1357,67 @@ class ProgramBuilder {
VarOptionals opts(std::forward<OPTIONAL>(optional)...); VarOptionals opts(std::forward<OPTIONAL>(optional)...);
return create<ast::Variable>(source, Sym(std::forward<NAME>(name)), return create<ast::Variable>(source, Sym(std::forward<NAME>(name)),
opts.storage, opts.access, type, false, opts.storage, opts.access, type, false,
opts.constructor, std::move(opts.decorations)); opts.constructor, std::move(opts.attributes));
} }
/// @param name the variable name /// @param name the variable name
/// @param type the variable type /// @param type the variable type
/// @param constructor constructor expression /// @param constructor constructor expression
/// @param decorations optional variable decorations /// @param attributes optional variable attributes
/// @returns a constant `ast::Variable` with the given name and type /// @returns a constant `ast::Variable` with the given name and type
template <typename NAME> template <typename NAME>
const ast::Variable* Const(NAME&& name, const ast::Variable* Const(NAME&& name,
const ast::Type* type, const ast::Type* type,
const ast::Expression* constructor, const ast::Expression* constructor,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
return create<ast::Variable>( return create<ast::Variable>(
Sym(std::forward<NAME>(name)), ast::StorageClass::kNone, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
ast::Access::kUndefined, type, true, constructor, decorations); ast::Access::kUndefined, type, true, constructor, attributes);
} }
/// @param source the variable source /// @param source the variable source
/// @param name the variable name /// @param name the variable name
/// @param type the variable type /// @param type the variable type
/// @param constructor constructor expression /// @param constructor constructor expression
/// @param decorations optional variable decorations /// @param attributes optional variable attributes
/// @returns a constant `ast::Variable` with the given name and type /// @returns a constant `ast::Variable` with the given name and type
template <typename NAME> template <typename NAME>
const ast::Variable* Const(const Source& source, const ast::Variable* Const(const Source& source,
NAME&& name, NAME&& name,
const ast::Type* type, const ast::Type* type,
const ast::Expression* constructor, const ast::Expression* constructor,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
return create<ast::Variable>( return create<ast::Variable>(
source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone, source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
ast::Access::kUndefined, type, true, constructor, decorations); ast::Access::kUndefined, type, true, constructor, attributes);
} }
/// @param name the parameter name /// @param name the parameter name
/// @param type the parameter type /// @param type the parameter type
/// @param decorations optional parameter decorations /// @param attributes optional parameter attributes
/// @returns a constant `ast::Variable` with the given name and type /// @returns a constant `ast::Variable` with the given name and type
template <typename NAME> template <typename NAME>
const ast::Variable* Param(NAME&& name, const ast::Variable* Param(NAME&& name,
const ast::Type* type, const ast::Type* type,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
return create<ast::Variable>( return create<ast::Variable>(
Sym(std::forward<NAME>(name)), ast::StorageClass::kNone, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
ast::Access::kUndefined, type, true, nullptr, decorations); ast::Access::kUndefined, type, true, nullptr, attributes);
} }
/// @param source the parameter source /// @param source the parameter source
/// @param name the parameter name /// @param name the parameter name
/// @param type the parameter type /// @param type the parameter type
/// @param decorations optional parameter decorations /// @param attributes optional parameter attributes
/// @returns a constant `ast::Variable` with the given name and type /// @returns a constant `ast::Variable` with the given name and type
template <typename NAME> template <typename NAME>
const ast::Variable* Param(const Source& source, const ast::Variable* Param(const Source& source,
NAME&& name, NAME&& name,
const ast::Type* type, const ast::Type* type,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
return create<ast::Variable>( return create<ast::Variable>(
source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone, source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
ast::Access::kUndefined, type, true, nullptr, decorations); ast::Access::kUndefined, type, true, nullptr, attributes);
} }
/// @param name the variable name /// @param name the variable name
@ -1427,7 +1427,7 @@ class ProgramBuilder {
/// * ast::StorageClass - specifies the variable storage class /// * ast::StorageClass - specifies the variable storage class
/// * ast::Access - specifies the variable's access control /// * ast::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression /// * ast::Expression* - specifies the variable's initializer expression
/// * ast::DecorationList - specifies the variable's decorations /// * ast::AttributeList - specifies the variable's attributes
/// Note that repeated arguments of the same type will use the last argument's /// Note that repeated arguments of the same type will use the last argument's
/// value. /// value.
/// @returns a new `ast::Variable`, which is automatically registered as a /// @returns a new `ast::Variable`, which is automatically registered as a
@ -1452,7 +1452,7 @@ class ProgramBuilder {
/// * ast::StorageClass - specifies the variable storage class /// * ast::StorageClass - specifies the variable storage class
/// * ast::Access - specifies the variable's access control /// * ast::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression /// * ast::Expression* - specifies the variable's initializer expression
/// * ast::DecorationList - specifies the variable's decorations /// * ast::AttributeList - specifies the variable's attributes
/// Note that repeated arguments of the same type will use the last argument's /// Note that repeated arguments of the same type will use the last argument's
/// value. /// value.
/// @returns a new `ast::Variable`, which is automatically registered as a /// @returns a new `ast::Variable`, which is automatically registered as a
@ -1471,7 +1471,7 @@ class ProgramBuilder {
/// @param name the variable name /// @param name the variable name
/// @param type the variable type /// @param type the variable type
/// @param constructor constructor expression /// @param constructor constructor expression
/// @param decorations optional variable decorations /// @param attributes optional variable attributes
/// @returns a const `ast::Variable` constructed by calling Var() with the /// @returns a const `ast::Variable` constructed by calling Var() with the
/// arguments of `args`, which is automatically registered as a global /// arguments of `args`, which is automatically registered as a global
/// variable with the ast::Module. /// variable with the ast::Module.
@ -1479,9 +1479,9 @@ class ProgramBuilder {
const ast::Variable* GlobalConst(NAME&& name, const ast::Variable* GlobalConst(NAME&& name,
const ast::Type* type, const ast::Type* type,
const ast::Expression* constructor, const ast::Expression* constructor,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
auto* var = Const(std::forward<NAME>(name), type, constructor, auto* var = Const(std::forward<NAME>(name), type, constructor,
std::move(decorations)); std::move(attributes));
AST().AddGlobalVariable(var); AST().AddGlobalVariable(var);
return var; return var;
} }
@ -1490,7 +1490,7 @@ class ProgramBuilder {
/// @param name the variable name /// @param name the variable name
/// @param type the variable type /// @param type the variable type
/// @param constructor constructor expression /// @param constructor constructor expression
/// @param decorations optional variable decorations /// @param attributes optional variable attributes
/// @returns a const `ast::Variable` constructed by calling Var() with the /// @returns a const `ast::Variable` constructed by calling Var() with the
/// arguments of `args`, which is automatically registered as a global /// arguments of `args`, which is automatically registered as a global
/// variable with the ast::Module. /// variable with the ast::Module.
@ -1499,9 +1499,9 @@ class ProgramBuilder {
NAME&& name, NAME&& name,
const ast::Type* type, const ast::Type* type,
const ast::Expression* constructor, const ast::Expression* constructor,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
auto* var = Const(source, std::forward<NAME>(name), type, constructor, auto* var = Const(source, std::forward<NAME>(name), type, constructor,
std::move(decorations)); std::move(attributes));
AST().AddGlobalVariable(var); AST().AddGlobalVariable(var);
return var; return var;
} }
@ -1747,71 +1747,71 @@ class ProgramBuilder {
Expr(std::forward<IDX>(idx))); Expr(std::forward<IDX>(idx)));
} }
/// Creates a ast::StructMemberOffsetDecoration /// Creates a ast::StructMemberOffsetAttribute
/// @param val the offset value /// @param val the offset value
/// @returns the offset decoration pointer /// @returns the offset attribute pointer
const ast::StructMemberOffsetDecoration* MemberOffset(uint32_t val) { const ast::StructMemberOffsetAttribute* MemberOffset(uint32_t val) {
return create<ast::StructMemberOffsetDecoration>(source_, val); return create<ast::StructMemberOffsetAttribute>(source_, val);
} }
/// Creates a ast::StructMemberSizeDecoration /// Creates a ast::StructMemberSizeAttribute
/// @param source the source information /// @param source the source information
/// @param val the size value /// @param val the size value
/// @returns the size decoration pointer /// @returns the size attribute pointer
const ast::StructMemberSizeDecoration* MemberSize(const Source& source, const ast::StructMemberSizeAttribute* MemberSize(const Source& source,
uint32_t val) { uint32_t val) {
return create<ast::StructMemberSizeDecoration>(source, val); return create<ast::StructMemberSizeAttribute>(source, val);
} }
/// Creates a ast::StructMemberSizeDecoration /// Creates a ast::StructMemberSizeAttribute
/// @param val the size value /// @param val the size value
/// @returns the size decoration pointer /// @returns the size attribute pointer
const ast::StructMemberSizeDecoration* MemberSize(uint32_t val) { const ast::StructMemberSizeAttribute* MemberSize(uint32_t val) {
return create<ast::StructMemberSizeDecoration>(source_, val); return create<ast::StructMemberSizeAttribute>(source_, val);
} }
/// Creates a ast::StructMemberAlignDecoration /// Creates a ast::StructMemberAlignAttribute
/// @param source the source information /// @param source the source information
/// @param val the align value /// @param val the align value
/// @returns the align decoration pointer /// @returns the align attribute pointer
const ast::StructMemberAlignDecoration* MemberAlign(const Source& source, const ast::StructMemberAlignAttribute* MemberAlign(const Source& source,
uint32_t val) { uint32_t val) {
return create<ast::StructMemberAlignDecoration>(source, val); return create<ast::StructMemberAlignAttribute>(source, val);
} }
/// Creates a ast::StructMemberAlignDecoration /// Creates a ast::StructMemberAlignAttribute
/// @param val the align value /// @param val the align value
/// @returns the align decoration pointer /// @returns the align attribute pointer
const ast::StructMemberAlignDecoration* MemberAlign(uint32_t val) { const ast::StructMemberAlignAttribute* MemberAlign(uint32_t val) {
return create<ast::StructMemberAlignDecoration>(source_, val); return create<ast::StructMemberAlignAttribute>(source_, val);
} }
/// Creates a ast::StructBlockDecoration /// Creates a ast::StructBlockAttribute
/// @returns the struct block decoration pointer /// @returns the struct block attribute pointer
const ast::StructBlockDecoration* StructBlock() { const ast::StructBlockAttribute* StructBlock() {
return create<ast::StructBlockDecoration>(); return create<ast::StructBlockAttribute>();
} }
/// Creates the ast::GroupDecoration /// Creates the ast::GroupAttribute
/// @param value group decoration index /// @param value group attribute index
/// @returns the group decoration pointer /// @returns the group attribute pointer
const ast::GroupDecoration* Group(uint32_t value) { const ast::GroupAttribute* Group(uint32_t value) {
return create<ast::GroupDecoration>(value); return create<ast::GroupAttribute>(value);
} }
/// Creates the ast::BindingDecoration /// Creates the ast::BindingAttribute
/// @param value the binding index /// @param value the binding index
/// @returns the binding deocration pointer /// @returns the binding deocration pointer
const ast::BindingDecoration* Binding(uint32_t value) { const ast::BindingAttribute* Binding(uint32_t value) {
return create<ast::BindingDecoration>(value); return create<ast::BindingAttribute>(value);
} }
/// Convenience function to create both a ast::GroupDecoration and /// Convenience function to create both a ast::GroupAttribute and
/// ast::BindingDecoration /// ast::BindingAttribute
/// @param group the group index /// @param group the group index
/// @param binding the binding index /// @param binding the binding index
/// @returns a decoration list with both the group and binding decorations /// @returns a attribute list with both the group and binding attributes
ast::DecorationList GroupAndBinding(uint32_t group, uint32_t binding) { ast::AttributeList GroupAndBinding(uint32_t group, uint32_t binding) {
return {Group(group), Binding(binding)}; return {Group(group), Binding(binding)};
} }
@ -1821,9 +1821,9 @@ class ProgramBuilder {
/// @param params the function parameters /// @param params the function parameters
/// @param type the function return type /// @param type the function return type
/// @param body the function body /// @param body the function body
/// @param decorations the optional function decorations /// @param attributes the optional function attributes
/// @param return_type_decorations the optional function return type /// @param return_type_attributes the optional function return type
/// decorations /// attributes
/// @returns the function pointer /// @returns the function pointer
template <typename NAME> template <typename NAME>
const ast::Function* Func(const Source& source, const ast::Function* Func(const Source& source,
@ -1831,12 +1831,11 @@ class ProgramBuilder {
ast::VariableList params, ast::VariableList params,
const ast::Type* type, const ast::Type* type,
ast::StatementList body, ast::StatementList body,
ast::DecorationList decorations = {}, ast::AttributeList attributes = {},
ast::DecorationList return_type_decorations = {}) { ast::AttributeList return_type_attributes = {}) {
auto* func = auto* func = create<ast::Function>(
create<ast::Function>(source, Sym(std::forward<NAME>(name)), params, source, Sym(std::forward<NAME>(name)), params, type,
type, create<ast::BlockStatement>(body), create<ast::BlockStatement>(body), attributes, return_type_attributes);
decorations, return_type_decorations);
AST().AddFunction(func); AST().AddFunction(func);
return func; return func;
} }
@ -1846,20 +1845,20 @@ class ProgramBuilder {
/// @param params the function parameters /// @param params the function parameters
/// @param type the function return type /// @param type the function return type
/// @param body the function body /// @param body the function body
/// @param decorations the optional function decorations /// @param attributes the optional function attributes
/// @param return_type_decorations the optional function return type /// @param return_type_attributes the optional function return type
/// decorations /// attributes
/// @returns the function pointer /// @returns the function pointer
template <typename NAME> template <typename NAME>
const ast::Function* Func(NAME&& name, const ast::Function* Func(NAME&& name,
ast::VariableList params, ast::VariableList params,
const ast::Type* type, const ast::Type* type,
ast::StatementList body, ast::StatementList body,
ast::DecorationList decorations = {}, ast::AttributeList attributes = {},
ast::DecorationList return_type_decorations = {}) { ast::AttributeList return_type_attributes = {}) {
auto* func = create<ast::Function>(Sym(std::forward<NAME>(name)), params, auto* func = create<ast::Function>(Sym(std::forward<NAME>(name)), params,
type, create<ast::BlockStatement>(body), type, create<ast::BlockStatement>(body),
decorations, return_type_decorations); attributes, return_type_attributes);
AST().AddFunction(func); AST().AddFunction(func);
return func; return func;
} }
@ -1960,16 +1959,16 @@ class ProgramBuilder {
/// @param source the source information /// @param source the source information
/// @param name the struct name /// @param name the struct name
/// @param members the struct members /// @param members the struct members
/// @param decorations the optional struct decorations /// @param attributes the optional struct attributes
/// @returns the struct type /// @returns the struct type
template <typename NAME> template <typename NAME>
const ast::Struct* Structure(const Source& source, const ast::Struct* Structure(const Source& source,
NAME&& name, NAME&& name,
ast::StructMemberList members, ast::StructMemberList members,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
auto sym = Sym(std::forward<NAME>(name)); auto sym = Sym(std::forward<NAME>(name));
auto* type = create<ast::Struct>(source, sym, std::move(members), auto* type = create<ast::Struct>(source, sym, std::move(members),
std::move(decorations)); std::move(attributes));
AST().AddTypeDecl(type); AST().AddTypeDecl(type);
return type; return type;
} }
@ -1977,15 +1976,15 @@ class ProgramBuilder {
/// Creates a ast::Struct registering it with the AST().TypeDecls(). /// Creates a ast::Struct registering it with the AST().TypeDecls().
/// @param name the struct name /// @param name the struct name
/// @param members the struct members /// @param members the struct members
/// @param decorations the optional struct decorations /// @param attributes the optional struct attributes
/// @returns the struct type /// @returns the struct type
template <typename NAME> template <typename NAME>
const ast::Struct* Structure(NAME&& name, const ast::Struct* Structure(NAME&& name,
ast::StructMemberList members, ast::StructMemberList members,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
auto sym = Sym(std::forward<NAME>(name)); auto sym = Sym(std::forward<NAME>(name));
auto* type = auto* type =
create<ast::Struct>(sym, std::move(members), std::move(decorations)); create<ast::Struct>(sym, std::move(members), std::move(attributes));
AST().AddTypeDecl(type); AST().AddTypeDecl(type);
return type; return type;
} }
@ -1994,32 +1993,32 @@ class ProgramBuilder {
/// @param source the source information /// @param source the source information
/// @param name the struct member name /// @param name the struct member name
/// @param type the struct member type /// @param type the struct member type
/// @param decorations the optional struct member decorations /// @param attributes the optional struct member attributes
/// @returns the struct member pointer /// @returns the struct member pointer
template <typename NAME> template <typename NAME>
const ast::StructMember* Member(const Source& source, const ast::StructMember* Member(const Source& source,
NAME&& name, NAME&& name,
const ast::Type* type, const ast::Type* type,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
return create<ast::StructMember>(source, Sym(std::forward<NAME>(name)), return create<ast::StructMember>(source, Sym(std::forward<NAME>(name)),
type, std::move(decorations)); type, std::move(attributes));
} }
/// Creates a ast::StructMember /// Creates a ast::StructMember
/// @param name the struct member name /// @param name the struct member name
/// @param type the struct member type /// @param type the struct member type
/// @param decorations the optional struct member decorations /// @param attributes the optional struct member attributes
/// @returns the struct member pointer /// @returns the struct member pointer
template <typename NAME> template <typename NAME>
const ast::StructMember* Member(NAME&& name, const ast::StructMember* Member(NAME&& name,
const ast::Type* type, const ast::Type* type,
ast::DecorationList decorations = {}) { ast::AttributeList attributes = {}) {
return create<ast::StructMember>(source_, Sym(std::forward<NAME>(name)), return create<ast::StructMember>(source_, Sym(std::forward<NAME>(name)),
type, std::move(decorations)); type, std::move(attributes));
} }
/// Creates a ast::StructMember with the given byte offset /// Creates a ast::StructMember with the given byte offset
/// @param offset the offset to use in the StructMemberOffsetDecoration /// @param offset the offset to use in the StructMemberOffsetattribute
/// @param name the struct member name /// @param name the struct member name
/// @param type the struct member type /// @param type the struct member type
/// @returns the struct member pointer /// @returns the struct member pointer
@ -2029,8 +2028,8 @@ class ProgramBuilder {
const ast::Type* type) { const ast::Type* type) {
return create<ast::StructMember>( return create<ast::StructMember>(
source_, Sym(std::forward<NAME>(name)), type, source_, Sym(std::forward<NAME>(name)), type,
ast::DecorationList{ ast::AttributeList{
create<ast::StructMemberOffsetDecoration>(offset), create<ast::StructMemberOffsetAttribute>(offset),
}); });
} }
@ -2276,183 +2275,182 @@ class ProgramBuilder {
return create<ast::FallthroughStatement>(); return create<ast::FallthroughStatement>();
} }
/// Creates an ast::BuiltinDecoration /// Creates an ast::BuiltinAttribute
/// @param source the source information /// @param source the source information
/// @param builtin the builtin value /// @param builtin the builtin value
/// @returns the builtin decoration pointer /// @returns the builtin attribute pointer
const ast::BuiltinDecoration* Builtin(const Source& source, const ast::BuiltinAttribute* Builtin(const Source& source,
ast::Builtin builtin) { ast::Builtin builtin) {
return create<ast::BuiltinDecoration>(source, builtin); return create<ast::BuiltinAttribute>(source, builtin);
} }
/// Creates an ast::BuiltinDecoration /// Creates an ast::BuiltinAttribute
/// @param builtin the builtin value /// @param builtin the builtin value
/// @returns the builtin decoration pointer /// @returns the builtin attribute pointer
const ast::BuiltinDecoration* Builtin(ast::Builtin builtin) { const ast::BuiltinAttribute* Builtin(ast::Builtin builtin) {
return create<ast::BuiltinDecoration>(source_, builtin); return create<ast::BuiltinAttribute>(source_, builtin);
} }
/// Creates an ast::InterpolateDecoration /// Creates an ast::InterpolateAttribute
/// @param source the source information /// @param source the source information
/// @param type the interpolation type /// @param type the interpolation type
/// @param sampling the interpolation sampling /// @param sampling the interpolation sampling
/// @returns the interpolate decoration pointer /// @returns the interpolate attribute pointer
const ast::InterpolateDecoration* Interpolate( const ast::InterpolateAttribute* Interpolate(
const Source& source, const Source& source,
ast::InterpolationType type, ast::InterpolationType type,
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone) { ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone) {
return create<ast::InterpolateDecoration>(source, type, sampling); return create<ast::InterpolateAttribute>(source, type, sampling);
} }
/// Creates an ast::InterpolateDecoration /// Creates an ast::InterpolateAttribute
/// @param type the interpolation type /// @param type the interpolation type
/// @param sampling the interpolation sampling /// @param sampling the interpolation sampling
/// @returns the interpolate decoration pointer /// @returns the interpolate attribute pointer
const ast::InterpolateDecoration* Interpolate( const ast::InterpolateAttribute* Interpolate(
ast::InterpolationType type, ast::InterpolationType type,
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone) { ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone) {
return create<ast::InterpolateDecoration>(source_, type, sampling); return create<ast::InterpolateAttribute>(source_, type, sampling);
} }
/// Creates an ast::InterpolateDecoration using flat interpolation /// Creates an ast::InterpolateAttribute using flat interpolation
/// @param source the source information /// @param source the source information
/// @returns the interpolate decoration pointer /// @returns the interpolate attribute pointer
const ast::InterpolateDecoration* Flat(const Source& source) { const ast::InterpolateAttribute* Flat(const Source& source) {
return Interpolate(source, ast::InterpolationType::kFlat); return Interpolate(source, ast::InterpolationType::kFlat);
} }
/// Creates an ast::InterpolateDecoration using flat interpolation /// Creates an ast::InterpolateAttribute using flat interpolation
/// @returns the interpolate decoration pointer /// @returns the interpolate attribute pointer
const ast::InterpolateDecoration* Flat() { const ast::InterpolateAttribute* Flat() {
return Interpolate(ast::InterpolationType::kFlat); return Interpolate(ast::InterpolationType::kFlat);
} }
/// Creates an ast::InvariantDecoration /// Creates an ast::InvariantAttribute
/// @param source the source information /// @param source the source information
/// @returns the invariant decoration pointer /// @returns the invariant attribute pointer
const ast::InvariantDecoration* Invariant(const Source& source) { const ast::InvariantAttribute* Invariant(const Source& source) {
return create<ast::InvariantDecoration>(source); return create<ast::InvariantAttribute>(source);
} }
/// Creates an ast::InvariantDecoration /// Creates an ast::InvariantAttribute
/// @returns the invariant decoration pointer /// @returns the invariant attribute pointer
const ast::InvariantDecoration* Invariant() { const ast::InvariantAttribute* Invariant() {
return create<ast::InvariantDecoration>(source_); return create<ast::InvariantAttribute>(source_);
} }
/// Creates an ast::LocationDecoration /// Creates an ast::LocationAttribute
/// @param source the source information /// @param source the source information
/// @param location the location value /// @param location the location value
/// @returns the location decoration pointer /// @returns the location attribute pointer
const ast::LocationDecoration* Location(const Source& source, const ast::LocationAttribute* Location(const Source& source,
uint32_t location) { uint32_t location) {
return create<ast::LocationDecoration>(source, location); return create<ast::LocationAttribute>(source, location);
} }
/// Creates an ast::LocationDecoration /// Creates an ast::LocationAttribute
/// @param location the location value /// @param location the location value
/// @returns the location decoration pointer /// @returns the location attribute pointer
const ast::LocationDecoration* Location(uint32_t location) { const ast::LocationAttribute* Location(uint32_t location) {
return create<ast::LocationDecoration>(source_, location); return create<ast::LocationAttribute>(source_, location);
} }
/// Creates an ast::OverrideDecoration with a specific constant ID /// Creates an ast::OverrideAttribute with a specific constant ID
/// @param source the source information /// @param source the source information
/// @param id the id value /// @param id the id value
/// @returns the override decoration pointer /// @returns the override attribute pointer
const ast::OverrideDecoration* Override(const Source& source, uint32_t id) { const ast::OverrideAttribute* Override(const Source& source, uint32_t id) {
return create<ast::OverrideDecoration>(source, id); return create<ast::OverrideAttribute>(source, id);
} }
/// Creates an ast::OverrideDecoration with a specific constant ID /// Creates an ast::OverrideAttribute with a specific constant ID
/// @param id the optional id value /// @param id the optional id value
/// @returns the override decoration pointer /// @returns the override attribute pointer
const ast::OverrideDecoration* Override(uint32_t id) { const ast::OverrideAttribute* Override(uint32_t id) {
return Override(source_, id); return Override(source_, id);
} }
/// Creates an ast::OverrideDecoration without a constant ID /// Creates an ast::OverrideAttribute without a constant ID
/// @param source the source information /// @param source the source information
/// @returns the override decoration pointer /// @returns the override attribute pointer
const ast::OverrideDecoration* Override(const Source& source) { const ast::OverrideAttribute* Override(const Source& source) {
return create<ast::OverrideDecoration>(source); return create<ast::OverrideAttribute>(source);
} }
/// Creates an ast::OverrideDecoration without a constant ID /// Creates an ast::OverrideAttribute without a constant ID
/// @returns the override decoration pointer /// @returns the override attribute pointer
const ast::OverrideDecoration* Override() { return Override(source_); } const ast::OverrideAttribute* Override() { return Override(source_); }
/// Creates an ast::StageDecoration /// Creates an ast::StageAttribute
/// @param source the source information /// @param source the source information
/// @param stage the pipeline stage /// @param stage the pipeline stage
/// @returns the stage decoration pointer /// @returns the stage attribute pointer
const ast::StageDecoration* Stage(const Source& source, const ast::StageAttribute* Stage(const Source& source,
ast::PipelineStage stage) { ast::PipelineStage stage) {
return create<ast::StageDecoration>(source, stage); return create<ast::StageAttribute>(source, stage);
} }
/// Creates an ast::StageDecoration /// Creates an ast::StageAttribute
/// @param stage the pipeline stage /// @param stage the pipeline stage
/// @returns the stage decoration pointer /// @returns the stage attribute pointer
const ast::StageDecoration* Stage(ast::PipelineStage stage) { const ast::StageAttribute* Stage(ast::PipelineStage stage) {
return create<ast::StageDecoration>(source_, stage); return create<ast::StageAttribute>(source_, stage);
} }
/// Creates an ast::WorkgroupDecoration /// Creates an ast::WorkgroupAttribute
/// @param x the x dimension expression /// @param x the x dimension expression
/// @returns the workgroup decoration pointer /// @returns the workgroup attribute pointer
template <typename EXPR_X> template <typename EXPR_X>
const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x) { const ast::WorkgroupAttribute* WorkgroupSize(EXPR_X&& x) {
return WorkgroupSize(std::forward<EXPR_X>(x), nullptr, nullptr); return WorkgroupSize(std::forward<EXPR_X>(x), nullptr, nullptr);
} }
/// Creates an ast::WorkgroupDecoration /// Creates an ast::WorkgroupAttribute
/// @param x the x dimension expression /// @param x the x dimension expression
/// @param y the y dimension expression /// @param y the y dimension expression
/// @returns the workgroup decoration pointer /// @returns the workgroup attribute pointer
template <typename EXPR_X, typename EXPR_Y> template <typename EXPR_X, typename EXPR_Y>
const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x, EXPR_Y&& y) { const ast::WorkgroupAttribute* WorkgroupSize(EXPR_X&& x, EXPR_Y&& y) {
return WorkgroupSize(std::forward<EXPR_X>(x), std::forward<EXPR_Y>(y), return WorkgroupSize(std::forward<EXPR_X>(x), std::forward<EXPR_Y>(y),
nullptr); nullptr);
} }
/// Creates an ast::WorkgroupDecoration /// Creates an ast::WorkgroupAttribute
/// @param source the source information /// @param source the source information
/// @param x the x dimension expression /// @param x the x dimension expression
/// @param y the y dimension expression /// @param y the y dimension expression
/// @param z the z dimension expression /// @param z the z dimension expression
/// @returns the workgroup decoration pointer /// @returns the workgroup attribute pointer
template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z> template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
const ast::WorkgroupDecoration* WorkgroupSize(const Source& source, const ast::WorkgroupAttribute* WorkgroupSize(const Source& source,
EXPR_X&& x, EXPR_X&& x,
EXPR_Y&& y, EXPR_Y&& y,
EXPR_Z&& z) { EXPR_Z&& z) {
return create<ast::WorkgroupDecoration>( return create<ast::WorkgroupAttribute>(
source, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)), source, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
Expr(std::forward<EXPR_Z>(z))); Expr(std::forward<EXPR_Z>(z)));
} }
/// Creates an ast::WorkgroupDecoration /// Creates an ast::WorkgroupAttribute
/// @param x the x dimension expression /// @param x the x dimension expression
/// @param y the y dimension expression /// @param y the y dimension expression
/// @param z the z dimension expression /// @param z the z dimension expression
/// @returns the workgroup decoration pointer /// @returns the workgroup attribute pointer
template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z> template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x, const ast::WorkgroupAttribute* WorkgroupSize(EXPR_X&& x,
EXPR_Y&& y, EXPR_Y&& y,
EXPR_Z&& z) { EXPR_Z&& z) {
return create<ast::WorkgroupDecoration>( return create<ast::WorkgroupAttribute>(
source_, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)), source_, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
Expr(std::forward<EXPR_Z>(z))); Expr(std::forward<EXPR_Z>(z)));
} }
/// Creates an ast::DisableValidationDecoration /// Creates an ast::DisableValidationAttribute
/// @param validation the validation to disable /// @param validation the validation to disable
/// @returns the disable validation decoration pointer /// @returns the disable validation attribute pointer
const ast::DisableValidationDecoration* Disable( const ast::DisableValidationAttribute* Disable(
ast::DisabledValidation validation) { ast::DisabledValidation validation) {
return ASTNodes().Create<ast::DisableValidationDecoration>(ID(), return ASTNodes().Create<ast::DisableValidationAttribute>(ID(), validation);
validation);
} }
/// Sets the current builder source to `src` /// Sets the current builder source to `src`

View File

@ -21,7 +21,7 @@
#include "src/ast/bitcast_expression.h" #include "src/ast/bitcast_expression.h"
#include "src/ast/break_statement.h" #include "src/ast/break_statement.h"
#include "src/ast/builtin.h" #include "src/ast/builtin.h"
#include "src/ast/builtin_decoration.h" #include "src/ast/builtin_attribute.h"
#include "src/ast/call_statement.h" #include "src/ast/call_statement.h"
#include "src/ast/continue_statement.h" #include "src/ast/continue_statement.h"
#include "src/ast/discard_statement.h" #include "src/ast/discard_statement.h"
@ -29,7 +29,7 @@
#include "src/ast/if_statement.h" #include "src/ast/if_statement.h"
#include "src/ast/loop_statement.h" #include "src/ast/loop_statement.h"
#include "src/ast/return_statement.h" #include "src/ast/return_statement.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include "src/ast/switch_statement.h" #include "src/ast/switch_statement.h"
#include "src/ast/unary_op_expression.h" #include "src/ast/unary_op_expression.h"
#include "src/ast/variable_decl_statement.h" #include "src/ast/variable_decl_statement.h"
@ -712,8 +712,8 @@ struct LoopStatementBuilder
/// @param decos a list of parsed decorations /// @param decos a list of parsed decorations
/// @returns true if the decorations include a SampleMask builtin /// @returns true if the decorations include a SampleMask builtin
bool HasBuiltinSampleMask(const ast::DecorationList& decos) { bool HasBuiltinSampleMask(const ast::AttributeList& decos) {
if (auto* builtin = ast::GetDecoration<ast::BuiltinDecoration>(decos)) { if (auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(decos)) {
return builtin->builtin == ast::Builtin::kSampleMask; return builtin->builtin == ast::Builtin::kSampleMask;
} }
return false; return false;
@ -915,7 +915,7 @@ bool FunctionEmitter::Emit() {
builder_.AST().AddFunction(create<ast::Function>( builder_.AST().AddFunction(create<ast::Function>(
decl.source, builder_.Symbols().Register(decl.name), decl.source, builder_.Symbols().Register(decl.name),
std::move(decl.params), decl.return_type->Build(builder_), body, std::move(decl.params), decl.return_type->Build(builder_), body,
std::move(decl.decorations), ast::DecorationList{})); std::move(decl.attributes), ast::AttributeList{}));
} }
if (ep_info_ && !ep_info_->inner_name.empty()) { if (ep_info_ && !ep_info_->inner_name.empty()) {
@ -953,7 +953,7 @@ const ast::BlockStatement* FunctionEmitter::MakeFunctionBody() {
bool FunctionEmitter::EmitPipelineInput(std::string var_name, bool FunctionEmitter::EmitPipelineInput(std::string var_name,
const Type* var_type, const Type* var_type,
ast::DecorationList* decos, ast::AttributeList* decos,
std::vector<int> index_prefix, std::vector<int> index_prefix,
const Type* tip_type, const Type* tip_type,
const Type* forced_param_type, const Type* forced_param_type,
@ -997,7 +997,7 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
index_prefix.push_back(0); index_prefix.push_back(0);
for (int i = 0; i < static_cast<int>(members.size()); ++i) { for (int i = 0; i < static_cast<int>(members.size()); ++i) {
index_prefix.back() = i; index_prefix.back() = i;
ast::DecorationList member_decos(*decos); ast::AttributeList member_decos(*decos);
if (!parser_impl_.ConvertPipelineDecorations( if (!parser_impl_.ConvertPipelineDecorations(
struct_type, struct_type,
parser_impl_.GetMemberPipelineDecorations(*struct_type, i), parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
@ -1015,7 +1015,7 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
return success(); return success();
} }
const bool is_builtin = ast::HasDecoration<ast::BuiltinDecoration>(*decos); const bool is_builtin = ast::HasAttribute<ast::BuiltinAttribute>(*decos);
const Type* param_type = is_builtin ? forced_param_type : tip_type; const Type* param_type = is_builtin ? forced_param_type : tip_type;
@ -1067,22 +1067,22 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
return success(); return success();
} }
void FunctionEmitter::IncrementLocation(ast::DecorationList* decos) { void FunctionEmitter::IncrementLocation(ast::AttributeList* attributes) {
for (auto*& deco : *decos) { for (auto*& attr : *attributes) {
if (auto* loc_deco = deco->As<ast::LocationDecoration>()) { if (auto* loc_attr = attr->As<ast::LocationAttribute>()) {
// Replace this location decoration with a new one with one higher index. // Replace this location attribute with a new one with one higher index.
// The old one doesn't leak because it's kept in the builder's AST node // The old one doesn't leak because it's kept in the builder's AST node
// list. // list.
deco = builder_.Location(loc_deco->source, loc_deco->value + 1); attr = builder_.Location(loc_attr->source, loc_attr->value + 1);
} }
} }
} }
const ast::Decoration* FunctionEmitter::GetLocation( const ast::Attribute* FunctionEmitter::GetLocation(
const ast::DecorationList& decos) { const ast::AttributeList& attributes) {
for (auto* const& deco : decos) { for (auto* const& attr : attributes) {
if (deco->Is<ast::LocationDecoration>()) { if (attr->Is<ast::LocationAttribute>()) {
return deco; return attr;
} }
} }
return nullptr; return nullptr;
@ -1090,7 +1090,7 @@ const ast::Decoration* FunctionEmitter::GetLocation(
bool FunctionEmitter::EmitPipelineOutput(std::string var_name, bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
const Type* var_type, const Type* var_type,
ast::DecorationList* decos, ast::AttributeList* decos,
std::vector<int> index_prefix, std::vector<int> index_prefix,
const Type* tip_type, const Type* tip_type,
const Type* forced_member_type, const Type* forced_member_type,
@ -1135,7 +1135,7 @@ bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
index_prefix.push_back(0); index_prefix.push_back(0);
for (int i = 0; i < static_cast<int>(members.size()); ++i) { for (int i = 0; i < static_cast<int>(members.size()); ++i) {
index_prefix.back() = i; index_prefix.back() = i;
ast::DecorationList member_decos(*decos); ast::AttributeList member_decos(*decos);
if (!parser_impl_.ConvertPipelineDecorations( if (!parser_impl_.ConvertPipelineDecorations(
struct_type, struct_type,
parser_impl_.GetMemberPipelineDecorations(*struct_type, i), parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
@ -1153,7 +1153,7 @@ bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
return success(); return success();
} }
const bool is_builtin = ast::HasDecoration<ast::BuiltinDecoration>(*decos); const bool is_builtin = ast::HasAttribute<ast::BuiltinAttribute>(*decos);
const Type* member_type = is_builtin ? forced_member_type : tip_type; const Type* member_type = is_builtin ? forced_member_type : tip_type;
// Derive the member name directly from the variable name. They can't // Derive the member name directly from the variable name. They can't
@ -1224,7 +1224,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
TINT_ASSERT(Reader, var->opcode() == SpvOpVariable); TINT_ASSERT(Reader, var->opcode() == SpvOpVariable);
auto* store_type = GetVariableStoreType(*var); auto* store_type = GetVariableStoreType(*var);
auto* forced_param_type = store_type; auto* forced_param_type = store_type;
ast::DecorationList param_decos; ast::AttributeList param_decos;
if (!parser_impl_.ConvertDecorationsForVariable(var_id, &forced_param_type, if (!parser_impl_.ConvertDecorationsForVariable(var_id, &forced_param_type,
&param_decos, true)) { &param_decos, true)) {
// This occurs, and is not an error, for the PointSize builtin. // This occurs, and is not an error, for the PointSize builtin.
@ -1293,8 +1293,8 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
// The SPIR-V gl_PerVertex variable has already been remapped to // The SPIR-V gl_PerVertex variable has already been remapped to
// a gl_Position variable. Substitute the type. // a gl_Position variable. Substitute the type.
const Type* param_type = ty_.Vector(ty_.F32(), 4); const Type* param_type = ty_.Vector(ty_.F32(), 4);
ast::DecorationList out_decos{ ast::AttributeList out_decos{
create<ast::BuiltinDecoration>(source, ast::Builtin::kPosition)}; create<ast::BuiltinAttribute>(source, ast::Builtin::kPosition)};
const auto var_name = namer_.GetName(var_id); const auto var_name = namer_.GetName(var_id);
return_members.push_back( return_members.push_back(
@ -1307,7 +1307,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
TINT_ASSERT(Reader, var->opcode() == SpvOpVariable); TINT_ASSERT(Reader, var->opcode() == SpvOpVariable);
const Type* store_type = GetVariableStoreType(*var); const Type* store_type = GetVariableStoreType(*var);
const Type* forced_member_type = store_type; const Type* forced_member_type = store_type;
ast::DecorationList out_decos; ast::AttributeList out_decos;
if (!parser_impl_.ConvertDecorationsForVariable( if (!parser_impl_.ConvertDecorationsForVariable(
var_id, &forced_member_type, &out_decos, true)) { var_id, &forced_member_type, &out_decos, true)) {
// This occurs, and is not an error, for the PointSize builtin. // This occurs, and is not an error, for the PointSize builtin.
@ -1349,7 +1349,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
} else { } else {
// Create and register the result type. // Create and register the result type.
auto* str = create<ast::Struct>(Source{}, return_struct_sym, auto* str = create<ast::Struct>(Source{}, return_struct_sym,
return_members, ast::DecorationList{}); return_members, ast::AttributeList{});
parser_impl_.AddTypeDecl(return_struct_sym, str); parser_impl_.AddTypeDecl(return_struct_sym, str);
return_type = builder_.ty.Of(str); return_type = builder_.ty.Of(str);
@ -1361,8 +1361,8 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
} }
auto* body = create<ast::BlockStatement>(source, stmts); auto* body = create<ast::BlockStatement>(source, stmts);
ast::DecorationList fn_decos; ast::AttributeList fn_attrs;
fn_decos.emplace_back(create<ast::StageDecoration>(source, ep_info_->stage)); fn_attrs.emplace_back(create<ast::StageAttribute>(source, ep_info_->stage));
if (ep_info_->stage == ast::PipelineStage::kCompute) { if (ep_info_->stage == ast::PipelineStage::kCompute) {
auto& size = ep_info_->workgroup_size; auto& size = ep_info_->workgroup_size;
@ -1372,15 +1372,14 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
size.y ? builder_.Expr(static_cast<int>(size.y)) : nullptr; size.y ? builder_.Expr(static_cast<int>(size.y)) : nullptr;
const ast::Expression* z = const ast::Expression* z =
size.z ? builder_.Expr(static_cast<int>(size.z)) : nullptr; size.z ? builder_.Expr(static_cast<int>(size.z)) : nullptr;
fn_decos.emplace_back( fn_attrs.emplace_back(create<ast::WorkgroupAttribute>(Source{}, x, y, z));
create<ast::WorkgroupDecoration>(Source{}, x, y, z));
} }
} }
builder_.AST().AddFunction( builder_.AST().AddFunction(
create<ast::Function>(source, builder_.Symbols().Register(ep_info_->name), create<ast::Function>(source, builder_.Symbols().Register(ep_info_->name),
std::move(decl.params), return_type, body, std::move(decl.params), return_type, body,
std::move(fn_decos), ast::DecorationList{})); std::move(fn_attrs), ast::AttributeList{}));
return true; return true;
} }
@ -1412,7 +1411,7 @@ bool FunctionEmitter::ParseFunctionDeclaration(FunctionDeclaration* decl) {
if (type != nullptr) { if (type != nullptr) {
auto* ast_param = parser_impl_.MakeVariable( auto* ast_param = parser_impl_.MakeVariable(
param->result_id(), ast::StorageClass::kNone, type, true, nullptr, param->result_id(), ast::StorageClass::kNone, type, true, nullptr,
ast::DecorationList{}); ast::AttributeList{});
// Parameters are treated as const declarations. // Parameters are treated as const declarations.
ast_params.emplace_back(ast_param); ast_params.emplace_back(ast_param);
// The value is accessible by name. // The value is accessible by name.
@ -1428,7 +1427,7 @@ bool FunctionEmitter::ParseFunctionDeclaration(FunctionDeclaration* decl) {
decl->name = name; decl->name = name;
decl->params = std::move(ast_params); decl->params = std::move(ast_params);
decl->return_type = ret_ty; decl->return_type = ret_ty;
decl->decorations.clear(); decl->attributes.clear();
return success(); return success();
} }
@ -2513,7 +2512,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
} }
auto* var = parser_impl_.MakeVariable( auto* var = parser_impl_.MakeVariable(
inst.result_id(), ast::StorageClass::kNone, var_store_type, false, inst.result_id(), ast::StorageClass::kNone, var_store_type, false,
constructor, ast::DecorationList{}); constructor, ast::AttributeList{});
auto* var_decl_stmt = create<ast::VariableDeclStatement>(Source{}, var); auto* var_decl_stmt = create<ast::VariableDeclStatement>(Source{}, var);
AddStatement(var_decl_stmt); AddStatement(var_decl_stmt);
auto* var_type = ty_.Reference(var_store_type, ast::StorageClass::kNone); auto* var_type = ty_.Reference(var_store_type, ast::StorageClass::kNone);
@ -3417,7 +3416,7 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
AddStatement(create<ast::VariableDeclStatement>( AddStatement(create<ast::VariableDeclStatement>(
Source{}, Source{},
parser_impl_.MakeVariable(id, ast::StorageClass::kNone, storage_type, parser_impl_.MakeVariable(id, ast::StorageClass::kNone, storage_type,
false, nullptr, ast::DecorationList{}))); false, nullptr, ast::AttributeList{})));
auto* type = ty_.Reference(storage_type, ast::StorageClass::kNone); auto* type = ty_.Reference(storage_type, ast::StorageClass::kNone);
identifier_types_.emplace(id, type); identifier_types_.emplace(id, type);
} }
@ -3490,7 +3489,7 @@ bool FunctionEmitter::EmitConstDefinition(
expr = AddressOfIfNeeded(expr, &inst); expr = AddressOfIfNeeded(expr, &inst);
auto* ast_const = parser_impl_.MakeVariable( auto* ast_const = parser_impl_.MakeVariable(
inst.result_id(), ast::StorageClass::kNone, expr.type, true, expr.expr, inst.result_id(), ast::StorageClass::kNone, expr.type, true, expr.expr,
ast::DecorationList{}); ast::AttributeList{});
if (!ast_const) { if (!ast_const) {
return false; return false;
} }

View File

@ -441,7 +441,7 @@ class FunctionEmitter {
/// @returns false if emission failed /// @returns false if emission failed
bool EmitPipelineInput(std::string var_name, bool EmitPipelineInput(std::string var_name,
const Type* var_type, const Type* var_type,
ast::DecorationList* decos, ast::AttributeList* decos,
std::vector<int> index_prefix, std::vector<int> index_prefix,
const Type* tip_type, const Type* tip_type,
const Type* forced_param_type, const Type* forced_param_type,
@ -470,24 +470,24 @@ class FunctionEmitter {
/// @returns false if emission failed /// @returns false if emission failed
bool EmitPipelineOutput(std::string var_name, bool EmitPipelineOutput(std::string var_name,
const Type* var_type, const Type* var_type,
ast::DecorationList* decos, ast::AttributeList* decos,
std::vector<int> index_prefix, std::vector<int> index_prefix,
const Type* tip_type, const Type* tip_type,
const Type* forced_member_type, const Type* forced_member_type,
ast::StructMemberList* return_members, ast::StructMemberList* return_members,
ast::ExpressionList* return_exprs); ast::ExpressionList* return_exprs);
/// Updates the decoration list, replacing an existing Location decoration /// Updates the attribute list, replacing an existing Location attribute
/// with another having one higher location value. Does nothing if no /// with another having one higher location value. Does nothing if no
/// location decoration exists. /// location attribute exists.
/// Assumes the list contains at most one Location decoration. /// Assumes the list contains at most one Location attribute.
/// @param decos the decoration list to modify /// @param attributes the attribute list to modify
void IncrementLocation(ast::DecorationList* decos); void IncrementLocation(ast::AttributeList* attributes);
/// Returns the Location dcoration, if it exists. /// Returns the Location attribute, if it exists.
/// @param decos the list of decorations to search /// @param attributes the list of attributes to search
/// @returns the Location decoration, or nullptr if it doesn't exist /// @returns the Location attribute, or nullptr if it doesn't exist
const ast::Decoration* GetLocation(const ast::DecorationList& decos); const ast::Attribute* GetLocation(const ast::AttributeList& attributes);
/// Create an ast::BlockStatement representing the body of the function. /// Create an ast::BlockStatement representing the body of the function.
/// This creates the statement stack, which is non-empty for the lifetime /// This creates the statement stack, which is non-empty for the lifetime
@ -948,8 +948,8 @@ class FunctionEmitter {
ast::VariableList params; ast::VariableList params;
/// Function return type /// Function return type
const Type* return_type; const Type* return_type;
/// Function decorations /// Function attributes
ast::DecorationList decorations; ast::AttributeList attributes;
}; };
/// Parse the function declaration, which comprises the name, parameters, and /// Parse the function declaration, which comprises the name, parameters, and

View File

@ -21,9 +21,9 @@
#include "source/opt/build_module.h" #include "source/opt/build_module.h"
#include "src/ast/bitcast_expression.h" #include "src/ast/bitcast_expression.h"
#include "src/ast/disable_validation_decoration.h" #include "src/ast/disable_validation_attribute.h"
#include "src/ast/interpolate_decoration.h" #include "src/ast/interpolate_attribute.h"
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/type_name.h" #include "src/ast/type_name.h"
#include "src/ast/unary_op_expression.h" #include "src/ast/unary_op_expression.h"
#include "src/reader/spirv/function.h" #include "src/reader/spirv/function.h"
@ -439,7 +439,7 @@ std::string ParserImpl::ShowType(uint32_t type_id) {
return "SPIR-V type " + std::to_string(type_id); return "SPIR-V type " + std::to_string(type_id);
} }
ast::DecorationList ParserImpl::ConvertMemberDecoration( ast::AttributeList ParserImpl::ConvertMemberDecoration(
uint32_t struct_type_id, uint32_t struct_type_id,
uint32_t member_index, uint32_t member_index,
const Type* member_ty, const Type* member_ty,
@ -458,7 +458,7 @@ ast::DecorationList ParserImpl::ConvertMemberDecoration(
return {}; return {};
} }
return { return {
create<ast::StructMemberOffsetDecoration>(Source{}, decoration[1]), create<ast::StructMemberOffsetAttribute>(Source{}, decoration[1]),
}; };
case SpvDecorationNonReadable: case SpvDecorationNonReadable:
// WGSL doesn't have a member decoration for this. Silently drop it. // WGSL doesn't have a member decoration for this. Silently drop it.
@ -505,9 +505,9 @@ ast::DecorationList ParserImpl::ConvertMemberDecoration(
return {}; return {};
} }
return { return {
create<ast::StrideDecoration>(Source{}, decoration[1]), create<ast::StrideAttribute>(Source{}, decoration[1]),
builder_.ASTNodes().Create<ast::DisableValidationDecoration>( builder_.ASTNodes().Create<ast::DisableValidationAttribute>(
builder_.ID(), ast::DisabledValidation::kIgnoreStrideDecoration), builder_.ID(), ast::DisabledValidation::kIgnoreStrideAttribute),
}; };
} }
default: default:
@ -1152,7 +1152,7 @@ const Type* ParserImpl::ConvertType(
} }
bool is_non_writable = false; bool is_non_writable = false;
ast::DecorationList ast_member_decorations; ast::AttributeList ast_member_decorations;
for (auto& decoration : GetDecorationsForMember(type_id, member_index)) { for (auto& decoration : GetDecorationsForMember(type_id, member_index)) {
if (IsPipelineDecoration(decoration)) { if (IsPipelineDecoration(decoration)) {
// IO decorations are handled when emitting the entry point. // IO decorations are handled when emitting the entry point.
@ -1198,7 +1198,7 @@ const Type* ParserImpl::ConvertType(
// Now make the struct. // Now make the struct.
auto sym = builder_.Symbols().Register(name); auto sym = builder_.Symbols().Register(name);
auto* ast_struct = create<ast::Struct>(Source{}, sym, std::move(ast_members), auto* ast_struct = create<ast::Struct>(Source{}, sym, std::move(ast_members),
ast::DecorationList()); ast::AttributeList());
if (num_non_writable_members == members.size()) { if (num_non_writable_members == members.size()) {
read_only_struct_types_.insert(ast_struct->name); read_only_struct_types_.insert(ast_struct->name);
} }
@ -1386,7 +1386,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
break; break;
} }
if (ast_type && ast_expr) { if (ast_type && ast_expr) {
ast::DecorationList spec_id_decos; ast::AttributeList spec_id_decos;
for (const auto& deco : GetDecorationsFor(inst.result_id())) { for (const auto& deco : GetDecorationsFor(inst.result_id())) {
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) { if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
const uint32_t id = deco[1]; const uint32_t id = deco[1];
@ -1395,7 +1395,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
"between 0 and 65535: ID %" "between 0 and 65535: ID %"
<< inst.result_id() << " has SpecId " << id; << inst.result_id() << " has SpecId " << id;
} }
auto* cid = create<ast::OverrideDecoration>(Source{}, id); auto* cid = create<ast::OverrideAttribute>(Source{}, id);
spec_id_decos.push_back(cid); spec_id_decos.push_back(cid);
break; break;
} }
@ -1526,7 +1526,7 @@ bool ParserImpl::EmitModuleScopeVariables() {
} }
auto* ast_var = auto* ast_var =
MakeVariable(var.result_id(), ast_storage_class, ast_store_type, false, MakeVariable(var.result_id(), ast_storage_class, ast_store_type, false,
ast_constructor, ast::DecorationList{}); ast_constructor, ast::AttributeList{});
// TODO(dneto): initializers (a.k.a. constructor expression) // TODO(dneto): initializers (a.k.a. constructor expression)
if (ast_var) { if (ast_var) {
builder_.AST().AddGlobalVariable(ast_var); builder_.AST().AddGlobalVariable(ast_var);
@ -1599,7 +1599,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
const Type* storage_type, const Type* storage_type,
bool is_const, bool is_const,
const ast::Expression* constructor, const ast::Expression* constructor,
ast::DecorationList decorations) { ast::AttributeList decorations) {
if (storage_type == nullptr) { if (storage_type == nullptr) {
Fail() << "internal error: can't make ast::Variable for null type"; Fail() << "internal error: can't make ast::Variable for null type";
return nullptr; return nullptr;
@ -1640,7 +1640,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
bool ParserImpl::ConvertDecorationsForVariable(uint32_t id, bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
const Type** store_type, const Type** store_type,
ast::DecorationList* decorations, ast::AttributeList* decorations,
bool transfer_pipeline_io) { bool transfer_pipeline_io) {
DecorationList non_builtin_pipeline_decorations; DecorationList non_builtin_pipeline_decorations;
for (auto& deco : GetDecorationsFor(id)) { for (auto& deco : GetDecorationsFor(id)) {
@ -1702,7 +1702,7 @@ bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
} }
if (transfer_pipeline_io) { if (transfer_pipeline_io) {
decorations->emplace_back( decorations->emplace_back(
create<ast::BuiltinDecoration>(Source{}, ast_builtin)); create<ast::BuiltinAttribute>(Source{}, ast_builtin));
} }
} }
if (transfer_pipeline_io && IsPipelineDecoration(deco)) { if (transfer_pipeline_io && IsPipelineDecoration(deco)) {
@ -1713,8 +1713,7 @@ bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
return Fail() << "malformed DescriptorSet decoration on ID " << id return Fail() << "malformed DescriptorSet decoration on ID " << id
<< ": has no operand"; << ": has no operand";
} }
decorations->emplace_back( decorations->emplace_back(create<ast::GroupAttribute>(Source{}, deco[1]));
create<ast::GroupDecoration>(Source{}, deco[1]));
} }
if (deco[0] == SpvDecorationBinding) { if (deco[0] == SpvDecorationBinding) {
if (deco.size() == 1) { if (deco.size() == 1) {
@ -1722,7 +1721,7 @@ bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
<< ": has no operand"; << ": has no operand";
} }
decorations->emplace_back( decorations->emplace_back(
create<ast::BindingDecoration>(Source{}, deco[1])); create<ast::BindingAttribute>(Source{}, deco[1]));
} }
} }
@ -1750,31 +1749,31 @@ DecorationList ParserImpl::GetMemberPipelineDecorations(
return result; return result;
} }
const ast::Decoration* ParserImpl::SetLocation( const ast::Attribute* ParserImpl::SetLocation(
ast::DecorationList* decos, ast::AttributeList* attributes,
const ast::Decoration* replacement) { const ast::Attribute* replacement) {
if (!replacement) { if (!replacement) {
return nullptr; return nullptr;
} }
for (auto*& deco : *decos) { for (auto*& attribute : *attributes) {
if (deco->Is<ast::LocationDecoration>()) { if (attribute->Is<ast::LocationAttribute>()) {
// Replace this location decoration with the replacement. // Replace this location attribute with the replacement.
// The old one doesn't leak because it's kept in the builder's AST node // The old one doesn't leak because it's kept in the builder's AST node
// list. // list.
const ast::Decoration* result = nullptr; const ast::Attribute* result = nullptr;
result = deco; result = attribute;
deco = replacement; attribute = replacement;
return result; // Assume there is only one such decoration. return result; // Assume there is only one such decoration.
} }
} }
// The list didn't have a location. Add it. // The list didn't have a location. Add it.
decos->push_back(replacement); attributes->push_back(replacement);
return nullptr; return nullptr;
} }
bool ParserImpl::ConvertPipelineDecorations(const Type* store_type, bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
const DecorationList& decorations, const DecorationList& decorations,
ast::DecorationList* ast_decos) { ast::AttributeList* attributes) {
// Vulkan defaults to perspective-correct interpolation. // Vulkan defaults to perspective-correct interpolation.
ast::InterpolationType type = ast::InterpolationType::kPerspective; ast::InterpolationType type = ast::InterpolationType::kPerspective;
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone; ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
@ -1787,8 +1786,8 @@ bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
return Fail() << "malformed Location decoration on ID requires one " return Fail() << "malformed Location decoration on ID requires one "
"literal operand"; "literal operand";
} }
SetLocation(ast_decos, SetLocation(attributes,
create<ast::LocationDecoration>(Source{}, deco[1])); create<ast::LocationAttribute>(Source{}, deco[1]));
if (store_type->IsIntegerScalarOrVector()) { if (store_type->IsIntegerScalarOrVector()) {
// Default to flat interpolation for integral user-defined IO types. // Default to flat interpolation for integral user-defined IO types.
type = ast::InterpolationType::kFlat; type = ast::InterpolationType::kFlat;
@ -1830,7 +1829,7 @@ bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
sampling == ast::InterpolationSampling::kNone) { sampling == ast::InterpolationSampling::kNone) {
// This is the default. Don't add a decoration. // This is the default. Don't add a decoration.
} else { } else {
ast_decos->emplace_back(create<ast::InterpolateDecoration>(type, sampling)); attributes->emplace_back(create<ast::InterpolateAttribute>(type, sampling));
} }
return success(); return success();

View File

@ -243,34 +243,34 @@ class ParserImpl : Reader {
/// @param id the ID of the SPIR-V variable /// @param id the ID of the SPIR-V variable
/// @param store_type the WGSL store type for the variable, which should be /// @param store_type the WGSL store type for the variable, which should be
/// prepopulatd /// prepopulatd
/// @param ast_decos the decoration list to populate /// @param attributes the attribute list to populate
/// @param transfer_pipeline_io true if pipeline IO decorations (builtins, /// @param transfer_pipeline_io true if pipeline IO decorations (builtins,
/// or locations) will update the store type and the decorations list /// or locations) will update the store type and the decorations list
/// @returns false when the variable should not be emitted as a variable /// @returns false when the variable should not be emitted as a variable
bool ConvertDecorationsForVariable(uint32_t id, bool ConvertDecorationsForVariable(uint32_t id,
const Type** store_type, const Type** store_type,
ast::DecorationList* ast_decos, ast::AttributeList* attributes,
bool transfer_pipeline_io); bool transfer_pipeline_io);
/// Converts SPIR-V decorations for pipeline IO into AST decorations. /// Converts SPIR-V decorations for pipeline IO into AST decorations.
/// @param store_type the store type for the variable or member /// @param store_type the store type for the variable or member
/// @param decorations the SPIR-V interpolation decorations /// @param decorations the SPIR-V interpolation decorations
/// @param ast_decos the decoration list to populate. /// @param attributes the attribute list to populate.
/// @returns false if conversion fails /// @returns false if conversion fails
bool ConvertPipelineDecorations(const Type* store_type, bool ConvertPipelineDecorations(const Type* store_type,
const DecorationList& decorations, const DecorationList& decorations,
ast::DecorationList* ast_decos); ast::AttributeList* attributes);
/// Updates the decoration list, placing a non-null location decoration into /// Updates the attribute list, placing a non-null location decoration into
/// the list, replacing an existing one if it exists. Does nothing if the /// the list, replacing an existing one if it exists. Does nothing if the
/// replacement is nullptr. /// replacement is nullptr.
/// Assumes the list contains at most one Location decoration. /// Assumes the list contains at most one Location decoration.
/// @param decos the decoration list to modify /// @param decos the attribute list to modify
/// @param replacement the location decoration to place into the list /// @param replacement the location decoration to place into the list
/// @returns the location decoration that was replaced, if one was replaced, /// @returns the location decoration that was replaced, if one was replaced,
/// or null otherwise. /// or null otherwise.
const ast::Decoration* SetLocation(ast::DecorationList* decos, const ast::Attribute* SetLocation(ast::AttributeList* decos,
const ast::Decoration* replacement); const ast::Attribute* replacement);
/// Converts a SPIR-V struct member decoration into a number of AST /// Converts a SPIR-V struct member decoration into a number of AST
/// decorations. If the decoration is recognized but deliberately dropped, /// decorations. If the decoration is recognized but deliberately dropped,
@ -281,10 +281,10 @@ class ParserImpl : Reader {
/// @param member_ty the type of the member /// @param member_ty the type of the member
/// @param decoration an encoded SPIR-V Decoration /// @param decoration an encoded SPIR-V Decoration
/// @returns the AST decorations /// @returns the AST decorations
ast::DecorationList ConvertMemberDecoration(uint32_t struct_type_id, ast::AttributeList ConvertMemberDecoration(uint32_t struct_type_id,
uint32_t member_index, uint32_t member_index,
const Type* member_ty, const Type* member_ty,
const Decoration& decoration); const Decoration& decoration);
/// Returns a string for the given type. If the type ID is invalid, /// Returns a string for the given type. If the type ID is invalid,
/// then the resulting string only names the type ID. /// then the resulting string only names the type ID.
@ -430,7 +430,7 @@ class ParserImpl : Reader {
const Type* storage_type, const Type* storage_type,
bool is_const, bool is_const,
const ast::Expression* constructor, const ast::Expression* constructor,
ast::DecorationList decorations); ast::AttributeList decorations);
/// Returns true if a constant expression can be generated. /// Returns true if a constant expression can be generated.
/// @param id the SPIR-V ID of the value /// @param id the SPIR-V ID of the value

View File

@ -56,8 +56,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
auto result = auto result =
p->ConvertMemberDecoration(1, 1, nullptr, {SpvDecorationOffset, 8}); p->ConvertMemberDecoration(1, 1, nullptr, {SpvDecorationOffset, 8});
ASSERT_FALSE(result.empty()); ASSERT_FALSE(result.empty());
EXPECT_TRUE(result[0]->Is<ast::StructMemberOffsetDecoration>()); EXPECT_TRUE(result[0]->Is<ast::StructMemberOffsetAttribute>());
auto* offset_deco = result[0]->As<ast::StructMemberOffsetDecoration>(); auto* offset_deco = result[0]->As<ast::StructMemberOffsetAttribute>();
ASSERT_NE(offset_deco, nullptr); ASSERT_NE(offset_deco, nullptr);
EXPECT_EQ(offset_deco->offset, 8u); EXPECT_EQ(offset_deco->offset, 8u);
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
@ -82,8 +82,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Custom) {
auto result = p->ConvertMemberDecoration(1, 1, &matrix, auto result = p->ConvertMemberDecoration(1, 1, &matrix,
{SpvDecorationMatrixStride, 16}); {SpvDecorationMatrixStride, 16});
ASSERT_FALSE(result.empty()); ASSERT_FALSE(result.empty());
EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>()); EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
auto* stride_deco = result[0]->As<ast::StrideDecoration>(); auto* stride_deco = result[0]->As<ast::StrideAttribute>();
ASSERT_NE(stride_deco, nullptr); ASSERT_NE(stride_deco, nullptr);
EXPECT_EQ(stride_deco->stride, 16u); EXPECT_EQ(stride_deco->stride, 16u);
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
@ -108,8 +108,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Custom) {
auto result = p->ConvertMemberDecoration(1, 1, &matrix, auto result = p->ConvertMemberDecoration(1, 1, &matrix,
{SpvDecorationMatrixStride, 64}); {SpvDecorationMatrixStride, 64});
ASSERT_FALSE(result.empty()); ASSERT_FALSE(result.empty());
EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>()); EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
auto* stride_deco = result[0]->As<ast::StrideDecoration>(); auto* stride_deco = result[0]->As<ast::StrideAttribute>();
ASSERT_NE(stride_deco, nullptr); ASSERT_NE(stride_deco, nullptr);
EXPECT_EQ(stride_deco->stride, 64u); EXPECT_EQ(stride_deco->stride, 64u);
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
@ -123,8 +123,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x3_Stride_Custom) {
auto result = p->ConvertMemberDecoration(1, 1, &matrix, auto result = p->ConvertMemberDecoration(1, 1, &matrix,
{SpvDecorationMatrixStride, 32}); {SpvDecorationMatrixStride, 32});
ASSERT_FALSE(result.empty()); ASSERT_FALSE(result.empty());
EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>()); EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
auto* stride_deco = result[0]->As<ast::StrideDecoration>(); auto* stride_deco = result[0]->As<ast::StrideAttribute>();
ASSERT_NE(stride_deco, nullptr); ASSERT_NE(stride_deco, nullptr);
EXPECT_EQ(stride_deco->stride, 32u); EXPECT_EQ(stride_deco->stride, 32u);
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());

View File

@ -196,10 +196,10 @@ class ParserImplWrapperForTest {
/// @param member_ty the type of the member /// @param member_ty the type of the member
/// @param decoration an encoded SPIR-V Decoration /// @param decoration an encoded SPIR-V Decoration
/// @returns the AST decorations /// @returns the AST decorations
ast::DecorationList ConvertMemberDecoration(uint32_t struct_type_id, ast::AttributeList ConvertMemberDecoration(uint32_t struct_type_id,
uint32_t member_index, uint32_t member_index,
const Type* member_ty, const Type* member_ty,
const Decoration& decoration) { const Decoration& decoration) {
return impl_.ConvertMemberDecoration(struct_type_id, member_index, return impl_.ConvertMemberDecoration(struct_type_id, member_index,
member_ty, decoration); member_ty, decoration);
} }

View File

@ -24,18 +24,18 @@
#include "src/ast/external_texture.h" #include "src/ast/external_texture.h"
#include "src/ast/fallthrough_statement.h" #include "src/ast/fallthrough_statement.h"
#include "src/ast/if_statement.h" #include "src/ast/if_statement.h"
#include "src/ast/invariant_decoration.h" #include "src/ast/invariant_attribute.h"
#include "src/ast/loop_statement.h" #include "src/ast/loop_statement.h"
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/ast/return_statement.h" #include "src/ast/return_statement.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_attribute.h"
#include "src/ast/struct_block_decoration.h" #include "src/ast/struct_block_attribute.h"
#include "src/ast/switch_statement.h" #include "src/ast/switch_statement.h"
#include "src/ast/type_name.h" #include "src/ast/type_name.h"
#include "src/ast/unary_op_expression.h" #include "src/ast/unary_op_expression.h"
#include "src/ast/variable_decl_statement.h" #include "src/ast/variable_decl_statement.h"
#include "src/ast/vector.h" #include "src/ast/vector.h"
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
#include "src/reader/wgsl/lexer.h" #include "src/reader/wgsl/lexer.h"
#include "src/sem/depth_texture_type.h" #include "src/sem/depth_texture_type.h"
#include "src/sem/external_texture_type.h" #include "src/sem/external_texture_type.h"
@ -110,27 +110,27 @@ ast::Builtin ident_to_builtin(std::string_view str) {
return ast::Builtin::kNone; return ast::Builtin::kNone;
} }
const char kBindingDecoration[] = "binding"; const char kBindingAttribute[] = "binding";
const char kBlockDecoration[] = "block"; const char kBlockAttribute[] = "block";
const char kBuiltinDecoration[] = "builtin"; const char kBuiltinAttribute[] = "builtin";
const char kGroupDecoration[] = "group"; const char kGroupAttribute[] = "group";
const char kInterpolateDecoration[] = "interpolate"; const char kInterpolateAttribute[] = "interpolate";
const char kInvariantDecoration[] = "invariant"; const char kInvariantAttribute[] = "invariant";
const char kLocationDecoration[] = "location"; const char kLocationAttribute[] = "location";
const char kOverrideDecoration[] = "override"; const char kOverrideAttribute[] = "override";
const char kSizeDecoration[] = "size"; const char kSizeAttribute[] = "size";
const char kAlignDecoration[] = "align"; const char kAlignAttribute[] = "align";
const char kStageDecoration[] = "stage"; const char kStageAttribute[] = "stage";
const char kStrideDecoration[] = "stride"; const char kStrideAttribute[] = "stride";
const char kWorkgroupSizeDecoration[] = "workgroup_size"; const char kWorkgroupSizeAttribute[] = "workgroup_size";
bool is_decoration(Token t) { bool is_attribute(Token t) {
return t == kAlignDecoration || t == kBindingDecoration || return t == kAlignAttribute || t == kBindingAttribute ||
t == kBlockDecoration || t == kBuiltinDecoration || t == kBlockAttribute || t == kBuiltinAttribute ||
t == kGroupDecoration || t == kInterpolateDecoration || t == kGroupAttribute || t == kInterpolateAttribute ||
t == kLocationDecoration || t == kOverrideDecoration || t == kLocationAttribute || t == kOverrideAttribute ||
t == kSizeDecoration || t == kStageDecoration || t == kSizeAttribute || t == kStageAttribute || t == kStrideAttribute ||
t == kStrideDecoration || t == kWorkgroupSizeDecoration; t == kWorkgroupSizeAttribute;
} }
// https://gpuweb.github.io/gpuweb/wgsl.html#reserved-keywords // https://gpuweb.github.io/gpuweb/wgsl.html#reserved-keywords
@ -225,12 +225,12 @@ ParserImpl::FunctionHeader::FunctionHeader(Source src,
std::string n, std::string n,
ast::VariableList p, ast::VariableList p,
const ast::Type* ret_ty, const ast::Type* ret_ty,
ast::DecorationList ret_decos) ast::AttributeList ret_attrs)
: source(src), : source(src),
name(n), name(n),
params(p), params(p),
return_type(ret_ty), return_type(ret_ty),
return_type_decorations(ret_decos) {} return_type_attributes(ret_attrs) {}
ParserImpl::FunctionHeader::~FunctionHeader() = default; ParserImpl::FunctionHeader::~FunctionHeader() = default;
@ -351,14 +351,14 @@ Expect<bool> ParserImpl::expect_global_decl() {
bool errored = false; bool errored = false;
auto decos = decoration_list(); auto attrs = attribute_list();
if (decos.errored) if (attrs.errored)
errored = true; errored = true;
if (!continue_parsing()) if (!continue_parsing())
return Failure::kErrored; return Failure::kErrored;
auto decl = sync(Token::Type::kSemicolon, [&]() -> Maybe<bool> { auto decl = sync(Token::Type::kSemicolon, [&]() -> Maybe<bool> {
auto gv = global_variable_decl(decos.value); auto gv = global_variable_decl(attrs.value);
if (gv.errored) if (gv.errored)
return Failure::kErrored; return Failure::kErrored;
if (gv.matched) { if (gv.matched) {
@ -369,7 +369,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
return true; return true;
} }
auto gc = global_constant_decl(decos.value); auto gc = global_constant_decl(attrs.value);
if (gc.errored) if (gc.errored)
return Failure::kErrored; return Failure::kErrored;
@ -393,7 +393,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
return true; return true;
} }
auto str = struct_decl(decos.value); auto str = struct_decl(attrs.value);
if (str.errored) if (str.errored)
return Failure::kErrored; return Failure::kErrored;
@ -409,10 +409,10 @@ Expect<bool> ParserImpl::expect_global_decl() {
errored = true; errored = true;
} }
if (decl.matched) { if (decl.matched) {
return expect_decorations_consumed(decos.value); return expect_attributes_consumed(attrs.value);
} }
auto func = function_decl(decos.value); auto func = function_decl(attrs.value);
if (func.errored) { if (func.errored) {
errored = true; errored = true;
} }
@ -427,9 +427,9 @@ Expect<bool> ParserImpl::expect_global_decl() {
// Invalid syntax found - try and determine the best error message // Invalid syntax found - try and determine the best error message
// We have decorations parsed, but nothing to consume them? // We have attributes parsed, but nothing to consume them?
if (decos.value.size() > 0) { if (attrs.value.size() > 0) {
return add_error(next(), "expected declaration after decorations"); return add_error(next(), "expected declaration after attributes");
} }
// We have a statement outside of a function? // We have a statement outside of a function?
@ -460,10 +460,10 @@ Expect<bool> ParserImpl::expect_global_decl() {
} }
// global_variable_decl // global_variable_decl
// : variable_decoration_list* variable_decl // : variable_attribute_list* variable_decl
// | variable_decoration_list* variable_decl EQUAL const_expr // | variable_attribute_list* variable_decl EQUAL const_expr
Maybe<const ast::Variable*> ParserImpl::global_variable_decl( Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
ast::DecorationList& decos) { ast::AttributeList& attrs) {
auto decl = variable_decl(); auto decl = variable_decl();
if (decl.errored) if (decl.errored)
return Failure::kErrored; return Failure::kErrored;
@ -486,7 +486,7 @@ Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
decl->type, // type decl->type, // type
false, // is_const false, // is_const
constructor, // constructor constructor, // constructor
std::move(decos)); // decorations std::move(attrs)); // attributes
} }
// global_constant_decl // global_constant_decl
@ -494,7 +494,7 @@ Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
// global_const_initializer // global_const_initializer
// : EQUAL const_expr // : EQUAL const_expr
Maybe<const ast::Variable*> ParserImpl::global_constant_decl( Maybe<const ast::Variable*> ParserImpl::global_constant_decl(
ast::DecorationList& decos) { ast::AttributeList& attrs) {
if (!match(Token::Type::kLet)) { if (!match(Token::Type::kLet)) {
return Failure::kNoMatch; return Failure::kNoMatch;
} }
@ -522,7 +522,7 @@ Maybe<const ast::Variable*> ParserImpl::global_constant_decl(
decl->type, // type decl->type, // type
true, // is_const true, // is_const
initializer, // constructor initializer, // constructor
std::move(decos)); // decorations std::move(attrs)); // attributes
} }
// variable_decl // variable_decl
@ -807,7 +807,7 @@ Expect<ast::TexelFormat> ParserImpl::expect_texel_format(std::string_view use) {
} }
// variable_ident_decl // variable_ident_decl
// : IDENT COLON variable_decoration_list* type_decl // : IDENT COLON variable_attribute_list* type_decl
Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl( Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
std::string_view use, std::string_view use,
bool allow_inferred) { bool allow_inferred) {
@ -822,18 +822,18 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
if (!expect(use, Token::Type::kColon)) if (!expect(use, Token::Type::kColon))
return Failure::kErrored; return Failure::kErrored;
auto decos = decoration_list(); auto attrs = attribute_list();
if (decos.errored) if (attrs.errored)
return Failure::kErrored; return Failure::kErrored;
auto t = peek(); auto t = peek();
auto type = type_decl(decos.value); auto type = type_decl(attrs.value);
if (type.errored) if (type.errored)
return Failure::kErrored; return Failure::kErrored;
if (!type.matched) if (!type.matched)
return add_error(t.source(), "invalid type", use); return add_error(t.source(), "invalid type", use);
if (!expect_decorations_consumed(decos.value)) if (!expect_attributes_consumed(attrs.value))
return Failure::kErrored; return Failure::kErrored;
return TypedIdentifier{type.value, ident.value, ident.source}; return TypedIdentifier{type.value, ident.value, ident.source};
@ -922,9 +922,9 @@ Maybe<const ast::Alias*> ParserImpl::type_alias() {
// | VEC3 LESS_THAN type_decl GREATER_THAN // | VEC3 LESS_THAN type_decl GREATER_THAN
// | VEC4 LESS_THAN type_decl GREATER_THAN // | VEC4 LESS_THAN type_decl GREATER_THAN
// | PTR LESS_THAN storage_class, type_decl (COMMA access_mode)? GREATER_THAN // | PTR LESS_THAN storage_class, type_decl (COMMA access_mode)? GREATER_THAN
// | array_decoration_list* ARRAY LESS_THAN type_decl COMMA // | array_attribute_list* ARRAY LESS_THAN type_decl COMMA
// INT_LITERAL GREATER_THAN // INT_LITERAL GREATER_THAN
// | array_decoration_list* ARRAY LESS_THAN type_decl // | array_attribute_list* ARRAY LESS_THAN type_decl
// GREATER_THAN // GREATER_THAN
// | MAT2x2 LESS_THAN type_decl GREATER_THAN // | MAT2x2 LESS_THAN type_decl GREATER_THAN
// | MAT2x3 LESS_THAN type_decl GREATER_THAN // | MAT2x3 LESS_THAN type_decl GREATER_THAN
@ -937,15 +937,15 @@ Maybe<const ast::Alias*> ParserImpl::type_alias() {
// | MAT4x4 LESS_THAN type_decl GREATER_THAN // | MAT4x4 LESS_THAN type_decl GREATER_THAN
// | texture_sampler_types // | texture_sampler_types
Maybe<const ast::Type*> ParserImpl::type_decl() { Maybe<const ast::Type*> ParserImpl::type_decl() {
auto decos = decoration_list(); auto attrs = attribute_list();
if (decos.errored) if (attrs.errored)
return Failure::kErrored; return Failure::kErrored;
auto type = type_decl(decos.value); auto type = type_decl(attrs.value);
if (type.errored) { if (type.errored) {
return Failure::kErrored; return Failure::kErrored;
} }
if (!expect_decorations_consumed(decos.value)) { if (!expect_attributes_consumed(attrs.value)) {
return Failure::kErrored; return Failure::kErrored;
} }
if (!type.matched) { if (!type.matched) {
@ -955,7 +955,7 @@ Maybe<const ast::Type*> ParserImpl::type_decl() {
return type; return type;
} }
Maybe<const ast::Type*> ParserImpl::type_decl(ast::DecorationList& decos) { Maybe<const ast::Type*> ParserImpl::type_decl(ast::AttributeList& attrs) {
auto t = peek(); auto t = peek();
Source source; Source source;
if (match(Token::Type::kIdentifier, &source)) { if (match(Token::Type::kIdentifier, &source)) {
@ -989,7 +989,7 @@ Maybe<const ast::Type*> ParserImpl::type_decl(ast::DecorationList& decos) {
} }
if (match(Token::Type::kArray, &source)) { if (match(Token::Type::kArray, &source)) {
return expect_type_decl_array(t, std::move(decos)); return expect_type_decl_array(t, std::move(attrs));
} }
if (t.IsMatrix()) { if (t.IsMatrix()) {
@ -1090,7 +1090,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_decl_vector(Token t) {
Expect<const ast::Type*> ParserImpl::expect_type_decl_array( Expect<const ast::Type*> ParserImpl::expect_type_decl_array(
Token t, Token t,
ast::DecorationList decos) { ast::AttributeList attrs) {
const char* use = "array declaration"; const char* use = "array declaration";
const ast::Expression* size = nullptr; const ast::Expression* size = nullptr;
@ -1119,7 +1119,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_decl_array(
} }
return builder_.ty.array(make_source_range_from(t.source()), subtype.value, return builder_.ty.array(make_source_range_from(t.source()), subtype.value,
size, std::move(decos)); size, std::move(attrs));
} }
Expect<const ast::Type*> ParserImpl::expect_type_decl_matrix(Token t) { Expect<const ast::Type*> ParserImpl::expect_type_decl_matrix(Token t) {
@ -1181,8 +1181,8 @@ Expect<ast::StorageClass> ParserImpl::expect_storage_class(
} }
// struct_decl // struct_decl
// : struct_decoration_decl* STRUCT IDENT struct_body_decl // : struct_attribute_decl* STRUCT IDENT struct_body_decl
Maybe<const ast::Struct*> ParserImpl::struct_decl(ast::DecorationList& decos) { Maybe<const ast::Struct*> ParserImpl::struct_decl(ast::AttributeList& attrs) {
auto t = peek(); auto t = peek();
auto source = t.source(); auto source = t.source();
@ -1199,7 +1199,7 @@ Maybe<const ast::Struct*> ParserImpl::struct_decl(ast::DecorationList& decos) {
auto sym = builder_.Symbols().Register(name.value); auto sym = builder_.Symbols().Register(name.value);
return create<ast::Struct>(source, sym, std::move(body.value), return create<ast::Struct>(source, sym, std::move(body.value),
std::move(decos)); std::move(attrs));
} }
// struct_body_decl // struct_body_decl
@ -1215,14 +1215,14 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
!peek_is(Token::Type::kEOF)) { !peek_is(Token::Type::kEOF)) {
auto member = sync(Token::Type::kSemicolon, auto member = sync(Token::Type::kSemicolon,
[&]() -> Expect<ast::StructMember*> { [&]() -> Expect<ast::StructMember*> {
auto decos = decoration_list(); auto attrs = attribute_list();
if (decos.errored) { if (attrs.errored) {
errored = true; errored = true;
} }
if (!synchronized_) { if (!synchronized_) {
return Failure::kErrored; return Failure::kErrored;
} }
return expect_struct_member(decos.value); return expect_struct_member(attrs.value);
}); });
if (member.errored) { if (member.errored) {
@ -1240,9 +1240,9 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
} }
// struct_member // struct_member
// : struct_member_decoration_decl+ variable_ident_decl SEMICOLON // : struct_member_attribute_decl+ variable_ident_decl SEMICOLON
Expect<ast::StructMember*> ParserImpl::expect_struct_member( Expect<ast::StructMember*> ParserImpl::expect_struct_member(
ast::DecorationList& decos) { ast::AttributeList& attrs) {
auto decl = expect_variable_ident_decl("struct member"); auto decl = expect_variable_ident_decl("struct member");
if (decl.errored) if (decl.errored)
return Failure::kErrored; return Failure::kErrored;
@ -1252,13 +1252,13 @@ Expect<ast::StructMember*> ParserImpl::expect_struct_member(
return create<ast::StructMember>(decl->source, return create<ast::StructMember>(decl->source,
builder_.Symbols().Register(decl->name), builder_.Symbols().Register(decl->name),
decl->type, std::move(decos)); decl->type, std::move(attrs));
} }
// function_decl // function_decl
// : function_header body_stmt // : function_header body_stmt
Maybe<const ast::Function*> ParserImpl::function_decl( Maybe<const ast::Function*> ParserImpl::function_decl(
ast::DecorationList& decos) { ast::AttributeList& attrs) {
auto header = function_header(); auto header = function_header();
if (header.errored) { if (header.errored) {
if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) { if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) {
@ -1286,7 +1286,7 @@ Maybe<const ast::Function*> ParserImpl::function_decl(
return create<ast::Function>( return create<ast::Function>(
header->source, builder_.Symbols().Register(header->name), header->params, header->source, builder_.Symbols().Register(header->name), header->params,
header->return_type, body.value, decos, header->return_type_decorations); header->return_type, body.value, attrs, header->return_type_attributes);
} }
// function_header // function_header
@ -1320,28 +1320,28 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
} }
const ast::Type* return_type = nullptr; const ast::Type* return_type = nullptr;
ast::DecorationList return_decorations; ast::AttributeList return_attributes;
if (match(Token::Type::kArrow)) { if (match(Token::Type::kArrow)) {
auto decos = decoration_list(); auto attrs = attribute_list();
if (decos.errored) { if (attrs.errored) {
return Failure::kErrored; return Failure::kErrored;
} }
return_decorations = decos.value; return_attributes = attrs.value;
// Apply stride decorations to the type node instead of the function. // Apply stride attributes to the type node instead of the function.
ast::DecorationList type_decorations; ast::AttributeList type_attributes;
auto itr = std::find_if( auto itr =
return_decorations.begin(), return_decorations.end(), std::find_if(return_attributes.begin(), return_attributes.end(),
[](auto* deco) { return Is<ast::StrideDecoration>(deco); }); [](auto* attr) { return Is<ast::StrideAttribute>(attr); });
if (itr != return_decorations.end()) { if (itr != return_attributes.end()) {
type_decorations.emplace_back(*itr); type_attributes.emplace_back(*itr);
return_decorations.erase(itr); return_attributes.erase(itr);
} }
auto tok = peek(); auto tok = peek();
auto type = type_decl(type_decorations); auto type = type_decl(type_attributes);
if (type.errored) { if (type.errored) {
errored = true; errored = true;
} else if (!type.matched) { } else if (!type.matched) {
@ -1358,7 +1358,7 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
} }
return FunctionHeader{source, name.value, std::move(params.value), return FunctionHeader{source, name.value, std::move(params.value),
return_type, std::move(return_decorations)}; return_type, std::move(return_attributes)};
} }
// param_list // param_list
@ -1387,9 +1387,9 @@ Expect<ast::VariableList> ParserImpl::expect_param_list() {
} }
// param // param
// : decoration_list* variable_ident_decl // : attribute_list* variable_ident_decl
Expect<ast::Variable*> ParserImpl::expect_param() { Expect<ast::Variable*> ParserImpl::expect_param() {
auto decos = decoration_list(); auto attrs = attribute_list();
auto decl = expect_variable_ident_decl("parameter"); auto decl = expect_variable_ident_decl("parameter");
if (decl.errored) if (decl.errored)
@ -1403,7 +1403,7 @@ Expect<ast::Variable*> ParserImpl::expect_param() {
decl->type, // type decl->type, // type
true, // is_const true, // is_const
nullptr, // constructor nullptr, // constructor
std::move(decos.value)); // decorations std::move(attrs.value)); // attributes
// Formal parameters are treated like a const declaration where the // Formal parameters are treated like a const declaration where the
// initializer value is provided by the call's argument. The key point is // initializer value is provided by the call's argument. The key point is
// that it's not updatable after initially set. This is unlike C or GLSL // that it's not updatable after initially set. This is unlike C or GLSL
@ -1430,7 +1430,7 @@ Expect<ast::PipelineStage> ParserImpl::expect_pipeline_stage() {
next(); // Consume the peek next(); // Consume the peek
return {ast::PipelineStage::kCompute, t.source()}; return {ast::PipelineStage::kCompute, t.source()};
} }
return add_error(peek(), "invalid value for stage decoration"); return add_error(peek(), "invalid value for stage attribute");
} }
Expect<ast::Builtin> ParserImpl::expect_builtin() { Expect<ast::Builtin> ParserImpl::expect_builtin() {
@ -1440,7 +1440,7 @@ Expect<ast::Builtin> ParserImpl::expect_builtin() {
ast::Builtin builtin = ident_to_builtin(ident.value); ast::Builtin builtin = ident_to_builtin(ident.value);
if (builtin == ast::Builtin::kNone) if (builtin == ast::Builtin::kNone)
return add_error(ident.source, "invalid value for builtin decoration"); return add_error(ident.source, "invalid value for builtin attribute");
return {builtin, ident.source}; return {builtin, ident.source};
} }
@ -1661,7 +1661,7 @@ Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
decl->type, // type decl->type, // type
true, // is_const true, // is_const
constructor.value, // constructor constructor.value, // constructor
ast::DecorationList{}); // decorations ast::AttributeList{}); // attributes
return create<ast::VariableDeclStatement>(decl->source, var); return create<ast::VariableDeclStatement>(decl->source, var);
} }
@ -1686,12 +1686,12 @@ Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
auto* var = auto* var =
create<ast::Variable>(decl->source, // source create<ast::Variable>(decl->source, // source
builder_.Symbols().Register(decl->name), // symbol builder_.Symbols().Register(decl->name), // symbol
decl->storage_class, // storage class decl->storage_class, // storage class
decl->access, // access control decl->access, // access control
decl->type, // type decl->type, // type
false, // is_const false, // is_const
constructor, // constructor constructor, // constructor
ast::DecorationList{}); // decorations ast::AttributeList{}); // attributes
return create<ast::VariableDeclStatement>(var->source, var); return create<ast::VariableDeclStatement>(var->source, var);
} }
@ -2809,20 +2809,20 @@ Expect<const ast::Expression*> ParserImpl::expect_const_expr() {
return add_error(peek(), "unable to parse const_expr"); return add_error(peek(), "unable to parse const_expr");
} }
Maybe<ast::DecorationList> ParserImpl::decoration_list() { Maybe<ast::AttributeList> ParserImpl::attribute_list() {
bool errored = false; bool errored = false;
bool matched = false; bool matched = false;
ast::DecorationList decos; ast::AttributeList attrs;
while (continue_parsing()) { while (continue_parsing()) {
if (match(Token::Type::kAttr)) { if (match(Token::Type::kAttr)) {
if (auto deco = expect_decoration(); deco.errored) { if (auto attr = expect_attribute(); attr.errored) {
errored = true; errored = true;
} else { } else {
decos.emplace_back(deco.value); attrs.emplace_back(attr.value);
} }
} else { // [DEPRECATED] - old [[decoration]] style } else { // [DEPRECATED] - old [[attribute]] style
auto list = decoration_bracketed_list(decos); auto list = attribute_bracketed_list(attrs);
if (list.errored) { if (list.errored) {
errored = true; errored = true;
} }
@ -2840,11 +2840,11 @@ Maybe<ast::DecorationList> ParserImpl::decoration_list() {
if (!matched) if (!matched)
return Failure::kNoMatch; return Failure::kNoMatch;
return decos; return attrs;
} }
Maybe<bool> ParserImpl::decoration_bracketed_list(ast::DecorationList& decos) { Maybe<bool> ParserImpl::attribute_bracketed_list(ast::AttributeList& attrs) {
const char* use = "decoration list"; const char* use = "attribute list";
Source source; Source source;
if (!match(Token::Type::kAttrLeft, &source)) { if (!match(Token::Type::kAttrLeft, &source)) {
@ -2852,28 +2852,28 @@ Maybe<bool> ParserImpl::decoration_bracketed_list(ast::DecorationList& decos) {
} }
deprecated(source, deprecated(source,
"[[decoration]] style decorations have been replaced with " "[[attribute]] style attributes have been replaced with "
"@decoration style"); "@attribute style");
if (match(Token::Type::kAttrRight, &source)) if (match(Token::Type::kAttrRight, &source))
return add_error(source, "empty decoration list"); return add_error(source, "empty attribute list");
return sync(Token::Type::kAttrRight, [&]() -> Expect<bool> { return sync(Token::Type::kAttrRight, [&]() -> Expect<bool> {
bool errored = false; bool errored = false;
while (continue_parsing()) { while (continue_parsing()) {
auto deco = expect_decoration(); auto attr = expect_attribute();
if (deco.errored) { if (attr.errored) {
errored = true; errored = true;
} }
decos.emplace_back(deco.value); attrs.emplace_back(attr.value);
if (match(Token::Type::kComma)) { if (match(Token::Type::kComma)) {
continue; continue;
} }
if (is_decoration(peek())) { if (is_attribute(peek())) {
// We have two decorations in a bracket without a separating comma. // We have two attributes in a bracket without a separating comma.
// e.g. @location(1) group(2) // e.g. @location(1) group(2)
// ^^^ expected comma // ^^^ expected comma
expect(use, Token::Type::kComma); expect(use, Token::Type::kComma);
@ -2895,59 +2895,59 @@ Maybe<bool> ParserImpl::decoration_bracketed_list(ast::DecorationList& decos) {
}); });
} }
Expect<const ast::Decoration*> ParserImpl::expect_decoration() { Expect<const ast::Attribute*> ParserImpl::expect_attribute() {
auto t = peek(); auto t = peek();
auto deco = decoration(); auto attr = attribute();
if (deco.errored) if (attr.errored)
return Failure::kErrored; return Failure::kErrored;
if (deco.matched) if (attr.matched)
return deco.value; return attr.value;
return add_error(t, "expected decoration"); return add_error(t, "expected attribute");
} }
Maybe<const ast::Decoration*> ParserImpl::decoration() { Maybe<const ast::Attribute*> ParserImpl::attribute() {
using Result = Maybe<const ast::Decoration*>; using Result = Maybe<const ast::Attribute*>;
auto t = next(); auto t = next();
if (!t.IsIdentifier()) { if (!t.IsIdentifier()) {
return Failure::kNoMatch; return Failure::kNoMatch;
} }
if (t == kLocationDecoration) { if (t == kLocationAttribute) {
const char* use = "location decoration"; const char* use = "location attribute";
return expect_paren_block(use, [&]() -> Result { return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use); auto val = expect_positive_sint(use);
if (val.errored) if (val.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ast::LocationDecoration>(t.source(), val.value); return create<ast::LocationAttribute>(t.source(), val.value);
}); });
} }
if (t == kBindingDecoration) { if (t == kBindingAttribute) {
const char* use = "binding decoration"; const char* use = "binding attribute";
return expect_paren_block(use, [&]() -> Result { return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use); auto val = expect_positive_sint(use);
if (val.errored) if (val.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ast::BindingDecoration>(t.source(), val.value); return create<ast::BindingAttribute>(t.source(), val.value);
}); });
} }
if (t == kGroupDecoration) { if (t == kGroupAttribute) {
const char* use = "group decoration"; const char* use = "group attribute";
return expect_paren_block(use, [&]() -> Result { return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use); auto val = expect_positive_sint(use);
if (val.errored) if (val.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ast::GroupDecoration>(t.source(), val.value); return create<ast::GroupAttribute>(t.source(), val.value);
}); });
} }
if (t == kInterpolateDecoration) { if (t == kInterpolateAttribute) {
return expect_paren_block("interpolate decoration", [&]() -> Result { return expect_paren_block("interpolate attribute", [&]() -> Result {
ast::InterpolationType type; ast::InterpolationType type;
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone; ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
@ -2975,26 +2975,26 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
} }
} }
return create<ast::InterpolateDecoration>(t.source(), type, sampling); return create<ast::InterpolateAttribute>(t.source(), type, sampling);
}); });
} }
if (t == kInvariantDecoration) { if (t == kInvariantAttribute) {
return create<ast::InvariantDecoration>(t.source()); return create<ast::InvariantAttribute>(t.source());
} }
if (t == kBuiltinDecoration) { if (t == kBuiltinAttribute) {
return expect_paren_block("builtin decoration", [&]() -> Result { return expect_paren_block("builtin attribute", [&]() -> Result {
auto builtin = expect_builtin(); auto builtin = expect_builtin();
if (builtin.errored) if (builtin.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ast::BuiltinDecoration>(t.source(), builtin.value); return create<ast::BuiltinAttribute>(t.source(), builtin.value);
}); });
} }
if (t == kWorkgroupSizeDecoration) { if (t == kWorkgroupSizeAttribute) {
return expect_paren_block("workgroup_size decoration", [&]() -> Result { return expect_paren_block("workgroup_size attribute", [&]() -> Result {
const ast::Expression* x = nullptr; const ast::Expression* x = nullptr;
const ast::Expression* y = nullptr; const ast::Expression* y = nullptr;
const ast::Expression* z = nullptr; const ast::Expression* z = nullptr;
@ -3027,27 +3027,27 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
} }
} }
return create<ast::WorkgroupDecoration>(t.source(), x, y, z); return create<ast::WorkgroupAttribute>(t.source(), x, y, z);
}); });
} }
if (t == kStageDecoration) { if (t == kStageAttribute) {
return expect_paren_block("stage decoration", [&]() -> Result { return expect_paren_block("stage attribute", [&]() -> Result {
auto stage = expect_pipeline_stage(); auto stage = expect_pipeline_stage();
if (stage.errored) if (stage.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ast::StageDecoration>(t.source(), stage.value); return create<ast::StageAttribute>(t.source(), stage.value);
}); });
} }
if (t == kBlockDecoration) { if (t == kBlockAttribute) {
deprecated(t.source(), "[[block]] attributes have been removed from WGSL"); deprecated(t.source(), "[[block]] attributes have been removed from WGSL");
return create<ast::StructBlockDecoration>(t.source()); return create<ast::StructBlockAttribute>(t.source());
} }
if (t == kStrideDecoration) { if (t == kStrideAttribute) {
const char* use = "stride decoration"; const char* use = "stride attribute";
return expect_paren_block(use, [&]() -> Result { return expect_paren_block(use, [&]() -> Result {
auto val = expect_nonzero_positive_sint(use); auto val = expect_nonzero_positive_sint(use);
if (val.errored) if (val.errored)
@ -3055,34 +3055,34 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
deprecated(t.source(), deprecated(t.source(),
"the @stride attribute is deprecated; use a larger type if " "the @stride attribute is deprecated; use a larger type if "
"necessary"); "necessary");
return create<ast::StrideDecoration>(t.source(), val.value); return create<ast::StrideAttribute>(t.source(), val.value);
}); });
} }
if (t == kSizeDecoration) { if (t == kSizeAttribute) {
const char* use = "size decoration"; const char* use = "size attribute";
return expect_paren_block(use, [&]() -> Result { return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use); auto val = expect_positive_sint(use);
if (val.errored) if (val.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ast::StructMemberSizeDecoration>(t.source(), val.value); return create<ast::StructMemberSizeAttribute>(t.source(), val.value);
}); });
} }
if (t == kAlignDecoration) { if (t == kAlignAttribute) {
const char* use = "align decoration"; const char* use = "align attribute";
return expect_paren_block(use, [&]() -> Result { return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use); auto val = expect_positive_sint(use);
if (val.errored) if (val.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ast::StructMemberAlignDecoration>(t.source(), val.value); return create<ast::StructMemberAlignAttribute>(t.source(), val.value);
}); });
} }
if (t == kOverrideDecoration) { if (t == kOverrideAttribute) {
const char* use = "override decoration"; const char* use = "override attribute";
if (peek_is(Token::Type::kParenLeft)) { if (peek_is(Token::Type::kParenLeft)) {
// @override(x) // @override(x)
@ -3091,22 +3091,22 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
if (val.errored) if (val.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ast::OverrideDecoration>(t.source(), val.value); return create<ast::OverrideAttribute>(t.source(), val.value);
}); });
} else { } else {
// [[override]] // [[override]]
return create<ast::OverrideDecoration>(t.source()); return create<ast::OverrideAttribute>(t.source());
} }
} }
return Failure::kNoMatch; return Failure::kNoMatch;
} }
bool ParserImpl::expect_decorations_consumed(ast::DecorationList& in) { bool ParserImpl::expect_attributes_consumed(ast::AttributeList& in) {
if (in.empty()) { if (in.empty()) {
return true; return true;
} }
add_error(in[0]->source, "unexpected decorations"); add_error(in[0]->source, "unexpected attributes");
return false; return false;
} }

View File

@ -239,12 +239,12 @@ class ParserImpl {
/// @param n function name /// @param n function name
/// @param p function parameters /// @param p function parameters
/// @param ret_ty function return type /// @param ret_ty function return type
/// @param ret_decos return type decorations /// @param ret_attrs return type attributes
FunctionHeader(Source src, FunctionHeader(Source src,
std::string n, std::string n,
ast::VariableList p, ast::VariableList p,
const ast::Type* ret_ty, const ast::Type* ret_ty,
ast::DecorationList ret_decos); ast::AttributeList ret_attrs);
/// Destructor /// Destructor
~FunctionHeader(); ~FunctionHeader();
/// Assignment operator /// Assignment operator
@ -260,8 +260,8 @@ class ParserImpl {
ast::VariableList params; ast::VariableList params;
/// Function return type /// Function return type
const ast::Type* return_type = nullptr; const ast::Type* return_type = nullptr;
/// Function return type decorations /// Function return type attributes
ast::DecorationList return_type_decorations; ast::AttributeList return_type_attributes;
}; };
/// VarDeclInfo contains the parsed information for variable declaration. /// VarDeclInfo contains the parsed information for variable declaration.
@ -387,15 +387,15 @@ class ParserImpl {
/// @return true on parse success, otherwise an error. /// @return true on parse success, otherwise an error.
Expect<bool> expect_global_decl(); Expect<bool> expect_global_decl();
/// Parses a `global_variable_decl` grammar element with the initial /// Parses a `global_variable_decl` grammar element with the initial
/// `variable_decoration_list*` provided as `decos` /// `variable_attribute_list*` provided as `attrs`
/// @returns the variable parsed or nullptr /// @returns the variable parsed or nullptr
/// @param decos the list of decorations for the variable declaration. /// @param attrs the list of attributes for the variable declaration.
Maybe<const ast::Variable*> global_variable_decl(ast::DecorationList& decos); Maybe<const ast::Variable*> global_variable_decl(ast::AttributeList& attrs);
/// Parses a `global_constant_decl` grammar element with the initial /// Parses a `global_constant_decl` grammar element with the initial
/// `variable_decoration_list*` provided as `decos` /// `variable_attribute_list*` provided as `attrs`
/// @returns the const object or nullptr /// @returns the const object or nullptr
/// @param decos the list of decorations for the constant declaration. /// @param attrs the list of attributes for the constant declaration.
Maybe<const ast::Variable*> global_constant_decl(ast::DecorationList& decos); Maybe<const ast::Variable*> global_constant_decl(ast::AttributeList& attrs);
/// Parses a `variable_decl` grammar element /// Parses a `variable_decl` grammar element
/// @param allow_inferred if true, do not fail if variable decl does not /// @param allow_inferred if true, do not fail if variable decl does not
/// specify type /// specify type
@ -420,33 +420,33 @@ class ParserImpl {
/// @returns the parsed Type or nullptr if none matched. /// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> type_decl(); Maybe<const ast::Type*> type_decl();
/// Parses a `type_decl` grammar element with the given pre-parsed /// Parses a `type_decl` grammar element with the given pre-parsed
/// decorations. /// attributes.
/// @param decos the list of decorations for the type. /// @param attrs the list of attributes for the type.
/// @returns the parsed Type or nullptr if none matched. /// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> type_decl(ast::DecorationList& decos); Maybe<const ast::Type*> type_decl(ast::AttributeList& attrs);
/// Parses a `storage_class` grammar element, erroring on parse failure. /// Parses a `storage_class` grammar element, erroring on parse failure.
/// @param use a description of what was being parsed if an error was raised. /// @param use a description of what was being parsed if an error was raised.
/// @returns the storage class or StorageClass::kNone if none matched /// @returns the storage class or StorageClass::kNone if none matched
Expect<ast::StorageClass> expect_storage_class(std::string_view use); Expect<ast::StorageClass> expect_storage_class(std::string_view use);
/// Parses a `struct_decl` grammar element with the initial /// Parses a `struct_decl` grammar element with the initial
/// `struct_decoration_decl*` provided as `decos`. /// `struct_attribute_decl*` provided as `attrs`.
/// @returns the struct type or nullptr on error /// @returns the struct type or nullptr on error
/// @param decos the list of decorations for the struct declaration. /// @param attrs the list of attributes for the struct declaration.
Maybe<const ast::Struct*> struct_decl(ast::DecorationList& decos); Maybe<const ast::Struct*> struct_decl(ast::AttributeList& attrs);
/// Parses a `struct_body_decl` grammar element, erroring on parse failure. /// Parses a `struct_body_decl` grammar element, erroring on parse failure.
/// @returns the struct members /// @returns the struct members
Expect<ast::StructMemberList> expect_struct_body_decl(); Expect<ast::StructMemberList> expect_struct_body_decl();
/// Parses a `struct_member` grammar element with the initial /// Parses a `struct_member` grammar element with the initial
/// `struct_member_decoration_decl+` provided as `decos`, erroring on parse /// `struct_member_attribute_decl+` provided as `attrs`, erroring on parse
/// failure. /// failure.
/// @param decos the list of decorations for the struct member. /// @param attrs the list of attributes for the struct member.
/// @returns the struct member or nullptr /// @returns the struct member or nullptr
Expect<ast::StructMember*> expect_struct_member(ast::DecorationList& decos); Expect<ast::StructMember*> expect_struct_member(ast::AttributeList& attrs);
/// Parses a `function_decl` grammar element with the initial /// Parses a `function_decl` grammar element with the initial
/// `function_decoration_decl*` provided as `decos`. /// `function_attribute_decl*` provided as `attrs`.
/// @param decos the list of decorations for the function declaration. /// @param attrs the list of attributes for the function declaration.
/// @returns the parsed function, nullptr otherwise /// @returns the parsed function, nullptr otherwise
Maybe<const ast::Function*> function_decl(ast::DecorationList& decos); Maybe<const ast::Function*> function_decl(ast::AttributeList& attrs);
/// Parses a `texture_sampler_types` grammar element /// Parses a `texture_sampler_types` grammar element
/// @returns the parsed Type or nullptr if none matched. /// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> texture_sampler_types(); Maybe<const ast::Type*> texture_sampler_types();
@ -670,28 +670,28 @@ class ParserImpl {
/// Parses a `assignment_stmt` grammar element /// Parses a `assignment_stmt` grammar element
/// @returns the parsed assignment or nullptr /// @returns the parsed assignment or nullptr
Maybe<const ast::AssignmentStatement*> assignment_stmt(); Maybe<const ast::AssignmentStatement*> assignment_stmt();
/// Parses one or more decoration lists. /// Parses one or more attribute lists.
/// @return the parsed decoration list, or an empty list on error. /// @return the parsed attribute list, or an empty list on error.
Maybe<ast::DecorationList> decoration_list(); Maybe<ast::AttributeList> attribute_list();
/// Parses a list of decorations between `ATTR_LEFT` and `ATTR_RIGHT` /// Parses a list of attributes between `ATTR_LEFT` and `ATTR_RIGHT`
/// brackets. /// brackets.
/// @param decos the list to append newly parsed decorations to. /// @param attrs the list to append newly parsed attributes to.
/// @return true if any decorations were be parsed, otherwise false. /// @return true if any attributes were be parsed, otherwise false.
Maybe<bool> decoration_bracketed_list(ast::DecorationList& decos); Maybe<bool> attribute_bracketed_list(ast::AttributeList& attrs);
/// Parses a single decoration of the following types: /// Parses a single attribute of the following types:
/// * `struct_decoration` /// * `struct_attribute`
/// * `struct_member_decoration` /// * `struct_member_attribute`
/// * `array_decoration` /// * `array_attribute`
/// * `variable_decoration` /// * `variable_attribute`
/// * `global_const_decoration` /// * `global_const_attribute`
/// * `function_decoration` /// * `function_attribute`
/// @return the parsed decoration, or nullptr. /// @return the parsed attribute, or nullptr.
Maybe<const ast::Decoration*> decoration(); Maybe<const ast::Attribute*> attribute();
/// Parses a single decoration, reporting an error if the next token does not /// Parses a single attribute, reporting an error if the next token does not
/// represent a decoration. /// represent a attribute.
/// @see #decoration for the full list of decorations this method parses. /// @see #attribute for the full list of attributes this method parses.
/// @return the parsed decoration, or nullptr on error. /// @return the parsed attribute, or nullptr on error.
Expect<const ast::Decoration*> expect_decoration(); Expect<const ast::Attribute*> expect_attribute();
private: private:
/// ReturnType resolves to the return type for the function or lambda F. /// ReturnType resolves to the return type for the function or lambda F.
@ -843,15 +843,15 @@ class ParserImpl {
template <typename F, typename T = ReturnType<F>> template <typename F, typename T = ReturnType<F>>
T without_error(F&& func); T without_error(F&& func);
/// Reports an error if the decoration list `list` is not empty. /// Reports an error if the attribute list `list` is not empty.
/// Used to ensure that all decorations are consumed. /// Used to ensure that all attributes are consumed.
bool expect_decorations_consumed(ast::DecorationList& list); bool expect_attributes_consumed(ast::AttributeList& list);
Expect<const ast::Type*> expect_type_decl_pointer(Token t); Expect<const ast::Type*> expect_type_decl_pointer(Token t);
Expect<const ast::Type*> expect_type_decl_atomic(Token t); Expect<const ast::Type*> expect_type_decl_atomic(Token t);
Expect<const ast::Type*> expect_type_decl_vector(Token t); Expect<const ast::Type*> expect_type_decl_vector(Token t);
Expect<const ast::Type*> expect_type_decl_array(Token t, Expect<const ast::Type*> expect_type_decl_array(Token t,
ast::DecorationList decos); ast::AttributeList attrs);
Expect<const ast::Type*> expect_type_decl_matrix(Token t); Expect<const ast::Type*> expect_type_decl_matrix(Token t);
Expect<const ast::Type*> expect_type(std::string_view use); Expect<const ast::Type*> expect_type(std::string_view use);

View File

@ -53,23 +53,23 @@ fn f() { return 1 & >; }
)"); )");
} }
TEST_F(ParserImplErrorTest, AliasDeclInvalidDeco) { TEST_F(ParserImplErrorTest, AliasDeclInvalidAttribute) {
EXPECT("@override type e=u32;", EXPECT("@override type e=u32;",
R"(test.wgsl:1:2 error: unexpected decorations R"(test.wgsl:1:2 error: unexpected attributes
@override type e=u32; @override type e=u32;
^^^^^^^^ ^^^^^^^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_AliasDeclInvalidDeco) { TEST_F(ParserImplErrorTest, DEPRECATED_AliasDeclInvalidAttribute) {
EXPECT( EXPECT(
"[[override]]type e=u32;", "[[override]]type e=u32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[override]]type e=u32; [[override]]type e=u32;
^^ ^^
test.wgsl:1:3 error: unexpected decorations test.wgsl:1:3 error: unexpected attributes
[[override]]type e=u32; [[override]]type e=u32;
^^^^^^^^ ^^^^^^^^
)"); )");
@ -322,61 +322,61 @@ fn f() { for (var i : i32 = 0; i < 8; i=i+1) {
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageMissingLParen) { TEST_F(ParserImplErrorTest, FunctionDeclStageMissingLParen) {
EXPECT("@stage vertex) fn f() {}", EXPECT("@stage vertex) fn f() {}",
R"(test.wgsl:1:8 error: expected '(' for stage decoration R"(test.wgsl:1:8 error: expected '(' for stage attribute
@stage vertex) fn f() {} @stage vertex) fn f() {}
^^^^^^ ^^^^^^
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageMissingRParen) { TEST_F(ParserImplErrorTest, FunctionDeclStageMissingRParen) {
EXPECT("@stage(vertex fn f() {}", EXPECT("@stage(vertex fn f() {}",
R"(test.wgsl:1:15 error: expected ')' for stage decoration R"(test.wgsl:1:15 error: expected ')' for stage attribute
@stage(vertex fn f() {} @stage(vertex fn f() {}
^^ ^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclDecoStageMissingLParen) { TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStageMissingLParen) {
EXPECT( EXPECT(
"[[stage vertex]] fn f() {}", "[[stage vertex]] fn f() {}",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[stage vertex]] fn f() {} [[stage vertex]] fn f() {}
^^ ^^
test.wgsl:1:9 error: expected '(' for stage decoration test.wgsl:1:9 error: expected '(' for stage attribute
[[stage vertex]] fn f() {} [[stage vertex]] fn f() {}
^^^^^^ ^^^^^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclDecoStageMissingRParen) { TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStageMissingRParen) {
EXPECT( EXPECT(
"[[stage(vertex]] fn f() {}", "[[stage(vertex]] fn f() {}",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[stage(vertex]] fn f() {} [[stage(vertex]] fn f() {}
^^ ^^
test.wgsl:1:15 error: expected ')' for stage decoration test.wgsl:1:15 error: expected ')' for stage attribute
[[stage(vertex]] fn f() {} [[stage(vertex]] fn f() {}
^^ ^^
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageInvalid) { TEST_F(ParserImplErrorTest, FunctionDeclStageInvalid) {
EXPECT("@stage(x) fn f() {}", EXPECT("@stage(x) fn f() {}",
R"(test.wgsl:1:8 error: invalid value for stage decoration R"(test.wgsl:1:8 error: invalid value for stage attribute
@stage(x) fn f() {} @stage(x) fn f() {}
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageTypeInvalid) { TEST_F(ParserImplErrorTest, FunctionDeclStageTypeInvalid) {
EXPECT("@shader(vertex) fn main() {}", EXPECT("@shader(vertex) fn main() {}",
R"(test.wgsl:1:2 error: expected decoration R"(test.wgsl:1:2 error: expected attribute
@shader(vertex) fn main() {} @shader(vertex) fn main() {}
^^^^^^ ^^^^^^
@ -387,36 +387,34 @@ test.wgsl:1:8 error: unexpected token
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclWorkgroupSizeMissingLParen) {
DEPRECATED_FunctionDeclDecoWorkgroupSizeMissingLParen) {
EXPECT( EXPECT(
"[[workgroup_size 1]] fn f() {}", "[[workgroup_size 1]] fn f() {}",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[workgroup_size 1]] fn f() {} [[workgroup_size 1]] fn f() {}
^^ ^^
test.wgsl:1:18 error: expected '(' for workgroup_size decoration test.wgsl:1:18 error: expected '(' for workgroup_size attribute
[[workgroup_size 1]] fn f() {} [[workgroup_size 1]] fn f() {}
^ ^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclWorkgroupSizeMissingRParen) {
DEPRECATED_FunctionDeclDecoWorkgroupSizeMissingRParen) {
EXPECT( EXPECT(
"[[workgroup_size(1]] fn f() {}", "[[workgroup_size(1]] fn f() {}",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[workgroup_size(1]] fn f() {} [[workgroup_size(1]] fn f() {}
^^ ^^
test.wgsl:1:19 error: expected ')' for workgroup_size decoration test.wgsl:1:19 error: expected ')' for workgroup_size attribute
[[workgroup_size(1]] fn f() {} [[workgroup_size(1]] fn f() {}
^^ ^^
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeXInvalid) { TEST_F(ParserImplErrorTest, FunctionDeclWorkgroupSizeXInvalid) {
EXPECT("@workgroup_size() fn f() {}", EXPECT("@workgroup_size() fn f() {}",
R"(test.wgsl:1:17 error: expected workgroup_size x parameter R"(test.wgsl:1:17 error: expected workgroup_size x parameter
@workgroup_size() fn f() {} @workgroup_size() fn f() {}
@ -424,7 +422,7 @@ TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeXInvalid) {
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeYInvalid) { TEST_F(ParserImplErrorTest, FunctionDeclWorkgroupSizeYInvalid) {
EXPECT("@workgroup_size(1, ) fn f() {}", EXPECT("@workgroup_size(1, ) fn f() {}",
R"(test.wgsl:1:20 error: expected workgroup_size y parameter R"(test.wgsl:1:20 error: expected workgroup_size y parameter
@workgroup_size(1, ) fn f() {} @workgroup_size(1, ) fn f() {}
@ -432,7 +430,7 @@ TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeYInvalid) {
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeZInvalid) { TEST_F(ParserImplErrorTest, FunctionDeclWorkgroupSizeZInvalid) {
EXPECT("@workgroup_size(1, 2, ) fn f() {}", EXPECT("@workgroup_size(1, 2, ) fn f() {}",
R"(test.wgsl:1:23 error: expected workgroup_size z parameter R"(test.wgsl:1:23 error: expected workgroup_size z parameter
@workgroup_size(1, 2, ) fn f() {} @workgroup_size(1, 2, ) fn f() {}
@ -517,7 +515,7 @@ fn f() {
TEST_F(ParserImplErrorTest, FunctionScopeUnusedDecl) { TEST_F(ParserImplErrorTest, FunctionScopeUnusedDecl) {
EXPECT("fn f(a:i32)->i32{return a;@size(1)}", EXPECT("fn f(a:i32)->i32{return a;@size(1)}",
R"(test.wgsl:1:28 error: unexpected decorations R"(test.wgsl:1:28 error: unexpected attributes
fn f(a:i32)->i32{return a;@size(1)} fn f(a:i32)->i32{return a;@size(1)}
^^^^ ^^^^
)"); )");
@ -639,9 +637,9 @@ let i : vec2<i32> = vec2<i32>(1, 2;
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclInvalidDeco) { TEST_F(ParserImplErrorTest, GlobalDeclInvalidAttribute) {
EXPECT("@stage(vertex) x;", EXPECT("@stage(vertex) x;",
R"(test.wgsl:1:16 error: expected declaration after decorations R"(test.wgsl:1:16 error: expected declaration after attributes
@stage(vertex) x; @stage(vertex) x;
^ ^
)"); )");
@ -728,10 +726,10 @@ var x : texture_storage_2d<1>;
} }
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed. // TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructDecoMissingStruct) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructAttrMissingStruct) {
EXPECT( EXPECT(
"[[block]];", "[[block]];",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[block]]; [[block]];
^^ ^^
@ -739,17 +737,17 @@ test.wgsl:1:3 warning: use of deprecated language feature: [[block]] attributes
[[block]]; [[block]];
^^^^^ ^^^^^
test.wgsl:1:10 error: expected declaration after decorations test.wgsl:1:10 error: expected declaration after attributes
[[block]]; [[block]];
^ ^
)"); )");
} }
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed. // TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructDecoMissingEnd) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructAttrMissingEnd) {
EXPECT( EXPECT(
"[[block struct {};", "[[block struct {};",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[block struct {}; [[block struct {};
^^ ^^
@ -757,7 +755,7 @@ test.wgsl:1:3 warning: use of deprecated language feature: [[block]] attributes
[[block struct {}; [[block struct {};
^^^^^ ^^^^^
test.wgsl:1:9 error: expected ']]' for decoration list test.wgsl:1:9 error: expected ']]' for attribute list
[[block struct {}; [[block struct {};
^^^^^^ ^^^^^^
)"); )");
@ -788,28 +786,28 @@ struct S { i : i32;
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberDecoEmpty) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberAttrEmpty) {
EXPECT( EXPECT(
"struct S { [[]] i : i32; };", "struct S { [[]] i : i32; };",
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
struct S { [[]] i : i32; }; struct S { [[]] i : i32; };
^^ ^^
test.wgsl:1:14 error: empty decoration list test.wgsl:1:14 error: empty attribute list
struct S { [[]] i : i32; }; struct S { [[]] i : i32; };
^^ ^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberDecoMissingEnd) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberAttrMissingEnd) {
EXPECT( EXPECT(
"struct S { [[ i : i32; };", "struct S { [[ i : i32; };",
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
struct S { [[ i : i32; }; struct S { [[ i : i32; };
^^ ^^
test.wgsl:1:15 error: expected decoration test.wgsl:1:15 error: expected attribute
struct S { [[ i : i32; }; struct S { [[ i : i32; };
^ ^
)"); )");
@ -836,11 +834,11 @@ TEST_F(ParserImplErrorTest,
DEPRECATED_GlobalDeclStructMemberAlignMissingLParen) { DEPRECATED_GlobalDeclStructMemberAlignMissingLParen) {
EXPECT( EXPECT(
"struct S { [[align 1)]] i : i32; };", "struct S { [[align 1)]] i : i32; };",
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
struct S { [[align 1)]] i : i32; }; struct S { [[align 1)]] i : i32; };
^^ ^^
test.wgsl:1:20 error: expected '(' for align decoration test.wgsl:1:20 error: expected '(' for align attribute
struct S { [[align 1)]] i : i32; }; struct S { [[align 1)]] i : i32; };
^ ^
)"); )");
@ -851,11 +849,11 @@ TEST_F(ParserImplErrorTest,
DEPRECATED_GlobalDeclStructMemberAlignMissingRParen) { DEPRECATED_GlobalDeclStructMemberAlignMissingRParen) {
EXPECT( EXPECT(
"struct S { [[align(1]] i : i32; };", "struct S { [[align(1]] i : i32; };",
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
struct S { [[align(1]] i : i32; }; struct S { [[align(1]] i : i32; };
^^ ^^
test.wgsl:1:21 error: expected ')' for align decoration test.wgsl:1:21 error: expected ')' for align attribute
struct S { [[align(1]] i : i32; }; struct S { [[align(1]] i : i32; };
^^ ^^
)"); )");
@ -864,7 +862,7 @@ struct S { [[align(1]] i : i32; };
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignInvaldValue) { TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignInvaldValue) {
EXPECT( EXPECT(
"struct S { @align(x) i : i32; };", "struct S { @align(x) i : i32; };",
R"(test.wgsl:1:19 error: expected signed integer literal for align decoration R"(test.wgsl:1:19 error: expected signed integer literal for align attribute
struct S { @align(x) i : i32; }; struct S { @align(x) i : i32; };
^ ^
)"); )");
@ -872,7 +870,7 @@ struct S { @align(x) i : i32; };
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignNegativeValue) { TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignNegativeValue) {
EXPECT("struct S { @align(-2) i : i32; };", EXPECT("struct S { @align(-2) i : i32; };",
R"(test.wgsl:1:19 error: align decoration must be positive R"(test.wgsl:1:19 error: align attribute must be positive
struct S { @align(-2) i : i32; }; struct S { @align(-2) i : i32; };
^^ ^^
)"); )");
@ -883,11 +881,11 @@ TEST_F(ParserImplErrorTest,
DEPRECATED_GlobalDeclStructMemberSizeMissingLParen) { DEPRECATED_GlobalDeclStructMemberSizeMissingLParen) {
EXPECT( EXPECT(
"struct S { [[size 1)]] i : i32; };", "struct S { [[size 1)]] i : i32; };",
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
struct S { [[size 1)]] i : i32; }; struct S { [[size 1)]] i : i32; };
^^ ^^
test.wgsl:1:19 error: expected '(' for size decoration test.wgsl:1:19 error: expected '(' for size attribute
struct S { [[size 1)]] i : i32; }; struct S { [[size 1)]] i : i32; };
^ ^
)"); )");
@ -898,11 +896,11 @@ TEST_F(ParserImplErrorTest,
DEPRECATED_GlobalDeclStructMemberSizeMissingRParen) { DEPRECATED_GlobalDeclStructMemberSizeMissingRParen) {
EXPECT( EXPECT(
"struct S { [[size(1]] i : i32; };", "struct S { [[size(1]] i : i32; };",
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
struct S { [[size(1]] i : i32; }; struct S { [[size(1]] i : i32; };
^^ ^^
test.wgsl:1:20 error: expected ')' for size decoration test.wgsl:1:20 error: expected ')' for size attribute
struct S { [[size(1]] i : i32; }; struct S { [[size(1]] i : i32; };
^^ ^^
)"); )");
@ -911,7 +909,7 @@ struct S { [[size(1]] i : i32; };
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeInvaldValue) { TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeInvaldValue) {
EXPECT( EXPECT(
"struct S { @size(x) i : i32; };", "struct S { @size(x) i : i32; };",
R"(test.wgsl:1:18 error: expected signed integer literal for size decoration R"(test.wgsl:1:18 error: expected signed integer literal for size attribute
struct S { @size(x) i : i32; }; struct S { @size(x) i : i32; };
^ ^
)"); )");
@ -919,7 +917,7 @@ struct S { @size(x) i : i32; };
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeNegativeValue) { TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeNegativeValue) {
EXPECT("struct S { @size(-2) i : i32; };", EXPECT("struct S { @size(-2) i : i32; };",
R"(test.wgsl:1:18 error: size decoration must be positive R"(test.wgsl:1:18 error: size attribute must be positive
struct S { @size(-2) i : i32; }; struct S { @size(-2) i : i32; };
^^ ^^
)"); )");
@ -955,14 +953,14 @@ type meow = f32
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclTypeDecoInvalid) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclTypeAttrInvalid) {
EXPECT( EXPECT(
"var x : [[]] i32;", "var x : [[]] i32;",
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:9 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
var x : [[]] i32; var x : [[]] i32;
^^ ^^
test.wgsl:1:11 error: empty decoration list test.wgsl:1:11 error: empty attribute list
var x : [[]] i32; var x : [[]] i32;
^^ ^^
)"); )");
@ -984,70 +982,68 @@ var i : array<u32, 3;
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoNotArray) { TEST_F(ParserImplErrorTest, GlobalDeclVarArrayAttrNotArray) {
EXPECT("var i : @location(1) i32;", EXPECT("var i : @location(1) i32;",
R"(test.wgsl:1:10 error: unexpected decorations R"(test.wgsl:1:10 error: unexpected attributes
var i : @location(1) i32; var i : @location(1) i32;
^^^^^^^^ ^^^^^^^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayDecoMissingEnd) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayAttrMissingEnd) {
EXPECT( EXPECT(
"var i : [[location(1) array<i32>;", "var i : [[location(1) array<i32>;",
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:9 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
var i : [[location(1) array<i32>; var i : [[location(1) array<i32>;
^^ ^^
test.wgsl:1:23 error: expected ']]' for decoration list test.wgsl:1:23 error: expected ']]' for attribute list
var i : [[location(1) array<i32>; var i : [[location(1) array<i32>;
^^^^^ ^^^^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayStrideMissingLParen) {
DEPRECATED_GlobalDeclVarArrayDecoStrideMissingLParen) {
EXPECT( EXPECT(
"var i : [[stride 1)]] array<i32>;", "var i : [[stride 1)]] array<i32>;",
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:9 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
var i : [[stride 1)]] array<i32>; var i : [[stride 1)]] array<i32>;
^^ ^^
test.wgsl:1:18 error: expected '(' for stride decoration test.wgsl:1:18 error: expected '(' for stride attribute
var i : [[stride 1)]] array<i32>; var i : [[stride 1)]] array<i32>;
^ ^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayStrideMissingRParen) {
DEPRECATED_GlobalDeclVarArrayDecoStrideMissingRParen) {
EXPECT( EXPECT(
"var i : [[location(1]] array<i32>;", "var i : [[location(1]] array<i32>;",
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:9 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
var i : [[location(1]] array<i32>; var i : [[location(1]] array<i32>;
^^ ^^
test.wgsl:1:21 error: expected ')' for location decoration test.wgsl:1:21 error: expected ')' for location attribute
var i : [[location(1]] array<i32>; var i : [[location(1]] array<i32>;
^^ ^^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoStrideInvalid) { TEST_F(ParserImplErrorTest, GlobalDeclVarArrayStrideInvalid) {
EXPECT( EXPECT(
"var i : @stride(x) array<i32>;", "var i : @stride(x) array<i32>;",
R"(test.wgsl:1:17 error: expected signed integer literal for stride decoration R"(test.wgsl:1:17 error: expected signed integer literal for stride attribute
var i : @stride(x) array<i32>; var i : @stride(x) array<i32>;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoStrideNegative) { TEST_F(ParserImplErrorTest, GlobalDeclVarArrayStrideNegative) {
EXPECT("var i : @stride(-1) array<i32>;", EXPECT("var i : @stride(-1) array<i32>;",
R"(test.wgsl:1:17 error: stride decoration must be greater than 0 R"(test.wgsl:1:17 error: stride attribute must be greater than 0
var i : @stride(-1) array<i32>; var i : @stride(-1) array<i32>;
^^ ^^
)"); )");
@ -1078,36 +1074,36 @@ var i : array<u32, !>;
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoListEmpty) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrListEmpty) {
EXPECT( EXPECT(
"[[]] var i : i32;", "[[]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[]] var i : i32; [[]] var i : i32;
^^ ^^
test.wgsl:1:3 error: empty decoration list test.wgsl:1:3 error: empty attribute list
[[]] var i : i32; [[]] var i : i32;
^^ ^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoListInvalid) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrListInvalid) {
EXPECT( EXPECT(
"[[location(1), meow]] var i : i32;", "[[location(1), meow]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[location(1), meow]] var i : i32; [[location(1), meow]] var i : i32;
^^ ^^
test.wgsl:1:16 error: expected decoration test.wgsl:1:16 error: expected attribute
[[location(1), meow]] var i : i32; [[location(1), meow]] var i : i32;
^^^^ ^^^^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoListMissingComma) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrListMissingComma) {
EXPECT("@location(1) group(2) var i : i32;", EXPECT("@location(1) group(2) var i : i32;",
R"(test.wgsl:1:14 error: expected declaration after decorations R"(test.wgsl:1:14 error: expected declaration after attributes
@location(1) group(2) var i : i32; @location(1) group(2) var i : i32;
^^^^^ ^^^^^
@ -1118,117 +1114,117 @@ test.wgsl:1:19 error: unexpected token
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoListMissingEnd) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrListMissingEnd) {
EXPECT( EXPECT(
"[[location(1) meow]] var i : i32;", "[[location(1) meow]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[location(1) meow]] var i : i32; [[location(1) meow]] var i : i32;
^^ ^^
test.wgsl:1:15 error: expected ']]' for decoration list test.wgsl:1:15 error: expected ']]' for attribute list
[[location(1) meow]] var i : i32; [[location(1) meow]] var i : i32;
^^^^ ^^^^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationMissingLParen) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrLocationMissingLParen) {
EXPECT("@location 1) var i : i32;", EXPECT("@location 1) var i : i32;",
R"(test.wgsl:1:11 error: expected '(' for location decoration R"(test.wgsl:1:11 error: expected '(' for location attribute
@location 1) var i : i32; @location 1) var i : i32;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationMissingRParen) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrLocationMissingRParen) {
EXPECT("@location (1 var i : i32;", EXPECT("@location (1 var i : i32;",
R"(test.wgsl:1:14 error: expected ')' for location decoration R"(test.wgsl:1:14 error: expected ')' for location attribute
@location (1 var i : i32; @location (1 var i : i32;
^^^ ^^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoLocationMissingLParen) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrLocationMissingLParen) {
EXPECT( EXPECT(
"[[location 1]] var i : i32;", "[[location 1]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[location 1]] var i : i32; [[location 1]] var i : i32;
^^ ^^
test.wgsl:1:12 error: expected '(' for location decoration test.wgsl:1:12 error: expected '(' for location attribute
[[location 1]] var i : i32; [[location 1]] var i : i32;
^ ^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoLocationMissingRParen) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrLocationMissingRParen) {
EXPECT( EXPECT(
"[[location (1]] var i : i32;", "[[location (1]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[location (1]] var i : i32; [[location (1]] var i : i32;
^^ ^^
test.wgsl:1:14 error: expected ')' for location decoration test.wgsl:1:14 error: expected ')' for location attribute
[[location (1]] var i : i32; [[location (1]] var i : i32;
^^ ^^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationInvalidValue) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrLocationInvalidValue) {
EXPECT( EXPECT(
"@location(x) var i : i32;", "@location(x) var i : i32;",
R"(test.wgsl:1:11 error: expected signed integer literal for location decoration R"(test.wgsl:1:11 error: expected signed integer literal for location attribute
@location(x) var i : i32; @location(x) var i : i32;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinMissingLParen) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinMissingLParen) {
EXPECT("@builtin position) var i : i32;", EXPECT("@builtin position) var i : i32;",
R"(test.wgsl:1:10 error: expected '(' for builtin decoration R"(test.wgsl:1:10 error: expected '(' for builtin attribute
@builtin position) var i : i32; @builtin position) var i : i32;
^^^^^^^^ ^^^^^^^^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinMissingRParen) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinMissingRParen) {
EXPECT("@builtin(position var i : i32;", EXPECT("@builtin(position var i : i32;",
R"(test.wgsl:1:19 error: expected ')' for builtin decoration R"(test.wgsl:1:19 error: expected ')' for builtin attribute
@builtin(position var i : i32; @builtin(position var i : i32;
^^^ ^^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBuiltinMissingLParen) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBuiltinMissingLParen) {
EXPECT( EXPECT(
"[[builtin position]] var i : i32;", "[[builtin position]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[builtin position]] var i : i32; [[builtin position]] var i : i32;
^^ ^^
test.wgsl:1:11 error: expected '(' for builtin decoration test.wgsl:1:11 error: expected '(' for builtin attribute
[[builtin position]] var i : i32; [[builtin position]] var i : i32;
^^^^^^^^ ^^^^^^^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBuiltinMissingRParen) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBuiltinMissingRParen) {
EXPECT( EXPECT(
"[[builtin(position]] var i : i32;", "[[builtin(position]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[builtin(position]] var i : i32; [[builtin(position]] var i : i32;
^^ ^^
test.wgsl:1:19 error: expected ')' for builtin decoration test.wgsl:1:19 error: expected ')' for builtin attribute
[[builtin(position]] var i : i32; [[builtin(position]] var i : i32;
^^ ^^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinInvalidIdentifer) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinInvalidIdentifer) {
EXPECT("@builtin(1) var i : i32;", EXPECT("@builtin(1) var i : i32;",
R"(test.wgsl:1:10 error: expected identifier for builtin R"(test.wgsl:1:10 error: expected identifier for builtin
@builtin(1) var i : i32; @builtin(1) var i : i32;
@ -1236,115 +1232,115 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinInvalidIdentifer) {
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinInvalidValue) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinInvalidValue) {
EXPECT("@builtin(x) var i : i32;", EXPECT("@builtin(x) var i : i32;",
R"(test.wgsl:1:10 error: invalid value for builtin decoration R"(test.wgsl:1:10 error: invalid value for builtin attribute
@builtin(x) var i : i32; @builtin(x) var i : i32;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingMissingLParen) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingMissingLParen) {
EXPECT("@binding 1) var i : i32;", EXPECT("@binding 1) var i : i32;",
R"(test.wgsl:1:10 error: expected '(' for binding decoration R"(test.wgsl:1:10 error: expected '(' for binding attribute
@binding 1) var i : i32; @binding 1) var i : i32;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingMissingRParen) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingMissingRParen) {
EXPECT("@binding(1 var i : i32;", EXPECT("@binding(1 var i : i32;",
R"(test.wgsl:1:12 error: expected ')' for binding decoration R"(test.wgsl:1:12 error: expected ')' for binding attribute
@binding(1 var i : i32; @binding(1 var i : i32;
^^^ ^^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBindingMissingLParen) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBindingMissingLParen) {
EXPECT( EXPECT(
"[[binding 1]] var i : i32;", "[[binding 1]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[binding 1]] var i : i32; [[binding 1]] var i : i32;
^^ ^^
test.wgsl:1:11 error: expected '(' for binding decoration test.wgsl:1:11 error: expected '(' for binding attribute
[[binding 1]] var i : i32; [[binding 1]] var i : i32;
^ ^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBindingMissingRParen) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBindingMissingRParen) {
EXPECT( EXPECT(
"[[binding(1]] var i : i32;", "[[binding(1]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[binding(1]] var i : i32; [[binding(1]] var i : i32;
^^ ^^
test.wgsl:1:12 error: expected ')' for binding decoration test.wgsl:1:12 error: expected ')' for binding attribute
[[binding(1]] var i : i32; [[binding(1]] var i : i32;
^^ ^^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingInvalidValue) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingInvalidValue) {
EXPECT( EXPECT(
"@binding(x) var i : i32;", "@binding(x) var i : i32;",
R"(test.wgsl:1:10 error: expected signed integer literal for binding decoration R"(test.wgsl:1:10 error: expected signed integer literal for binding attribute
@binding(x) var i : i32; @binding(x) var i : i32;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoGroupMissingLParen) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrGroupMissingLParen) {
EXPECT("@group 1) var i : i32;", EXPECT("@group 1) var i : i32;",
R"(test.wgsl:1:8 error: expected '(' for group decoration R"(test.wgsl:1:8 error: expected '(' for group attribute
@group 1) var i : i32; @group 1) var i : i32;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoGroupMissingRParen) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrGroupMissingRParen) {
EXPECT("@group(1 var i : i32;", EXPECT("@group(1 var i : i32;",
R"(test.wgsl:1:10 error: expected ')' for group decoration R"(test.wgsl:1:10 error: expected ')' for group attribute
@group(1 var i : i32; @group(1 var i : i32;
^^^ ^^^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoGroupMissingLParen) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrGroupMissingLParen) {
EXPECT( EXPECT(
"[[group 1]] var i : i32;", "[[group 1]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[group 1]] var i : i32; [[group 1]] var i : i32;
^^ ^^
test.wgsl:1:9 error: expected '(' for group decoration test.wgsl:1:9 error: expected '(' for group attribute
[[group 1]] var i : i32; [[group 1]] var i : i32;
^ ^
)"); )");
} }
// TODO(crbug.com/tint/1382): Remove // TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoGroupMissingRParen) { TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrGroupMissingRParen) {
EXPECT( EXPECT(
"[[group(1]] var i : i32;", "[[group(1]] var i : i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
[[group(1]] var i : i32; [[group(1]] var i : i32;
^^ ^^
test.wgsl:1:10 error: expected ')' for group decoration test.wgsl:1:10 error: expected ')' for group attribute
[[group(1]] var i : i32; [[group(1]] var i : i32;
^^ ^^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingGroupValue) { TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingGroupValue) {
EXPECT( EXPECT(
"@group(x) var i : i32;", "@group(x) var i : i32;",
R"(test.wgsl:1:8 error: expected signed integer literal for group decoration R"(test.wgsl:1:8 error: expected signed integer literal for group attribute
@group(x) var i : i32; @group(x) var i : i32;
^ ^
)"); )");

View File

@ -55,7 +55,7 @@ test.wgsl:3:6 error: expected ')' for function declaration
fn x(.) {} fn x(.) {}
^ ^
test.wgsl:4:2 error: expected decoration test.wgsl:4:2 error: expected attribute
@_ fn -> {} @_ fn -> {}
^ ^
@ -126,7 +126,7 @@ test.wgsl:5:10 error: expected ':' for struct member
blah blah blah; blah blah blah;
^^^^ ^^^^
test.wgsl:7:6 error: expected decoration test.wgsl:7:6 error: expected attribute
@- x : i32; @- x : i32;
^ ^
)"); )");

View File

@ -0,0 +1,162 @@
// 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/ast/workgroup_attribute.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, AttributeList_Parses) {
auto p = parser("@workgroup_size(2) @stage(compute)");
auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
ASSERT_EQ(attrs.value.size(), 2u);
auto* attr_0 = attrs.value[0]->As<ast::Attribute>();
auto* attr_1 = attrs.value[1]->As<ast::Attribute>();
ASSERT_NE(attr_0, nullptr);
ASSERT_NE(attr_1, nullptr);
ASSERT_TRUE(attr_0->Is<ast::WorkgroupAttribute>());
const ast::Expression* x = attr_0->As<ast::WorkgroupAttribute>()->x;
ASSERT_NE(x, nullptr);
auto* x_literal = x->As<ast::LiteralExpression>();
ASSERT_NE(x_literal, nullptr);
ASSERT_TRUE(x_literal->Is<ast::IntLiteralExpression>());
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
ASSERT_TRUE(attr_1->Is<ast::StageAttribute>());
EXPECT_EQ(attr_1->As<ast::StageAttribute>()->stage,
ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, AttributeList_Invalid) {
auto p = parser("@invalid");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(p->error(), "1:2: expected attribute");
}
TEST_F(ParserImplTest, AttributeList_ExtraComma) {
auto p = parser("[[workgroup_size(2), ]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:22: expected attribute)");
}
TEST_F(ParserImplTest, AttributeList_BadAttribute) {
auto p = parser("@stage()");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(p->error(), "1:8: invalid value for stage attribute");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_Empty) {
auto p = parser("[[]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:3: empty attribute list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_Invalid) {
auto p = parser("[[invalid]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:3: expected attribute)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_ExtraComma) {
auto p = parser("[[workgroup_size(2), ]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:22: expected attribute)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_MissingComma) {
auto p = parser("[[workgroup_size(2) workgroup_size(2)]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:21: expected ',' for attribute list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_BadAttribute) {
auto p = parser("[[stage()]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:9: invalid value for stage attribute)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_MissingRightAttr) {
auto p = parser("[[workgroup_size(2), workgroup_size(3, 4, 5)");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:45: expected ']]' for attribute list)");
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

@ -0,0 +1,260 @@
// 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/ast/stage_attribute.h"
#include "src/ast/workgroup_attribute.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, Attribute_Workgroup) {
auto p = parser("workgroup_size(4)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
EXPECT_EQ(values[1], nullptr);
EXPECT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Attribute_Workgroup_2Param) {
auto p = parser("workgroup_size(4, 5)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr) << p->error();
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
EXPECT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Attribute_Workgroup_3Param) {
auto p = parser("workgroup_size(4, 5, 6)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
}
TEST_F(ParserImplTest, Attribute_Workgroup_WithIdent) {
auto p = parser("workgroup_size(4, height)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_NE(values[1], nullptr);
auto* y_ident = values[1]->As<ast::IdentifierExpression>();
ASSERT_NE(y_ident, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(y_ident->symbol), "height");
ASSERT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Attribute_Workgroup_TooManyValues) {
auto p = parser("workgroup_size(1, 2, 3, 4)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_MissingLeftParam) {
auto p = parser("workgroup_size 4, 5, 6)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected '(' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_MissingRightParam) {
auto p = parser("workgroup_size(4, 5, 6");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_MissingValues) {
auto p = parser("workgroup_size()");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_X_Value) {
auto p = parser("workgroup_size(, 2, 3)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Y_Comma) {
auto p = parser("workgroup_size(1 2, 3)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:18: expected ')' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Y_Value) {
auto p = parser("workgroup_size(1, , 3)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:19: expected workgroup_size y parameter");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Z_Comma) {
auto p = parser("workgroup_size(1, 2 3)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:21: expected ')' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Z_Value) {
auto p = parser("workgroup_size(1, 2, )");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:22: expected workgroup_size z parameter");
}
TEST_F(ParserImplTest, Attribute_Stage) {
auto p = parser("stage(compute)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::StageAttribute>());
EXPECT_EQ(func_attr->As<ast::StageAttribute>()->stage,
ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, Attribute_Stage_MissingValue) {
auto p = parser("stage()");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: invalid value for stage attribute");
}
TEST_F(ParserImplTest, Attribute_Stage_MissingInvalid) {
auto p = parser("stage(nan)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: invalid value for stage attribute");
}
TEST_F(ParserImplTest, Attribute_Stage_MissingLeftParen) {
auto p = parser("stage compute)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: expected '(' for stage attribute");
}
TEST_F(ParserImplTest, Attribute_Stage_MissingRightParen) {
auto p = parser("stage(compute");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:14: expected ')' for stage attribute");
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_attribute.h"
#include "src/reader/wgsl/parser_impl_test_helper.h" #include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint { namespace tint {
@ -22,11 +22,11 @@ namespace {
TEST_F(ParserImplTest, FunctionDecl) { TEST_F(ParserImplTest, FunctionDecl) {
auto p = parser("fn main(a : i32, b : f32) { return; }"); auto p = parser("fn main(a : i32, b : f32) { return; }");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decos.errored); ASSERT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto f = p->function_decl(decos.value); auto f = p->function_decl(attrs.value);
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(f.errored); EXPECT_FALSE(f.errored);
EXPECT_TRUE(f.matched); EXPECT_TRUE(f.matched);
@ -48,13 +48,13 @@ TEST_F(ParserImplTest, FunctionDecl) {
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>()); EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
} }
TEST_F(ParserImplTest, FunctionDecl_DecorationList) { TEST_F(ParserImplTest, FunctionDecl_AttributeList) {
auto p = parser("@workgroup_size(2, 3, 4) fn main() { return; }"); auto p = parser("@workgroup_size(2, 3, 4) fn main() { return; }");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decos.errored); ASSERT_FALSE(attrs.errored);
ASSERT_TRUE(decos.matched); ASSERT_TRUE(attrs.matched);
auto f = p->function_decl(decos.value); auto f = p->function_decl(attrs.value);
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(f.errored); EXPECT_FALSE(f.errored);
EXPECT_TRUE(f.matched); EXPECT_TRUE(f.matched);
@ -65,11 +65,11 @@ TEST_F(ParserImplTest, FunctionDecl_DecorationList) {
EXPECT_TRUE(f->return_type->Is<ast::Void>()); EXPECT_TRUE(f->return_type->Is<ast::Void>());
ASSERT_EQ(f->params.size(), 0u); ASSERT_EQ(f->params.size(), 0u);
auto& decorations = f->decorations; auto& attributes = f->attributes;
ASSERT_EQ(decorations.size(), 1u); ASSERT_EQ(attributes.size(), 1u);
ASSERT_TRUE(decorations[0]->Is<ast::WorkgroupDecoration>()); ASSERT_TRUE(attributes[0]->Is<ast::WorkgroupAttribute>());
auto values = decorations[0]->As<ast::WorkgroupDecoration>()->Values(); auto values = attributes[0]->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>()); ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u); EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
@ -85,15 +85,15 @@ TEST_F(ParserImplTest, FunctionDecl_DecorationList) {
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>()); EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
} }
TEST_F(ParserImplTest, FunctionDecl_DecorationList_MultipleEntries) { TEST_F(ParserImplTest, FunctionDecl_AttributeList_MultipleEntries) {
auto p = parser(R"( auto p = parser(R"(
@workgroup_size(2, 3, 4) @stage(compute) @workgroup_size(2, 3, 4) @stage(compute)
fn main() { return; })"); fn main() { return; })");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decos.errored); ASSERT_FALSE(attrs.errored);
ASSERT_TRUE(decos.matched); ASSERT_TRUE(attrs.matched);
auto f = p->function_decl(decos.value); auto f = p->function_decl(attrs.value);
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(f.errored); EXPECT_FALSE(f.errored);
EXPECT_TRUE(f.matched); EXPECT_TRUE(f.matched);
@ -104,11 +104,11 @@ fn main() { return; })");
EXPECT_TRUE(f->return_type->Is<ast::Void>()); EXPECT_TRUE(f->return_type->Is<ast::Void>());
ASSERT_EQ(f->params.size(), 0u); ASSERT_EQ(f->params.size(), 0u);
auto& decorations = f->decorations; auto& attributes = f->attributes;
ASSERT_EQ(decorations.size(), 2u); ASSERT_EQ(attributes.size(), 2u);
ASSERT_TRUE(decorations[0]->Is<ast::WorkgroupDecoration>()); ASSERT_TRUE(attributes[0]->Is<ast::WorkgroupAttribute>());
auto values = decorations[0]->As<ast::WorkgroupDecoration>()->Values(); auto values = attributes[0]->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>()); ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u); EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
@ -119,8 +119,8 @@ fn main() { return; })");
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>()); ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u); EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(decorations[1]->Is<ast::StageDecoration>()); ASSERT_TRUE(attributes[1]->Is<ast::StageAttribute>());
EXPECT_EQ(decorations[1]->As<ast::StageDecoration>()->stage, EXPECT_EQ(attributes[1]->As<ast::StageAttribute>()->stage,
ast::PipelineStage::kCompute); ast::PipelineStage::kCompute);
auto* body = f->body; auto* body = f->body;
@ -128,16 +128,16 @@ fn main() { return; })");
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>()); EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
} }
TEST_F(ParserImplTest, FunctionDecl_DecorationList_MultipleLists) { TEST_F(ParserImplTest, FunctionDecl_AttributeList_MultipleLists) {
auto p = parser(R"( auto p = parser(R"(
@workgroup_size(2, 3, 4) @workgroup_size(2, 3, 4)
@stage(compute) @stage(compute)
fn main() { return; })"); fn main() { return; })");
auto decorations = p->decoration_list(); auto attributes = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decorations.errored); ASSERT_FALSE(attributes.errored);
ASSERT_TRUE(decorations.matched); ASSERT_TRUE(attributes.matched);
auto f = p->function_decl(decorations.value); auto f = p->function_decl(attributes.value);
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(f.errored); EXPECT_FALSE(f.errored);
EXPECT_TRUE(f.matched); EXPECT_TRUE(f.matched);
@ -148,11 +148,11 @@ fn main() { return; })");
EXPECT_TRUE(f->return_type->Is<ast::Void>()); EXPECT_TRUE(f->return_type->Is<ast::Void>());
ASSERT_EQ(f->params.size(), 0u); ASSERT_EQ(f->params.size(), 0u);
auto& decos = f->decorations; auto& attrs = f->attributes;
ASSERT_EQ(decos.size(), 2u); ASSERT_EQ(attrs.size(), 2u);
ASSERT_TRUE(decos[0]->Is<ast::WorkgroupDecoration>()); ASSERT_TRUE(attrs[0]->Is<ast::WorkgroupAttribute>());
auto values = decos[0]->As<ast::WorkgroupDecoration>()->Values(); auto values = attrs[0]->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>()); ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u); EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
@ -163,8 +163,8 @@ fn main() { return; })");
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>()); ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u); EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(decos[1]->Is<ast::StageDecoration>()); ASSERT_TRUE(attrs[1]->Is<ast::StageAttribute>());
EXPECT_EQ(decos[1]->As<ast::StageDecoration>()->stage, EXPECT_EQ(attrs[1]->As<ast::StageAttribute>()->stage,
ast::PipelineStage::kCompute); ast::PipelineStage::kCompute);
auto* body = f->body; auto* body = f->body;
@ -172,13 +172,13 @@ fn main() { return; })");
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>()); EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
} }
TEST_F(ParserImplTest, FunctionDecl_ReturnTypeDecorationList) { TEST_F(ParserImplTest, FunctionDecl_ReturnTypeAttributeList) {
auto p = parser("fn main() -> @location(1) f32 { return 1.0; }"); auto p = parser("fn main() -> @location(1) f32 { return 1.0; }");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decos.errored); ASSERT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto f = p->function_decl(decos.value); auto f = p->function_decl(attrs.value);
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(f.errored); EXPECT_FALSE(f.errored);
EXPECT_TRUE(f.matched); EXPECT_TRUE(f.matched);
@ -189,12 +189,12 @@ TEST_F(ParserImplTest, FunctionDecl_ReturnTypeDecorationList) {
EXPECT_TRUE(f->return_type->Is<ast::F32>()); EXPECT_TRUE(f->return_type->Is<ast::F32>());
ASSERT_EQ(f->params.size(), 0u); ASSERT_EQ(f->params.size(), 0u);
auto& decorations = f->decorations; auto& attributes = f->attributes;
EXPECT_EQ(decorations.size(), 0u); EXPECT_EQ(attributes.size(), 0u);
auto& ret_type_decorations = f->return_type_decorations; auto& ret_type_attributes = f->return_type_attributes;
ASSERT_EQ(ret_type_decorations.size(), 1u); ASSERT_EQ(ret_type_attributes.size(), 1u);
auto* loc = ret_type_decorations[0]->As<ast::LocationDecoration>(); auto* loc = ret_type_attributes[0]->As<ast::LocationAttribute>();
ASSERT_TRUE(loc != nullptr); ASSERT_TRUE(loc != nullptr);
EXPECT_EQ(loc->value, 1u); EXPECT_EQ(loc->value, 1u);
@ -205,11 +205,11 @@ TEST_F(ParserImplTest, FunctionDecl_ReturnTypeDecorationList) {
TEST_F(ParserImplTest, FunctionDecl_InvalidHeader) { TEST_F(ParserImplTest, FunctionDecl_InvalidHeader) {
auto p = parser("fn main() -> { }"); auto p = parser("fn main() -> { }");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decos.errored); ASSERT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto f = p->function_decl(decos.value); auto f = p->function_decl(attrs.value);
EXPECT_TRUE(f.errored); EXPECT_TRUE(f.errored);
EXPECT_FALSE(f.matched); EXPECT_FALSE(f.matched);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
@ -219,11 +219,11 @@ TEST_F(ParserImplTest, FunctionDecl_InvalidHeader) {
TEST_F(ParserImplTest, FunctionDecl_InvalidBody) { TEST_F(ParserImplTest, FunctionDecl_InvalidBody) {
auto p = parser("fn main() { return }"); auto p = parser("fn main() { return }");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decos.errored); ASSERT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto f = p->function_decl(decos.value); auto f = p->function_decl(attrs.value);
EXPECT_TRUE(f.errored); EXPECT_TRUE(f.errored);
EXPECT_FALSE(f.matched); EXPECT_FALSE(f.matched);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
@ -233,11 +233,11 @@ TEST_F(ParserImplTest, FunctionDecl_InvalidBody) {
TEST_F(ParserImplTest, FunctionDecl_MissingLeftBrace) { TEST_F(ParserImplTest, FunctionDecl_MissingLeftBrace) {
auto p = parser("fn main() return; }"); auto p = parser("fn main() return; }");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decos.errored); ASSERT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto f = p->function_decl(decos.value); auto f = p->function_decl(attrs.value);
EXPECT_TRUE(f.errored); EXPECT_TRUE(f.errored);
EXPECT_FALSE(f.matched); EXPECT_FALSE(f.matched);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());

View File

@ -1,162 +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/ast/workgroup_decoration.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, DecorationList_Parses) {
auto p = parser("@workgroup_size(2) @stage(compute)");
auto decos = p->decoration_list();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(decos.errored);
EXPECT_TRUE(decos.matched);
ASSERT_EQ(decos.value.size(), 2u);
auto* deco_0 = decos.value[0]->As<ast::Decoration>();
auto* deco_1 = decos.value[1]->As<ast::Decoration>();
ASSERT_NE(deco_0, nullptr);
ASSERT_NE(deco_1, nullptr);
ASSERT_TRUE(deco_0->Is<ast::WorkgroupDecoration>());
const ast::Expression* x = deco_0->As<ast::WorkgroupDecoration>()->x;
ASSERT_NE(x, nullptr);
auto* x_literal = x->As<ast::LiteralExpression>();
ASSERT_NE(x_literal, nullptr);
ASSERT_TRUE(x_literal->Is<ast::IntLiteralExpression>());
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
ASSERT_TRUE(deco_1->Is<ast::StageDecoration>());
EXPECT_EQ(deco_1->As<ast::StageDecoration>()->stage,
ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, DecorationList_Invalid) {
auto p = parser("@invalid");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_TRUE(decos.value.empty());
EXPECT_EQ(p->error(), "1:2: expected decoration");
}
TEST_F(ParserImplTest, DecorationList_ExtraComma) {
auto p = parser("[[workgroup_size(2), ]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:22: expected decoration)");
}
TEST_F(ParserImplTest, DecorationList_BadDecoration) {
auto p = parser("@stage()");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(p->error(), "1:8: invalid value for stage decoration");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_Empty) {
auto p = parser("[[]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:3: empty decoration list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_Invalid) {
auto p = parser("[[invalid]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_TRUE(decos.value.empty());
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:3: expected decoration)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_ExtraComma) {
auto p = parser("[[workgroup_size(2), ]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:22: expected decoration)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_MissingComma) {
auto p = parser("[[workgroup_size(2) workgroup_size(2)]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:21: expected ',' for decoration list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_BadDecoration) {
auto p = parser("[[stage()]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:9: invalid value for stage decoration)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_MissingRightAttr) {
auto p = parser("[[workgroup_size(2), workgroup_size(3, 4, 5)");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:45: expected ']]' for decoration list)");
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

@ -1,260 +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/ast/stage_decoration.h"
#include "src/ast/workgroup_decoration.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, Decoration_Workgroup) {
auto p = parser("workgroup_size(4)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
EXPECT_EQ(values[1], nullptr);
EXPECT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Decoration_Workgroup_2Param) {
auto p = parser("workgroup_size(4, 5)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr) << p->error();
ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
EXPECT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Decoration_Workgroup_3Param) {
auto p = parser("workgroup_size(4, 5, 6)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
}
TEST_F(ParserImplTest, Decoration_Workgroup_WithIdent) {
auto p = parser("workgroup_size(4, height)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_NE(values[1], nullptr);
auto* y_ident = values[1]->As<ast::IdentifierExpression>();
ASSERT_NE(y_ident, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(y_ident->symbol), "height");
ASSERT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Decoration_Workgroup_TooManyValues) {
auto p = parser("workgroup_size(1, 2, 3, 4)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_MissingLeftParam) {
auto p = parser("workgroup_size 4, 5, 6)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected '(' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_MissingRightParam) {
auto p = parser("workgroup_size(4, 5, 6");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_MissingValues) {
auto p = parser("workgroup_size()");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_X_Value) {
auto p = parser("workgroup_size(, 2, 3)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Y_Comma) {
auto p = parser("workgroup_size(1 2, 3)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:18: expected ')' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Y_Value) {
auto p = parser("workgroup_size(1, , 3)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:19: expected workgroup_size y parameter");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Z_Comma) {
auto p = parser("workgroup_size(1, 2 3)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:21: expected ')' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Z_Value) {
auto p = parser("workgroup_size(1, 2, )");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:22: expected workgroup_size z parameter");
}
TEST_F(ParserImplTest, Decoration_Stage) {
auto p = parser("stage(compute)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->Is<ast::StageDecoration>());
EXPECT_EQ(func_deco->As<ast::StageDecoration>()->stage,
ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, Decoration_Stage_MissingValue) {
auto p = parser("stage()");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: invalid value for stage decoration");
}
TEST_F(ParserImplTest, Decoration_Stage_MissingInvalid) {
auto p = parser("stage(nan)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: invalid value for stage decoration");
}
TEST_F(ParserImplTest, Decoration_Stage_MissingLeftParen) {
auto p = parser("stage compute)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: expected '(' for stage decoration");
}
TEST_F(ParserImplTest, Decoration_Stage_MissingRightParen) {
auto p = parser("stage(compute");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:14: expected ')' for stage decoration");
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

@ -45,7 +45,7 @@ TEST_F(ParserImplTest, FunctionHeader_TrailingComma) {
EXPECT_TRUE(f->return_type->Is<ast::Void>()); EXPECT_TRUE(f->return_type->Is<ast::Void>());
} }
TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType) { TEST_F(ParserImplTest, FunctionHeader_AttributeReturnType) {
auto p = parser("fn main() -> @location(1) f32"); auto p = parser("fn main() -> @location(1) f32");
auto f = p->function_header(); auto f = p->function_header();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
@ -55,8 +55,8 @@ TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType) {
EXPECT_EQ(f->name, "main"); EXPECT_EQ(f->name, "main");
EXPECT_EQ(f->params.size(), 0u); EXPECT_EQ(f->params.size(), 0u);
EXPECT_TRUE(f->return_type->Is<ast::F32>()); EXPECT_TRUE(f->return_type->Is<ast::F32>());
ASSERT_EQ(f->return_type_decorations.size(), 1u); ASSERT_EQ(f->return_type_attributes.size(), 1u);
auto* loc = f->return_type_decorations[0]->As<ast::LocationDecoration>(); auto* loc = f->return_type_attributes[0]->As<ast::LocationAttribute>();
ASSERT_TRUE(loc != nullptr); ASSERT_TRUE(loc != nullptr);
EXPECT_EQ(loc->value, 1u); EXPECT_EQ(loc->value, 1u);
} }
@ -71,11 +71,11 @@ TEST_F(ParserImplTest, FunctionHeader_InvariantReturnType) {
EXPECT_EQ(f->name, "main"); EXPECT_EQ(f->name, "main");
EXPECT_EQ(f->params.size(), 0u); EXPECT_EQ(f->params.size(), 0u);
EXPECT_TRUE(f->return_type->Is<ast::F32>()); EXPECT_TRUE(f->return_type->Is<ast::F32>());
ASSERT_EQ(f->return_type_decorations.size(), 1u); ASSERT_EQ(f->return_type_attributes.size(), 1u);
EXPECT_TRUE(f->return_type_decorations[0]->Is<ast::InvariantDecoration>()); EXPECT_TRUE(f->return_type_attributes[0]->Is<ast::InvariantAttribute>());
} }
TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType_WithArrayStride) { TEST_F(ParserImplTest, FunctionHeader_AttributeReturnType_WithArrayStride) {
auto p = parser("fn main() -> @location(1) @stride(16) array<f32, 4>"); auto p = parser("fn main() -> @location(1) @stride(16) array<f32, 4>");
auto f = p->function_header(); auto f = p->function_header();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
@ -84,14 +84,14 @@ TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType_WithArrayStride) {
EXPECT_EQ(f->name, "main"); EXPECT_EQ(f->name, "main");
EXPECT_EQ(f->params.size(), 0u); EXPECT_EQ(f->params.size(), 0u);
ASSERT_EQ(f->return_type_decorations.size(), 1u); ASSERT_EQ(f->return_type_attributes.size(), 1u);
auto* loc = f->return_type_decorations[0]->As<ast::LocationDecoration>(); auto* loc = f->return_type_attributes[0]->As<ast::LocationAttribute>();
ASSERT_TRUE(loc != nullptr); ASSERT_TRUE(loc != nullptr);
EXPECT_EQ(loc->value, 1u); EXPECT_EQ(loc->value, 1u);
auto* array_type = f->return_type->As<ast::Array>(); auto* array_type = f->return_type->As<ast::Array>();
ASSERT_EQ(array_type->decorations.size(), 1u); ASSERT_EQ(array_type->attributes.size(), 1u);
auto* stride = array_type->decorations[0]->As<ast::StrideDecoration>(); auto* stride = array_type->attributes[0]->As<ast::StrideAttribute>();
ASSERT_TRUE(stride != nullptr); ASSERT_TRUE(stride != nullptr);
EXPECT_EQ(stride->stride, 16u); EXPECT_EQ(stride->stride, 16u);
} }

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/override_decoration.h" #include "src/ast/override_attribute.h"
#include "src/reader/wgsl/parser_impl_test_helper.h" #include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint { namespace tint {
@ -22,10 +22,10 @@ namespace {
TEST_F(ParserImplTest, GlobalConstantDecl) { TEST_F(ParserImplTest, GlobalConstantDecl) {
auto p = parser("let a : f32 = 1."); auto p = parser("let a : f32 = 1.");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_constant_decl(decos.value); auto e = p->global_constant_decl(attrs.value);
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
@ -44,16 +44,15 @@ TEST_F(ParserImplTest, GlobalConstantDecl) {
ASSERT_NE(e->constructor, nullptr); ASSERT_NE(e->constructor, nullptr);
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>()); EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
EXPECT_FALSE( EXPECT_FALSE(ast::HasAttribute<ast::OverrideAttribute>(e.value->attributes));
ast::HasDecoration<ast::OverrideDecoration>(e.value->decorations));
} }
TEST_F(ParserImplTest, GlobalConstantDecl_Inferred) { TEST_F(ParserImplTest, GlobalConstantDecl_Inferred) {
auto p = parser("let a = 1."); auto p = parser("let a = 1.");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_constant_decl(decos.value); auto e = p->global_constant_decl(attrs.value);
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
@ -71,16 +70,15 @@ TEST_F(ParserImplTest, GlobalConstantDecl_Inferred) {
ASSERT_NE(e->constructor, nullptr); ASSERT_NE(e->constructor, nullptr);
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>()); EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
EXPECT_FALSE( EXPECT_FALSE(ast::HasAttribute<ast::OverrideAttribute>(e.value->attributes));
ast::HasDecoration<ast::OverrideDecoration>(e.value->decorations));
} }
TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) { TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
auto p = parser("let a : f32 = if (a) {}"); auto p = parser("let a : f32 = if (a) {}");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_constant_decl(decos.value); auto e = p->global_constant_decl(attrs.value);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
@ -90,10 +88,10 @@ TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) { TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
auto p = parser("let a : f32 ="); auto p = parser("let a : f32 =");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_constant_decl(decos.value); auto e = p->global_constant_decl(attrs.value);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
@ -103,11 +101,11 @@ TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
TEST_F(ParserImplTest, GlobalConstantDec_Override_WithId) { TEST_F(ParserImplTest, GlobalConstantDec_Override_WithId) {
auto p = parser("@override(7) let a : f32 = 1."); auto p = parser("@override(7) let a : f32 = 1.");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(decos.matched); EXPECT_TRUE(attrs.matched);
auto e = p->global_constant_decl(decos.value); auto e = p->global_constant_decl(attrs.value);
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
@ -126,20 +124,20 @@ TEST_F(ParserImplTest, GlobalConstantDec_Override_WithId) {
ASSERT_NE(e->constructor, nullptr); ASSERT_NE(e->constructor, nullptr);
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>()); EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
auto* override_deco = auto* override_attr =
ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations); ast::GetAttribute<ast::OverrideAttribute>(e.value->attributes);
ASSERT_NE(override_deco, nullptr); ASSERT_NE(override_attr, nullptr);
EXPECT_TRUE(override_deco->has_value); EXPECT_TRUE(override_attr->has_value);
EXPECT_EQ(override_deco->value, 7u); EXPECT_EQ(override_attr->value, 7u);
} }
TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) { TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) {
auto p = parser("[[override]] let a : f32 = 1."); auto p = parser("[[override]] let a : f32 = 1.");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(decos.matched); EXPECT_TRUE(attrs.matched);
auto e = p->global_constant_decl(decos.value); auto e = p->global_constant_decl(attrs.value);
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
@ -158,41 +156,41 @@ TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) {
ASSERT_NE(e->constructor, nullptr); ASSERT_NE(e->constructor, nullptr);
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>()); EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
auto* override_deco = auto* override_attr =
ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations); ast::GetAttribute<ast::OverrideAttribute>(e.value->attributes);
ASSERT_NE(override_deco, nullptr); ASSERT_NE(override_attr, nullptr);
EXPECT_FALSE(override_deco->has_value); EXPECT_FALSE(override_attr->has_value);
} }
TEST_F(ParserImplTest, GlobalConstantDec_Override_MissingId) { TEST_F(ParserImplTest, GlobalConstantDec_Override_MissingId) {
auto p = parser("@override() let a : f32 = 1."); auto p = parser("@override() let a : f32 = 1.");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_TRUE(decos.errored); EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_constant_decl(decos.value); auto e = p->global_constant_decl(attrs.value);
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
ASSERT_NE(e.value, nullptr); ASSERT_NE(e.value, nullptr);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), EXPECT_EQ(p->error(),
"1:11: expected signed integer literal for override decoration"); "1:11: expected signed integer literal for override attribute");
} }
TEST_F(ParserImplTest, GlobalConstantDec_Override_InvalidId) { TEST_F(ParserImplTest, GlobalConstantDec_Override_InvalidId) {
auto p = parser("@override(-7) let a : f32 = 1."); auto p = parser("@override(-7) let a : f32 = 1.");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_TRUE(decos.errored); EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_constant_decl(decos.value); auto e = p->global_constant_decl(attrs.value);
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
ASSERT_NE(e.value, nullptr); ASSERT_NE(e.value, nullptr);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:11: override decoration must be positive"); EXPECT_EQ(p->error(), "1:11: override attribute must be positive");
} }
} // namespace } // namespace

View File

@ -131,7 +131,7 @@ TEST_F(ParserImplTest, GlobalDecl_Function) {
"main"); "main");
} }
TEST_F(ParserImplTest, GlobalDecl_Function_WithDecoration) { TEST_F(ParserImplTest, GlobalDecl_Function_WithAttribute) {
auto p = parser("@workgroup_size(2) fn main() { return; }"); auto p = parser("@workgroup_size(2) fn main() { return; }");
p->expect_global_decl(); p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
@ -187,14 +187,14 @@ TEST_F(ParserImplTest, GlobalDecl_Struct_WithStride) {
ASSERT_TRUE(ty->Is<ast::Array>()); ASSERT_TRUE(ty->Is<ast::Array>());
const auto* arr = ty->As<ast::Array>(); const auto* arr = ty->As<ast::Array>();
ASSERT_EQ(arr->decorations.size(), 1u); ASSERT_EQ(arr->attributes.size(), 1u);
auto* stride = arr->decorations[0]; auto* stride = arr->attributes[0];
ASSERT_TRUE(stride->Is<ast::StrideDecoration>()); ASSERT_TRUE(stride->Is<ast::StrideAttribute>());
ASSERT_EQ(stride->As<ast::StrideDecoration>()->stride, 4u); ASSERT_EQ(stride->As<ast::StrideAttribute>()->stride, 4u);
} }
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed. // TODO(crbug.com/tint/1324): DEPRECATED: Remove when @block is removed.
TEST_F(ParserImplTest, GlobalDecl_Struct_WithDecoration) { TEST_F(ParserImplTest, GlobalDecl_Struct_WithAttribute) {
auto p = parser("[[block]] struct A { data: f32; }"); auto p = parser("[[block]] struct A { data: f32; }");
p->expect_global_decl(); p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();

View File

@ -21,10 +21,10 @@ namespace {
TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) { TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
auto p = parser("var<private> a : f32"); auto p = parser("var<private> a : f32");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_variable_decl(decos.value); auto e = p->global_variable_decl(attrs.value);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
@ -44,10 +44,10 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) { TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
auto p = parser("var<private> a : f32 = 1."); auto p = parser("var<private> a : f32 = 1.");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_variable_decl(decos.value); auto e = p->global_variable_decl(attrs.value);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
@ -66,12 +66,12 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
ASSERT_TRUE(e->constructor->Is<ast::FloatLiteralExpression>()); ASSERT_TRUE(e->constructor->Is<ast::FloatLiteralExpression>());
} }
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) { TEST_F(ParserImplTest, GlobalVariableDecl_WithAttribute) {
auto p = parser("@binding(2) @group(1) var<uniform> a : f32"); auto p = parser("@binding(2) @group(1) var<uniform> a : f32");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(decos.matched); EXPECT_TRUE(attrs.matched);
auto e = p->global_variable_decl(decos.value); auto e = p->global_variable_decl(attrs.value);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
@ -89,19 +89,19 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
ASSERT_EQ(e->constructor, nullptr); ASSERT_EQ(e->constructor, nullptr);
auto& decorations = e->decorations; auto& attributes = e->attributes;
ASSERT_EQ(decorations.size(), 2u); ASSERT_EQ(attributes.size(), 2u);
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>()); ASSERT_TRUE(attributes[0]->Is<ast::BindingAttribute>());
ASSERT_TRUE(decorations[1]->Is<ast::GroupDecoration>()); ASSERT_TRUE(attributes[1]->Is<ast::GroupAttribute>());
} }
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) { TEST_F(ParserImplTest, GlobalVariableDecl_WithAttribute_MulitpleGroups) {
auto p = parser("@binding(2) @group(1) var<uniform> a : f32"); auto p = parser("@binding(2) @group(1) var<uniform> a : f32");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(decos.matched); EXPECT_TRUE(attrs.matched);
auto e = p->global_variable_decl(decos.value); auto e = p->global_variable_decl(attrs.value);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
@ -119,34 +119,34 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
ASSERT_EQ(e->constructor, nullptr); ASSERT_EQ(e->constructor, nullptr);
auto& decorations = e->decorations; auto& attributes = e->attributes;
ASSERT_EQ(decorations.size(), 2u); ASSERT_EQ(attributes.size(), 2u);
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>()); ASSERT_TRUE(attributes[0]->Is<ast::BindingAttribute>());
ASSERT_TRUE(decorations[1]->Is<ast::GroupDecoration>()); ASSERT_TRUE(attributes[1]->Is<ast::GroupAttribute>());
} }
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidDecoration) { TEST_F(ParserImplTest, GlobalVariableDecl_InvalidAttribute) {
auto p = parser("@binding() var<uniform> a : f32"); auto p = parser("@binding() var<uniform> a : f32");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_TRUE(decos.errored); EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_variable_decl(decos.value); auto e = p->global_variable_decl(attrs.value);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_NE(e.value, nullptr); EXPECT_NE(e.value, nullptr);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), EXPECT_EQ(p->error(),
"1:10: expected signed integer literal for binding decoration"); "1:10: expected signed integer literal for binding attribute");
} }
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) { TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
auto p = parser("var<private> a : f32 = if (a) {}"); auto p = parser("var<private> a : f32 = if (a) {}");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_variable_decl(decos.value); auto e = p->global_variable_decl(attrs.value);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
@ -156,10 +156,10 @@ TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) { TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
auto p = parser("var<invalid> a : f32;"); auto p = parser("var<invalid> a : f32;");
auto decos = p->decoration_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(attrs.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(attrs.matched);
auto e = p->global_variable_decl(decos.value); auto e = p->global_variable_decl(attrs.value);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);

View File

@ -91,7 +91,7 @@ TEST_F(ParserImplTest, ParamList_TrailingComma) {
EXPECT_EQ(e.value.size(), 1u); EXPECT_EQ(e.value.size(), 1u);
} }
TEST_F(ParserImplTest, ParamList_Decorations) { TEST_F(ParserImplTest, ParamList_Attributes) {
auto p = auto p =
parser("@builtin(position) coord : vec4<f32>, @location(1) loc1 : f32"); parser("@builtin(position) coord : vec4<f32>, @location(1) loc1 : f32");
@ -105,10 +105,10 @@ TEST_F(ParserImplTest, ParamList_Decorations) {
EXPECT_TRUE(e.value[0]->type->As<ast::Vector>()->type->Is<ast::F32>()); EXPECT_TRUE(e.value[0]->type->As<ast::Vector>()->type->Is<ast::F32>());
EXPECT_EQ(e.value[0]->type->As<ast::Vector>()->width, 4u); EXPECT_EQ(e.value[0]->type->As<ast::Vector>()->width, 4u);
EXPECT_TRUE(e.value[0]->is_const); EXPECT_TRUE(e.value[0]->is_const);
auto decos0 = e.value[0]->decorations; auto attrs_0 = e.value[0]->attributes;
ASSERT_EQ(decos0.size(), 1u); ASSERT_EQ(attrs_0.size(), 1u);
EXPECT_TRUE(decos0[0]->Is<ast::BuiltinDecoration>()); EXPECT_TRUE(attrs_0[0]->Is<ast::BuiltinAttribute>());
EXPECT_EQ(decos0[0]->As<ast::BuiltinDecoration>()->builtin, EXPECT_EQ(attrs_0[0]->As<ast::BuiltinAttribute>()->builtin,
ast::Builtin::kPosition); ast::Builtin::kPosition);
ASSERT_EQ(e.value[0]->source.range.begin.line, 1u); ASSERT_EQ(e.value[0]->source.range.begin.line, 1u);
@ -119,10 +119,10 @@ TEST_F(ParserImplTest, ParamList_Decorations) {
EXPECT_EQ(e.value[1]->symbol, p->builder().Symbols().Get("loc1")); EXPECT_EQ(e.value[1]->symbol, p->builder().Symbols().Get("loc1"));
EXPECT_TRUE(e.value[1]->type->Is<ast::F32>()); EXPECT_TRUE(e.value[1]->type->Is<ast::F32>());
EXPECT_TRUE(e.value[1]->is_const); EXPECT_TRUE(e.value[1]->is_const);
auto decos1 = e.value[1]->decorations; auto attrs_1 = e.value[1]->attributes;
ASSERT_EQ(decos1.size(), 1u); ASSERT_EQ(attrs_1.size(), 1u);
EXPECT_TRUE(decos1[0]->Is<ast::LocationDecoration>()); EXPECT_TRUE(attrs_1[0]->Is<ast::LocationAttribute>());
EXPECT_EQ(decos1[0]->As<ast::LocationDecoration>()->value, 1u); EXPECT_EQ(attrs_1[0]->As<ast::LocationAttribute>()->value, 1u);
EXPECT_EQ(e.value[1]->source.range.begin.line, 1u); EXPECT_EQ(e.value[1]->source.range.begin.line, 1u);
EXPECT_EQ(e.value[1]->source.range.begin.column, 52u); EXPECT_EQ(e.value[1]->source.range.begin.column, 52u);

View File

@ -58,7 +58,7 @@ TEST_F(ParserImplTest, PipelineStage_NoMatch) {
auto stage = p->expect_pipeline_stage(); auto stage = p->expect_pipeline_stage();
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(stage.errored); ASSERT_TRUE(stage.errored);
ASSERT_EQ(p->error(), "1:1: invalid value for stage decoration"); ASSERT_EQ(p->error(), "1:1: invalid value for stage attribute");
} }
} // namespace } // namespace

View File

@ -0,0 +1,113 @@
// 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/ast/override_attribute.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, AttributeDecl_Parses) {
auto p = parser("@override");
auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
ASSERT_EQ(attrs.value.size(), 1u);
auto* override_attr = attrs.value[0]->As<ast::Attribute>();
EXPECT_TRUE(override_attr->Is<ast::OverrideAttribute>());
}
TEST_F(ParserImplTest, AttributeDecl_MissingParenLeft) {
auto p = parser("@location 1)");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(p->error(), "1:11: expected '(' for location attribute");
}
TEST_F(ParserImplTest, AttributeDecl_MissingValue) {
auto p = parser("@location()");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(p->error(),
"1:11: expected signed integer literal for location attribute");
}
TEST_F(ParserImplTest, AttributeDecl_MissingParenRight) {
auto p = parser("@location(1");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(p->error(), "1:12: expected ')' for location attribute");
}
TEST_F(ParserImplTest, AttributeDecl_Invalidattribute) {
auto p = parser("@invalid");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_attributeDecl_Parses) {
auto p = parser("[[override]]");
auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
ASSERT_EQ(attrs.value.size(), 1u);
auto* override_attr = attrs.value[0]->As<ast::Attribute>();
EXPECT_TRUE(override_attr->Is<ast::OverrideAttribute>());
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_attributeDecl_MissingAttrRight) {
auto p = parser("[[override");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:11: expected ']]' for attribute list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_attributeDecl_Invalidattribute) {
auto p = parser("[[invalid]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/struct_block_decoration.h" #include "src/ast/struct_block_attribute.h"
#include "src/reader/wgsl/parser_impl_test_helper.h" #include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint { namespace tint {
@ -20,40 +20,40 @@ namespace reader {
namespace wgsl { namespace wgsl {
namespace { namespace {
struct DecorationData { struct AttributeData {
const char* input; const char* input;
bool is_block; bool is_block;
}; };
inline std::ostream& operator<<(std::ostream& out, DecorationData data) { inline std::ostream& operator<<(std::ostream& out, AttributeData data) {
out << std::string(data.input); out << std::string(data.input);
return out; return out;
} }
class DecorationTest : public ParserImplTestWithParam<DecorationData> {}; class AttributeTest : public ParserImplTestWithParam<AttributeData> {};
TEST_P(DecorationTest, Parses) { TEST_P(AttributeTest, Parses) {
auto params = GetParam(); auto params = GetParam();
auto p = parser(params.input); auto p = parser(params.input);
auto deco = p->decoration(); auto attr = p->attribute();
ASSERT_FALSE(p->has_error()); ASSERT_FALSE(p->has_error());
EXPECT_TRUE(deco.matched); EXPECT_TRUE(attr.matched);
EXPECT_FALSE(deco.errored); EXPECT_FALSE(attr.errored);
ASSERT_NE(deco.value, nullptr); ASSERT_NE(attr.value, nullptr);
auto* struct_deco = deco.value->As<ast::Decoration>(); auto* struct_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(struct_deco, nullptr); ASSERT_NE(struct_attr, nullptr);
EXPECT_EQ(struct_deco->Is<ast::StructBlockDecoration>(), params.is_block); EXPECT_EQ(struct_attr->Is<ast::StructBlockAttribute>(), params.is_block);
} }
INSTANTIATE_TEST_SUITE_P(ParserImplTest, INSTANTIATE_TEST_SUITE_P(ParserImplTest,
DecorationTest, AttributeTest,
testing::Values(DecorationData{"block", true})); testing::Values(AttributeData{"block", true}));
TEST_F(ParserImplTest, Decoration_NoMatch) { TEST_F(ParserImplTest, Attribute_NoMatch) {
auto p = parser("not-a-stage"); auto p = parser("not-a-stage");
auto deco = p->decoration(); auto attr = p->attribute();
EXPECT_FALSE(deco.matched); EXPECT_FALSE(attr.matched);
EXPECT_FALSE(deco.errored); EXPECT_FALSE(attr.errored);
ASSERT_EQ(deco.value, nullptr); ASSERT_EQ(attr.value, nullptr);
} }
} // namespace } // namespace

View File

@ -32,7 +32,7 @@ TEST_F(ParserImplTest, StructBodyDecl_Parses) {
const auto* mem = m.value[0]; const auto* mem = m.value[0];
EXPECT_EQ(mem->symbol, builder.Symbols().Get("a")); EXPECT_EQ(mem->symbol, builder.Symbols().Get("a"));
EXPECT_TRUE(mem->type->Is<ast::I32>()); EXPECT_TRUE(mem->type->Is<ast::I32>());
EXPECT_EQ(mem->decorations.size(), 0u); EXPECT_EQ(mem->attributes.size(), 0u);
} }
TEST_F(ParserImplTest, StructBodyDecl_ParsesEmpty) { TEST_F(ParserImplTest, StructBodyDecl_ParsesEmpty) {
@ -52,7 +52,7 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidAlign) {
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(m.errored); ASSERT_TRUE(m.errored);
EXPECT_EQ(p->error(), EXPECT_EQ(p->error(),
"3:10: expected signed integer literal for align decoration"); "3:10: expected signed integer literal for align attribute");
} }
TEST_F(ParserImplTest, StructBodyDecl_InvalidSize) { TEST_F(ParserImplTest, StructBodyDecl_InvalidSize) {
@ -64,7 +64,7 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidSize) {
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(m.errored); ASSERT_TRUE(m.errored);
EXPECT_EQ(p->error(), EXPECT_EQ(p->error(),
"3:9: expected signed integer literal for size decoration"); "3:9: expected signed integer literal for size attribute");
} }
TEST_F(ParserImplTest, StructBodyDecl_MissingClosingBracket) { TEST_F(ParserImplTest, StructBodyDecl_MissingClosingBracket) {

Some files were not shown because too many files have changed in this diff Show More