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:
parent
d4d7153bad
commit
a996ffbd1f
|
@ -94,7 +94,7 @@ Each `ast::Node` represents a **single** part of the program's source, and so
|
|||
`ast::Node`s are not shared.
|
||||
|
||||
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
|
||||
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.
|
||||
|
|
72
src/BUILD.gn
72
src/BUILD.gn
|
@ -186,8 +186,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/atomic.h",
|
||||
"ast/binary_expression.cc",
|
||||
"ast/binary_expression.h",
|
||||
"ast/binding_decoration.cc",
|
||||
"ast/binding_decoration.h",
|
||||
"ast/binding_attribute.cc",
|
||||
"ast/binding_attribute.h",
|
||||
"ast/bitcast_expression.cc",
|
||||
"ast/bitcast_expression.h",
|
||||
"ast/block_statement.cc",
|
||||
|
@ -200,8 +200,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/break_statement.h",
|
||||
"ast/builtin.cc",
|
||||
"ast/builtin.h",
|
||||
"ast/builtin_decoration.cc",
|
||||
"ast/builtin_decoration.h",
|
||||
"ast/builtin_attribute.cc",
|
||||
"ast/builtin_attribute.h",
|
||||
"ast/call_expression.cc",
|
||||
"ast/call_expression.h",
|
||||
"ast/call_statement.cc",
|
||||
|
@ -210,14 +210,14 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/case_statement.h",
|
||||
"ast/continue_statement.cc",
|
||||
"ast/continue_statement.h",
|
||||
"ast/decoration.cc",
|
||||
"ast/decoration.h",
|
||||
"ast/attribute.cc",
|
||||
"ast/attribute.h",
|
||||
"ast/depth_multisampled_texture.cc",
|
||||
"ast/depth_multisampled_texture.h",
|
||||
"ast/depth_texture.cc",
|
||||
"ast/depth_texture.h",
|
||||
"ast/disable_validation_decoration.cc",
|
||||
"ast/disable_validation_decoration.h",
|
||||
"ast/disable_validation_attribute.cc",
|
||||
"ast/disable_validation_attribute.h",
|
||||
"ast/discard_statement.cc",
|
||||
"ast/discard_statement.h",
|
||||
"ast/else_statement.cc",
|
||||
|
@ -236,8 +236,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/for_loop_statement.h",
|
||||
"ast/function.cc",
|
||||
"ast/function.h",
|
||||
"ast/group_decoration.cc",
|
||||
"ast/group_decoration.h",
|
||||
"ast/group_attribute.cc",
|
||||
"ast/group_attribute.h",
|
||||
"ast/i32.cc",
|
||||
"ast/i32.h",
|
||||
"ast/identifier_expression.cc",
|
||||
|
@ -248,16 +248,16 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/index_accessor_expression.h",
|
||||
"ast/int_literal_expression.cc",
|
||||
"ast/int_literal_expression.h",
|
||||
"ast/internal_decoration.cc",
|
||||
"ast/internal_decoration.h",
|
||||
"ast/interpolate_decoration.cc",
|
||||
"ast/interpolate_decoration.h",
|
||||
"ast/invariant_decoration.cc",
|
||||
"ast/invariant_decoration.h",
|
||||
"ast/internal_attribute.cc",
|
||||
"ast/internal_attribute.h",
|
||||
"ast/interpolate_attribute.cc",
|
||||
"ast/interpolate_attribute.h",
|
||||
"ast/invariant_attribute.cc",
|
||||
"ast/invariant_attribute.h",
|
||||
"ast/literal_expression.cc",
|
||||
"ast/literal_expression.h",
|
||||
"ast/location_decoration.cc",
|
||||
"ast/location_decoration.h",
|
||||
"ast/location_attribute.cc",
|
||||
"ast/location_attribute.h",
|
||||
"ast/loop_statement.cc",
|
||||
"ast/loop_statement.h",
|
||||
"ast/matrix.cc",
|
||||
|
@ -270,8 +270,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/multisampled_texture.h",
|
||||
"ast/node.cc",
|
||||
"ast/node.h",
|
||||
"ast/override_decoration.cc",
|
||||
"ast/override_decoration.h",
|
||||
"ast/override_attribute.cc",
|
||||
"ast/override_attribute.h",
|
||||
"ast/phony_expression.cc",
|
||||
"ast/phony_expression.h",
|
||||
"ast/pipeline_stage.cc",
|
||||
|
@ -286,28 +286,28 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/sampler.h",
|
||||
"ast/sint_literal_expression.cc",
|
||||
"ast/sint_literal_expression.h",
|
||||
"ast/stage_decoration.cc",
|
||||
"ast/stage_decoration.h",
|
||||
"ast/stage_attribute.cc",
|
||||
"ast/stage_attribute.h",
|
||||
"ast/statement.cc",
|
||||
"ast/statement.h",
|
||||
"ast/storage_class.cc",
|
||||
"ast/storage_class.h",
|
||||
"ast/storage_texture.cc",
|
||||
"ast/storage_texture.h",
|
||||
"ast/stride_decoration.cc",
|
||||
"ast/stride_decoration.h",
|
||||
"ast/stride_attribute.cc",
|
||||
"ast/stride_attribute.h",
|
||||
"ast/struct.cc",
|
||||
"ast/struct.h",
|
||||
"ast/struct_block_decoration.cc",
|
||||
"ast/struct_block_decoration.h",
|
||||
"ast/struct_block_attribute.cc",
|
||||
"ast/struct_block_attribute.h",
|
||||
"ast/struct_member.cc",
|
||||
"ast/struct_member.h",
|
||||
"ast/struct_member_align_decoration.cc",
|
||||
"ast/struct_member_align_decoration.h",
|
||||
"ast/struct_member_offset_decoration.cc",
|
||||
"ast/struct_member_offset_decoration.h",
|
||||
"ast/struct_member_size_decoration.cc",
|
||||
"ast/struct_member_size_decoration.h",
|
||||
"ast/struct_member_align_attribute.cc",
|
||||
"ast/struct_member_align_attribute.h",
|
||||
"ast/struct_member_offset_attribute.cc",
|
||||
"ast/struct_member_offset_attribute.h",
|
||||
"ast/struct_member_size_attribute.cc",
|
||||
"ast/struct_member_size_attribute.h",
|
||||
"ast/switch_statement.cc",
|
||||
"ast/switch_statement.h",
|
||||
"ast/texture.cc",
|
||||
|
@ -334,8 +334,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"ast/vector.h",
|
||||
"ast/void.cc",
|
||||
"ast/void.h",
|
||||
"ast/workgroup_decoration.cc",
|
||||
"ast/workgroup_decoration.h",
|
||||
"ast/workgroup_attribute.cc",
|
||||
"ast/workgroup_attribute.h",
|
||||
"block_allocator.h",
|
||||
"castable.cc",
|
||||
"castable.h",
|
||||
|
@ -427,8 +427,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"traits.h",
|
||||
"transform/add_empty_entry_point.cc",
|
||||
"transform/add_empty_entry_point.h",
|
||||
"transform/add_spirv_block_decoration.cc",
|
||||
"transform/add_spirv_block_decoration.h",
|
||||
"transform/add_spirv_block_attribute.cc",
|
||||
"transform/add_spirv_block_attribute.h",
|
||||
"transform/array_length_from_uniform.cc",
|
||||
"transform/array_length_from_uniform.h",
|
||||
"transform/binding_remapper.cc",
|
||||
|
|
|
@ -55,6 +55,8 @@ set(TINT_LIB_SRCS
|
|||
../include/tint/tint.h
|
||||
ast/access.cc
|
||||
ast/access.h
|
||||
ast/attribute.cc
|
||||
ast/attribute.h
|
||||
ast/alias.cc
|
||||
ast/alias.h
|
||||
ast/index_accessor_expression.cc
|
||||
|
@ -67,8 +69,8 @@ set(TINT_LIB_SRCS
|
|||
ast/atomic.h
|
||||
ast/binary_expression.cc
|
||||
ast/binary_expression.h
|
||||
ast/binding_decoration.cc
|
||||
ast/binding_decoration.h
|
||||
ast/binding_attribute.cc
|
||||
ast/binding_attribute.h
|
||||
ast/bitcast_expression.cc
|
||||
ast/bitcast_expression.h
|
||||
ast/block_statement.cc
|
||||
|
@ -79,8 +81,8 @@ set(TINT_LIB_SRCS
|
|||
ast/bool.h
|
||||
ast/break_statement.cc
|
||||
ast/break_statement.h
|
||||
ast/builtin_decoration.cc
|
||||
ast/builtin_decoration.h
|
||||
ast/builtin_attribute.cc
|
||||
ast/builtin_attribute.h
|
||||
ast/builtin.cc
|
||||
ast/builtin.h
|
||||
ast/call_expression.cc
|
||||
|
@ -91,12 +93,10 @@ set(TINT_LIB_SRCS
|
|||
ast/case_statement.h
|
||||
ast/continue_statement.cc
|
||||
ast/continue_statement.h
|
||||
ast/decoration.cc
|
||||
ast/decoration.h
|
||||
ast/depth_multisampled_texture.cc
|
||||
ast/depth_multisampled_texture.h
|
||||
ast/disable_validation_decoration.cc
|
||||
ast/disable_validation_decoration.h
|
||||
ast/disable_validation_attribute.cc
|
||||
ast/disable_validation_attribute.h
|
||||
ast/depth_texture.cc
|
||||
ast/depth_texture.h
|
||||
ast/discard_statement.cc
|
||||
|
@ -117,8 +117,8 @@ set(TINT_LIB_SRCS
|
|||
ast/for_loop_statement.h
|
||||
ast/function.cc
|
||||
ast/function.h
|
||||
ast/group_decoration.cc
|
||||
ast/group_decoration.h
|
||||
ast/group_attribute.cc
|
||||
ast/group_attribute.h
|
||||
ast/i32.cc
|
||||
ast/i32.h
|
||||
ast/identifier_expression.cc
|
||||
|
@ -127,16 +127,16 @@ set(TINT_LIB_SRCS
|
|||
ast/if_statement.h
|
||||
ast/int_literal_expression.cc
|
||||
ast/int_literal_expression.h
|
||||
ast/internal_decoration.cc
|
||||
ast/internal_decoration.h
|
||||
ast/interpolate_decoration.cc
|
||||
ast/interpolate_decoration.h
|
||||
ast/invariant_decoration.cc
|
||||
ast/invariant_decoration.h
|
||||
ast/internal_attribute.cc
|
||||
ast/internal_attribute.h
|
||||
ast/interpolate_attribute.cc
|
||||
ast/interpolate_attribute.h
|
||||
ast/invariant_attribute.cc
|
||||
ast/invariant_attribute.h
|
||||
ast/literal_expression.cc
|
||||
ast/literal_expression.h
|
||||
ast/location_decoration.cc
|
||||
ast/location_decoration.h
|
||||
ast/location_attribute.cc
|
||||
ast/location_attribute.h
|
||||
ast/loop_statement.cc
|
||||
ast/loop_statement.h
|
||||
ast/matrix.cc
|
||||
|
@ -149,8 +149,8 @@ set(TINT_LIB_SRCS
|
|||
ast/multisampled_texture.h
|
||||
ast/node.cc
|
||||
ast/node.h
|
||||
ast/override_decoration.cc
|
||||
ast/override_decoration.h
|
||||
ast/override_attribute.cc
|
||||
ast/override_attribute.h
|
||||
ast/phony_expression.cc
|
||||
ast/phony_expression.h
|
||||
ast/pipeline_stage.cc
|
||||
|
@ -165,24 +165,24 @@ set(TINT_LIB_SRCS
|
|||
ast/sampler.h
|
||||
ast/sint_literal_expression.cc
|
||||
ast/sint_literal_expression.h
|
||||
ast/stage_decoration.cc
|
||||
ast/stage_decoration.h
|
||||
ast/stage_attribute.cc
|
||||
ast/stage_attribute.h
|
||||
ast/statement.cc
|
||||
ast/statement.h
|
||||
ast/storage_class.cc
|
||||
ast/storage_class.h
|
||||
ast/storage_texture.cc
|
||||
ast/storage_texture.h
|
||||
ast/stride_decoration.cc
|
||||
ast/stride_decoration.h
|
||||
ast/struct_block_decoration.cc
|
||||
ast/struct_block_decoration.h
|
||||
ast/struct_member_align_decoration.cc
|
||||
ast/struct_member_align_decoration.h
|
||||
ast/struct_member_offset_decoration.cc
|
||||
ast/struct_member_offset_decoration.h
|
||||
ast/struct_member_size_decoration.cc
|
||||
ast/struct_member_size_decoration.h
|
||||
ast/stride_attribute.cc
|
||||
ast/stride_attribute.h
|
||||
ast/struct_block_attribute.cc
|
||||
ast/struct_block_attribute.h
|
||||
ast/struct_member_align_attribute.cc
|
||||
ast/struct_member_align_attribute.h
|
||||
ast/struct_member_offset_attribute.cc
|
||||
ast/struct_member_offset_attribute.h
|
||||
ast/struct_member_size_attribute.cc
|
||||
ast/struct_member_size_attribute.h
|
||||
ast/struct_member.cc
|
||||
ast/struct_member.h
|
||||
ast/struct.cc
|
||||
|
@ -216,8 +216,8 @@ set(TINT_LIB_SRCS
|
|||
ast/vector.h
|
||||
ast/void.cc
|
||||
ast/void.h
|
||||
ast/workgroup_decoration.cc
|
||||
ast/workgroup_decoration.h
|
||||
ast/workgroup_attribute.cc
|
||||
ast/workgroup_attribute.h
|
||||
block_allocator.h
|
||||
castable.cc
|
||||
castable.h
|
||||
|
@ -295,8 +295,8 @@ set(TINT_LIB_SRCS
|
|||
traits.h
|
||||
transform/add_empty_entry_point.cc
|
||||
transform/add_empty_entry_point.h
|
||||
transform/add_spirv_block_decoration.cc
|
||||
transform/add_spirv_block_decoration.h
|
||||
transform/add_spirv_block_attribute.cc
|
||||
transform/add_spirv_block_attribute.h
|
||||
transform/array_length_from_uniform.cc
|
||||
transform/array_length_from_uniform.h
|
||||
transform/binding_remapper.cc
|
||||
|
@ -617,13 +617,13 @@ if(TINT_BUILD_TESTS)
|
|||
ast/assignment_statement_test.cc
|
||||
ast/atomic_test.cc
|
||||
ast/binary_expression_test.cc
|
||||
ast/binding_decoration_test.cc
|
||||
ast/binding_attribute_test.cc
|
||||
ast/bitcast_expression_test.cc
|
||||
ast/block_statement_test.cc
|
||||
ast/bool_literal_expression_test.cc
|
||||
ast/bool_test.cc
|
||||
ast/break_statement_test.cc
|
||||
ast/builtin_decoration_test.cc
|
||||
ast/builtin_attribute_test.cc
|
||||
ast/call_expression_test.cc
|
||||
ast/call_statement_test.cc
|
||||
ast/case_statement_test.cc
|
||||
|
@ -638,36 +638,36 @@ if(TINT_BUILD_TESTS)
|
|||
ast/float_literal_expression_test.cc
|
||||
ast/for_loop_statement_test.cc
|
||||
ast/function_test.cc
|
||||
ast/group_decoration_test.cc
|
||||
ast/group_attribute_test.cc
|
||||
ast/i32_test.cc
|
||||
ast/identifier_expression_test.cc
|
||||
ast/if_statement_test.cc
|
||||
ast/index_accessor_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.h
|
||||
ast/invariant_decoration_test.cc
|
||||
ast/location_decoration_test.cc
|
||||
ast/invariant_attribute_test.cc
|
||||
ast/location_attribute_test.cc
|
||||
ast/loop_statement_test.cc
|
||||
ast/matrix_test.cc
|
||||
ast/member_accessor_expression_test.cc
|
||||
ast/module_clone_test.cc
|
||||
ast/module_test.cc
|
||||
ast/multisampled_texture_test.cc
|
||||
ast/override_decoration_test.cc
|
||||
ast/override_attribute_test.cc
|
||||
ast/phony_expression_test.cc
|
||||
ast/pointer_test.cc
|
||||
ast/return_statement_test.cc
|
||||
ast/sampled_texture_test.cc
|
||||
ast/sampler_test.cc
|
||||
ast/sint_literal_expression_test.cc
|
||||
ast/stage_decoration_test.cc
|
||||
ast/stage_attribute_test.cc
|
||||
ast/storage_texture_test.cc
|
||||
ast/stride_decoration_test.cc
|
||||
ast/struct_member_align_decoration_test.cc
|
||||
ast/struct_member_offset_decoration_test.cc
|
||||
ast/struct_member_size_decoration_test.cc
|
||||
ast/stride_attribute_test.cc
|
||||
ast/struct_member_align_attribute_test.cc
|
||||
ast/struct_member_offset_attribute_test.cc
|
||||
ast/struct_member_size_attribute_test.cc
|
||||
ast/struct_member_test.cc
|
||||
ast/struct_test.cc
|
||||
ast/switch_statement_test.cc
|
||||
|
@ -680,7 +680,7 @@ if(TINT_BUILD_TESTS)
|
|||
ast/variable_decl_statement_test.cc
|
||||
ast/variable_test.cc
|
||||
ast/vector_test.cc
|
||||
ast/workgroup_decoration_test.cc
|
||||
ast/workgroup_attribute_test.cc
|
||||
block_allocator_test.cc
|
||||
castable_test.cc
|
||||
clone_context_test.cc
|
||||
|
@ -701,7 +701,7 @@ if(TINT_BUILD_TESTS)
|
|||
resolver/call_validation_test.cc
|
||||
resolver/compound_statement_test.cc
|
||||
resolver/control_block_validation_test.cc
|
||||
resolver/decoration_validation_test.cc
|
||||
resolver/attribute_validation_test.cc
|
||||
resolver/dependency_graph_test.cc
|
||||
resolver/entry_point_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_for_stmt_test.cc
|
||||
reader/wgsl/parser_impl_function_decl_test.cc
|
||||
reader/wgsl/parser_impl_function_decoration_list_test.cc
|
||||
reader/wgsl/parser_impl_function_decoration_test.cc
|
||||
reader/wgsl/parser_impl_function_attribute_list_test.cc
|
||||
reader/wgsl/parser_impl_function_attribute_test.cc
|
||||
reader/wgsl/parser_impl_function_header_test.cc
|
||||
reader/wgsl/parser_impl_global_constant_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_struct_body_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_decoration_test.cc
|
||||
reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc
|
||||
reader/wgsl/parser_impl_struct_member_decoration_test.cc
|
||||
reader/wgsl/parser_impl_struct_attribute_decl_test.cc
|
||||
reader/wgsl/parser_impl_struct_attribute_test.cc
|
||||
reader/wgsl/parser_impl_struct_member_attribute_decl_test.cc
|
||||
reader/wgsl/parser_impl_struct_member_attribute_test.cc
|
||||
reader/wgsl/parser_impl_struct_member_test.cc
|
||||
reader/wgsl/parser_impl_switch_body_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_unary_expression_test.cc
|
||||
reader/wgsl/parser_impl_variable_decl_test.cc
|
||||
reader/wgsl/parser_impl_variable_decoration_list_test.cc
|
||||
reader/wgsl/parser_impl_variable_decoration_test.cc
|
||||
reader/wgsl/parser_impl_variable_attribute_list_test.cc
|
||||
reader/wgsl/parser_impl_variable_attribute_test.cc
|
||||
reader/wgsl/parser_impl_variable_ident_decl_test.cc
|
||||
reader/wgsl/parser_impl_variable_stmt_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_entry_point_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_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})
|
||||
list(APPEND TINT_TEST_SRCS
|
||||
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/binding_remapper_test.cc
|
||||
transform/calculate_array_length_test.cc
|
||||
|
|
|
@ -43,8 +43,8 @@ Array::Array(ProgramID pid,
|
|||
const Source& src,
|
||||
const Type* subtype,
|
||||
const Expression* cnt,
|
||||
DecorationList decos)
|
||||
: Base(pid, src), type(subtype), count(cnt), decorations(decos) {}
|
||||
AttributeList attrs)
|
||||
: Base(pid, src), type(subtype), count(cnt), attributes(attrs) {}
|
||||
|
||||
Array::Array(Array&&) = default;
|
||||
|
||||
|
@ -52,8 +52,8 @@ Array::~Array() = default;
|
|||
|
||||
std::string Array::FriendlyName(const SymbolTable& symbols) const {
|
||||
std::ostringstream out;
|
||||
for (auto* deco : decorations) {
|
||||
if (auto* stride = deco->As<ast::StrideDecoration>()) {
|
||||
for (auto* attr : attributes) {
|
||||
if (auto* stride = attr->As<ast::StrideAttribute>()) {
|
||||
out << "@stride(" << stride->stride << ") ";
|
||||
}
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ const Array* Array::Clone(CloneContext* ctx) const {
|
|||
auto src = ctx->Clone(source);
|
||||
auto* ty = ctx->Clone(type);
|
||||
auto* cnt = ctx->Clone(count);
|
||||
auto decos = ctx->Clone(decorations);
|
||||
return ctx->dst->create<Array>(src, ty, cnt, decos);
|
||||
auto attrs = ctx->Clone(attributes);
|
||||
return ctx->dst->create<Array>(src, ty, cnt, attrs);
|
||||
}
|
||||
|
||||
} // namespace ast
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
#include "src/ast/type.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -35,12 +35,12 @@ class Array : public Castable<Array, Type> {
|
|||
/// @param subtype the type of the array elements
|
||||
/// @param count the number of elements in the array. nullptr represents a
|
||||
/// runtime-sized array.
|
||||
/// @param decorations the array decorations
|
||||
/// @param attributes the array attributes
|
||||
Array(ProgramID pid,
|
||||
const Source& src,
|
||||
const Type* subtype,
|
||||
const Expression* count,
|
||||
DecorationList decorations);
|
||||
AttributeList attributes);
|
||||
/// Move constructor
|
||||
Array(Array&&);
|
||||
~Array() override;
|
||||
|
@ -65,8 +65,8 @@ class Array : public Castable<Array, Type> {
|
|||
/// the array size in elements, or nullptr for a runtime array
|
||||
const Expression* const count;
|
||||
|
||||
/// the array decorations
|
||||
const DecorationList decorations;
|
||||
/// the array attributes
|
||||
const AttributeList attributes;
|
||||
};
|
||||
|
||||
} // namespace ast
|
||||
|
|
|
@ -25,7 +25,7 @@ using AstArrayTest = TestHelper;
|
|||
TEST_F(AstArrayTest, CreateSizedArray) {
|
||||
auto* u32 = create<U32>();
|
||||
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->count, count);
|
||||
EXPECT_TRUE(arr->Is<Array>());
|
||||
|
@ -34,7 +34,7 @@ TEST_F(AstArrayTest, CreateSizedArray) {
|
|||
|
||||
TEST_F(AstArrayTest, CreateRuntimeArray) {
|
||||
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->count, nullptr);
|
||||
EXPECT_TRUE(arr->Is<Array>());
|
||||
|
@ -43,26 +43,26 @@ TEST_F(AstArrayTest, CreateRuntimeArray) {
|
|||
|
||||
TEST_F(AstArrayTest, FriendlyName_RuntimeSized) {
|
||||
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>");
|
||||
}
|
||||
|
||||
TEST_F(AstArrayTest, FriendlyName_LiteralSized) {
|
||||
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>");
|
||||
}
|
||||
|
||||
TEST_F(AstArrayTest, FriendlyName_ConstantSized) {
|
||||
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>");
|
||||
}
|
||||
|
||||
TEST_F(AstArrayTest, FriendlyName_WithStride) {
|
||||
auto* i32 = create<I32>();
|
||||
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>");
|
||||
}
|
||||
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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 ast {
|
||||
|
||||
Decoration::~Decoration() = default;
|
||||
Attribute::~Attribute() = default;
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
|
@ -12,8 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_DECORATION_H_
|
||||
#define SRC_AST_DECORATION_H_
|
||||
#ifndef SRC_AST_ATTRIBUTE_H_
|
||||
#define SRC_AST_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -23,43 +23,43 @@
|
|||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// The base class for all decorations
|
||||
class Decoration : public Castable<Decoration, Node> {
|
||||
/// The base class for all attributes
|
||||
class Attribute : public Castable<Attribute, Node> {
|
||||
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;
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
/// @param pid the identifier of the program that owns 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
|
||||
using DecorationList = std::vector<const Decoration*>;
|
||||
/// A list of attributes
|
||||
using AttributeList = std::vector<const Attribute*>;
|
||||
|
||||
/// @param decorations the list of decorations to search
|
||||
/// @returns true if `decorations` includes a decoration of type `T`
|
||||
/// @param attributes the list of attributes to search
|
||||
/// @returns true if `attributes` includes a attribute of type `T`
|
||||
template <typename T>
|
||||
bool HasDecoration(const DecorationList& decorations) {
|
||||
for (auto* deco : decorations) {
|
||||
if (deco->Is<T>()) {
|
||||
bool HasAttribute(const AttributeList& attributes) {
|
||||
for (auto* attr : attributes) {
|
||||
if (attr->Is<T>()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @param decorations the list of decorations to search
|
||||
/// @returns a pointer to `T` from `decorations` if found, otherwise nullptr.
|
||||
/// @param attributes the list of attributes to search
|
||||
/// @returns a pointer to `T` from `attributes` if found, otherwise nullptr.
|
||||
template <typename T>
|
||||
const T* GetDecoration(const DecorationList& decorations) {
|
||||
for (auto* deco : decorations) {
|
||||
if (deco->Is<T>()) {
|
||||
return deco->As<T>();
|
||||
const T* GetAttribute(const AttributeList& attributes) {
|
||||
for (auto* attr : attributes) {
|
||||
if (attr->Is<T>()) {
|
||||
return attr->As<T>();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -68,4 +68,4 @@ const T* GetDecoration(const DecorationList& decorations) {
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_DECORATION_H_
|
||||
#endif // SRC_AST_ATTRIBUTE_H_
|
|
@ -12,32 +12,32 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/location_decoration.h"
|
||||
#include "src/ast/binding_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::LocationDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::BindingAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
LocationDecoration::LocationDecoration(ProgramID pid,
|
||||
BindingAttribute::BindingAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
uint32_t val)
|
||||
: Base(pid, src), value(val) {}
|
||||
|
||||
LocationDecoration::~LocationDecoration() = default;
|
||||
BindingAttribute::~BindingAttribute() = default;
|
||||
|
||||
std::string LocationDecoration::Name() const {
|
||||
return "location";
|
||||
std::string BindingAttribute::Name() const {
|
||||
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
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<LocationDecoration>(src, value);
|
||||
return ctx->dst->create<BindingAttribute>(src, value);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,34 +12,34 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_BINDING_DECORATION_H_
|
||||
#define SRC_AST_BINDING_DECORATION_H_
|
||||
#ifndef SRC_AST_BINDING_ATTRIBUTE_H_
|
||||
#define SRC_AST_BINDING_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A binding decoration
|
||||
class BindingDecoration : public Castable<BindingDecoration, Decoration> {
|
||||
/// A binding attribute
|
||||
class BindingAttribute : public Castable<BindingAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// Constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param value the binding value
|
||||
BindingDecoration(ProgramID pid, const Source& src, uint32_t value);
|
||||
~BindingDecoration() override;
|
||||
BindingAttribute(ProgramID pid, const Source& src, uint32_t value);
|
||||
~BindingAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const BindingDecoration* Clone(CloneContext* ctx) const override;
|
||||
const BindingAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// the binding value
|
||||
const uint32_t value;
|
||||
|
@ -48,4 +48,4 @@ class BindingDecoration : public Castable<BindingDecoration, Decoration> {
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_BINDING_DECORATION_H_
|
||||
#endif // SRC_AST_BINDING_ATTRIBUTE_H_
|
|
@ -12,17 +12,16 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using GroupDecorationTest = TestHelper;
|
||||
using BindingAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(GroupDecorationTest, Creation) {
|
||||
auto* d = create<GroupDecoration>(2);
|
||||
TEST_F(BindingAttributeTest, Creation) {
|
||||
auto* d = create<BindingAttribute>(2);
|
||||
EXPECT_EQ(2u, d->value);
|
||||
}
|
||||
|
|
@ -12,32 +12,30 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/builtin_decoration.h"
|
||||
#include "src/ast/builtin_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
BuiltinDecoration::BuiltinDecoration(ProgramID pid,
|
||||
const Source& src,
|
||||
Builtin b)
|
||||
BuiltinAttribute::BuiltinAttribute(ProgramID pid, const Source& 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";
|
||||
}
|
||||
|
||||
const BuiltinDecoration* BuiltinDecoration::Clone(CloneContext* ctx) const {
|
||||
const BuiltinAttribute* BuiltinAttribute::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<BuiltinDecoration>(src, builtin);
|
||||
return ctx->dst->create<BuiltinAttribute>(src, builtin);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,35 +12,35 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_BUILTIN_DECORATION_H_
|
||||
#define SRC_AST_BUILTIN_DECORATION_H_
|
||||
#ifndef SRC_AST_BUILTIN_ATTRIBUTE_H_
|
||||
#define SRC_AST_BUILTIN_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/attribute.h"
|
||||
#include "src/ast/builtin.h"
|
||||
#include "src/ast/decoration.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A builtin decoration
|
||||
class BuiltinDecoration : public Castable<BuiltinDecoration, Decoration> {
|
||||
/// A builtin attribute
|
||||
class BuiltinAttribute : public Castable<BuiltinAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param builtin the builtin value
|
||||
BuiltinDecoration(ProgramID pid, const Source& src, Builtin builtin);
|
||||
~BuiltinDecoration() override;
|
||||
BuiltinAttribute(ProgramID pid, const Source& src, Builtin builtin);
|
||||
~BuiltinAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const BuiltinDecoration* Clone(CloneContext* ctx) const override;
|
||||
const BuiltinAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The builtin value
|
||||
const Builtin builtin;
|
||||
|
@ -49,4 +49,4 @@ class BuiltinDecoration : public Castable<BuiltinDecoration, Decoration> {
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_BUILTIN_DECORATION_H_
|
||||
#endif // SRC_AST_BUILTIN_ATTRIBUTE_H_
|
|
@ -12,17 +12,16 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using BuiltinDecorationTest = TestHelper;
|
||||
using BuiltinAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(BuiltinDecorationTest, Creation) {
|
||||
auto* d = create<BuiltinDecoration>(Builtin::kFragDepth);
|
||||
TEST_F(BuiltinAttributeTest, Creation) {
|
||||
auto* d = create<BuiltinAttribute>(Builtin::kFragDepth);
|
||||
EXPECT_EQ(Builtin::kFragDepth, d->builtin);
|
||||
}
|
||||
|
|
@ -12,22 +12,22 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::DisableValidationDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::DisableValidationAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
DisableValidationDecoration::DisableValidationDecoration(ProgramID pid,
|
||||
DisableValidationAttribute::DisableValidationAttribute(ProgramID pid,
|
||||
DisabledValidation val)
|
||||
: Base(pid), validation(val) {}
|
||||
|
||||
DisableValidationDecoration::~DisableValidationDecoration() = default;
|
||||
DisableValidationAttribute::~DisableValidationAttribute() = default;
|
||||
|
||||
std::string DisableValidationDecoration::InternalName() const {
|
||||
std::string DisableValidationAttribute::InternalName() const {
|
||||
switch (validation) {
|
||||
case DisabledValidation::kFunctionHasNoBody:
|
||||
return "disable_validation__function_has_no_body";
|
||||
|
@ -39,7 +39,7 @@ std::string DisableValidationDecoration::InternalName() const {
|
|||
return "disable_validation__entry_point_parameter";
|
||||
case DisabledValidation::kIgnoreConstructibleFunctionParameter:
|
||||
return "disable_validation__ignore_constructible_function_parameter";
|
||||
case DisabledValidation::kIgnoreStrideDecoration:
|
||||
case DisabledValidation::kIgnoreStrideAttribute:
|
||||
return "disable_validation__ignore_stride";
|
||||
case DisabledValidation::kIgnoreInvalidPointerArgument:
|
||||
return "disable_validation__ignore_invalid_pointer_argument";
|
||||
|
@ -47,10 +47,10 @@ std::string DisableValidationDecoration::InternalName() const {
|
|||
return "<invalid>";
|
||||
}
|
||||
|
||||
const DisableValidationDecoration* DisableValidationDecoration::Clone(
|
||||
const DisableValidationAttribute* DisableValidationAttribute::Clone(
|
||||
CloneContext* ctx) const {
|
||||
return ctx->dst->ASTNodes().Create<DisableValidationDecoration>(
|
||||
ctx->dst->ID(), validation);
|
||||
return ctx->dst->ASTNodes().Create<DisableValidationAttribute>(ctx->dst->ID(),
|
||||
validation);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,18 +12,18 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_DISABLE_VALIDATION_DECORATION_H_
|
||||
#define SRC_AST_DISABLE_VALIDATION_DECORATION_H_
|
||||
#ifndef SRC_AST_DISABLE_VALIDATION_ATTRIBUTE_H_
|
||||
#define SRC_AST_DISABLE_VALIDATION_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/internal_decoration.h"
|
||||
#include "src/ast/internal_attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// Enumerator of validation features that can be disabled with a
|
||||
/// DisableValidationDecoration decoration.
|
||||
/// DisableValidationAttribute attribute.
|
||||
enum class DisabledValidation {
|
||||
/// When applied to a function, the validator will not complain there is no
|
||||
/// body to a function.
|
||||
|
@ -35,49 +35,49 @@ enum class DisabledValidation {
|
|||
/// declared storage class.
|
||||
kIgnoreStorageClass,
|
||||
/// When applied to an entry-point function parameter, the validator will not
|
||||
/// check for entry IO decorations.
|
||||
/// check for entry IO attributes.
|
||||
kEntryPointParameter,
|
||||
/// When applied to a function parameter, the validator will not
|
||||
/// check if parameter type is constructible
|
||||
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.
|
||||
kIgnoreStrideDecoration,
|
||||
kIgnoreStrideAttribute,
|
||||
/// When applied to a pointer function parameter, the validator will not
|
||||
/// require a function call argument passed for that parameter to have a
|
||||
/// certain form.
|
||||
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
|
||||
/// would otherwise cause validation errors.
|
||||
class DisableValidationDecoration
|
||||
: public Castable<DisableValidationDecoration, InternalDecoration> {
|
||||
class DisableValidationAttribute
|
||||
: public Castable<DisableValidationAttribute, InternalAttribute> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param program_id the identifier of the program that owns this node
|
||||
/// @param validation the validation to disable
|
||||
explicit DisableValidationDecoration(ProgramID program_id,
|
||||
explicit DisableValidationAttribute(ProgramID program_id,
|
||||
DisabledValidation validation);
|
||||
|
||||
/// 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).
|
||||
std::string InternalName() const override;
|
||||
|
||||
/// Performs a deep clone of this object using the CloneContext `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @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;
|
||||
};
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_DISABLE_VALIDATION_DECORATION_H_
|
||||
#endif // SRC_AST_DISABLE_VALIDATION_ATTRIBUTE_H_
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
#include "src/ast/function.h"
|
||||
|
||||
#include "src/ast/stage_decoration.h"
|
||||
#include "src/ast/workgroup_decoration.h"
|
||||
#include "src/ast/stage_attribute.h"
|
||||
#include "src/ast/workgroup_attribute.h"
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::Function);
|
||||
|
@ -29,15 +29,15 @@ Function::Function(ProgramID pid,
|
|||
VariableList parameters,
|
||||
const Type* return_ty,
|
||||
const BlockStatement* b,
|
||||
DecorationList decos,
|
||||
DecorationList return_type_decos)
|
||||
AttributeList attrs,
|
||||
AttributeList return_type_attrs)
|
||||
: Base(pid, src),
|
||||
symbol(sym),
|
||||
params(std::move(parameters)),
|
||||
return_type(return_ty),
|
||||
body(b),
|
||||
decorations(std::move(decos)),
|
||||
return_type_decorations(std::move(return_type_decos)) {
|
||||
attributes(std::move(attrs)),
|
||||
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, body, program_id);
|
||||
for (auto* param : params) {
|
||||
|
@ -46,11 +46,11 @@ Function::Function(ProgramID pid,
|
|||
}
|
||||
TINT_ASSERT(AST, symbol.IsValid());
|
||||
TINT_ASSERT(AST, return_type);
|
||||
for (auto* deco : decorations) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id);
|
||||
for (auto* attr : attributes) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
|
||||
}
|
||||
for (auto* deco : return_type_decorations) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id);
|
||||
for (auto* attr : return_type_attributes) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ Function::Function(Function&&) = default;
|
|||
Function::~Function() = default;
|
||||
|
||||
PipelineStage Function::PipelineStage() const {
|
||||
if (auto* stage = GetDecoration<StageDecoration>(decorations)) {
|
||||
if (auto* stage = GetAttribute<StageAttribute>(attributes)) {
|
||||
return stage->stage;
|
||||
}
|
||||
return PipelineStage::kNone;
|
||||
|
@ -72,9 +72,9 @@ const Function* Function::Clone(CloneContext* ctx) const {
|
|||
auto p = ctx->Clone(params);
|
||||
auto* ret = ctx->Clone(return_type);
|
||||
auto* b = ctx->Clone(body);
|
||||
auto decos = ctx->Clone(decorations);
|
||||
auto ret_decos = ctx->Clone(return_type_decorations);
|
||||
return ctx->dst->create<Function>(src, sym, p, ret, b, decos, ret_decos);
|
||||
auto attrs = ctx->Clone(attributes);
|
||||
auto ret_attrs = ctx->Clone(return_type_attributes);
|
||||
return ctx->dst->create<Function>(src, sym, p, ret, b, attrs, ret_attrs);
|
||||
}
|
||||
|
||||
const Function* FunctionList::Find(Symbol sym) const {
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
#include <utility>
|
||||
#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/builtin_decoration.h"
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/group_decoration.h"
|
||||
#include "src/ast/location_decoration.h"
|
||||
#include "src/ast/builtin_attribute.h"
|
||||
#include "src/ast/group_attribute.h"
|
||||
#include "src/ast/location_attribute.h"
|
||||
#include "src/ast/pipeline_stage.h"
|
||||
#include "src/ast/variable.h"
|
||||
|
||||
|
@ -42,16 +42,16 @@ class Function : public Castable<Function, Node> {
|
|||
/// @param params the function parameters
|
||||
/// @param return_type the return type
|
||||
/// @param body the function body
|
||||
/// @param decorations the function decorations
|
||||
/// @param return_type_decorations the return type decorations
|
||||
/// @param attributes the function attributes
|
||||
/// @param return_type_attributes the return type attributes
|
||||
Function(ProgramID program_id,
|
||||
const Source& source,
|
||||
Symbol symbol,
|
||||
VariableList params,
|
||||
const Type* return_type,
|
||||
const BlockStatement* body,
|
||||
DecorationList decorations,
|
||||
DecorationList return_type_decorations);
|
||||
AttributeList attributes,
|
||||
AttributeList return_type_attributes);
|
||||
/// Move constructor
|
||||
Function(Function&&);
|
||||
|
||||
|
@ -81,11 +81,11 @@ class Function : public Castable<Function, Node> {
|
|||
/// The function body
|
||||
const BlockStatement* const body;
|
||||
|
||||
/// The decorations attached to this function
|
||||
const DecorationList decorations;
|
||||
/// The attributes attached to this function
|
||||
const AttributeList attributes;
|
||||
|
||||
/// The decorations attached to the function return type.
|
||||
const DecorationList return_type_decorations;
|
||||
/// The attributes attached to the function return type.
|
||||
const AttributeList return_type_attributes;
|
||||
};
|
||||
|
||||
/// A list of functions
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
|
||||
#include "gtest/gtest-spi.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/workgroup_decoration.h"
|
||||
#include "src/ast/workgroup_attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
@ -29,7 +29,7 @@ TEST_F(FunctionTest, Creation) {
|
|||
params.push_back(Param("var", ty.i32()));
|
||||
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"));
|
||||
ASSERT_EQ(f->params.size(), 1u);
|
||||
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||
|
@ -41,7 +41,7 @@ TEST_F(FunctionTest, Creation_WithSource) {
|
|||
params.push_back(Param("var", ty.i32()));
|
||||
|
||||
auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(),
|
||||
StatementList{}, DecorationList{});
|
||||
StatementList{}, AttributeList{});
|
||||
auto src = f->source;
|
||||
EXPECT_EQ(src.range.begin.line, 20u);
|
||||
EXPECT_EQ(src.range.begin.column, 2u);
|
||||
|
@ -52,7 +52,7 @@ TEST_F(FunctionTest, Assert_InvalidName) {
|
|||
{
|
||||
ProgramBuilder b;
|
||||
b.Func("", VariableList{}, b.ty.void_(), StatementList{},
|
||||
DecorationList{});
|
||||
AttributeList{});
|
||||
},
|
||||
"internal compiler error");
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ TEST_F(FunctionTest, Assert_Null_ReturnType) {
|
|||
EXPECT_FATAL_FAILURE(
|
||||
{
|
||||
ProgramBuilder b;
|
||||
b.Func("f", VariableList{}, nullptr, StatementList{}, DecorationList{});
|
||||
b.Func("f", VariableList{}, nullptr, StatementList{}, AttributeList{});
|
||||
},
|
||||
"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(nullptr);
|
||||
|
||||
b.Func("f", params, b.ty.void_(), StatementList{}, DecorationList{});
|
||||
b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
|
||||
},
|
||||
"internal compiler error");
|
||||
}
|
||||
|
@ -100,27 +100,27 @@ TEST_F(FunctionTest, Assert_DifferentProgramID_Param) {
|
|||
"internal compiler error");
|
||||
}
|
||||
|
||||
TEST_F(FunctionTest, Assert_DifferentProgramID_Deco) {
|
||||
TEST_F(FunctionTest, Assert_DifferentProgramID_Attr) {
|
||||
EXPECT_FATAL_FAILURE(
|
||||
{
|
||||
ProgramBuilder b1;
|
||||
ProgramBuilder b2;
|
||||
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
|
||||
DecorationList{
|
||||
AttributeList{
|
||||
b2.WorkgroupSize(2, 4, 6),
|
||||
});
|
||||
},
|
||||
"internal compiler error");
|
||||
}
|
||||
|
||||
TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnDeco) {
|
||||
TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnAttr) {
|
||||
EXPECT_FATAL_FAILURE(
|
||||
{
|
||||
ProgramBuilder b1;
|
||||
ProgramBuilder b2;
|
||||
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
|
||||
DecorationList{},
|
||||
DecorationList{
|
||||
AttributeList{},
|
||||
AttributeList{
|
||||
b2.WorkgroupSize(2, 4, 6),
|
||||
});
|
||||
},
|
||||
|
@ -134,7 +134,7 @@ TEST_F(FunctionTest, Assert_NonConstParam) {
|
|||
VariableList params;
|
||||
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");
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ using FunctionListTest = TestHelper;
|
|||
|
||||
TEST_F(FunctionListTest, FindSymbol) {
|
||||
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||
ast::DecorationList{});
|
||||
ast::AttributeList{});
|
||||
FunctionList list;
|
||||
list.Add(func);
|
||||
EXPECT_EQ(func, list.Find(Symbols().Register("main")));
|
||||
|
@ -156,11 +156,11 @@ TEST_F(FunctionListTest, FindSymbolMissing) {
|
|||
|
||||
TEST_F(FunctionListTest, FindSymbolStage) {
|
||||
auto* fs = Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(PipelineStage::kFragment),
|
||||
});
|
||||
auto* vs = Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(PipelineStage::kVertex),
|
||||
});
|
||||
FunctionList list;
|
||||
|
@ -174,7 +174,7 @@ TEST_F(FunctionListTest, FindSymbolStage) {
|
|||
TEST_F(FunctionListTest, FindSymbolStageMissing) {
|
||||
FunctionList list;
|
||||
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(PipelineStage::kFragment),
|
||||
}));
|
||||
EXPECT_EQ(nullptr,
|
||||
|
@ -184,7 +184,7 @@ TEST_F(FunctionListTest, FindSymbolStageMissing) {
|
|||
TEST_F(FunctionListTest, HasStage) {
|
||||
FunctionList list;
|
||||
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(PipelineStage::kFragment),
|
||||
}));
|
||||
EXPECT_TRUE(list.HasStage(PipelineStage::kFragment));
|
||||
|
|
|
@ -12,30 +12,30 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/group_decoration.h"
|
||||
#include "src/ast/group_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::GroupDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::GroupAttribute);
|
||||
|
||||
namespace tint {
|
||||
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) {}
|
||||
|
||||
GroupDecoration::~GroupDecoration() = default;
|
||||
GroupAttribute::~GroupAttribute() = default;
|
||||
|
||||
std::string GroupDecoration::Name() const {
|
||||
std::string GroupAttribute::Name() const {
|
||||
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
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<GroupDecoration>(src, value);
|
||||
return ctx->dst->create<GroupAttribute>(src, value);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,34 +12,34 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_GROUP_DECORATION_H_
|
||||
#define SRC_AST_GROUP_DECORATION_H_
|
||||
#ifndef SRC_AST_GROUP_ATTRIBUTE_H_
|
||||
#define SRC_AST_GROUP_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A group decoration
|
||||
class GroupDecoration : public Castable<GroupDecoration, Decoration> {
|
||||
/// A group attribute
|
||||
class GroupAttribute : public Castable<GroupAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param value the group value
|
||||
GroupDecoration(ProgramID pid, const Source& src, uint32_t value);
|
||||
~GroupDecoration() override;
|
||||
GroupAttribute(ProgramID pid, const Source& src, uint32_t value);
|
||||
~GroupAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const GroupDecoration* Clone(CloneContext* ctx) const override;
|
||||
const GroupAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The group value
|
||||
const uint32_t value;
|
||||
|
@ -48,4 +48,4 @@ class GroupDecoration : public Castable<GroupDecoration, Decoration> {
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_GROUP_DECORATION_H_
|
||||
#endif // SRC_AST_GROUP_ATTRIBUTE_H_
|
|
@ -12,17 +12,17 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
#include "src/ast/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using BindingDecorationTest = TestHelper;
|
||||
using GroupAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(BindingDecorationTest, Creation) {
|
||||
auto* d = create<BindingDecoration>(2);
|
||||
TEST_F(GroupAttributeTest, Creation) {
|
||||
auto* d = create<GroupAttribute>(2);
|
||||
EXPECT_EQ(2u, d->value);
|
||||
}
|
||||
|
|
@ -12,18 +12,18 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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 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";
|
||||
}
|
||||
|
|
@ -12,37 +12,37 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_INTERNAL_DECORATION_H_
|
||||
#define SRC_AST_INTERNAL_DECORATION_H_
|
||||
#ifndef SRC_AST_INTERNAL_ATTRIBUTE_H_
|
||||
#define SRC_AST_INTERNAL_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A decoration used to indicate that a function is tint-internal.
|
||||
/// These decorations are not produced by generators, but instead are usually
|
||||
/// An attribute used to indicate that a function is tint-internal.
|
||||
/// These attributes are not produced by generators, but instead are usually
|
||||
/// created by transforms for consumption by a particular backend.
|
||||
class InternalDecoration : public Castable<InternalDecoration, Decoration> {
|
||||
class InternalAttribute : public Castable<InternalAttribute, Attribute> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param program_id the identifier of the program that owns this node
|
||||
explicit InternalDecoration(ProgramID program_id);
|
||||
explicit InternalAttribute(ProgramID program_id);
|
||||
|
||||
/// 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).
|
||||
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;
|
||||
};
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_INTERNAL_DECORATION_H_
|
||||
#endif // SRC_AST_INTERNAL_ATTRIBUTE_H_
|
|
@ -12,34 +12,34 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/interpolate_decoration.h"
|
||||
#include "src/ast/interpolate_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::InterpolateDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::InterpolateAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
InterpolateDecoration::InterpolateDecoration(ProgramID pid,
|
||||
InterpolateAttribute::InterpolateAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
InterpolationType ty,
|
||||
InterpolationSampling 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";
|
||||
}
|
||||
|
||||
const InterpolateDecoration* InterpolateDecoration::Clone(
|
||||
const InterpolateAttribute* InterpolateAttribute::Clone(
|
||||
CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
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) {
|
|
@ -12,13 +12,13 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_INTERPOLATE_DECORATION_H_
|
||||
#define SRC_AST_INTERPOLATE_DECORATION_H_
|
||||
#ifndef SRC_AST_INTERPOLATE_ATTRIBUTE_H_
|
||||
#define SRC_AST_INTERPOLATE_ATTRIBUTE_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
@ -29,29 +29,28 @@ enum class InterpolationType { kPerspective, kLinear, kFlat };
|
|||
/// The interpolation sampling.
|
||||
enum class InterpolationSampling { kNone = -1, kCenter, kCentroid, kSample };
|
||||
|
||||
/// An interpolate decoration
|
||||
class InterpolateDecoration
|
||||
: public Castable<InterpolateDecoration, Decoration> {
|
||||
/// An interpolate attribute
|
||||
class InterpolateAttribute : public Castable<InterpolateAttribute, Attribute> {
|
||||
public:
|
||||
/// Create an interpolate decoration.
|
||||
/// Create an interpolate attribute.
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param type the interpolation type
|
||||
/// @param sampling the interpolation sampling
|
||||
InterpolateDecoration(ProgramID pid,
|
||||
InterpolateAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
InterpolationType type,
|
||||
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;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const InterpolateDecoration* Clone(CloneContext* ctx) const override;
|
||||
const InterpolateAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The interpolation type
|
||||
const InterpolationType type;
|
||||
|
@ -73,4 +72,4 @@ std::ostream& operator<<(std::ostream& out, InterpolationSampling sampling);
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_INTERPOLATE_DECORATION_H_
|
||||
#endif // SRC_AST_INTERPOLATE_ATTRIBUTE_H_
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/interpolate_decoration.h"
|
||||
#include "src/ast/interpolate_attribute.h"
|
||||
|
||||
#include "src/ast/test_helper.h"
|
||||
|
||||
|
@ -20,10 +20,10 @@ namespace tint {
|
|||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using InterpolateDecorationTest = TestHelper;
|
||||
using InterpolateAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(InterpolateDecorationTest, Creation) {
|
||||
auto* d = create<InterpolateDecoration>(InterpolationType::kLinear,
|
||||
TEST_F(InterpolateAttributeTest, Creation) {
|
||||
auto* d = create<InterpolateAttribute>(InterpolationType::kLinear,
|
||||
InterpolationSampling::kCenter);
|
||||
EXPECT_EQ(InterpolationType::kLinear, d->type);
|
||||
EXPECT_EQ(InterpolationSampling::kCenter, d->sampling);
|
|
@ -151,36 +151,36 @@ const ast::Type* TextureOverloadCase::BuildResultVectorComponentType(
|
|||
|
||||
const ast::Variable* TextureOverloadCase::BuildTextureVariable(
|
||||
ProgramBuilder* b) const {
|
||||
DecorationList decos = {
|
||||
b->create<ast::GroupDecoration>(0),
|
||||
b->create<ast::BindingDecoration>(0),
|
||||
AttributeList attrs = {
|
||||
b->create<ast::GroupAttribute>(0),
|
||||
b->create<ast::BindingAttribute>(0),
|
||||
};
|
||||
switch (texture_kind) {
|
||||
case ast::intrinsic::test::TextureKind::kRegular:
|
||||
return b->Global("texture",
|
||||
b->ty.sampled_texture(texture_dimension,
|
||||
BuildResultVectorComponentType(b)),
|
||||
decos);
|
||||
attrs);
|
||||
|
||||
case ast::intrinsic::test::TextureKind::kDepth:
|
||||
return b->Global("texture", b->ty.depth_texture(texture_dimension),
|
||||
decos);
|
||||
attrs);
|
||||
|
||||
case ast::intrinsic::test::TextureKind::kDepthMultisampled:
|
||||
return b->Global("texture",
|
||||
b->ty.depth_multisampled_texture(texture_dimension),
|
||||
decos);
|
||||
attrs);
|
||||
|
||||
case ast::intrinsic::test::TextureKind::kMultisampled:
|
||||
return b->Global(
|
||||
"texture",
|
||||
b->ty.multisampled_texture(texture_dimension,
|
||||
BuildResultVectorComponentType(b)),
|
||||
decos);
|
||||
attrs);
|
||||
|
||||
case ast::intrinsic::test::TextureKind::kStorage: {
|
||||
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(
|
||||
ProgramBuilder* b) const {
|
||||
DecorationList decos = {
|
||||
b->create<ast::GroupDecoration>(0),
|
||||
b->create<ast::BindingDecoration>(1),
|
||||
AttributeList attrs = {
|
||||
b->create<ast::GroupAttribute>(0),
|
||||
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() {
|
||||
|
|
|
@ -12,28 +12,28 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/invariant_decoration.h"
|
||||
#include "src/ast/invariant_attribute.h"
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::InvariantDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::InvariantAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
InvariantDecoration::InvariantDecoration(ProgramID pid, const Source& src)
|
||||
InvariantAttribute::InvariantAttribute(ProgramID pid, const Source& src)
|
||||
: Base(pid, src) {}
|
||||
|
||||
InvariantDecoration::~InvariantDecoration() = default;
|
||||
InvariantAttribute::~InvariantAttribute() = default;
|
||||
|
||||
std::string InvariantDecoration::Name() const {
|
||||
std::string InvariantAttribute::Name() const {
|
||||
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
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<InvariantDecoration>(src);
|
||||
return ctx->dst->create<InvariantAttribute>(src);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,36 +12,36 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_INVARIANT_DECORATION_H_
|
||||
#define SRC_AST_INVARIANT_DECORATION_H_
|
||||
#ifndef SRC_AST_INVARIANT_ATTRIBUTE_H_
|
||||
#define SRC_AST_INVARIANT_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// The invariant attribute
|
||||
class InvariantDecoration : public Castable<InvariantDecoration, Decoration> {
|
||||
class InvariantAttribute : public Castable<InvariantAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
InvariantDecoration(ProgramID pid, const Source& src);
|
||||
~InvariantDecoration() override;
|
||||
InvariantAttribute(ProgramID pid, const Source& src);
|
||||
~InvariantAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const InvariantDecoration* Clone(CloneContext* ctx) const override;
|
||||
const InvariantAttribute* Clone(CloneContext* ctx) const override;
|
||||
};
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_INVARIANT_DECORATION_H_
|
||||
#endif // SRC_AST_INVARIANT_ATTRIBUTE_H_
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/invariant_decoration.h"
|
||||
#include "src/ast/invariant_attribute.h"
|
||||
|
||||
#include "src/ast/test_helper.h"
|
||||
|
||||
|
@ -20,7 +20,7 @@ namespace tint {
|
|||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using InvariantDecorationTest = TestHelper;
|
||||
using InvariantAttributeTest = TestHelper;
|
||||
|
||||
} // namespace
|
||||
} // namespace ast
|
|
@ -12,32 +12,32 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/binding_decoration.h"
|
||||
#include "src/ast/location_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::BindingDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::LocationAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
BindingDecoration::BindingDecoration(ProgramID pid,
|
||||
LocationAttribute::LocationAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
uint32_t val)
|
||||
: Base(pid, src), value(val) {}
|
||||
|
||||
BindingDecoration::~BindingDecoration() = default;
|
||||
LocationAttribute::~LocationAttribute() = default;
|
||||
|
||||
std::string BindingDecoration::Name() const {
|
||||
return "binding";
|
||||
std::string LocationAttribute::Name() const {
|
||||
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
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<BindingDecoration>(src, value);
|
||||
return ctx->dst->create<LocationAttribute>(src, value);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,34 +12,34 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_LOCATION_DECORATION_H_
|
||||
#define SRC_AST_LOCATION_DECORATION_H_
|
||||
#ifndef SRC_AST_LOCATION_ATTRIBUTE_H_
|
||||
#define SRC_AST_LOCATION_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A location decoration
|
||||
class LocationDecoration : public Castable<LocationDecoration, Decoration> {
|
||||
/// A location attribute
|
||||
class LocationAttribute : public Castable<LocationAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param value the location value
|
||||
LocationDecoration(ProgramID pid, const Source& src, uint32_t value);
|
||||
~LocationDecoration() override;
|
||||
LocationAttribute(ProgramID pid, const Source& src, uint32_t value);
|
||||
~LocationAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const LocationDecoration* Clone(CloneContext* ctx) const override;
|
||||
const LocationAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The location value
|
||||
const uint32_t value;
|
||||
|
@ -48,4 +48,4 @@ class LocationDecoration : public Castable<LocationDecoration, Decoration> {
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_LOCATION_DECORATION_H_
|
||||
#endif // SRC_AST_LOCATION_ATTRIBUTE_H_
|
|
@ -12,17 +12,17 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
#include "src/ast/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using LocationDecorationTest = TestHelper;
|
||||
using LocationAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(LocationDecorationTest, Creation) {
|
||||
auto* d = create<LocationDecoration>(2);
|
||||
TEST_F(LocationAttributeTest, Creation) {
|
||||
auto* d = create<LocationAttribute>(2);
|
||||
EXPECT_EQ(2u, d->value);
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ TEST_F(ModuleTest, Creation) {
|
|||
|
||||
TEST_F(ModuleTest, LookupFunction) {
|
||||
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||
ast::DecorationList{});
|
||||
ast::AttributeList{});
|
||||
|
||||
Program program(std::move(*this));
|
||||
EXPECT_EQ(func,
|
||||
|
@ -66,7 +66,7 @@ TEST_F(ModuleTest, Assert_DifferentProgramID_Function) {
|
|||
ProgramBuilder b2;
|
||||
b1.AST().AddFunction(b2.create<ast::Function>(
|
||||
b2.Symbols().Register("func"), VariableList{}, b2.ty.f32(),
|
||||
b2.Block(), DecorationList{}, DecorationList{}));
|
||||
b2.Block(), AttributeList{}, AttributeList{}));
|
||||
},
|
||||
"internal compiler error");
|
||||
}
|
||||
|
|
|
@ -12,38 +12,38 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::OverrideDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::OverrideAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
OverrideDecoration::OverrideDecoration(ProgramID pid, const Source& src)
|
||||
OverrideAttribute::OverrideAttribute(ProgramID pid, const Source& src)
|
||||
: Base(pid, src), has_value(false), value(0) {}
|
||||
|
||||
OverrideDecoration::OverrideDecoration(ProgramID pid,
|
||||
OverrideAttribute::OverrideAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
uint32_t 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";
|
||||
}
|
||||
|
||||
const OverrideDecoration* OverrideDecoration::Clone(CloneContext* ctx) const {
|
||||
const OverrideAttribute* OverrideAttribute::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
if (has_value) {
|
||||
return ctx->dst->create<OverrideDecoration>(src, value);
|
||||
return ctx->dst->create<OverrideAttribute>(src, value);
|
||||
} else {
|
||||
return ctx->dst->create<OverrideDecoration>(src);
|
||||
return ctx->dst->create<OverrideAttribute>(src);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,38 +12,38 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_OVERRIDE_DECORATION_H_
|
||||
#define SRC_AST_OVERRIDE_DECORATION_H_
|
||||
#ifndef SRC_AST_OVERRIDE_ATTRIBUTE_H_
|
||||
#define SRC_AST_OVERRIDE_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// An override decoration
|
||||
class OverrideDecoration : public Castable<OverrideDecoration, Decoration> {
|
||||
/// An override attribute
|
||||
class OverrideAttribute : public Castable<OverrideAttribute, Attribute> {
|
||||
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 src the source of this node
|
||||
OverrideDecoration(ProgramID pid, const Source& src);
|
||||
/// Create an override decoration with a specific id value.
|
||||
OverrideAttribute(ProgramID pid, const Source& src);
|
||||
/// Create an override attribute with a specific id value.
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param val the override value
|
||||
OverrideDecoration(ProgramID pid, const Source& src, uint32_t val);
|
||||
~OverrideDecoration() override;
|
||||
OverrideAttribute(ProgramID pid, const Source& src, uint32_t val);
|
||||
~OverrideAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @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
|
||||
const bool has_value;
|
||||
|
@ -55,4 +55,4 @@ class OverrideDecoration : public Castable<OverrideDecoration, Decoration> {
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_OVERRIDE_DECORATION_H_
|
||||
#endif // SRC_AST_OVERRIDE_ATTRIBUTE_H_
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
|
||||
#include "src/ast/test_helper.h"
|
||||
|
||||
|
@ -20,16 +20,16 @@ namespace tint {
|
|||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using OverrideDecorationTest = TestHelper;
|
||||
using OverrideAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(OverrideDecorationTest, Creation_WithValue) {
|
||||
auto* d = create<OverrideDecoration>(12);
|
||||
TEST_F(OverrideAttributeTest, Creation_WithValue) {
|
||||
auto* d = create<OverrideAttribute>(12);
|
||||
EXPECT_TRUE(d->has_value);
|
||||
EXPECT_EQ(12u, d->value);
|
||||
}
|
||||
|
||||
TEST_F(OverrideDecorationTest, Creation_WithoutValue) {
|
||||
auto* d = create<OverrideDecoration>();
|
||||
TEST_F(OverrideAttributeTest, Creation_WithoutValue) {
|
||||
auto* d = create<OverrideAttribute>();
|
||||
EXPECT_FALSE(d->has_value);
|
||||
}
|
||||
|
|
@ -12,32 +12,32 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/stage_decoration.h"
|
||||
#include "src/ast/stage_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StageDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StageAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
StageDecoration::StageDecoration(ProgramID pid,
|
||||
StageAttribute::StageAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
PipelineStage s)
|
||||
: Base(pid, src), stage(s) {}
|
||||
|
||||
StageDecoration::~StageDecoration() = default;
|
||||
StageAttribute::~StageAttribute() = default;
|
||||
|
||||
std::string StageDecoration::Name() const {
|
||||
std::string StageAttribute::Name() const {
|
||||
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
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<StageDecoration>(src, stage);
|
||||
return ctx->dst->create<StageAttribute>(src, stage);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,37 +12,37 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_STAGE_DECORATION_H_
|
||||
#define SRC_AST_STAGE_DECORATION_H_
|
||||
#ifndef SRC_AST_STAGE_ATTRIBUTE_H_
|
||||
#define SRC_AST_STAGE_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
#include "src/ast/pipeline_stage.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A workgroup decoration
|
||||
class StageDecoration : public Castable<StageDecoration, Decoration> {
|
||||
/// A workgroup attribute
|
||||
class StageAttribute : public Castable<StageAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @param program_id the identifier of the program that owns this node
|
||||
/// @param stage the pipeline stage
|
||||
/// @param source the source of this decoration
|
||||
StageDecoration(ProgramID program_id,
|
||||
/// @param source the source of this attribute
|
||||
StageAttribute(ProgramID program_id,
|
||||
const Source& source,
|
||||
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;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const StageDecoration* Clone(CloneContext* ctx) const override;
|
||||
const StageAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The pipeline stage
|
||||
const PipelineStage stage;
|
||||
|
@ -51,4 +51,4 @@ class StageDecoration : public Castable<StageDecoration, Decoration> {
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_STAGE_DECORATION_H_
|
||||
#endif // SRC_AST_STAGE_ATTRIBUTE_H_
|
|
@ -12,19 +12,19 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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/workgroup_decoration.h"
|
||||
#include "src/ast/workgroup_attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using StageDecorationTest = TestHelper;
|
||||
using StageAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(StageDecorationTest, Creation_1param) {
|
||||
auto* d = create<StageDecoration>(PipelineStage::kFragment);
|
||||
TEST_F(StageAttributeTest, Creation_1param) {
|
||||
auto* d = create<StageAttribute>(PipelineStage::kFragment);
|
||||
EXPECT_EQ(d->stage, PipelineStage::kFragment);
|
||||
}
|
||||
|
|
@ -12,30 +12,30 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/stride_decoration.h"
|
||||
#include "src/ast/stride_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StrideDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StrideAttribute);
|
||||
|
||||
namespace tint {
|
||||
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) {}
|
||||
|
||||
StrideDecoration::~StrideDecoration() = default;
|
||||
StrideAttribute::~StrideAttribute() = default;
|
||||
|
||||
std::string StrideDecoration::Name() const {
|
||||
std::string StrideAttribute::Name() const {
|
||||
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
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<StrideDecoration>(src, stride);
|
||||
return ctx->dst->create<StrideAttribute>(src, stride);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,34 +12,34 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_STRIDE_DECORATION_H_
|
||||
#define SRC_AST_STRIDE_DECORATION_H_
|
||||
#ifndef SRC_AST_STRIDE_ATTRIBUTE_H_
|
||||
#define SRC_AST_STRIDE_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A stride decoration
|
||||
class StrideDecoration : public Castable<StrideDecoration, Decoration> {
|
||||
/// A stride attribute
|
||||
class StrideAttribute : public Castable<StrideAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param stride the stride value
|
||||
StrideDecoration(ProgramID pid, const Source& src, uint32_t stride);
|
||||
~StrideDecoration() override;
|
||||
StrideAttribute(ProgramID pid, const Source& src, uint32_t stride);
|
||||
~StrideAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const StrideDecoration* Clone(CloneContext* ctx) const override;
|
||||
const StrideAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The stride value
|
||||
const uint32_t stride;
|
||||
|
@ -48,4 +48,4 @@ class StrideDecoration : public Castable<StrideDecoration, Decoration> {
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_STRIDE_DECORATION_H_
|
||||
#endif // SRC_AST_STRIDE_ATTRIBUTE_H_
|
|
@ -18,15 +18,15 @@ namespace tint {
|
|||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using StrideDecorationTest = TestHelper;
|
||||
using StrideAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(StrideDecorationTest, Creation) {
|
||||
auto* d = create<StrideDecoration>(2);
|
||||
TEST_F(StrideAttributeTest, Creation) {
|
||||
auto* d = create<StrideAttribute>(2);
|
||||
EXPECT_EQ(2u, d->stride);
|
||||
}
|
||||
|
||||
TEST_F(StrideDecorationTest, Source) {
|
||||
auto* d = create<StrideDecoration>(
|
||||
TEST_F(StrideAttributeTest, Source) {
|
||||
auto* d = create<StrideAttribute>(
|
||||
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.column, 2u);
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/struct_block_decoration.h"
|
||||
#include "src/ast/struct_block_attribute.h"
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::Struct);
|
||||
|
@ -28,15 +28,15 @@ Struct::Struct(ProgramID pid,
|
|||
const Source& src,
|
||||
Symbol n,
|
||||
StructMemberList m,
|
||||
DecorationList decos)
|
||||
: Base(pid, src, n), members(std::move(m)), decorations(std::move(decos)) {
|
||||
AttributeList attrs)
|
||||
: Base(pid, src, n), members(std::move(m)), attributes(std::move(attrs)) {
|
||||
for (auto* mem : members) {
|
||||
TINT_ASSERT(AST, mem);
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, mem, program_id);
|
||||
}
|
||||
for (auto* deco : decorations) {
|
||||
TINT_ASSERT(AST, deco);
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id);
|
||||
for (auto* attr : attributes) {
|
||||
TINT_ASSERT(AST, attr);
|
||||
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 n = ctx->Clone(name);
|
||||
auto mem = ctx->Clone(members);
|
||||
auto decos = ctx->Clone(decorations);
|
||||
return ctx->dst->create<Struct>(src, n, mem, decos);
|
||||
auto attrs = ctx->Clone(attributes);
|
||||
return ctx->dst->create<Struct>(src, n, mem, attrs);
|
||||
}
|
||||
|
||||
} // namespace ast
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
#include "src/ast/struct_member.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 name The name of the structure
|
||||
/// @param members The struct members
|
||||
/// @param decorations The struct decorations
|
||||
/// @param attributes The struct attributes
|
||||
Struct(ProgramID pid,
|
||||
const Source& src,
|
||||
Symbol name,
|
||||
StructMemberList members,
|
||||
DecorationList decorations);
|
||||
AttributeList attributes);
|
||||
/// Move constructor
|
||||
Struct(Struct&&);
|
||||
|
||||
|
@ -53,8 +53,8 @@ class Struct : public Castable<Struct, TypeDecl> {
|
|||
/// The members
|
||||
const StructMemberList members;
|
||||
|
||||
/// The struct decorations
|
||||
const DecorationList decorations;
|
||||
/// The struct attributes
|
||||
const AttributeList attributes;
|
||||
};
|
||||
|
||||
} // namespace ast
|
||||
|
|
|
@ -12,31 +12,31 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/struct_block_decoration.h"
|
||||
#include "src/ast/struct_block_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructBlockDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructBlockAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
StructBlockDecoration::StructBlockDecoration(ProgramID pid, const Source& src)
|
||||
StructBlockAttribute::StructBlockAttribute(ProgramID pid, const Source& src)
|
||||
: Base(pid, src) {}
|
||||
|
||||
StructBlockDecoration::~StructBlockDecoration() = default;
|
||||
StructBlockAttribute::~StructBlockAttribute() = default;
|
||||
|
||||
std::string StructBlockDecoration::Name() const {
|
||||
std::string StructBlockAttribute::Name() const {
|
||||
return "block";
|
||||
}
|
||||
|
||||
const StructBlockDecoration* StructBlockDecoration::Clone(
|
||||
const StructBlockAttribute* StructBlockAttribute::Clone(
|
||||
CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<StructBlockDecoration>(src);
|
||||
return ctx->dst->create<StructBlockAttribute>(src);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,38 +12,37 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
||||
#define SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
||||
#ifndef SRC_AST_STRUCT_BLOCK_ATTRIBUTE_H_
|
||||
#define SRC_AST_STRUCT_BLOCK_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// The struct decorations
|
||||
class StructBlockDecoration
|
||||
: public Castable<StructBlockDecoration, Decoration> {
|
||||
/// The struct block attribute
|
||||
class StructBlockAttribute : public Castable<StructBlockAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// Constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
StructBlockDecoration(ProgramID pid, const Source& src);
|
||||
~StructBlockDecoration() override;
|
||||
StructBlockAttribute(ProgramID pid, const Source& src);
|
||||
~StructBlockAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const StructBlockDecoration* Clone(CloneContext* ctx) const override;
|
||||
const StructBlockAttribute* Clone(CloneContext* ctx) const override;
|
||||
};
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
||||
#endif // SRC_AST_STRUCT_BLOCK_ATTRIBUTE_H_
|
|
@ -25,14 +25,14 @@ StructMember::StructMember(ProgramID pid,
|
|||
const Source& src,
|
||||
const Symbol& sym,
|
||||
const ast::Type* ty,
|
||||
DecorationList decos)
|
||||
: Base(pid, src), symbol(sym), type(ty), decorations(std::move(decos)) {
|
||||
AttributeList attrs)
|
||||
: Base(pid, src), symbol(sym), type(ty), attributes(std::move(attrs)) {
|
||||
TINT_ASSERT(AST, type);
|
||||
TINT_ASSERT(AST, symbol.IsValid());
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
|
||||
for (auto* deco : decorations) {
|
||||
TINT_ASSERT(AST, deco);
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id);
|
||||
for (auto* attr : attributes) {
|
||||
TINT_ASSERT(AST, attr);
|
||||
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 sym = ctx->Clone(symbol);
|
||||
auto* ty = ctx->Clone(type);
|
||||
auto decos = ctx->Clone(decorations);
|
||||
return ctx->dst->create<StructMember>(src, sym, ty, decos);
|
||||
auto attrs = ctx->Clone(attributes);
|
||||
return ctx->dst->create<StructMember>(src, sym, ty, attrs);
|
||||
}
|
||||
|
||||
} // namespace ast
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
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 sym The struct member symbol
|
||||
/// @param type The struct member type
|
||||
/// @param decorations The struct member decorations
|
||||
/// @param attributes The struct member attributes
|
||||
StructMember(ProgramID pid,
|
||||
const Source& src,
|
||||
const Symbol& sym,
|
||||
const ast::Type* type,
|
||||
DecorationList decorations);
|
||||
AttributeList attributes);
|
||||
/// Move constructor
|
||||
StructMember(StructMember&&);
|
||||
|
||||
|
@ -57,8 +57,8 @@ class StructMember : public Castable<StructMember, Node> {
|
|||
/// The type
|
||||
const ast::Type* const type;
|
||||
|
||||
/// The decorations
|
||||
const DecorationList decorations;
|
||||
/// The attributes
|
||||
const AttributeList attributes;
|
||||
};
|
||||
|
||||
/// A list of struct members
|
||||
|
|
|
@ -12,34 +12,34 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/struct_member_size_decoration.h"
|
||||
#include "src/ast/struct_member_align_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/clone_context.h"
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberSizeDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberAlignAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
StructMemberSizeDecoration::StructMemberSizeDecoration(ProgramID pid,
|
||||
StructMemberAlignAttribute::StructMemberAlignAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
uint32_t sz)
|
||||
: Base(pid, src), size(sz) {}
|
||||
uint32_t a)
|
||||
: Base(pid, src), align(a) {}
|
||||
|
||||
StructMemberSizeDecoration::~StructMemberSizeDecoration() = default;
|
||||
StructMemberAlignAttribute::~StructMemberAlignAttribute() = default;
|
||||
|
||||
std::string StructMemberSizeDecoration::Name() const {
|
||||
return "size";
|
||||
std::string StructMemberAlignAttribute::Name() const {
|
||||
return "align";
|
||||
}
|
||||
|
||||
const StructMemberSizeDecoration* StructMemberSizeDecoration::Clone(
|
||||
const StructMemberAlignAttribute* StructMemberAlignAttribute::Clone(
|
||||
CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<StructMemberSizeDecoration>(src, size);
|
||||
return ctx->dst->create<StructMemberAlignAttribute>(src, align);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,36 +12,36 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
|
||||
#define SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
|
||||
#ifndef SRC_AST_STRUCT_MEMBER_ALIGN_ATTRIBUTE_H_
|
||||
#define SRC_AST_STRUCT_MEMBER_ALIGN_ATTRIBUTE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A struct member align decoration
|
||||
class StructMemberAlignDecoration
|
||||
: public Castable<StructMemberAlignDecoration, Decoration> {
|
||||
/// A struct member align attribute
|
||||
class StructMemberAlignAttribute
|
||||
: public Castable<StructMemberAlignAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param align the align value
|
||||
StructMemberAlignDecoration(ProgramID pid, const Source& src, uint32_t align);
|
||||
~StructMemberAlignDecoration() override;
|
||||
StructMemberAlignAttribute(ProgramID pid, const Source& src, uint32_t align);
|
||||
~StructMemberAlignAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const StructMemberAlignDecoration* Clone(CloneContext* ctx) const override;
|
||||
const StructMemberAlignAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The align value
|
||||
const uint32_t align;
|
||||
|
@ -50,4 +50,4 @@ class StructMemberAlignDecoration
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
|
||||
#endif // SRC_AST_STRUCT_MEMBER_ALIGN_ATTRIBUTE_H_
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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"
|
||||
|
||||
|
@ -20,10 +20,10 @@ namespace tint {
|
|||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using StructMemberAlignDecorationTest = TestHelper;
|
||||
using StructMemberAlignAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(StructMemberAlignDecorationTest, Creation) {
|
||||
auto* d = create<StructMemberAlignDecoration>(2);
|
||||
TEST_F(StructMemberAlignAttributeTest, Creation) {
|
||||
auto* d = create<StructMemberAlignAttribute>(2);
|
||||
EXPECT_EQ(2u, d->align);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2021 The Tint Authors.
|
||||
// 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.
|
||||
|
@ -12,34 +12,33 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/struct_member_align_decoration.h"
|
||||
#include "src/ast/struct_member_offset_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/clone_context.h"
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberAlignDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberOffsetAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
StructMemberAlignDecoration::StructMemberAlignDecoration(ProgramID pid,
|
||||
StructMemberOffsetAttribute::StructMemberOffsetAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
uint32_t a)
|
||||
: Base(pid, src), align(a) {}
|
||||
uint32_t o)
|
||||
: Base(pid, src), offset(o) {}
|
||||
|
||||
StructMemberAlignDecoration::~StructMemberAlignDecoration() = default;
|
||||
StructMemberOffsetAttribute::~StructMemberOffsetAttribute() = default;
|
||||
|
||||
std::string StructMemberAlignDecoration::Name() const {
|
||||
return "align";
|
||||
std::string StructMemberOffsetAttribute::Name() const {
|
||||
return "offset";
|
||||
}
|
||||
|
||||
const StructMemberAlignDecoration* StructMemberAlignDecoration::Clone(
|
||||
const StructMemberOffsetAttribute* StructMemberOffsetAttribute::Clone(
|
||||
CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<StructMemberAlignDecoration>(src, align);
|
||||
return ctx->dst->create<StructMemberOffsetAttribute>(src, offset);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,46 +12,46 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
||||
#define SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
||||
#ifndef SRC_AST_STRUCT_MEMBER_OFFSET_ATTRIBUTE_H_
|
||||
#define SRC_AST_STRUCT_MEMBER_OFFSET_ATTRIBUTE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A struct member offset decoration
|
||||
/// @note The WGSL spec removed the `@offset(n)` decoration for `@size(n)`
|
||||
/// A struct member offset attribute
|
||||
/// @note The WGSL spec removed the `@offset(n)` attribute for `@size(n)`
|
||||
/// 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
|
||||
/// 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)` /
|
||||
/// `@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.
|
||||
class StructMemberOffsetDecoration
|
||||
: public Castable<StructMemberOffsetDecoration, Decoration> {
|
||||
class StructMemberOffsetAttribute
|
||||
: public Castable<StructMemberOffsetAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param offset the offset value
|
||||
StructMemberOffsetDecoration(ProgramID pid,
|
||||
StructMemberOffsetAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
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;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const StructMemberOffsetDecoration* Clone(CloneContext* ctx) const override;
|
||||
const StructMemberOffsetAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The offset value
|
||||
const uint32_t offset;
|
||||
|
@ -60,4 +60,4 @@ class StructMemberOffsetDecoration
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
||||
#endif // SRC_AST_STRUCT_MEMBER_OFFSET_ATTRIBUTE_H_
|
|
@ -18,10 +18,10 @@ namespace tint {
|
|||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using StructMemberOffsetDecorationTest = TestHelper;
|
||||
using StructMemberOffsetAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(StructMemberOffsetDecorationTest, Creation) {
|
||||
auto* d = create<StructMemberOffsetDecoration>(2);
|
||||
TEST_F(StructMemberOffsetAttributeTest, Creation) {
|
||||
auto* d = create<StructMemberOffsetAttribute>(2);
|
||||
EXPECT_EQ(2u, d->offset);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
// Copyright 2021 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.
|
||||
|
@ -12,33 +12,34 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/struct_member_offset_decoration.h"
|
||||
#include "src/ast/struct_member_size_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/clone_context.h"
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberOffsetDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberSizeAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
StructMemberOffsetDecoration::StructMemberOffsetDecoration(ProgramID pid,
|
||||
StructMemberSizeAttribute::StructMemberSizeAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
uint32_t o)
|
||||
: Base(pid, src), offset(o) {}
|
||||
uint32_t sz)
|
||||
: Base(pid, src), size(sz) {}
|
||||
|
||||
StructMemberOffsetDecoration::~StructMemberOffsetDecoration() = default;
|
||||
StructMemberSizeAttribute::~StructMemberSizeAttribute() = default;
|
||||
|
||||
std::string StructMemberOffsetDecoration::Name() const {
|
||||
return "offset";
|
||||
std::string StructMemberSizeAttribute::Name() const {
|
||||
return "size";
|
||||
}
|
||||
|
||||
const StructMemberOffsetDecoration* StructMemberOffsetDecoration::Clone(
|
||||
const StructMemberSizeAttribute* StructMemberSizeAttribute::Clone(
|
||||
CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
return ctx->dst->create<StructMemberOffsetDecoration>(src, offset);
|
||||
return ctx->dst->create<StructMemberSizeAttribute>(src, size);
|
||||
}
|
||||
|
||||
} // namespace ast
|
|
@ -12,36 +12,36 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
|
||||
#define SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
|
||||
#ifndef SRC_AST_STRUCT_MEMBER_SIZE_ATTRIBUTE_H_
|
||||
#define SRC_AST_STRUCT_MEMBER_SIZE_ATTRIBUTE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A struct member size decoration
|
||||
class StructMemberSizeDecoration
|
||||
: public Castable<StructMemberSizeDecoration, Decoration> {
|
||||
/// A struct member size attribute
|
||||
class StructMemberSizeAttribute
|
||||
: public Castable<StructMemberSizeAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param size the size value
|
||||
StructMemberSizeDecoration(ProgramID pid, const Source& src, uint32_t size);
|
||||
~StructMemberSizeDecoration() override;
|
||||
StructMemberSizeAttribute(ProgramID pid, const Source& src, uint32_t size);
|
||||
~StructMemberSizeAttribute() override;
|
||||
|
||||
/// @returns the WGSL name for the decoration
|
||||
/// @returns the WGSL name for the attribute
|
||||
std::string Name() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const StructMemberSizeDecoration* Clone(CloneContext* ctx) const override;
|
||||
const StructMemberSizeAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The size value
|
||||
const uint32_t size;
|
||||
|
@ -50,4 +50,4 @@ class StructMemberSizeDecoration
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
|
||||
#endif // SRC_AST_STRUCT_MEMBER_SIZE_ATTRIBUTE_H_
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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"
|
||||
|
||||
|
@ -20,10 +20,10 @@ namespace tint {
|
|||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using StructMemberOffsetDecorationTest = TestHelper;
|
||||
using StructMemberSizeAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(StructMemberOffsetDecorationTest, Creation) {
|
||||
auto* d = create<StructMemberSizeDecoration>(2);
|
||||
TEST_F(StructMemberSizeAttributeTest, Creation) {
|
||||
auto* d = create<StructMemberSizeAttribute>(2);
|
||||
EXPECT_EQ(2u, d->size);
|
||||
}
|
||||
|
|
@ -25,8 +25,8 @@ TEST_F(StructMemberTest, Creation) {
|
|||
auto* st = Member("a", ty.i32(), {MemberSize(4)});
|
||||
EXPECT_EQ(st->symbol, Symbol(1, ID()));
|
||||
EXPECT_TRUE(st->type->Is<ast::I32>());
|
||||
EXPECT_EQ(st->decorations.size(), 1u);
|
||||
EXPECT_TRUE(st->decorations[0]->Is<StructMemberSizeDecoration>());
|
||||
EXPECT_EQ(st->attributes.size(), 1u);
|
||||
EXPECT_TRUE(st->attributes[0]->Is<StructMemberSizeAttribute>());
|
||||
EXPECT_EQ(st->source.range.begin.line, 0u);
|
||||
EXPECT_EQ(st->source.range.begin.column, 0u);
|
||||
EXPECT_EQ(st->source.range.end.line, 0u);
|
||||
|
@ -39,7 +39,7 @@ TEST_F(StructMemberTest, CreationWithSource) {
|
|||
"a", ty.i32());
|
||||
EXPECT_EQ(st->symbol, Symbol(1, ID()));
|
||||
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.column, 4u);
|
||||
EXPECT_EQ(st->source.range.end.line, 27u);
|
||||
|
@ -64,7 +64,7 @@ TEST_F(StructMemberTest, Assert_Null_Type) {
|
|||
"internal compiler error");
|
||||
}
|
||||
|
||||
TEST_F(StructMemberTest, Assert_Null_Decoration) {
|
||||
TEST_F(StructMemberTest, Assert_Null_Attribute) {
|
||||
EXPECT_FATAL_FAILURE(
|
||||
{
|
||||
ProgramBuilder b;
|
||||
|
@ -83,7 +83,7 @@ TEST_F(StructMemberTest, Assert_DifferentProgramID_Symbol) {
|
|||
"internal compiler error");
|
||||
}
|
||||
|
||||
TEST_F(StructMemberTest, Assert_DifferentProgramID_Decoration) {
|
||||
TEST_F(StructMemberTest, Assert_DifferentProgramID_Attribute) {
|
||||
EXPECT_FATAL_FAILURE(
|
||||
{
|
||||
ProgramBuilder b1;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "src/ast/matrix.h"
|
||||
#include "src/ast/pointer.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/texture.h"
|
||||
#include "src/ast/u32.h"
|
||||
|
@ -37,43 +37,43 @@ using AstStructTest = TestHelper;
|
|||
TEST_F(AstStructTest, Creation) {
|
||||
auto name = Sym("s");
|
||||
auto* s = create<Struct>(name, StructMemberList{Member("a", ty.i32())},
|
||||
DecorationList{});
|
||||
AttributeList{});
|
||||
EXPECT_EQ(s->name, name);
|
||||
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.column, 0u);
|
||||
EXPECT_EQ(s->source.range.end.line, 0u);
|
||||
EXPECT_EQ(s->source.range.end.column, 0u);
|
||||
}
|
||||
|
||||
TEST_F(AstStructTest, Creation_WithDecorations) {
|
||||
TEST_F(AstStructTest, Creation_WithAttributes) {
|
||||
auto name = Sym("s");
|
||||
DecorationList decos;
|
||||
decos.push_back(create<StructBlockDecoration>());
|
||||
AttributeList attrs;
|
||||
attrs.push_back(create<StructBlockAttribute>());
|
||||
|
||||
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->members.size(), 1u);
|
||||
ASSERT_EQ(s->decorations.size(), 1u);
|
||||
EXPECT_TRUE(s->decorations[0]->Is<StructBlockDecoration>());
|
||||
ASSERT_EQ(s->attributes.size(), 1u);
|
||||
EXPECT_TRUE(s->attributes[0]->Is<StructBlockAttribute>());
|
||||
EXPECT_EQ(s->source.range.begin.line, 0u);
|
||||
EXPECT_EQ(s->source.range.begin.column, 0u);
|
||||
EXPECT_EQ(s->source.range.end.line, 0u);
|
||||
EXPECT_EQ(s->source.range.end.column, 0u);
|
||||
}
|
||||
|
||||
TEST_F(AstStructTest, CreationWithSourceAndDecorations) {
|
||||
TEST_F(AstStructTest, CreationWithSourceAndAttributes) {
|
||||
auto name = Sym("s");
|
||||
auto* s = create<Struct>(
|
||||
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
|
||||
name, StructMemberList{Member("a", ty.i32())},
|
||||
DecorationList{create<StructBlockDecoration>()});
|
||||
AttributeList{create<StructBlockAttribute>()});
|
||||
EXPECT_EQ(s->name, name);
|
||||
EXPECT_EQ(s->members.size(), 1u);
|
||||
ASSERT_EQ(s->decorations.size(), 1u);
|
||||
EXPECT_TRUE(s->decorations[0]->Is<StructBlockDecoration>());
|
||||
ASSERT_EQ(s->attributes.size(), 1u);
|
||||
EXPECT_TRUE(s->attributes[0]->Is<StructBlockAttribute>());
|
||||
EXPECT_EQ(s->source.range.begin.line, 27u);
|
||||
EXPECT_EQ(s->source.range.begin.column, 4u);
|
||||
EXPECT_EQ(s->source.range.end.line, 27u);
|
||||
|
@ -86,18 +86,18 @@ TEST_F(AstStructTest, Assert_Null_StructMember) {
|
|||
ProgramBuilder b;
|
||||
b.create<Struct>(b.Sym("S"),
|
||||
StructMemberList{b.Member("a", b.ty.i32()), nullptr},
|
||||
DecorationList{});
|
||||
AttributeList{});
|
||||
},
|
||||
"internal compiler error");
|
||||
}
|
||||
|
||||
TEST_F(AstStructTest, Assert_Null_Decoration) {
|
||||
TEST_F(AstStructTest, Assert_Null_Attribute) {
|
||||
EXPECT_FATAL_FAILURE(
|
||||
{
|
||||
ProgramBuilder b;
|
||||
b.create<Struct>(b.Sym("S"),
|
||||
StructMemberList{b.Member("a", b.ty.i32())},
|
||||
DecorationList{nullptr});
|
||||
AttributeList{nullptr});
|
||||
},
|
||||
"internal compiler error");
|
||||
}
|
||||
|
@ -109,19 +109,19 @@ TEST_F(AstStructTest, Assert_DifferentProgramID_StructMember) {
|
|||
ProgramBuilder b2;
|
||||
b1.create<Struct>(b1.Sym("S"),
|
||||
StructMemberList{b2.Member("a", b2.ty.i32())},
|
||||
DecorationList{});
|
||||
AttributeList{});
|
||||
},
|
||||
"internal compiler error");
|
||||
}
|
||||
|
||||
TEST_F(AstStructTest, Assert_DifferentProgramID_Decoration) {
|
||||
TEST_F(AstStructTest, Assert_DifferentProgramID_Attribute) {
|
||||
EXPECT_FATAL_FAILURE(
|
||||
{
|
||||
ProgramBuilder b1;
|
||||
ProgramBuilder b2;
|
||||
b1.create<Struct>(b1.Sym("S"),
|
||||
StructMemberList{b1.Member("a", b1.ty.i32())},
|
||||
DecorationList{b2.create<StructBlockDecoration>()});
|
||||
AttributeList{b2.create<StructBlockAttribute>()});
|
||||
},
|
||||
"internal compiler error");
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "src/ast/variable.h"
|
||||
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/sem/variable.h"
|
||||
|
||||
|
@ -31,13 +31,13 @@ Variable::Variable(ProgramID pid,
|
|||
const ast::Type* ty,
|
||||
bool constant,
|
||||
const Expression* ctor,
|
||||
DecorationList decos)
|
||||
AttributeList attrs)
|
||||
: Base(pid, src),
|
||||
symbol(sym),
|
||||
type(ty),
|
||||
is_const(constant),
|
||||
constructor(ctor),
|
||||
decorations(std::move(decos)),
|
||||
attributes(std::move(attrs)),
|
||||
declared_storage_class(dsc),
|
||||
declared_access(da) {
|
||||
TINT_ASSERT(AST, symbol.IsValid());
|
||||
|
@ -50,12 +50,12 @@ Variable::Variable(Variable&&) = default;
|
|||
Variable::~Variable() = default;
|
||||
|
||||
VariableBindingPoint Variable::BindingPoint() const {
|
||||
const GroupDecoration* group = nullptr;
|
||||
const BindingDecoration* binding = nullptr;
|
||||
for (auto* deco : decorations) {
|
||||
if (auto* g = deco->As<GroupDecoration>()) {
|
||||
const GroupAttribute* group = nullptr;
|
||||
const BindingAttribute* binding = nullptr;
|
||||
for (auto* attr : attributes) {
|
||||
if (auto* g = attr->As<GroupAttribute>()) {
|
||||
group = g;
|
||||
} else if (auto* b = deco->As<BindingDecoration>()) {
|
||||
} else if (auto* b = attr->As<BindingAttribute>()) {
|
||||
binding = b;
|
||||
}
|
||||
}
|
||||
|
@ -67,9 +67,9 @@ const Variable* Variable::Clone(CloneContext* ctx) const {
|
|||
auto sym = ctx->Clone(symbol);
|
||||
auto* ty = ctx->Clone(type);
|
||||
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,
|
||||
declared_access, ty, is_const, ctor, decos);
|
||||
declared_access, ty, is_const, ctor, attrs);
|
||||
}
|
||||
|
||||
} // namespace ast
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "src/ast/access.h"
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
#include "src/ast/expression.h"
|
||||
#include "src/ast/storage_class.h"
|
||||
|
||||
|
@ -27,20 +27,20 @@ namespace tint {
|
|||
namespace ast {
|
||||
|
||||
// Forward declarations
|
||||
class BindingDecoration;
|
||||
class GroupDecoration;
|
||||
class LocationDecoration;
|
||||
class BindingAttribute;
|
||||
class GroupAttribute;
|
||||
class LocationAttribute;
|
||||
class Type;
|
||||
|
||||
/// VariableBindingPoint holds a group and binding decoration.
|
||||
/// VariableBindingPoint holds a group and binding attribute.
|
||||
struct VariableBindingPoint {
|
||||
/// The `[[group]]` part of the binding point
|
||||
const GroupDecoration* group = nullptr;
|
||||
/// The `[[binding]]` part of the binding point
|
||||
const BindingDecoration* binding = nullptr;
|
||||
/// The `@group` part of the binding point
|
||||
const GroupAttribute* group = nullptr;
|
||||
/// The `@binding` part of the binding point
|
||||
const BindingAttribute* binding = nullptr;
|
||||
|
||||
/// @returns true if the BindingPoint has a valid group and binding
|
||||
/// decoration.
|
||||
/// attribute.
|
||||
inline operator bool() const { return group && binding; }
|
||||
};
|
||||
|
||||
|
@ -108,7 +108,7 @@ class Variable : public Castable<Variable, Node> {
|
|||
/// @param type the declared variable type
|
||||
/// @param is_const true if the variable is const
|
||||
/// @param constructor the constructor expression
|
||||
/// @param decorations the variable decorations
|
||||
/// @param attributes the variable attributes
|
||||
Variable(ProgramID program_id,
|
||||
const Source& source,
|
||||
const Symbol& sym,
|
||||
|
@ -117,7 +117,7 @@ class Variable : public Castable<Variable, Node> {
|
|||
const ast::Type* type,
|
||||
bool is_const,
|
||||
const Expression* constructor,
|
||||
DecorationList decorations);
|
||||
AttributeList attributes);
|
||||
/// Move constructor
|
||||
Variable(Variable&&);
|
||||
|
||||
|
@ -146,8 +146,8 @@ class Variable : public Castable<Variable, Node> {
|
|||
/// The constructor expression or nullptr if none set
|
||||
const Expression* const constructor;
|
||||
|
||||
/// The decorations attached to this variable
|
||||
const DecorationList decorations;
|
||||
/// The attributes attached to this variable
|
||||
const AttributeList attributes;
|
||||
|
||||
/// The declared storage class
|
||||
const StorageClass declared_storage_class;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
#include "src/ast/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -37,7 +37,7 @@ TEST_F(VariableTest, Creation) {
|
|||
TEST_F(VariableTest, CreationWithSource) {
|
||||
auto* v = Var(
|
||||
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->declared_storage_class, StorageClass::kPrivate);
|
||||
|
@ -51,7 +51,7 @@ TEST_F(VariableTest, CreationWithSource) {
|
|||
TEST_F(VariableTest, CreationEmpty) {
|
||||
auto* v = Var(
|
||||
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->declared_storage_class, StorageClass::kWorkgroup);
|
||||
|
@ -91,29 +91,29 @@ TEST_F(VariableTest, Assert_DifferentProgramID_Constructor) {
|
|||
"internal compiler error");
|
||||
}
|
||||
|
||||
TEST_F(VariableTest, WithDecorations) {
|
||||
TEST_F(VariableTest, WithAttributes) {
|
||||
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
||||
DecorationList{
|
||||
create<LocationDecoration>(1),
|
||||
create<BuiltinDecoration>(Builtin::kPosition),
|
||||
create<OverrideDecoration>(1200),
|
||||
AttributeList{
|
||||
create<LocationAttribute>(1),
|
||||
create<BuiltinAttribute>(Builtin::kPosition),
|
||||
create<OverrideAttribute>(1200),
|
||||
});
|
||||
|
||||
auto& decorations = var->decorations;
|
||||
EXPECT_TRUE(ast::HasDecoration<ast::LocationDecoration>(decorations));
|
||||
EXPECT_TRUE(ast::HasDecoration<ast::BuiltinDecoration>(decorations));
|
||||
EXPECT_TRUE(ast::HasDecoration<ast::OverrideDecoration>(decorations));
|
||||
auto& attributes = var->attributes;
|
||||
EXPECT_TRUE(ast::HasAttribute<ast::LocationAttribute>(attributes));
|
||||
EXPECT_TRUE(ast::HasAttribute<ast::BuiltinAttribute>(attributes));
|
||||
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);
|
||||
EXPECT_EQ(1u, location->value);
|
||||
}
|
||||
|
||||
TEST_F(VariableTest, BindingPoint) {
|
||||
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
||||
DecorationList{
|
||||
create<BindingDecoration>(2),
|
||||
create<GroupDecoration>(1),
|
||||
AttributeList{
|
||||
create<BindingAttribute>(2),
|
||||
create<GroupAttribute>(1),
|
||||
});
|
||||
EXPECT_TRUE(var->BindingPoint());
|
||||
ASSERT_NE(var->BindingPoint().binding, nullptr);
|
||||
|
@ -122,18 +122,18 @@ TEST_F(VariableTest, BindingPoint) {
|
|||
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,
|
||||
DecorationList{});
|
||||
AttributeList{});
|
||||
EXPECT_FALSE(var->BindingPoint());
|
||||
EXPECT_EQ(var->BindingPoint().group, 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,
|
||||
DecorationList{
|
||||
create<BindingDecoration>(2),
|
||||
AttributeList{
|
||||
create<BindingAttribute>(2),
|
||||
});
|
||||
EXPECT_FALSE(var->BindingPoint());
|
||||
ASSERT_NE(var->BindingPoint().binding, nullptr);
|
||||
|
@ -141,9 +141,9 @@ TEST_F(VariableTest, BindingPointMissingGroupDecoration) {
|
|||
EXPECT_EQ(var->BindingPoint().group, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(VariableTest, BindingPointMissingBindingDecoration) {
|
||||
TEST_F(VariableTest, BindingPointMissingBindingAttribute) {
|
||||
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
||||
DecorationList{create<GroupDecoration>(1)});
|
||||
AttributeList{create<GroupAttribute>(1)});
|
||||
EXPECT_FALSE(var->BindingPoint());
|
||||
ASSERT_NE(var->BindingPoint().group, nullptr);
|
||||
EXPECT_EQ(var->BindingPoint().group->value, 1u);
|
||||
|
|
|
@ -12,37 +12,37 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/ast/workgroup_decoration.h"
|
||||
#include "src/ast/workgroup_attribute.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::WorkgroupDecoration);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::WorkgroupAttribute);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
WorkgroupDecoration::WorkgroupDecoration(ProgramID pid,
|
||||
WorkgroupAttribute::WorkgroupAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
const ast::Expression* x_,
|
||||
const ast::Expression* y_,
|
||||
const ast::Expression* 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";
|
||||
}
|
||||
|
||||
const WorkgroupDecoration* WorkgroupDecoration::Clone(CloneContext* ctx) const {
|
||||
const WorkgroupAttribute* WorkgroupAttribute::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto src = ctx->Clone(source);
|
||||
auto* x_ = ctx->Clone(x);
|
||||
auto* y_ = ctx->Clone(y);
|
||||
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
|
|
@ -12,13 +12,13 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_AST_WORKGROUP_DECORATION_H_
|
||||
#define SRC_AST_WORKGROUP_DECORATION_H_
|
||||
#ifndef SRC_AST_WORKGROUP_ATTRIBUTE_H_
|
||||
#define SRC_AST_WORKGROUP_ATTRIBUTE_H_
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/decoration.h"
|
||||
#include "src/ast/attribute.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
@ -26,8 +26,8 @@ namespace ast {
|
|||
// Forward declaration
|
||||
class Expression;
|
||||
|
||||
/// A workgroup decoration
|
||||
class WorkgroupDecoration : public Castable<WorkgroupDecoration, Decoration> {
|
||||
/// A workgroup attribute
|
||||
class WorkgroupAttribute : public Castable<WorkgroupAttribute, Attribute> {
|
||||
public:
|
||||
/// constructor
|
||||
/// @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 y the optional workgroup y dimension expression
|
||||
/// @param z the optional workgroup z dimension expression
|
||||
WorkgroupDecoration(ProgramID pid,
|
||||
WorkgroupAttribute(ProgramID pid,
|
||||
const Source& src,
|
||||
const ast::Expression* x,
|
||||
const ast::Expression* y = nullptr,
|
||||
const ast::Expression* z = nullptr);
|
||||
|
||||
~WorkgroupDecoration() override;
|
||||
~WorkgroupAttribute() override;
|
||||
|
||||
/// @returns the workgroup dimensions
|
||||
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;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
const WorkgroupDecoration* Clone(CloneContext* ctx) const override;
|
||||
const WorkgroupAttribute* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The workgroup x dimension.
|
||||
const ast::Expression* const x;
|
||||
|
@ -66,4 +66,4 @@ class WorkgroupDecoration : public Castable<WorkgroupDecoration, Decoration> {
|
|||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_WORKGROUP_DECORATION_H_
|
||||
#endif // SRC_AST_WORKGROUP_ATTRIBUTE_H_
|
|
@ -12,18 +12,18 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using WorkgroupDecorationTest = TestHelper;
|
||||
using WorkgroupAttributeTest = TestHelper;
|
||||
|
||||
TEST_F(WorkgroupDecorationTest, Creation_1param) {
|
||||
TEST_F(WorkgroupAttributeTest, Creation_1param) {
|
||||
auto* d = WorkgroupSize(2);
|
||||
auto values = d->Values();
|
||||
|
||||
|
@ -33,7 +33,7 @@ TEST_F(WorkgroupDecorationTest, Creation_1param) {
|
|||
EXPECT_EQ(values[1], nullptr);
|
||||
EXPECT_EQ(values[2], nullptr);
|
||||
}
|
||||
TEST_F(WorkgroupDecorationTest, Creation_2param) {
|
||||
TEST_F(WorkgroupAttributeTest, Creation_2param) {
|
||||
auto* d = WorkgroupSize(2, 4);
|
||||
auto values = d->Values();
|
||||
|
||||
|
@ -46,7 +46,7 @@ TEST_F(WorkgroupDecorationTest, Creation_2param) {
|
|||
EXPECT_EQ(values[2], nullptr);
|
||||
}
|
||||
|
||||
TEST_F(WorkgroupDecorationTest, Creation_3param) {
|
||||
TEST_F(WorkgroupAttributeTest, Creation_3param) {
|
||||
auto* d = WorkgroupSize(2, 4, 6);
|
||||
auto values = d->Values();
|
||||
|
||||
|
@ -60,7 +60,7 @@ TEST_F(WorkgroupDecorationTest, Creation_3param) {
|
|||
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 values = d->Values();
|
||||
|
|
@ -17,6 +17,10 @@
|
|||
namespace tint {
|
||||
namespace inspector {
|
||||
|
||||
StageVariable::StageVariable() = default;
|
||||
StageVariable::StageVariable(const StageVariable&) = default;
|
||||
StageVariable::~StageVariable() = default;
|
||||
|
||||
EntryPoint::EntryPoint() = default;
|
||||
EntryPoint::EntryPoint(EntryPoint&) = default;
|
||||
EntryPoint::EntryPoint(EntryPoint&&) = default;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "src/ast/interpolate_decoration.h"
|
||||
#include "src/ast/interpolate_attribute.h"
|
||||
#include "src/ast/pipeline_stage.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -56,13 +56,27 @@ enum class InterpolationSampling {
|
|||
|
||||
/// Reflection data about an entry point input or output.
|
||||
struct StageVariable {
|
||||
/// Constructor
|
||||
StageVariable();
|
||||
/// Copy constructor
|
||||
StageVariable(const StageVariable&);
|
||||
/// Destructor
|
||||
~StageVariable();
|
||||
|
||||
/// Name of the variable in the shader.
|
||||
std::string name;
|
||||
/// Is Location Decoration present
|
||||
bool has_location_decoration = false;
|
||||
/// Value of Location Decoration, only valid if |has_location_decoration| is
|
||||
/// Is location attribute present
|
||||
bool has_location_attribute = false;
|
||||
/// Value of the location attribute, only valid if #has_location_attribute is
|
||||
/// 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.
|
||||
ComponentType component_type = ComponentType::kUnknown;
|
||||
/// How the scalars are composed for the variable.
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#include "src/ast/bool_literal_expression.h"
|
||||
#include "src/ast/call_expression.h"
|
||||
#include "src/ast/float_literal_expression.h"
|
||||
#include "src/ast/interpolate_decoration.h"
|
||||
#include "src/ast/location_decoration.h"
|
||||
#include "src/ast/interpolate_attribute.h"
|
||||
#include "src/ast/location_attribute.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/uint_literal_expression.h"
|
||||
#include "src/sem/array.h"
|
||||
|
@ -102,19 +102,19 @@ std::tuple<ComponentType, CompositionType> CalculateComponentAndComposition(
|
|||
|
||||
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
|
||||
const sem::Type* type,
|
||||
const ast::DecorationList& decorations) {
|
||||
auto* interpolation_decoration =
|
||||
ast::GetDecoration<ast::InterpolateDecoration>(decorations);
|
||||
const ast::AttributeList& attributes) {
|
||||
auto* interpolation_attribute =
|
||||
ast::GetAttribute<ast::InterpolateAttribute>(attributes);
|
||||
if (type->is_integer_scalar_or_vector()) {
|
||||
return {InterpolationType::kFlat, InterpolationSampling::kNone};
|
||||
}
|
||||
|
||||
if (!interpolation_decoration) {
|
||||
if (!interpolation_attribute) {
|
||||
return {InterpolationType::kPerspective, InterpolationSampling::kCenter};
|
||||
}
|
||||
|
||||
auto interpolation_type = interpolation_decoration->type;
|
||||
auto sampling = interpolation_decoration->sampling;
|
||||
auto interpolation_type = interpolation_attribute->type;
|
||||
auto sampling = interpolation_attribute->sampling;
|
||||
if (interpolation_type != ast::InterpolationType::kFlat &&
|
||||
sampling == ast::InterpolationSampling::kNone) {
|
||||
sampling = ast::InterpolationSampling::kCenter;
|
||||
|
@ -157,34 +157,34 @@ std::vector<EntryPoint> Inspector::GetEntryPoints() {
|
|||
for (auto* param : sem->Parameters()) {
|
||||
AddEntryPointInOutVariables(
|
||||
program_->Symbols().NameFor(param->Declaration()->symbol),
|
||||
param->Type(), param->Declaration()->decorations,
|
||||
param->Type(), param->Declaration()->attributes,
|
||||
entry_point.input_variables);
|
||||
|
||||
entry_point.input_position_used |=
|
||||
ContainsBuiltin(ast::Builtin::kPosition, param->Type(),
|
||||
param->Declaration()->decorations);
|
||||
param->Declaration()->attributes);
|
||||
entry_point.front_facing_used |=
|
||||
ContainsBuiltin(ast::Builtin::kFrontFacing, param->Type(),
|
||||
param->Declaration()->decorations);
|
||||
param->Declaration()->attributes);
|
||||
entry_point.sample_index_used |=
|
||||
ContainsBuiltin(ast::Builtin::kSampleIndex, param->Type(),
|
||||
param->Declaration()->decorations);
|
||||
param->Declaration()->attributes);
|
||||
entry_point.input_sample_mask_used |=
|
||||
ContainsBuiltin(ast::Builtin::kSampleMask, param->Type(),
|
||||
param->Declaration()->decorations);
|
||||
param->Declaration()->attributes);
|
||||
entry_point.num_workgroups_used |=
|
||||
ContainsBuiltin(ast::Builtin::kNumWorkgroups, param->Type(),
|
||||
param->Declaration()->decorations);
|
||||
param->Declaration()->attributes);
|
||||
}
|
||||
|
||||
if (!sem->ReturnType()->Is<sem::Void>()) {
|
||||
AddEntryPointInOutVariables("<retval>", sem->ReturnType(),
|
||||
func->return_type_decorations,
|
||||
func->return_type_attributes,
|
||||
entry_point.output_variables);
|
||||
|
||||
entry_point.output_sample_mask_used =
|
||||
ContainsBuiltin(ast::Builtin::kSampleMask, sem->ReturnType(),
|
||||
func->return_type_decorations);
|
||||
func->return_type_attributes);
|
||||
}
|
||||
|
||||
for (auto* var : sem->TransitivelyReferencedGlobals()) {
|
||||
|
@ -213,10 +213,10 @@ std::vector<EntryPoint> Inspector::GetEntryPoints() {
|
|||
|
||||
overridable_constant.is_initialized =
|
||||
global->Declaration()->constructor;
|
||||
auto* override_deco = ast::GetDecoration<ast::OverrideDecoration>(
|
||||
global->Declaration()->decorations);
|
||||
auto* override_attr = ast::GetAttribute<ast::OverrideAttribute>(
|
||||
global->Declaration()->attributes);
|
||||
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);
|
||||
}
|
||||
|
@ -579,10 +579,10 @@ const ast::Function* Inspector::FindEntryPointByName(const std::string& name) {
|
|||
void Inspector::AddEntryPointInOutVariables(
|
||||
std::string name,
|
||||
const sem::Type* type,
|
||||
const ast::DecorationList& decorations,
|
||||
const ast::AttributeList& attributes,
|
||||
std::vector<StageVariable>& variables) const {
|
||||
// Skip builtins.
|
||||
if (ast::HasDecoration<ast::BuiltinDecoration>(decorations)) {
|
||||
if (ast::HasAttribute<ast::BuiltinAttribute>(attributes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -594,7 +594,7 @@ void Inspector::AddEntryPointInOutVariables(
|
|||
AddEntryPointInOutVariables(
|
||||
name + "." +
|
||||
program_->Symbols().NameFor(member->Declaration()->symbol),
|
||||
member->Type(), member->Declaration()->decorations, variables);
|
||||
member->Type(), member->Declaration()->attributes, variables);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -606,28 +606,28 @@ void Inspector::AddEntryPointInOutVariables(
|
|||
std::tie(stage_variable.component_type, stage_variable.composition_type) =
|
||||
CalculateComponentAndComposition(type);
|
||||
|
||||
auto* location = ast::GetDecoration<ast::LocationDecoration>(decorations);
|
||||
auto* location = ast::GetAttribute<ast::LocationAttribute>(attributes);
|
||||
TINT_ASSERT(Inspector, location != nullptr);
|
||||
stage_variable.has_location_decoration = true;
|
||||
stage_variable.location_decoration = location->value;
|
||||
stage_variable.has_location_attribute = true;
|
||||
stage_variable.location_attribute = location->value;
|
||||
|
||||
std::tie(stage_variable.interpolation_type,
|
||||
stage_variable.interpolation_sampling) =
|
||||
CalculateInterpolationData(type, decorations);
|
||||
CalculateInterpolationData(type, attributes);
|
||||
|
||||
variables.push_back(stage_variable);
|
||||
}
|
||||
|
||||
bool Inspector::ContainsBuiltin(ast::Builtin builtin,
|
||||
const sem::Type* type,
|
||||
const ast::DecorationList& decorations) const {
|
||||
const ast::AttributeList& attributes) const {
|
||||
auto* unwrapped_type = type->UnwrapRef();
|
||||
|
||||
if (auto* struct_ty = unwrapped_type->As<sem::Struct>()) {
|
||||
// Recurse into members.
|
||||
for (auto* member : struct_ty->Members()) {
|
||||
if (ContainsBuiltin(builtin, member->Type(),
|
||||
member->Declaration()->decorations)) {
|
||||
member->Declaration()->attributes)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -636,7 +636,7 @@ bool Inspector::ContainsBuiltin(ast::Builtin builtin,
|
|||
|
||||
// Base case: check for builtin
|
||||
auto* builtin_declaration =
|
||||
ast::GetDecoration<ast::BuiltinDecoration>(decorations);
|
||||
ast::GetAttribute<ast::BuiltinAttribute>(attributes);
|
||||
if (!builtin_declaration || builtin_declaration->builtin != builtin) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -158,19 +158,19 @@ class Inspector {
|
|||
/// Otherwise, add the variable unless it is a builtin.
|
||||
/// @param name the name of the variable being added
|
||||
/// @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
|
||||
void AddEntryPointInOutVariables(std::string name,
|
||||
const sem::Type* type,
|
||||
const ast::DecorationList& decorations,
|
||||
const ast::AttributeList& attributes,
|
||||
std::vector<StageVariable>& variables) const;
|
||||
|
||||
/// Recursively determine if the type contains builtin.
|
||||
/// If `type` is a struct, recurse into members to check for the decoration.
|
||||
/// Otherwise, check `decorations` for the decoration.
|
||||
/// If `type` is a struct, recurse into members to check for the attribute.
|
||||
/// Otherwise, check `attributes` for the attribute.
|
||||
bool ContainsBuiltin(ast::Builtin builtin,
|
||||
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
|
||||
/// entry point.
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/ast/call_statement.h"
|
||||
#include "src/ast/disable_validation_decoration.h"
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/stage_decoration.h"
|
||||
#include "src/ast/struct_block_decoration.h"
|
||||
#include "src/ast/workgroup_decoration.h"
|
||||
#include "src/ast/disable_validation_attribute.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
#include "src/ast/stage_attribute.h"
|
||||
#include "src/ast/struct_block_attribute.h"
|
||||
#include "src/ast/workgroup_attribute.h"
|
||||
#include "src/inspector/test_inspector_builder.h"
|
||||
#include "src/inspector/test_inspector_runner.h"
|
||||
#include "src/program_builder.h"
|
||||
|
@ -172,7 +172,7 @@ TEST_F(InspectorGetEntryPointTest, NoEntryPoints) {
|
|||
}
|
||||
|
||||
TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
|
||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
||||
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -190,12 +190,12 @@ TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
|
|||
}
|
||||
|
||||
TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
|
||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
||||
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
MakeEmptyBodyFunction("bar",
|
||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1)});
|
||||
|
||||
// TODO(dsinclair): Update to run the namer transform when available.
|
||||
|
@ -217,13 +217,12 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
|
|||
TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
|
||||
MakeEmptyBodyFunction("func", {});
|
||||
|
||||
MakeCallerBodyFunction(
|
||||
"foo", {"func"},
|
||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
||||
MakeCallerBodyFunction("foo", {"func"},
|
||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1)});
|
||||
|
||||
MakeCallerBodyFunction("bar", {"func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -245,7 +244,7 @@ TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
|
|||
|
||||
TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
|
||||
MakeEmptyBodyFunction("foo",
|
||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(8, 2, 1)});
|
||||
|
||||
Inspector& inspector = Build();
|
||||
|
@ -282,7 +281,7 @@ TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
|
|||
MakeEmptyBodyFunction("func", {});
|
||||
|
||||
MakeCallerBodyFunction("foo", {"func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -315,14 +314,14 @@ TEST_P(InspectorGetEntryPointComponentAndCompositionTest, Test) {
|
|||
|
||||
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||
EXPECT_EQ("in_var", result[0].input_variables[0].name);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||
EXPECT_EQ(component, result[0].input_variables[0].component_type);
|
||||
|
||||
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||
EXPECT_EQ(component, result[0].output_variables[0].component_type);
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
|
@ -351,28 +350,28 @@ TEST_F(InspectorGetEntryPointTest, MultipleInOutVariables) {
|
|||
|
||||
ASSERT_EQ(3u, result[0].input_variables.size());
|
||||
EXPECT_EQ("in_var0", result[0].input_variables[0].name);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||
EXPECT_EQ(InterpolationType::kFlat,
|
||||
result[0].input_variables[0].interpolation_type);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
||||
EXPECT_EQ("in_var1", result[0].input_variables[1].name);
|
||||
EXPECT_TRUE(result[0].input_variables[1].has_location_decoration);
|
||||
EXPECT_EQ(1u, result[0].input_variables[1].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[1].has_location_attribute);
|
||||
EXPECT_EQ(1u, result[0].input_variables[1].location_attribute);
|
||||
EXPECT_EQ(InterpolationType::kFlat,
|
||||
result[0].input_variables[1].interpolation_type);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
|
||||
EXPECT_EQ("in_var4", result[0].input_variables[2].name);
|
||||
EXPECT_TRUE(result[0].input_variables[2].has_location_decoration);
|
||||
EXPECT_EQ(4u, result[0].input_variables[2].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[2].has_location_attribute);
|
||||
EXPECT_EQ(4u, result[0].input_variables[2].location_attribute);
|
||||
EXPECT_EQ(InterpolationType::kFlat,
|
||||
result[0].input_variables[2].interpolation_type);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type);
|
||||
|
||||
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||
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());
|
||||
EXPECT_EQ("in_var_foo", result[0].input_variables[0].name);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||
EXPECT_EQ(InterpolationType::kFlat,
|
||||
result[0].input_variables[0].interpolation_type);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
||||
|
||||
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
||||
|
||||
ASSERT_EQ(1u, result[1].input_variables.size());
|
||||
EXPECT_EQ("in_var_bar", result[1].input_variables[0].name);
|
||||
EXPECT_TRUE(result[1].input_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[1].input_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[1].input_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[1].input_variables[0].location_attribute);
|
||||
EXPECT_EQ(InterpolationType::kFlat,
|
||||
result[1].input_variables[0].interpolation_type);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type);
|
||||
|
||||
ASSERT_EQ(1u, result[1].output_variables.size());
|
||||
EXPECT_EQ("<retval>", result[1].output_variables[0].name);
|
||||
EXPECT_TRUE(result[1].output_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(1u, result[1].output_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[1].output_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(1u, result[1].output_variables[0].location_attribute);
|
||||
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());
|
||||
EXPECT_EQ("in_var1", result[0].input_variables[0].name);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[0].component_type);
|
||||
|
||||
ASSERT_EQ(0u, result[0].output_variables.size());
|
||||
|
@ -457,22 +456,22 @@ TEST_F(InspectorGetEntryPointTest, InOutStruct) {
|
|||
|
||||
ASSERT_EQ(2u, result[0].input_variables.size());
|
||||
EXPECT_EQ("param.a", result[0].input_variables[0].name);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
||||
EXPECT_EQ("param.b", result[0].input_variables[1].name);
|
||||
EXPECT_TRUE(result[0].input_variables[1].has_location_decoration);
|
||||
EXPECT_EQ(1u, result[0].input_variables[1].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[1].has_location_attribute);
|
||||
EXPECT_EQ(1u, result[0].input_variables[1].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
|
||||
|
||||
ASSERT_EQ(2u, result[0].output_variables.size());
|
||||
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
||||
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
|
||||
EXPECT_TRUE(result[0].output_variables[1].has_location_decoration);
|
||||
EXPECT_EQ(1u, result[0].output_variables[1].location_decoration);
|
||||
EXPECT_TRUE(result[0].output_variables[1].has_location_attribute);
|
||||
EXPECT_EQ(1u, result[0].output_variables[1].location_attribute);
|
||||
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());
|
||||
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
||||
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
|
||||
EXPECT_TRUE(result[0].output_variables[1].has_location_decoration);
|
||||
EXPECT_EQ(1u, result[0].output_variables[1].location_decoration);
|
||||
EXPECT_TRUE(result[0].output_variables[1].has_location_attribute);
|
||||
EXPECT_EQ(1u, result[0].output_variables[1].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
|
||||
|
||||
ASSERT_EQ(2u, result[1].input_variables.size());
|
||||
EXPECT_EQ("param.a", result[1].input_variables[0].name);
|
||||
EXPECT_TRUE(result[1].input_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[1].input_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[1].input_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[1].input_variables[0].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type);
|
||||
EXPECT_EQ("param.b", result[1].input_variables[1].name);
|
||||
EXPECT_TRUE(result[1].input_variables[1].has_location_decoration);
|
||||
EXPECT_EQ(1u, result[1].input_variables[1].location_decoration);
|
||||
EXPECT_TRUE(result[1].input_variables[1].has_location_attribute);
|
||||
EXPECT_EQ(1u, result[1].input_variables[1].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[1].component_type);
|
||||
|
||||
ASSERT_EQ(0u, result[1].output_variables.size());
|
||||
|
@ -532,34 +531,34 @@ TEST_F(InspectorGetEntryPointTest, MixInOutVariablesAndStruct) {
|
|||
|
||||
ASSERT_EQ(5u, result[0].input_variables.size());
|
||||
EXPECT_EQ("param_a.a", result[0].input_variables[0].name);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
||||
EXPECT_EQ("param_a.b", result[0].input_variables[1].name);
|
||||
EXPECT_TRUE(result[0].input_variables[1].has_location_decoration);
|
||||
EXPECT_EQ(1u, result[0].input_variables[1].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[1].has_location_attribute);
|
||||
EXPECT_EQ(1u, result[0].input_variables[1].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
|
||||
EXPECT_EQ("param_b.a", result[0].input_variables[2].name);
|
||||
EXPECT_TRUE(result[0].input_variables[2].has_location_decoration);
|
||||
EXPECT_EQ(2u, result[0].input_variables[2].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[2].has_location_attribute);
|
||||
EXPECT_EQ(2u, result[0].input_variables[2].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type);
|
||||
EXPECT_EQ("param_c", result[0].input_variables[3].name);
|
||||
EXPECT_TRUE(result[0].input_variables[3].has_location_decoration);
|
||||
EXPECT_EQ(3u, result[0].input_variables[3].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[3].has_location_attribute);
|
||||
EXPECT_EQ(3u, result[0].input_variables[3].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[3].component_type);
|
||||
EXPECT_EQ("param_d", result[0].input_variables[4].name);
|
||||
EXPECT_TRUE(result[0].input_variables[4].has_location_decoration);
|
||||
EXPECT_EQ(4u, result[0].input_variables[4].location_decoration);
|
||||
EXPECT_TRUE(result[0].input_variables[4].has_location_attribute);
|
||||
EXPECT_EQ(4u, result[0].input_variables[4].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[4].component_type);
|
||||
|
||||
ASSERT_EQ(2u, result[0].output_variables.size());
|
||||
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
||||
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
|
||||
EXPECT_TRUE(result[0].output_variables[1].has_location_decoration);
|
||||
EXPECT_EQ(1u, result[0].output_variables[1].location_decoration);
|
||||
EXPECT_TRUE(result[0].output_variables[1].has_location_attribute);
|
||||
EXPECT_EQ(1u, result[0].output_variables[1].location_attribute);
|
||||
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
|
||||
// through
|
||||
TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
|
||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
||||
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kVertex),
|
||||
});
|
||||
|
||||
|
@ -1069,7 +1068,7 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
|
|||
// through
|
||||
TEST_F(InspectorGetRemappedNameForEntryPointTest,
|
||||
DISABLED_MultipleEntryPoints) {
|
||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
||||
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kVertex),
|
||||
});
|
||||
|
||||
|
@ -1077,7 +1076,7 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest,
|
|||
// available.
|
||||
|
||||
MakeEmptyBodyFunction("bar",
|
||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1)});
|
||||
|
||||
Inspector& inspector = Build();
|
||||
|
@ -1222,7 +1221,7 @@ TEST_F(InspectorGetConstantNameToIdMapTest, WithAndWithoutIds) {
|
|||
|
||||
TEST_F(InspectorGetStorageSizeTest, Empty) {
|
||||
MakeEmptyBodyFunction("ep_func",
|
||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1)});
|
||||
Inspector& inspector = Build();
|
||||
EXPECT_EQ(0u, inspector.GetStorageSize("ep_func"));
|
||||
|
@ -1260,7 +1259,7 @@ TEST_F(InspectorGetStorageSizeTest, Simple_Struct) {
|
|||
{{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"ub_func", "sb_func", "rosb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1),
|
||||
});
|
||||
|
@ -1299,7 +1298,7 @@ TEST_F(InspectorGetStorageSizeTest, StructVec3) {
|
|||
|
||||
TEST_F(InspectorGetResourceBindingsTest, Empty) {
|
||||
MakeCallerBodyFunction("ep_func", {},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1353,7 +1352,7 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
|
|||
MakeCallerBodyFunction("ep_func",
|
||||
{"ub_func", "sb_func", "rosb_func", "s_func",
|
||||
"cs_func", "depth_ms_func", "st_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1424,7 +1423,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonEntryPointFunc) {
|
|||
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1440,7 +1439,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple_NonStruct) {
|
|||
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.i32(), {});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1465,7 +1464,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple_Struct) {
|
|||
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
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()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1518,7 +1517,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingPadding) {
|
|||
{{0, ty.vec3<f32>()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1541,7 +1540,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonStructVec3) {
|
|||
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1582,7 +1581,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) {
|
|||
Func("ep_func", ast::VariableList(), ty.void_(),
|
||||
ast::StatementList{FuncCall("ub_foo_func"), FuncCall("ub_bar_func"),
|
||||
FuncCall("ub_baz_func"), Return()},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1621,14 +1620,14 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingArray) {
|
|||
"foo_type",
|
||||
{Member("0i32", ty.i32()),
|
||||
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);
|
||||
|
||||
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1651,7 +1650,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple_NonStruct) {
|
|||
MakePlainGlobalReferenceBodyFunction("sb_func", "foo_sb", ty.i32(), {});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1676,7 +1675,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple_Struct) {
|
|||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
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()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1754,7 +1753,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
|
|||
FuncCall("sb_baz_func"),
|
||||
Return(),
|
||||
},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1794,7 +1793,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
|
|||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1822,7 +1821,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
|
|||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1848,7 +1847,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) {
|
|||
{{0, ty.vec3<f32>()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1871,7 +1870,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, NonStructVec3) {
|
|||
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1896,7 +1895,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
|
|||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1914,7 +1913,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
|
|||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -1963,7 +1962,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
|
|||
FuncCall("sb_baz_func"),
|
||||
Return(),
|
||||
},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2006,7 +2005,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
|
|||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2035,7 +2034,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
|
|||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2060,7 +2059,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
|
|||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2080,7 +2079,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
|
|||
|
||||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||
"foo_coords", ty.f32(),
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2096,7 +2095,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
|
|||
}
|
||||
|
||||
TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
|
||||
MakeEmptyBodyFunction("ep_func", ast::DecorationList{
|
||||
MakeEmptyBodyFunction("ep_func", ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2119,7 +2118,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
|
|||
"foo_coords", ty.f32(), {});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"foo_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2143,7 +2142,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
|
|||
|
||||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||
"foo_coords", ty.f32(),
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2162,7 +2161,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
|
|||
|
||||
MakeComparisonSamplerReferenceBodyFunction(
|
||||
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2183,7 +2182,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
|
|||
|
||||
MakeComparisonSamplerReferenceBodyFunction(
|
||||
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2200,7 +2199,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
|
|||
}
|
||||
|
||||
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
|
||||
MakeEmptyBodyFunction("ep_func", ast::DecorationList{
|
||||
MakeEmptyBodyFunction("ep_func", ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2224,7 +2223,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
|
|||
"foo_depth", ty.f32(), {});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"foo_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2249,7 +2248,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
|
|||
|
||||
MakeComparisonSamplerReferenceBodyFunction(
|
||||
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2268,7 +2267,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
|
|||
|
||||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||
"foo_coords", ty.f32(),
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2281,7 +2280,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
|
|||
}
|
||||
|
||||
TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
|
||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
||||
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2304,7 +2303,7 @@ TEST_P(InspectorGetSampledTextureResourceBindingsTestWithParam, textureSample) {
|
|||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||
"foo_coords",
|
||||
GetBaseType(GetParam().sampled_kind),
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2363,7 +2362,7 @@ TEST_P(InspectorGetSampledArrayTextureResourceBindingsTestWithParam,
|
|||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||
"foo_coords", "foo_array_index",
|
||||
GetBaseType(GetParam().sampled_kind),
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2408,7 +2407,7 @@ TEST_P(InspectorGetMultisampledTextureResourceBindingsTestWithParam,
|
|||
CallStmt(Call("textureLoad", "foo_texture", "foo_coords",
|
||||
"foo_sample_index")),
|
||||
},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2451,7 +2450,7 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
inspector::ResourceBinding::SampledKind::kUInt}));
|
||||
|
||||
TEST_F(InspectorGetMultisampledArrayTextureResourceBindingsTest, Empty) {
|
||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
||||
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2476,7 +2475,7 @@ TEST_P(InspectorGetMultisampledArrayTextureResourceBindingsTestWithParam,
|
|||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||
"foo_coords", "foo_array_index",
|
||||
GetBaseType(GetParam().sampled_kind),
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2512,7 +2511,7 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
inspector::ResourceBinding::SampledKind::kUInt}));
|
||||
|
||||
TEST_F(InspectorGetStorageTextureResourceBindingsTest, Empty) {
|
||||
MakeEmptyBodyFunction("ep", ast::DecorationList{
|
||||
MakeEmptyBodyFunction("ep", ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2560,7 +2559,7 @@ TEST_P(InspectorGetStorageTextureResourceBindingsTestWithParam, Simple) {
|
|||
|
||||
MakeStorageTextureBodyFunction(
|
||||
"ep", "st_var", dim_type,
|
||||
ast::DecorationList{Stage(ast::PipelineStage::kFragment)});
|
||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
|
||||
|
||||
Inspector& inspector = Build();
|
||||
|
||||
|
@ -2649,7 +2648,7 @@ TEST_P(InspectorGetDepthTextureResourceBindingsTestWithParam,
|
|||
ast::StatementList{
|
||||
CallStmt(Call("textureDimensions", "dt")),
|
||||
},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2693,7 +2692,7 @@ TEST_F(InspectorGetDepthMultisampledTextureResourceBindingsTest,
|
|||
ast::StatementList{
|
||||
CallStmt(Call("textureDimensions", "tex")),
|
||||
},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2718,7 +2717,7 @@ TEST_F(InspectorGetExternalTextureResourceBindingsTest, Simple) {
|
|||
ast::StatementList{
|
||||
CallStmt(Call("textureDimensions", "et")),
|
||||
},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
|
@ -2996,7 +2995,7 @@ fn direct(@location(0) fragUV: vec2<f32>,
|
|||
|
||||
TEST_F(InspectorGetWorkgroupStorageSizeTest, Empty) {
|
||||
MakeEmptyBodyFunction("ep_func",
|
||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1)});
|
||||
Inspector& inspector = Build();
|
||||
EXPECT_EQ(0u, inspector.GetWorkgroupStorageSize("ep_func"));
|
||||
|
@ -3007,7 +3006,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, Simple) {
|
|||
MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"f32_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1),
|
||||
});
|
||||
|
@ -3031,7 +3030,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, CompoundTypes) {
|
|||
MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"wg_struct_func", "f32_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1),
|
||||
});
|
||||
|
@ -3048,7 +3047,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, AlignmentPadding) {
|
|||
{});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"wg_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1),
|
||||
});
|
||||
|
@ -3064,7 +3063,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, StructAlignment) {
|
|||
const auto* wg_struct_type = MakeStructTypeFromMembers(
|
||||
"WgStruct",
|
||||
{MakeStructMember(0, ty.f32(),
|
||||
{create<ast::StructMemberAlignDecoration>(1024)})},
|
||||
{create<ast::StructMemberAlignAttribute>(1024)})},
|
||||
/*is_block=*/false);
|
||||
|
||||
AddWorkgroupStorage("wg_struct_var", ty.Of(wg_struct_type));
|
||||
|
@ -3072,7 +3071,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, StructAlignment) {
|
|||
{{0, ty.f32()}});
|
||||
|
||||
MakeCallerBodyFunction("ep_func", {"wg_struct_func"},
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1),
|
||||
});
|
||||
|
|
|
@ -29,14 +29,14 @@ InspectorBuilder::InspectorBuilder() = default;
|
|||
InspectorBuilder::~InspectorBuilder() = default;
|
||||
|
||||
void InspectorBuilder::MakeEmptyBodyFunction(std::string name,
|
||||
ast::DecorationList decorations) {
|
||||
ast::AttributeList attributes) {
|
||||
Func(name, ast::VariableList(), ty.void_(), ast::StatementList{Return()},
|
||||
decorations);
|
||||
attributes);
|
||||
}
|
||||
|
||||
void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
|
||||
std::vector<std::string> callees,
|
||||
ast::DecorationList decorations) {
|
||||
ast::AttributeList attributes) {
|
||||
ast::StatementList body;
|
||||
body.reserve(callees.size() + 1);
|
||||
for (auto callee : callees) {
|
||||
|
@ -44,7 +44,7 @@ void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
|
|||
}
|
||||
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(
|
||||
|
@ -65,13 +65,13 @@ const ast::Function* InspectorBuilder::MakePlainGlobalReferenceBodyFunction(
|
|||
std::string func,
|
||||
std::string var,
|
||||
const ast::Type* type,
|
||||
ast::DecorationList decorations) {
|
||||
ast::AttributeList attributes) {
|
||||
ast::StatementList stmts;
|
||||
stmts.emplace_back(Decl(Var("local_" + var, type)));
|
||||
stmts.emplace_back(Assign("local_" + var, var));
|
||||
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,
|
||||
|
@ -104,18 +104,18 @@ const ast::Struct* InspectorBuilder::MakeStructTypeFromMembers(
|
|||
const std::string& name,
|
||||
ast::StructMemberList members,
|
||||
bool is_block) {
|
||||
ast::DecorationList decos;
|
||||
ast::AttributeList attrs;
|
||||
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(
|
||||
size_t index,
|
||||
const ast::Type* type,
|
||||
ast::DecorationList decorations) {
|
||||
return Member(StructMemberName(index, type), type, std::move(decorations));
|
||||
ast::AttributeList attributes) {
|
||||
return Member(StructMemberName(index, type), type, std::move(attributes));
|
||||
}
|
||||
|
||||
const ast::Struct* InspectorBuilder::MakeUniformBufferType(
|
||||
|
@ -136,9 +136,9 @@ void InspectorBuilder::AddUniformBuffer(const std::string& name,
|
|||
uint32_t group,
|
||||
uint32_t binding) {
|
||||
Global(name, type, ast::StorageClass::kUniform,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(binding),
|
||||
create<ast::GroupDecoration>(group),
|
||||
ast::AttributeList{
|
||||
create<ast::BindingAttribute>(binding),
|
||||
create<ast::GroupAttribute>(group),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -153,9 +153,9 @@ void InspectorBuilder::AddStorageBuffer(const std::string& name,
|
|||
uint32_t group,
|
||||
uint32_t binding) {
|
||||
Global(name, type, ast::StorageClass::kStorage, access,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(binding),
|
||||
create<ast::GroupDecoration>(group),
|
||||
ast::AttributeList{
|
||||
create<ast::BindingAttribute>(binding),
|
||||
create<ast::GroupAttribute>(group),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -185,17 +185,16 @@ void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
|
|||
|
||||
stmts.emplace_back(Return());
|
||||
|
||||
Func(func_name, ast::VariableList(), ty.void_(), stmts,
|
||||
ast::DecorationList{});
|
||||
Func(func_name, ast::VariableList(), ty.void_(), stmts, ast::AttributeList{});
|
||||
}
|
||||
|
||||
void InspectorBuilder::AddSampler(const std::string& name,
|
||||
uint32_t group,
|
||||
uint32_t binding) {
|
||||
Global(name, sampler_type(),
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(binding),
|
||||
create<ast::GroupDecoration>(group),
|
||||
ast::AttributeList{
|
||||
create<ast::BindingAttribute>(binding),
|
||||
create<ast::GroupAttribute>(group),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -203,9 +202,9 @@ void InspectorBuilder::AddComparisonSampler(const std::string& name,
|
|||
uint32_t group,
|
||||
uint32_t binding) {
|
||||
Global(name, comparison_sampler_type(),
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(binding),
|
||||
create<ast::GroupDecoration>(group),
|
||||
ast::AttributeList{
|
||||
create<ast::BindingAttribute>(binding),
|
||||
create<ast::GroupAttribute>(group),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -214,9 +213,9 @@ void InspectorBuilder::AddResource(const std::string& name,
|
|||
uint32_t group,
|
||||
uint32_t binding) {
|
||||
Global(name, type,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(binding),
|
||||
create<ast::GroupDecoration>(group),
|
||||
ast::AttributeList{
|
||||
create<ast::BindingAttribute>(binding),
|
||||
create<ast::GroupAttribute>(group),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -231,7 +230,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
|||
const std::string& sampler_name,
|
||||
const std::string& coords_name,
|
||||
const ast::Type* base_type,
|
||||
ast::DecorationList decorations) {
|
||||
ast::AttributeList attributes) {
|
||||
std::string result_name = "sampler_result";
|
||||
|
||||
ast::StatementList stmts;
|
||||
|
@ -241,7 +240,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
|||
sampler_name, coords_name)));
|
||||
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(
|
||||
|
@ -251,7 +250,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
|||
const std::string& coords_name,
|
||||
const std::string& array_index,
|
||||
const ast::Type* base_type,
|
||||
ast::DecorationList decorations) {
|
||||
ast::AttributeList attributes) {
|
||||
std::string result_name = "sampler_result";
|
||||
|
||||
ast::StatementList stmts;
|
||||
|
@ -263,7 +262,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
|||
coords_name, array_index)));
|
||||
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*
|
||||
|
@ -274,7 +273,7 @@ InspectorBuilder::MakeComparisonSamplerReferenceBodyFunction(
|
|||
const std::string& coords_name,
|
||||
const std::string& depth_name,
|
||||
const ast::Type* base_type,
|
||||
ast::DecorationList decorations) {
|
||||
ast::AttributeList attributes) {
|
||||
std::string result_name = "sampler_result";
|
||||
|
||||
ast::StatementList stmts;
|
||||
|
@ -285,7 +284,7 @@ InspectorBuilder::MakeComparisonSamplerReferenceBodyFunction(
|
|||
sampler_name, coords_name, depth_name)));
|
||||
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(
|
||||
|
@ -331,9 +330,9 @@ void InspectorBuilder::AddStorageTexture(const std::string& name,
|
|||
uint32_t group,
|
||||
uint32_t binding) {
|
||||
Global(name, type,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(binding),
|
||||
create<ast::GroupDecoration>(group),
|
||||
ast::AttributeList{
|
||||
create<ast::BindingAttribute>(binding),
|
||||
create<ast::GroupAttribute>(group),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -341,14 +340,14 @@ const ast::Function* InspectorBuilder::MakeStorageTextureBodyFunction(
|
|||
const std::string& func_name,
|
||||
const std::string& st_name,
|
||||
const ast::Type* dim_type,
|
||||
ast::DecorationList decorations) {
|
||||
ast::AttributeList attributes) {
|
||||
ast::StatementList stmts;
|
||||
|
||||
stmts.emplace_back(Decl(Var("dim", dim_type)));
|
||||
stmts.emplace_back(Assign("dim", Call("textureDimensions", st_name)));
|
||||
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(
|
||||
|
|
|
@ -21,11 +21,11 @@
|
|||
#include <vector>
|
||||
|
||||
#include "src/ast/call_statement.h"
|
||||
#include "src/ast/disable_validation_decoration.h"
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/stage_decoration.h"
|
||||
#include "src/ast/struct_block_decoration.h"
|
||||
#include "src/ast/workgroup_decoration.h"
|
||||
#include "src/ast/disable_validation_attribute.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
#include "src/ast/stage_attribute.h"
|
||||
#include "src/ast/struct_block_attribute.h"
|
||||
#include "src/ast/workgroup_attribute.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/sem/depth_texture_type.h"
|
||||
#include "src/sem/external_texture_type.h"
|
||||
|
@ -45,16 +45,16 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
|
||||
/// Generates an empty function
|
||||
/// @param name name of the function created
|
||||
/// @param decorations the function decorations
|
||||
void MakeEmptyBodyFunction(std::string name, ast::DecorationList decorations);
|
||||
/// @param attributes the function attributes
|
||||
void MakeEmptyBodyFunction(std::string name, ast::AttributeList attributes);
|
||||
|
||||
/// Generates a function that calls other functions
|
||||
/// @param caller name of the function created
|
||||
/// @param callees names of the functions to be called
|
||||
/// @param decorations the function decorations
|
||||
/// @param attributes the function attributes
|
||||
void MakeCallerBodyFunction(std::string caller,
|
||||
std::vector<std::string> callees,
|
||||
ast::DecorationList decorations);
|
||||
ast::AttributeList attributes);
|
||||
|
||||
/// Generates a struct that contains user-defined IO members
|
||||
/// @param name the name of the generated struct
|
||||
|
@ -76,11 +76,11 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
/// @param name name of the function created
|
||||
/// @param inout_vars tuples of {in, out} that will be converted into out = in
|
||||
/// calls in the function body
|
||||
/// @param decorations the function decorations
|
||||
/// @param attributes the function attributes
|
||||
void MakeInOutVariableBodyFunction(
|
||||
std::string name,
|
||||
std::vector<std::tuple<std::string, std::string>> inout_vars,
|
||||
ast::DecorationList decorations);
|
||||
ast::AttributeList attributes);
|
||||
|
||||
// TODO(crbug.com/tint/697): Remove this.
|
||||
/// 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 inout_vars tuples of {in, out} that will be converted into out = in
|
||||
/// calls in the function body
|
||||
/// @param decorations the function decorations
|
||||
/// @param attributes the function attributes
|
||||
/// @returns a function object
|
||||
const ast::Function* MakeInOutVariableCallerBodyFunction(
|
||||
std::string caller,
|
||||
std::string callee,
|
||||
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.
|
||||
/// @param name name of the variable to add
|
||||
|
@ -110,7 +110,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
const ast::Type* type,
|
||||
const ast::Expression* constructor) {
|
||||
return GlobalConst(name, type, constructor,
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Override(id),
|
||||
});
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
const ast::Type* type,
|
||||
const ast::Expression* constructor) {
|
||||
return GlobalConst(name, type, constructor,
|
||||
ast::DecorationList{
|
||||
ast::AttributeList{
|
||||
Override(),
|
||||
});
|
||||
}
|
||||
|
@ -136,13 +136,13 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
/// @param func name of the function created
|
||||
/// @param var name of the constant to be reference
|
||||
/// @param type type of the const being referenced
|
||||
/// @param decorations the function decorations
|
||||
/// @param attributes the function attributes
|
||||
/// @returns a function object
|
||||
const ast::Function* MakePlainGlobalReferenceBodyFunction(
|
||||
std::string func,
|
||||
std::string var,
|
||||
const ast::Type* type,
|
||||
ast::DecorationList decorations);
|
||||
ast::AttributeList attributes);
|
||||
|
||||
/// @param vec Vector of StageVariable to be searched
|
||||
/// @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.
|
||||
/// @param index index of the field within the struct
|
||||
/// @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
|
||||
const ast::StructMember* MakeStructMember(size_t index,
|
||||
const ast::Type* type,
|
||||
ast::DecorationList decorations);
|
||||
ast::AttributeList attributes);
|
||||
|
||||
/// Generates types appropriate for using in an uniform buffer
|
||||
/// @param name name for the type
|
||||
|
@ -270,7 +270,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
/// @param sampler_name name of the sampler to use
|
||||
/// @param coords_name name of the coords variable to use
|
||||
/// @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
|
||||
const ast::Function* MakeSamplerReferenceBodyFunction(
|
||||
const std::string& func_name,
|
||||
|
@ -278,7 +278,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
const std::string& sampler_name,
|
||||
const std::string& coords_name,
|
||||
const ast::Type* base_type,
|
||||
ast::DecorationList decorations);
|
||||
ast::AttributeList attributes);
|
||||
|
||||
/// Generates a function that references a specific sampler variable
|
||||
/// @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 array_index name of the array index variable to use
|
||||
/// @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
|
||||
const ast::Function* MakeSamplerReferenceBodyFunction(
|
||||
const std::string& func_name,
|
||||
|
@ -296,7 +296,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
const std::string& coords_name,
|
||||
const std::string& array_index,
|
||||
const ast::Type* base_type,
|
||||
ast::DecorationList decorations);
|
||||
ast::AttributeList attributes);
|
||||
|
||||
/// Generates a function that references a specific comparison sampler
|
||||
/// variable.
|
||||
|
@ -306,7 +306,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
/// @param coords_name name of the coords variable to use
|
||||
/// @param depth_name name of the depth reference to use
|
||||
/// @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
|
||||
const ast::Function* MakeComparisonSamplerReferenceBodyFunction(
|
||||
const std::string& func_name,
|
||||
|
@ -315,7 +315,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||
const std::string& coords_name,
|
||||
const std::string& depth_name,
|
||||
const ast::Type* base_type,
|
||||
ast::DecorationList decorations);
|
||||
ast::AttributeList attributes);
|
||||
|
||||
/// Gets an appropriate type for the data in a given texture type.
|
||||
/// @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 st_name name of the storage texture to use
|
||||
/// @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
|
||||
const ast::Function* MakeStorageTextureBodyFunction(
|
||||
const std::string& func_name,
|
||||
const std::string& st_name,
|
||||
const ast::Type* dim_type,
|
||||
ast::DecorationList decorations);
|
||||
ast::AttributeList attributes);
|
||||
|
||||
/// Get a generator function that returns a type appropriate for a stage
|
||||
/// variable with the given combination of component and composition type.
|
||||
|
|
|
@ -131,7 +131,7 @@ const ast::Statement* ProgramBuilder::WrapInStatement(
|
|||
const ast::Function* ProgramBuilder::WrapInFunction(
|
||||
const ast::StatementList 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)});
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "src/ast/assignment_statement.h"
|
||||
#include "src/ast/atomic.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/bool.h"
|
||||
#include "src/ast/bool_literal_expression.h"
|
||||
|
@ -35,7 +35,7 @@
|
|||
#include "src/ast/continue_statement.h"
|
||||
#include "src/ast/depth_multisampled_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/external_texture.h"
|
||||
#include "src/ast/f32.h"
|
||||
|
@ -45,27 +45,27 @@
|
|||
#include "src/ast/i32.h"
|
||||
#include "src/ast/if_statement.h"
|
||||
#include "src/ast/index_accessor_expression.h"
|
||||
#include "src/ast/interpolate_decoration.h"
|
||||
#include "src/ast/invariant_decoration.h"
|
||||
#include "src/ast/interpolate_attribute.h"
|
||||
#include "src/ast/invariant_attribute.h"
|
||||
#include "src/ast/loop_statement.h"
|
||||
#include "src/ast/matrix.h"
|
||||
#include "src/ast/member_accessor_expression.h"
|
||||
#include "src/ast/module.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/pointer.h"
|
||||
#include "src/ast/return_statement.h"
|
||||
#include "src/ast/sampled_texture.h"
|
||||
#include "src/ast/sampler.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/stride_decoration.h"
|
||||
#include "src/ast/struct_block_decoration.h"
|
||||
#include "src/ast/struct_member_align_decoration.h"
|
||||
#include "src/ast/struct_member_offset_decoration.h"
|
||||
#include "src/ast/struct_member_size_decoration.h"
|
||||
#include "src/ast/stride_attribute.h"
|
||||
#include "src/ast/struct_block_attribute.h"
|
||||
#include "src/ast/struct_member_align_attribute.h"
|
||||
#include "src/ast/struct_member_offset_attribute.h"
|
||||
#include "src/ast/struct_member_size_attribute.h"
|
||||
#include "src/ast/switch_statement.h"
|
||||
#include "src/ast/type_name.h"
|
||||
#include "src/ast/u32.h"
|
||||
|
@ -74,7 +74,7 @@
|
|||
#include "src/ast/variable_decl_statement.h"
|
||||
#include "src/ast/vector.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_id.h"
|
||||
#include "src/sem/array.h"
|
||||
|
@ -131,13 +131,13 @@ class ProgramBuilder {
|
|||
ast::StorageClass storage = ast::StorageClass::kNone;
|
||||
ast::Access access = ast::Access::kUndefined;
|
||||
const ast::Expression* constructor = nullptr;
|
||||
ast::DecorationList decorations = {};
|
||||
ast::AttributeList attributes = {};
|
||||
|
||||
private:
|
||||
void Set(ast::StorageClass sc) { storage = sc; }
|
||||
void Set(ast::Access ac) { access = ac; }
|
||||
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>
|
||||
void Apply(FIRST&& first, ARGS&&... args) {
|
||||
|
@ -640,28 +640,28 @@ class ProgramBuilder {
|
|||
|
||||
/// @param subtype the array element type
|
||||
/// @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`
|
||||
template <typename EXPR = ast::Expression*>
|
||||
const ast::Array* array(const ast::Type* subtype,
|
||||
EXPR&& n = nullptr,
|
||||
ast::DecorationList decos = {}) const {
|
||||
ast::AttributeList attrs = {}) const {
|
||||
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 subtype the array element type
|
||||
/// @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`
|
||||
template <typename EXPR = ast::Expression*>
|
||||
const ast::Array* array(const Source& source,
|
||||
const ast::Type* subtype,
|
||||
EXPR&& n = nullptr,
|
||||
ast::DecorationList decos = {}) const {
|
||||
ast::AttributeList attrs = {}) const {
|
||||
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
|
||||
|
@ -672,11 +672,11 @@ class ProgramBuilder {
|
|||
const ast::Array* array(const ast::Type* subtype,
|
||||
EXPR&& n,
|
||||
uint32_t stride) const {
|
||||
ast::DecorationList decos;
|
||||
ast::AttributeList attrs;
|
||||
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
|
||||
|
@ -689,11 +689,11 @@ class ProgramBuilder {
|
|||
const ast::Type* subtype,
|
||||
EXPR&& n,
|
||||
uint32_t stride) const {
|
||||
ast::DecorationList decos;
|
||||
ast::AttributeList attrs;
|
||||
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`
|
||||
|
@ -1322,7 +1322,7 @@ class ProgramBuilder {
|
|||
/// * ast::StorageClass - specifies the variable storage class
|
||||
/// * ast::Access - specifies the variable's access control
|
||||
/// * 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
|
||||
/// value.
|
||||
/// @returns a `ast::Variable` with the given name, type and additional
|
||||
|
@ -1334,7 +1334,7 @@ class ProgramBuilder {
|
|||
VarOptionals opts(std::forward<OPTIONAL>(optional)...);
|
||||
return create<ast::Variable>(Sym(std::forward<NAME>(name)), opts.storage,
|
||||
opts.access, type, false, opts.constructor,
|
||||
std::move(opts.decorations));
|
||||
std::move(opts.attributes));
|
||||
}
|
||||
|
||||
/// @param source the variable source
|
||||
|
@ -1345,7 +1345,7 @@ class ProgramBuilder {
|
|||
/// * ast::StorageClass - specifies the variable storage class
|
||||
/// * ast::Access - specifies the variable's access control
|
||||
/// * 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
|
||||
/// value.
|
||||
/// @returns a `ast::Variable` with the given name, storage and type
|
||||
|
@ -1357,67 +1357,67 @@ class ProgramBuilder {
|
|||
VarOptionals opts(std::forward<OPTIONAL>(optional)...);
|
||||
return create<ast::Variable>(source, Sym(std::forward<NAME>(name)),
|
||||
opts.storage, opts.access, type, false,
|
||||
opts.constructor, std::move(opts.decorations));
|
||||
opts.constructor, std::move(opts.attributes));
|
||||
}
|
||||
|
||||
/// @param name the variable name
|
||||
/// @param type the variable type
|
||||
/// @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
|
||||
template <typename NAME>
|
||||
const ast::Variable* Const(NAME&& name,
|
||||
const ast::Type* type,
|
||||
const ast::Expression* constructor,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
return create<ast::Variable>(
|
||||
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 name the variable name
|
||||
/// @param type the variable type
|
||||
/// @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
|
||||
template <typename NAME>
|
||||
const ast::Variable* Const(const Source& source,
|
||||
NAME&& name,
|
||||
const ast::Type* type,
|
||||
const ast::Expression* constructor,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
return create<ast::Variable>(
|
||||
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 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
|
||||
template <typename NAME>
|
||||
const ast::Variable* Param(NAME&& name,
|
||||
const ast::Type* type,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
return create<ast::Variable>(
|
||||
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 name the parameter name
|
||||
/// @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
|
||||
template <typename NAME>
|
||||
const ast::Variable* Param(const Source& source,
|
||||
NAME&& name,
|
||||
const ast::Type* type,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
return create<ast::Variable>(
|
||||
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
|
||||
|
@ -1427,7 +1427,7 @@ class ProgramBuilder {
|
|||
/// * ast::StorageClass - specifies the variable storage class
|
||||
/// * ast::Access - specifies the variable's access control
|
||||
/// * 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
|
||||
/// value.
|
||||
/// @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::Access - specifies the variable's access control
|
||||
/// * 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
|
||||
/// value.
|
||||
/// @returns a new `ast::Variable`, which is automatically registered as a
|
||||
|
@ -1471,7 +1471,7 @@ class ProgramBuilder {
|
|||
/// @param name the variable name
|
||||
/// @param type the variable type
|
||||
/// @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
|
||||
/// arguments of `args`, which is automatically registered as a global
|
||||
/// variable with the ast::Module.
|
||||
|
@ -1479,9 +1479,9 @@ class ProgramBuilder {
|
|||
const ast::Variable* GlobalConst(NAME&& name,
|
||||
const ast::Type* type,
|
||||
const ast::Expression* constructor,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
auto* var = Const(std::forward<NAME>(name), type, constructor,
|
||||
std::move(decorations));
|
||||
std::move(attributes));
|
||||
AST().AddGlobalVariable(var);
|
||||
return var;
|
||||
}
|
||||
|
@ -1490,7 +1490,7 @@ class ProgramBuilder {
|
|||
/// @param name the variable name
|
||||
/// @param type the variable type
|
||||
/// @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
|
||||
/// arguments of `args`, which is automatically registered as a global
|
||||
/// variable with the ast::Module.
|
||||
|
@ -1499,9 +1499,9 @@ class ProgramBuilder {
|
|||
NAME&& name,
|
||||
const ast::Type* type,
|
||||
const ast::Expression* constructor,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
auto* var = Const(source, std::forward<NAME>(name), type, constructor,
|
||||
std::move(decorations));
|
||||
std::move(attributes));
|
||||
AST().AddGlobalVariable(var);
|
||||
return var;
|
||||
}
|
||||
|
@ -1747,71 +1747,71 @@ class ProgramBuilder {
|
|||
Expr(std::forward<IDX>(idx)));
|
||||
}
|
||||
|
||||
/// Creates a ast::StructMemberOffsetDecoration
|
||||
/// Creates a ast::StructMemberOffsetAttribute
|
||||
/// @param val the offset value
|
||||
/// @returns the offset decoration pointer
|
||||
const ast::StructMemberOffsetDecoration* MemberOffset(uint32_t val) {
|
||||
return create<ast::StructMemberOffsetDecoration>(source_, val);
|
||||
/// @returns the offset attribute pointer
|
||||
const ast::StructMemberOffsetAttribute* MemberOffset(uint32_t val) {
|
||||
return create<ast::StructMemberOffsetAttribute>(source_, val);
|
||||
}
|
||||
|
||||
/// Creates a ast::StructMemberSizeDecoration
|
||||
/// Creates a ast::StructMemberSizeAttribute
|
||||
/// @param source the source information
|
||||
/// @param val the size value
|
||||
/// @returns the size decoration pointer
|
||||
const ast::StructMemberSizeDecoration* MemberSize(const Source& source,
|
||||
/// @returns the size attribute pointer
|
||||
const ast::StructMemberSizeAttribute* MemberSize(const Source& source,
|
||||
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
|
||||
/// @returns the size decoration pointer
|
||||
const ast::StructMemberSizeDecoration* MemberSize(uint32_t val) {
|
||||
return create<ast::StructMemberSizeDecoration>(source_, val);
|
||||
/// @returns the size attribute pointer
|
||||
const ast::StructMemberSizeAttribute* MemberSize(uint32_t val) {
|
||||
return create<ast::StructMemberSizeAttribute>(source_, val);
|
||||
}
|
||||
|
||||
/// Creates a ast::StructMemberAlignDecoration
|
||||
/// Creates a ast::StructMemberAlignAttribute
|
||||
/// @param source the source information
|
||||
/// @param val the align value
|
||||
/// @returns the align decoration pointer
|
||||
const ast::StructMemberAlignDecoration* MemberAlign(const Source& source,
|
||||
/// @returns the align attribute pointer
|
||||
const ast::StructMemberAlignAttribute* MemberAlign(const Source& source,
|
||||
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
|
||||
/// @returns the align decoration pointer
|
||||
const ast::StructMemberAlignDecoration* MemberAlign(uint32_t val) {
|
||||
return create<ast::StructMemberAlignDecoration>(source_, val);
|
||||
/// @returns the align attribute pointer
|
||||
const ast::StructMemberAlignAttribute* MemberAlign(uint32_t val) {
|
||||
return create<ast::StructMemberAlignAttribute>(source_, val);
|
||||
}
|
||||
|
||||
/// Creates a ast::StructBlockDecoration
|
||||
/// @returns the struct block decoration pointer
|
||||
const ast::StructBlockDecoration* StructBlock() {
|
||||
return create<ast::StructBlockDecoration>();
|
||||
/// Creates a ast::StructBlockAttribute
|
||||
/// @returns the struct block attribute pointer
|
||||
const ast::StructBlockAttribute* StructBlock() {
|
||||
return create<ast::StructBlockAttribute>();
|
||||
}
|
||||
|
||||
/// Creates the ast::GroupDecoration
|
||||
/// @param value group decoration index
|
||||
/// @returns the group decoration pointer
|
||||
const ast::GroupDecoration* Group(uint32_t value) {
|
||||
return create<ast::GroupDecoration>(value);
|
||||
/// Creates the ast::GroupAttribute
|
||||
/// @param value group attribute index
|
||||
/// @returns the group attribute pointer
|
||||
const ast::GroupAttribute* Group(uint32_t value) {
|
||||
return create<ast::GroupAttribute>(value);
|
||||
}
|
||||
|
||||
/// Creates the ast::BindingDecoration
|
||||
/// Creates the ast::BindingAttribute
|
||||
/// @param value the binding index
|
||||
/// @returns the binding deocration pointer
|
||||
const ast::BindingDecoration* Binding(uint32_t value) {
|
||||
return create<ast::BindingDecoration>(value);
|
||||
const ast::BindingAttribute* Binding(uint32_t value) {
|
||||
return create<ast::BindingAttribute>(value);
|
||||
}
|
||||
|
||||
/// Convenience function to create both a ast::GroupDecoration and
|
||||
/// ast::BindingDecoration
|
||||
/// Convenience function to create both a ast::GroupAttribute and
|
||||
/// ast::BindingAttribute
|
||||
/// @param group the group index
|
||||
/// @param binding the binding index
|
||||
/// @returns a decoration list with both the group and binding decorations
|
||||
ast::DecorationList GroupAndBinding(uint32_t group, uint32_t binding) {
|
||||
/// @returns a attribute list with both the group and binding attributes
|
||||
ast::AttributeList GroupAndBinding(uint32_t group, uint32_t binding) {
|
||||
return {Group(group), Binding(binding)};
|
||||
}
|
||||
|
||||
|
@ -1821,9 +1821,9 @@ class ProgramBuilder {
|
|||
/// @param params the function parameters
|
||||
/// @param type the function return type
|
||||
/// @param body the function body
|
||||
/// @param decorations the optional function decorations
|
||||
/// @param return_type_decorations the optional function return type
|
||||
/// decorations
|
||||
/// @param attributes the optional function attributes
|
||||
/// @param return_type_attributes the optional function return type
|
||||
/// attributes
|
||||
/// @returns the function pointer
|
||||
template <typename NAME>
|
||||
const ast::Function* Func(const Source& source,
|
||||
|
@ -1831,12 +1831,11 @@ class ProgramBuilder {
|
|||
ast::VariableList params,
|
||||
const ast::Type* type,
|
||||
ast::StatementList body,
|
||||
ast::DecorationList decorations = {},
|
||||
ast::DecorationList return_type_decorations = {}) {
|
||||
auto* func =
|
||||
create<ast::Function>(source, Sym(std::forward<NAME>(name)), params,
|
||||
type, create<ast::BlockStatement>(body),
|
||||
decorations, return_type_decorations);
|
||||
ast::AttributeList attributes = {},
|
||||
ast::AttributeList return_type_attributes = {}) {
|
||||
auto* func = create<ast::Function>(
|
||||
source, Sym(std::forward<NAME>(name)), params, type,
|
||||
create<ast::BlockStatement>(body), attributes, return_type_attributes);
|
||||
AST().AddFunction(func);
|
||||
return func;
|
||||
}
|
||||
|
@ -1846,20 +1845,20 @@ class ProgramBuilder {
|
|||
/// @param params the function parameters
|
||||
/// @param type the function return type
|
||||
/// @param body the function body
|
||||
/// @param decorations the optional function decorations
|
||||
/// @param return_type_decorations the optional function return type
|
||||
/// decorations
|
||||
/// @param attributes the optional function attributes
|
||||
/// @param return_type_attributes the optional function return type
|
||||
/// attributes
|
||||
/// @returns the function pointer
|
||||
template <typename NAME>
|
||||
const ast::Function* Func(NAME&& name,
|
||||
ast::VariableList params,
|
||||
const ast::Type* type,
|
||||
ast::StatementList body,
|
||||
ast::DecorationList decorations = {},
|
||||
ast::DecorationList return_type_decorations = {}) {
|
||||
ast::AttributeList attributes = {},
|
||||
ast::AttributeList return_type_attributes = {}) {
|
||||
auto* func = create<ast::Function>(Sym(std::forward<NAME>(name)), params,
|
||||
type, create<ast::BlockStatement>(body),
|
||||
decorations, return_type_decorations);
|
||||
attributes, return_type_attributes);
|
||||
AST().AddFunction(func);
|
||||
return func;
|
||||
}
|
||||
|
@ -1960,16 +1959,16 @@ class ProgramBuilder {
|
|||
/// @param source the source information
|
||||
/// @param name the struct name
|
||||
/// @param members the struct members
|
||||
/// @param decorations the optional struct decorations
|
||||
/// @param attributes the optional struct attributes
|
||||
/// @returns the struct type
|
||||
template <typename NAME>
|
||||
const ast::Struct* Structure(const Source& source,
|
||||
NAME&& name,
|
||||
ast::StructMemberList members,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
auto sym = Sym(std::forward<NAME>(name));
|
||||
auto* type = create<ast::Struct>(source, sym, std::move(members),
|
||||
std::move(decorations));
|
||||
std::move(attributes));
|
||||
AST().AddTypeDecl(type);
|
||||
return type;
|
||||
}
|
||||
|
@ -1977,15 +1976,15 @@ class ProgramBuilder {
|
|||
/// Creates a ast::Struct registering it with the AST().TypeDecls().
|
||||
/// @param name the struct name
|
||||
/// @param members the struct members
|
||||
/// @param decorations the optional struct decorations
|
||||
/// @param attributes the optional struct attributes
|
||||
/// @returns the struct type
|
||||
template <typename NAME>
|
||||
const ast::Struct* Structure(NAME&& name,
|
||||
ast::StructMemberList members,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
auto sym = Sym(std::forward<NAME>(name));
|
||||
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);
|
||||
return type;
|
||||
}
|
||||
|
@ -1994,32 +1993,32 @@ class ProgramBuilder {
|
|||
/// @param source the source information
|
||||
/// @param name the struct member name
|
||||
/// @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
|
||||
template <typename NAME>
|
||||
const ast::StructMember* Member(const Source& source,
|
||||
NAME&& name,
|
||||
const ast::Type* type,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
return create<ast::StructMember>(source, Sym(std::forward<NAME>(name)),
|
||||
type, std::move(decorations));
|
||||
type, std::move(attributes));
|
||||
}
|
||||
|
||||
/// Creates a ast::StructMember
|
||||
/// @param name the struct member name
|
||||
/// @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
|
||||
template <typename NAME>
|
||||
const ast::StructMember* Member(NAME&& name,
|
||||
const ast::Type* type,
|
||||
ast::DecorationList decorations = {}) {
|
||||
ast::AttributeList attributes = {}) {
|
||||
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
|
||||
/// @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 type the struct member type
|
||||
/// @returns the struct member pointer
|
||||
|
@ -2029,8 +2028,8 @@ class ProgramBuilder {
|
|||
const ast::Type* type) {
|
||||
return create<ast::StructMember>(
|
||||
source_, Sym(std::forward<NAME>(name)), type,
|
||||
ast::DecorationList{
|
||||
create<ast::StructMemberOffsetDecoration>(offset),
|
||||
ast::AttributeList{
|
||||
create<ast::StructMemberOffsetAttribute>(offset),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2276,183 +2275,182 @@ class ProgramBuilder {
|
|||
return create<ast::FallthroughStatement>();
|
||||
}
|
||||
|
||||
/// Creates an ast::BuiltinDecoration
|
||||
/// Creates an ast::BuiltinAttribute
|
||||
/// @param source the source information
|
||||
/// @param builtin the builtin value
|
||||
/// @returns the builtin decoration pointer
|
||||
const ast::BuiltinDecoration* Builtin(const Source& source,
|
||||
/// @returns the builtin attribute pointer
|
||||
const ast::BuiltinAttribute* Builtin(const Source& source,
|
||||
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
|
||||
/// @returns the builtin decoration pointer
|
||||
const ast::BuiltinDecoration* Builtin(ast::Builtin builtin) {
|
||||
return create<ast::BuiltinDecoration>(source_, builtin);
|
||||
/// @returns the builtin attribute pointer
|
||||
const ast::BuiltinAttribute* Builtin(ast::Builtin builtin) {
|
||||
return create<ast::BuiltinAttribute>(source_, builtin);
|
||||
}
|
||||
|
||||
/// Creates an ast::InterpolateDecoration
|
||||
/// Creates an ast::InterpolateAttribute
|
||||
/// @param source the source information
|
||||
/// @param type the interpolation type
|
||||
/// @param sampling the interpolation sampling
|
||||
/// @returns the interpolate decoration pointer
|
||||
const ast::InterpolateDecoration* Interpolate(
|
||||
/// @returns the interpolate attribute pointer
|
||||
const ast::InterpolateAttribute* Interpolate(
|
||||
const Source& source,
|
||||
ast::InterpolationType type,
|
||||
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 sampling the interpolation sampling
|
||||
/// @returns the interpolate decoration pointer
|
||||
const ast::InterpolateDecoration* Interpolate(
|
||||
/// @returns the interpolate attribute pointer
|
||||
const ast::InterpolateAttribute* Interpolate(
|
||||
ast::InterpolationType type,
|
||||
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
|
||||
/// @returns the interpolate decoration pointer
|
||||
const ast::InterpolateDecoration* Flat(const Source& source) {
|
||||
/// @returns the interpolate attribute pointer
|
||||
const ast::InterpolateAttribute* Flat(const Source& source) {
|
||||
return Interpolate(source, ast::InterpolationType::kFlat);
|
||||
}
|
||||
|
||||
/// Creates an ast::InterpolateDecoration using flat interpolation
|
||||
/// @returns the interpolate decoration pointer
|
||||
const ast::InterpolateDecoration* Flat() {
|
||||
/// Creates an ast::InterpolateAttribute using flat interpolation
|
||||
/// @returns the interpolate attribute pointer
|
||||
const ast::InterpolateAttribute* Flat() {
|
||||
return Interpolate(ast::InterpolationType::kFlat);
|
||||
}
|
||||
|
||||
/// Creates an ast::InvariantDecoration
|
||||
/// Creates an ast::InvariantAttribute
|
||||
/// @param source the source information
|
||||
/// @returns the invariant decoration pointer
|
||||
const ast::InvariantDecoration* Invariant(const Source& source) {
|
||||
return create<ast::InvariantDecoration>(source);
|
||||
/// @returns the invariant attribute pointer
|
||||
const ast::InvariantAttribute* Invariant(const Source& source) {
|
||||
return create<ast::InvariantAttribute>(source);
|
||||
}
|
||||
|
||||
/// Creates an ast::InvariantDecoration
|
||||
/// @returns the invariant decoration pointer
|
||||
const ast::InvariantDecoration* Invariant() {
|
||||
return create<ast::InvariantDecoration>(source_);
|
||||
/// Creates an ast::InvariantAttribute
|
||||
/// @returns the invariant attribute pointer
|
||||
const ast::InvariantAttribute* Invariant() {
|
||||
return create<ast::InvariantAttribute>(source_);
|
||||
}
|
||||
|
||||
/// Creates an ast::LocationDecoration
|
||||
/// Creates an ast::LocationAttribute
|
||||
/// @param source the source information
|
||||
/// @param location the location value
|
||||
/// @returns the location decoration pointer
|
||||
const ast::LocationDecoration* Location(const Source& source,
|
||||
/// @returns the location attribute pointer
|
||||
const ast::LocationAttribute* Location(const Source& source,
|
||||
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
|
||||
/// @returns the location decoration pointer
|
||||
const ast::LocationDecoration* Location(uint32_t location) {
|
||||
return create<ast::LocationDecoration>(source_, location);
|
||||
/// @returns the location attribute pointer
|
||||
const ast::LocationAttribute* Location(uint32_t 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 id the id value
|
||||
/// @returns the override decoration pointer
|
||||
const ast::OverrideDecoration* Override(const Source& source, uint32_t id) {
|
||||
return create<ast::OverrideDecoration>(source, id);
|
||||
/// @returns the override attribute pointer
|
||||
const ast::OverrideAttribute* Override(const Source& source, uint32_t 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
|
||||
/// @returns the override decoration pointer
|
||||
const ast::OverrideDecoration* Override(uint32_t id) {
|
||||
/// @returns the override attribute pointer
|
||||
const ast::OverrideAttribute* Override(uint32_t 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
|
||||
/// @returns the override decoration pointer
|
||||
const ast::OverrideDecoration* Override(const Source& source) {
|
||||
return create<ast::OverrideDecoration>(source);
|
||||
/// @returns the override attribute pointer
|
||||
const ast::OverrideAttribute* Override(const Source& source) {
|
||||
return create<ast::OverrideAttribute>(source);
|
||||
}
|
||||
|
||||
/// Creates an ast::OverrideDecoration without a constant ID
|
||||
/// @returns the override decoration pointer
|
||||
const ast::OverrideDecoration* Override() { return Override(source_); }
|
||||
/// Creates an ast::OverrideAttribute without a constant ID
|
||||
/// @returns the override attribute pointer
|
||||
const ast::OverrideAttribute* Override() { return Override(source_); }
|
||||
|
||||
/// Creates an ast::StageDecoration
|
||||
/// Creates an ast::StageAttribute
|
||||
/// @param source the source information
|
||||
/// @param stage the pipeline stage
|
||||
/// @returns the stage decoration pointer
|
||||
const ast::StageDecoration* Stage(const Source& source,
|
||||
/// @returns the stage attribute pointer
|
||||
const ast::StageAttribute* Stage(const Source& source,
|
||||
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
|
||||
/// @returns the stage decoration pointer
|
||||
const ast::StageDecoration* Stage(ast::PipelineStage stage) {
|
||||
return create<ast::StageDecoration>(source_, stage);
|
||||
/// @returns the stage attribute pointer
|
||||
const ast::StageAttribute* Stage(ast::PipelineStage stage) {
|
||||
return create<ast::StageAttribute>(source_, stage);
|
||||
}
|
||||
|
||||
/// Creates an ast::WorkgroupDecoration
|
||||
/// Creates an ast::WorkgroupAttribute
|
||||
/// @param x the x dimension expression
|
||||
/// @returns the workgroup decoration pointer
|
||||
/// @returns the workgroup attribute pointer
|
||||
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);
|
||||
}
|
||||
|
||||
/// Creates an ast::WorkgroupDecoration
|
||||
/// Creates an ast::WorkgroupAttribute
|
||||
/// @param x the x 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>
|
||||
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),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
/// Creates an ast::WorkgroupDecoration
|
||||
/// Creates an ast::WorkgroupAttribute
|
||||
/// @param source the source information
|
||||
/// @param x the x dimension expression
|
||||
/// @param y the y 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>
|
||||
const ast::WorkgroupDecoration* WorkgroupSize(const Source& source,
|
||||
const ast::WorkgroupAttribute* WorkgroupSize(const Source& source,
|
||||
EXPR_X&& x,
|
||||
EXPR_Y&& y,
|
||||
EXPR_Z&& z) {
|
||||
return create<ast::WorkgroupDecoration>(
|
||||
return create<ast::WorkgroupAttribute>(
|
||||
source, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
|
||||
Expr(std::forward<EXPR_Z>(z)));
|
||||
}
|
||||
|
||||
/// Creates an ast::WorkgroupDecoration
|
||||
/// Creates an ast::WorkgroupAttribute
|
||||
/// @param x the x dimension expression
|
||||
/// @param y the y 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>
|
||||
const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x,
|
||||
const ast::WorkgroupAttribute* WorkgroupSize(EXPR_X&& x,
|
||||
EXPR_Y&& y,
|
||||
EXPR_Z&& z) {
|
||||
return create<ast::WorkgroupDecoration>(
|
||||
return create<ast::WorkgroupAttribute>(
|
||||
source_, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
|
||||
Expr(std::forward<EXPR_Z>(z)));
|
||||
}
|
||||
|
||||
/// Creates an ast::DisableValidationDecoration
|
||||
/// Creates an ast::DisableValidationAttribute
|
||||
/// @param validation the validation to disable
|
||||
/// @returns the disable validation decoration pointer
|
||||
const ast::DisableValidationDecoration* Disable(
|
||||
/// @returns the disable validation attribute pointer
|
||||
const ast::DisableValidationAttribute* Disable(
|
||||
ast::DisabledValidation validation) {
|
||||
return ASTNodes().Create<ast::DisableValidationDecoration>(ID(),
|
||||
validation);
|
||||
return ASTNodes().Create<ast::DisableValidationAttribute>(ID(), validation);
|
||||
}
|
||||
|
||||
/// Sets the current builder source to `src`
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "src/ast/bitcast_expression.h"
|
||||
#include "src/ast/break_statement.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/continue_statement.h"
|
||||
#include "src/ast/discard_statement.h"
|
||||
|
@ -29,7 +29,7 @@
|
|||
#include "src/ast/if_statement.h"
|
||||
#include "src/ast/loop_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/unary_op_expression.h"
|
||||
#include "src/ast/variable_decl_statement.h"
|
||||
|
@ -712,8 +712,8 @@ struct LoopStatementBuilder
|
|||
|
||||
/// @param decos a list of parsed decorations
|
||||
/// @returns true if the decorations include a SampleMask builtin
|
||||
bool HasBuiltinSampleMask(const ast::DecorationList& decos) {
|
||||
if (auto* builtin = ast::GetDecoration<ast::BuiltinDecoration>(decos)) {
|
||||
bool HasBuiltinSampleMask(const ast::AttributeList& decos) {
|
||||
if (auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(decos)) {
|
||||
return builtin->builtin == ast::Builtin::kSampleMask;
|
||||
}
|
||||
return false;
|
||||
|
@ -915,7 +915,7 @@ bool FunctionEmitter::Emit() {
|
|||
builder_.AST().AddFunction(create<ast::Function>(
|
||||
decl.source, builder_.Symbols().Register(decl.name),
|
||||
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()) {
|
||||
|
@ -953,7 +953,7 @@ const ast::BlockStatement* FunctionEmitter::MakeFunctionBody() {
|
|||
|
||||
bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
||||
const Type* var_type,
|
||||
ast::DecorationList* decos,
|
||||
ast::AttributeList* decos,
|
||||
std::vector<int> index_prefix,
|
||||
const Type* tip_type,
|
||||
const Type* forced_param_type,
|
||||
|
@ -997,7 +997,7 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
|||
index_prefix.push_back(0);
|
||||
for (int i = 0; i < static_cast<int>(members.size()); ++i) {
|
||||
index_prefix.back() = i;
|
||||
ast::DecorationList member_decos(*decos);
|
||||
ast::AttributeList member_decos(*decos);
|
||||
if (!parser_impl_.ConvertPipelineDecorations(
|
||||
struct_type,
|
||||
parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
|
||||
|
@ -1015,7 +1015,7 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
|||
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;
|
||||
|
||||
|
@ -1067,22 +1067,22 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
|||
return success();
|
||||
}
|
||||
|
||||
void FunctionEmitter::IncrementLocation(ast::DecorationList* decos) {
|
||||
for (auto*& deco : *decos) {
|
||||
if (auto* loc_deco = deco->As<ast::LocationDecoration>()) {
|
||||
// Replace this location decoration with a new one with one higher index.
|
||||
void FunctionEmitter::IncrementLocation(ast::AttributeList* attributes) {
|
||||
for (auto*& attr : *attributes) {
|
||||
if (auto* loc_attr = attr->As<ast::LocationAttribute>()) {
|
||||
// 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
|
||||
// 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::DecorationList& decos) {
|
||||
for (auto* const& deco : decos) {
|
||||
if (deco->Is<ast::LocationDecoration>()) {
|
||||
return deco;
|
||||
const ast::Attribute* FunctionEmitter::GetLocation(
|
||||
const ast::AttributeList& attributes) {
|
||||
for (auto* const& attr : attributes) {
|
||||
if (attr->Is<ast::LocationAttribute>()) {
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -1090,7 +1090,7 @@ const ast::Decoration* FunctionEmitter::GetLocation(
|
|||
|
||||
bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
|
||||
const Type* var_type,
|
||||
ast::DecorationList* decos,
|
||||
ast::AttributeList* decos,
|
||||
std::vector<int> index_prefix,
|
||||
const Type* tip_type,
|
||||
const Type* forced_member_type,
|
||||
|
@ -1135,7 +1135,7 @@ bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
|
|||
index_prefix.push_back(0);
|
||||
for (int i = 0; i < static_cast<int>(members.size()); ++i) {
|
||||
index_prefix.back() = i;
|
||||
ast::DecorationList member_decos(*decos);
|
||||
ast::AttributeList member_decos(*decos);
|
||||
if (!parser_impl_.ConvertPipelineDecorations(
|
||||
struct_type,
|
||||
parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
|
||||
|
@ -1153,7 +1153,7 @@ bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
|
|||
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;
|
||||
// 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);
|
||||
auto* store_type = GetVariableStoreType(*var);
|
||||
auto* forced_param_type = store_type;
|
||||
ast::DecorationList param_decos;
|
||||
ast::AttributeList param_decos;
|
||||
if (!parser_impl_.ConvertDecorationsForVariable(var_id, &forced_param_type,
|
||||
¶m_decos, true)) {
|
||||
// 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
|
||||
// a gl_Position variable. Substitute the type.
|
||||
const Type* param_type = ty_.Vector(ty_.F32(), 4);
|
||||
ast::DecorationList out_decos{
|
||||
create<ast::BuiltinDecoration>(source, ast::Builtin::kPosition)};
|
||||
ast::AttributeList out_decos{
|
||||
create<ast::BuiltinAttribute>(source, ast::Builtin::kPosition)};
|
||||
|
||||
const auto var_name = namer_.GetName(var_id);
|
||||
return_members.push_back(
|
||||
|
@ -1307,7 +1307,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||
TINT_ASSERT(Reader, var->opcode() == SpvOpVariable);
|
||||
const Type* store_type = GetVariableStoreType(*var);
|
||||
const Type* forced_member_type = store_type;
|
||||
ast::DecorationList out_decos;
|
||||
ast::AttributeList out_decos;
|
||||
if (!parser_impl_.ConvertDecorationsForVariable(
|
||||
var_id, &forced_member_type, &out_decos, true)) {
|
||||
// This occurs, and is not an error, for the PointSize builtin.
|
||||
|
@ -1349,7 +1349,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||
} else {
|
||||
// Create and register the result type.
|
||||
auto* str = create<ast::Struct>(Source{}, return_struct_sym,
|
||||
return_members, ast::DecorationList{});
|
||||
return_members, ast::AttributeList{});
|
||||
parser_impl_.AddTypeDecl(return_struct_sym, str);
|
||||
return_type = builder_.ty.Of(str);
|
||||
|
||||
|
@ -1361,8 +1361,8 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||
}
|
||||
|
||||
auto* body = create<ast::BlockStatement>(source, stmts);
|
||||
ast::DecorationList fn_decos;
|
||||
fn_decos.emplace_back(create<ast::StageDecoration>(source, ep_info_->stage));
|
||||
ast::AttributeList fn_attrs;
|
||||
fn_attrs.emplace_back(create<ast::StageAttribute>(source, ep_info_->stage));
|
||||
|
||||
if (ep_info_->stage == ast::PipelineStage::kCompute) {
|
||||
auto& size = ep_info_->workgroup_size;
|
||||
|
@ -1372,15 +1372,14 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||
size.y ? builder_.Expr(static_cast<int>(size.y)) : nullptr;
|
||||
const ast::Expression* z =
|
||||
size.z ? builder_.Expr(static_cast<int>(size.z)) : nullptr;
|
||||
fn_decos.emplace_back(
|
||||
create<ast::WorkgroupDecoration>(Source{}, x, y, z));
|
||||
fn_attrs.emplace_back(create<ast::WorkgroupAttribute>(Source{}, x, y, z));
|
||||
}
|
||||
}
|
||||
|
||||
builder_.AST().AddFunction(
|
||||
create<ast::Function>(source, builder_.Symbols().Register(ep_info_->name),
|
||||
std::move(decl.params), return_type, body,
|
||||
std::move(fn_decos), ast::DecorationList{}));
|
||||
std::move(fn_attrs), ast::AttributeList{}));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1412,7 +1411,7 @@ bool FunctionEmitter::ParseFunctionDeclaration(FunctionDeclaration* decl) {
|
|||
if (type != nullptr) {
|
||||
auto* ast_param = parser_impl_.MakeVariable(
|
||||
param->result_id(), ast::StorageClass::kNone, type, true, nullptr,
|
||||
ast::DecorationList{});
|
||||
ast::AttributeList{});
|
||||
// Parameters are treated as const declarations.
|
||||
ast_params.emplace_back(ast_param);
|
||||
// The value is accessible by name.
|
||||
|
@ -1428,7 +1427,7 @@ bool FunctionEmitter::ParseFunctionDeclaration(FunctionDeclaration* decl) {
|
|||
decl->name = name;
|
||||
decl->params = std::move(ast_params);
|
||||
decl->return_type = ret_ty;
|
||||
decl->decorations.clear();
|
||||
decl->attributes.clear();
|
||||
|
||||
return success();
|
||||
}
|
||||
|
@ -2513,7 +2512,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
|
|||
}
|
||||
auto* var = parser_impl_.MakeVariable(
|
||||
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);
|
||||
AddStatement(var_decl_stmt);
|
||||
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>(
|
||||
Source{},
|
||||
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);
|
||||
identifier_types_.emplace(id, type);
|
||||
}
|
||||
|
@ -3490,7 +3489,7 @@ bool FunctionEmitter::EmitConstDefinition(
|
|||
expr = AddressOfIfNeeded(expr, &inst);
|
||||
auto* ast_const = parser_impl_.MakeVariable(
|
||||
inst.result_id(), ast::StorageClass::kNone, expr.type, true, expr.expr,
|
||||
ast::DecorationList{});
|
||||
ast::AttributeList{});
|
||||
if (!ast_const) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -441,7 +441,7 @@ class FunctionEmitter {
|
|||
/// @returns false if emission failed
|
||||
bool EmitPipelineInput(std::string var_name,
|
||||
const Type* var_type,
|
||||
ast::DecorationList* decos,
|
||||
ast::AttributeList* decos,
|
||||
std::vector<int> index_prefix,
|
||||
const Type* tip_type,
|
||||
const Type* forced_param_type,
|
||||
|
@ -470,24 +470,24 @@ class FunctionEmitter {
|
|||
/// @returns false if emission failed
|
||||
bool EmitPipelineOutput(std::string var_name,
|
||||
const Type* var_type,
|
||||
ast::DecorationList* decos,
|
||||
ast::AttributeList* decos,
|
||||
std::vector<int> index_prefix,
|
||||
const Type* tip_type,
|
||||
const Type* forced_member_type,
|
||||
ast::StructMemberList* return_members,
|
||||
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
|
||||
/// location decoration exists.
|
||||
/// Assumes the list contains at most one Location decoration.
|
||||
/// @param decos the decoration list to modify
|
||||
void IncrementLocation(ast::DecorationList* decos);
|
||||
/// location attribute exists.
|
||||
/// Assumes the list contains at most one Location attribute.
|
||||
/// @param attributes the attribute list to modify
|
||||
void IncrementLocation(ast::AttributeList* attributes);
|
||||
|
||||
/// Returns the Location dcoration, if it exists.
|
||||
/// @param decos the list of decorations to search
|
||||
/// @returns the Location decoration, or nullptr if it doesn't exist
|
||||
const ast::Decoration* GetLocation(const ast::DecorationList& decos);
|
||||
/// Returns the Location attribute, if it exists.
|
||||
/// @param attributes the list of attributes to search
|
||||
/// @returns the Location attribute, or nullptr if it doesn't exist
|
||||
const ast::Attribute* GetLocation(const ast::AttributeList& attributes);
|
||||
|
||||
/// Create an ast::BlockStatement representing the body of the function.
|
||||
/// This creates the statement stack, which is non-empty for the lifetime
|
||||
|
@ -948,8 +948,8 @@ class FunctionEmitter {
|
|||
ast::VariableList params;
|
||||
/// Function return type
|
||||
const Type* return_type;
|
||||
/// Function decorations
|
||||
ast::DecorationList decorations;
|
||||
/// Function attributes
|
||||
ast::AttributeList attributes;
|
||||
};
|
||||
|
||||
/// Parse the function declaration, which comprises the name, parameters, and
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
#include "source/opt/build_module.h"
|
||||
#include "src/ast/bitcast_expression.h"
|
||||
#include "src/ast/disable_validation_decoration.h"
|
||||
#include "src/ast/interpolate_decoration.h"
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/disable_validation_attribute.h"
|
||||
#include "src/ast/interpolate_attribute.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
#include "src/ast/type_name.h"
|
||||
#include "src/ast/unary_op_expression.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);
|
||||
}
|
||||
|
||||
ast::DecorationList ParserImpl::ConvertMemberDecoration(
|
||||
ast::AttributeList ParserImpl::ConvertMemberDecoration(
|
||||
uint32_t struct_type_id,
|
||||
uint32_t member_index,
|
||||
const Type* member_ty,
|
||||
|
@ -458,7 +458,7 @@ ast::DecorationList ParserImpl::ConvertMemberDecoration(
|
|||
return {};
|
||||
}
|
||||
return {
|
||||
create<ast::StructMemberOffsetDecoration>(Source{}, decoration[1]),
|
||||
create<ast::StructMemberOffsetAttribute>(Source{}, decoration[1]),
|
||||
};
|
||||
case SpvDecorationNonReadable:
|
||||
// WGSL doesn't have a member decoration for this. Silently drop it.
|
||||
|
@ -505,9 +505,9 @@ ast::DecorationList ParserImpl::ConvertMemberDecoration(
|
|||
return {};
|
||||
}
|
||||
return {
|
||||
create<ast::StrideDecoration>(Source{}, decoration[1]),
|
||||
builder_.ASTNodes().Create<ast::DisableValidationDecoration>(
|
||||
builder_.ID(), ast::DisabledValidation::kIgnoreStrideDecoration),
|
||||
create<ast::StrideAttribute>(Source{}, decoration[1]),
|
||||
builder_.ASTNodes().Create<ast::DisableValidationAttribute>(
|
||||
builder_.ID(), ast::DisabledValidation::kIgnoreStrideAttribute),
|
||||
};
|
||||
}
|
||||
default:
|
||||
|
@ -1152,7 +1152,7 @@ const Type* ParserImpl::ConvertType(
|
|||
}
|
||||
|
||||
bool is_non_writable = false;
|
||||
ast::DecorationList ast_member_decorations;
|
||||
ast::AttributeList ast_member_decorations;
|
||||
for (auto& decoration : GetDecorationsForMember(type_id, member_index)) {
|
||||
if (IsPipelineDecoration(decoration)) {
|
||||
// IO decorations are handled when emitting the entry point.
|
||||
|
@ -1198,7 +1198,7 @@ const Type* ParserImpl::ConvertType(
|
|||
// Now make the struct.
|
||||
auto sym = builder_.Symbols().Register(name);
|
||||
auto* ast_struct = create<ast::Struct>(Source{}, sym, std::move(ast_members),
|
||||
ast::DecorationList());
|
||||
ast::AttributeList());
|
||||
if (num_non_writable_members == members.size()) {
|
||||
read_only_struct_types_.insert(ast_struct->name);
|
||||
}
|
||||
|
@ -1386,7 +1386,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
|||
break;
|
||||
}
|
||||
if (ast_type && ast_expr) {
|
||||
ast::DecorationList spec_id_decos;
|
||||
ast::AttributeList spec_id_decos;
|
||||
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
|
||||
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
|
||||
const uint32_t id = deco[1];
|
||||
|
@ -1395,7 +1395,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
|||
"between 0 and 65535: 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);
|
||||
break;
|
||||
}
|
||||
|
@ -1526,7 +1526,7 @@ bool ParserImpl::EmitModuleScopeVariables() {
|
|||
}
|
||||
auto* ast_var =
|
||||
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)
|
||||
if (ast_var) {
|
||||
builder_.AST().AddGlobalVariable(ast_var);
|
||||
|
@ -1599,7 +1599,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
|||
const Type* storage_type,
|
||||
bool is_const,
|
||||
const ast::Expression* constructor,
|
||||
ast::DecorationList decorations) {
|
||||
ast::AttributeList decorations) {
|
||||
if (storage_type == nullptr) {
|
||||
Fail() << "internal error: can't make ast::Variable for null type";
|
||||
return nullptr;
|
||||
|
@ -1640,7 +1640,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
|||
|
||||
bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
|
||||
const Type** store_type,
|
||||
ast::DecorationList* decorations,
|
||||
ast::AttributeList* decorations,
|
||||
bool transfer_pipeline_io) {
|
||||
DecorationList non_builtin_pipeline_decorations;
|
||||
for (auto& deco : GetDecorationsFor(id)) {
|
||||
|
@ -1702,7 +1702,7 @@ bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
|
|||
}
|
||||
if (transfer_pipeline_io) {
|
||||
decorations->emplace_back(
|
||||
create<ast::BuiltinDecoration>(Source{}, ast_builtin));
|
||||
create<ast::BuiltinAttribute>(Source{}, ast_builtin));
|
||||
}
|
||||
}
|
||||
if (transfer_pipeline_io && IsPipelineDecoration(deco)) {
|
||||
|
@ -1713,8 +1713,7 @@ bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
|
|||
return Fail() << "malformed DescriptorSet decoration on ID " << id
|
||||
<< ": has no operand";
|
||||
}
|
||||
decorations->emplace_back(
|
||||
create<ast::GroupDecoration>(Source{}, deco[1]));
|
||||
decorations->emplace_back(create<ast::GroupAttribute>(Source{}, deco[1]));
|
||||
}
|
||||
if (deco[0] == SpvDecorationBinding) {
|
||||
if (deco.size() == 1) {
|
||||
|
@ -1722,7 +1721,7 @@ bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
|
|||
<< ": has no operand";
|
||||
}
|
||||
decorations->emplace_back(
|
||||
create<ast::BindingDecoration>(Source{}, deco[1]));
|
||||
create<ast::BindingAttribute>(Source{}, deco[1]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1750,31 +1749,31 @@ DecorationList ParserImpl::GetMemberPipelineDecorations(
|
|||
return result;
|
||||
}
|
||||
|
||||
const ast::Decoration* ParserImpl::SetLocation(
|
||||
ast::DecorationList* decos,
|
||||
const ast::Decoration* replacement) {
|
||||
const ast::Attribute* ParserImpl::SetLocation(
|
||||
ast::AttributeList* attributes,
|
||||
const ast::Attribute* replacement) {
|
||||
if (!replacement) {
|
||||
return nullptr;
|
||||
}
|
||||
for (auto*& deco : *decos) {
|
||||
if (deco->Is<ast::LocationDecoration>()) {
|
||||
// Replace this location decoration with the replacement.
|
||||
for (auto*& attribute : *attributes) {
|
||||
if (attribute->Is<ast::LocationAttribute>()) {
|
||||
// Replace this location attribute with the replacement.
|
||||
// The old one doesn't leak because it's kept in the builder's AST node
|
||||
// list.
|
||||
const ast::Decoration* result = nullptr;
|
||||
result = deco;
|
||||
deco = replacement;
|
||||
const ast::Attribute* result = nullptr;
|
||||
result = attribute;
|
||||
attribute = replacement;
|
||||
return result; // Assume there is only one such decoration.
|
||||
}
|
||||
}
|
||||
// The list didn't have a location. Add it.
|
||||
decos->push_back(replacement);
|
||||
attributes->push_back(replacement);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
|
||||
const DecorationList& decorations,
|
||||
ast::DecorationList* ast_decos) {
|
||||
ast::AttributeList* attributes) {
|
||||
// Vulkan defaults to perspective-correct interpolation.
|
||||
ast::InterpolationType type = ast::InterpolationType::kPerspective;
|
||||
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 "
|
||||
"literal operand";
|
||||
}
|
||||
SetLocation(ast_decos,
|
||||
create<ast::LocationDecoration>(Source{}, deco[1]));
|
||||
SetLocation(attributes,
|
||||
create<ast::LocationAttribute>(Source{}, deco[1]));
|
||||
if (store_type->IsIntegerScalarOrVector()) {
|
||||
// Default to flat interpolation for integral user-defined IO types.
|
||||
type = ast::InterpolationType::kFlat;
|
||||
|
@ -1830,7 +1829,7 @@ bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
|
|||
sampling == ast::InterpolationSampling::kNone) {
|
||||
// This is the default. Don't add a decoration.
|
||||
} else {
|
||||
ast_decos->emplace_back(create<ast::InterpolateDecoration>(type, sampling));
|
||||
attributes->emplace_back(create<ast::InterpolateAttribute>(type, sampling));
|
||||
}
|
||||
|
||||
return success();
|
||||
|
|
|
@ -243,34 +243,34 @@ class ParserImpl : Reader {
|
|||
/// @param id the ID of the SPIR-V variable
|
||||
/// @param store_type the WGSL store type for the variable, which should be
|
||||
/// 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,
|
||||
/// or locations) will update the store type and the decorations list
|
||||
/// @returns false when the variable should not be emitted as a variable
|
||||
bool ConvertDecorationsForVariable(uint32_t id,
|
||||
const Type** store_type,
|
||||
ast::DecorationList* ast_decos,
|
||||
ast::AttributeList* attributes,
|
||||
bool transfer_pipeline_io);
|
||||
|
||||
/// Converts SPIR-V decorations for pipeline IO into AST decorations.
|
||||
/// @param store_type the store type for the variable or member
|
||||
/// @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
|
||||
bool ConvertPipelineDecorations(const Type* store_type,
|
||||
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
|
||||
/// replacement is nullptr.
|
||||
/// 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
|
||||
/// @returns the location decoration that was replaced, if one was replaced,
|
||||
/// or null otherwise.
|
||||
const ast::Decoration* SetLocation(ast::DecorationList* decos,
|
||||
const ast::Decoration* replacement);
|
||||
const ast::Attribute* SetLocation(ast::AttributeList* decos,
|
||||
const ast::Attribute* replacement);
|
||||
|
||||
/// Converts a SPIR-V struct member decoration into a number of AST
|
||||
/// decorations. If the decoration is recognized but deliberately dropped,
|
||||
|
@ -281,7 +281,7 @@ class ParserImpl : Reader {
|
|||
/// @param member_ty the type of the member
|
||||
/// @param decoration an encoded SPIR-V Decoration
|
||||
/// @returns the AST decorations
|
||||
ast::DecorationList ConvertMemberDecoration(uint32_t struct_type_id,
|
||||
ast::AttributeList ConvertMemberDecoration(uint32_t struct_type_id,
|
||||
uint32_t member_index,
|
||||
const Type* member_ty,
|
||||
const Decoration& decoration);
|
||||
|
@ -430,7 +430,7 @@ class ParserImpl : Reader {
|
|||
const Type* storage_type,
|
||||
bool is_const,
|
||||
const ast::Expression* constructor,
|
||||
ast::DecorationList decorations);
|
||||
ast::AttributeList decorations);
|
||||
|
||||
/// Returns true if a constant expression can be generated.
|
||||
/// @param id the SPIR-V ID of the value
|
||||
|
|
|
@ -56,8 +56,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
|
|||
auto result =
|
||||
p->ConvertMemberDecoration(1, 1, nullptr, {SpvDecorationOffset, 8});
|
||||
ASSERT_FALSE(result.empty());
|
||||
EXPECT_TRUE(result[0]->Is<ast::StructMemberOffsetDecoration>());
|
||||
auto* offset_deco = result[0]->As<ast::StructMemberOffsetDecoration>();
|
||||
EXPECT_TRUE(result[0]->Is<ast::StructMemberOffsetAttribute>());
|
||||
auto* offset_deco = result[0]->As<ast::StructMemberOffsetAttribute>();
|
||||
ASSERT_NE(offset_deco, nullptr);
|
||||
EXPECT_EQ(offset_deco->offset, 8u);
|
||||
EXPECT_TRUE(p->error().empty());
|
||||
|
@ -82,8 +82,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Custom) {
|
|||
auto result = p->ConvertMemberDecoration(1, 1, &matrix,
|
||||
{SpvDecorationMatrixStride, 16});
|
||||
ASSERT_FALSE(result.empty());
|
||||
EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>());
|
||||
auto* stride_deco = result[0]->As<ast::StrideDecoration>();
|
||||
EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
|
||||
auto* stride_deco = result[0]->As<ast::StrideAttribute>();
|
||||
ASSERT_NE(stride_deco, nullptr);
|
||||
EXPECT_EQ(stride_deco->stride, 16u);
|
||||
EXPECT_TRUE(p->error().empty());
|
||||
|
@ -108,8 +108,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Custom) {
|
|||
auto result = p->ConvertMemberDecoration(1, 1, &matrix,
|
||||
{SpvDecorationMatrixStride, 64});
|
||||
ASSERT_FALSE(result.empty());
|
||||
EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>());
|
||||
auto* stride_deco = result[0]->As<ast::StrideDecoration>();
|
||||
EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
|
||||
auto* stride_deco = result[0]->As<ast::StrideAttribute>();
|
||||
ASSERT_NE(stride_deco, nullptr);
|
||||
EXPECT_EQ(stride_deco->stride, 64u);
|
||||
EXPECT_TRUE(p->error().empty());
|
||||
|
@ -123,8 +123,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x3_Stride_Custom) {
|
|||
auto result = p->ConvertMemberDecoration(1, 1, &matrix,
|
||||
{SpvDecorationMatrixStride, 32});
|
||||
ASSERT_FALSE(result.empty());
|
||||
EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>());
|
||||
auto* stride_deco = result[0]->As<ast::StrideDecoration>();
|
||||
EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
|
||||
auto* stride_deco = result[0]->As<ast::StrideAttribute>();
|
||||
ASSERT_NE(stride_deco, nullptr);
|
||||
EXPECT_EQ(stride_deco->stride, 32u);
|
||||
EXPECT_TRUE(p->error().empty());
|
||||
|
|
|
@ -196,7 +196,7 @@ class ParserImplWrapperForTest {
|
|||
/// @param member_ty the type of the member
|
||||
/// @param decoration an encoded SPIR-V Decoration
|
||||
/// @returns the AST decorations
|
||||
ast::DecorationList ConvertMemberDecoration(uint32_t struct_type_id,
|
||||
ast::AttributeList ConvertMemberDecoration(uint32_t struct_type_id,
|
||||
uint32_t member_index,
|
||||
const Type* member_ty,
|
||||
const Decoration& decoration) {
|
||||
|
|
|
@ -24,18 +24,18 @@
|
|||
#include "src/ast/external_texture.h"
|
||||
#include "src/ast/fallthrough_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/override_decoration.h"
|
||||
#include "src/ast/override_attribute.h"
|
||||
#include "src/ast/return_statement.h"
|
||||
#include "src/ast/stage_decoration.h"
|
||||
#include "src/ast/struct_block_decoration.h"
|
||||
#include "src/ast/stage_attribute.h"
|
||||
#include "src/ast/struct_block_attribute.h"
|
||||
#include "src/ast/switch_statement.h"
|
||||
#include "src/ast/type_name.h"
|
||||
#include "src/ast/unary_op_expression.h"
|
||||
#include "src/ast/variable_decl_statement.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/sem/depth_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;
|
||||
}
|
||||
|
||||
const char kBindingDecoration[] = "binding";
|
||||
const char kBlockDecoration[] = "block";
|
||||
const char kBuiltinDecoration[] = "builtin";
|
||||
const char kGroupDecoration[] = "group";
|
||||
const char kInterpolateDecoration[] = "interpolate";
|
||||
const char kInvariantDecoration[] = "invariant";
|
||||
const char kLocationDecoration[] = "location";
|
||||
const char kOverrideDecoration[] = "override";
|
||||
const char kSizeDecoration[] = "size";
|
||||
const char kAlignDecoration[] = "align";
|
||||
const char kStageDecoration[] = "stage";
|
||||
const char kStrideDecoration[] = "stride";
|
||||
const char kWorkgroupSizeDecoration[] = "workgroup_size";
|
||||
const char kBindingAttribute[] = "binding";
|
||||
const char kBlockAttribute[] = "block";
|
||||
const char kBuiltinAttribute[] = "builtin";
|
||||
const char kGroupAttribute[] = "group";
|
||||
const char kInterpolateAttribute[] = "interpolate";
|
||||
const char kInvariantAttribute[] = "invariant";
|
||||
const char kLocationAttribute[] = "location";
|
||||
const char kOverrideAttribute[] = "override";
|
||||
const char kSizeAttribute[] = "size";
|
||||
const char kAlignAttribute[] = "align";
|
||||
const char kStageAttribute[] = "stage";
|
||||
const char kStrideAttribute[] = "stride";
|
||||
const char kWorkgroupSizeAttribute[] = "workgroup_size";
|
||||
|
||||
bool is_decoration(Token t) {
|
||||
return t == kAlignDecoration || t == kBindingDecoration ||
|
||||
t == kBlockDecoration || t == kBuiltinDecoration ||
|
||||
t == kGroupDecoration || t == kInterpolateDecoration ||
|
||||
t == kLocationDecoration || t == kOverrideDecoration ||
|
||||
t == kSizeDecoration || t == kStageDecoration ||
|
||||
t == kStrideDecoration || t == kWorkgroupSizeDecoration;
|
||||
bool is_attribute(Token t) {
|
||||
return t == kAlignAttribute || t == kBindingAttribute ||
|
||||
t == kBlockAttribute || t == kBuiltinAttribute ||
|
||||
t == kGroupAttribute || t == kInterpolateAttribute ||
|
||||
t == kLocationAttribute || t == kOverrideAttribute ||
|
||||
t == kSizeAttribute || t == kStageAttribute || t == kStrideAttribute ||
|
||||
t == kWorkgroupSizeAttribute;
|
||||
}
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/wgsl.html#reserved-keywords
|
||||
|
@ -225,12 +225,12 @@ ParserImpl::FunctionHeader::FunctionHeader(Source src,
|
|||
std::string n,
|
||||
ast::VariableList p,
|
||||
const ast::Type* ret_ty,
|
||||
ast::DecorationList ret_decos)
|
||||
ast::AttributeList ret_attrs)
|
||||
: source(src),
|
||||
name(n),
|
||||
params(p),
|
||||
return_type(ret_ty),
|
||||
return_type_decorations(ret_decos) {}
|
||||
return_type_attributes(ret_attrs) {}
|
||||
|
||||
ParserImpl::FunctionHeader::~FunctionHeader() = default;
|
||||
|
||||
|
@ -351,14 +351,14 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||
|
||||
bool errored = false;
|
||||
|
||||
auto decos = decoration_list();
|
||||
if (decos.errored)
|
||||
auto attrs = attribute_list();
|
||||
if (attrs.errored)
|
||||
errored = true;
|
||||
if (!continue_parsing())
|
||||
return Failure::kErrored;
|
||||
|
||||
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)
|
||||
return Failure::kErrored;
|
||||
if (gv.matched) {
|
||||
|
@ -369,7 +369,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto gc = global_constant_decl(decos.value);
|
||||
auto gc = global_constant_decl(attrs.value);
|
||||
if (gc.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
|
@ -393,7 +393,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto str = struct_decl(decos.value);
|
||||
auto str = struct_decl(attrs.value);
|
||||
if (str.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
|
@ -409,10 +409,10 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||
errored = true;
|
||||
}
|
||||
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) {
|
||||
errored = true;
|
||||
}
|
||||
|
@ -427,9 +427,9 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||
|
||||
// Invalid syntax found - try and determine the best error message
|
||||
|
||||
// We have decorations parsed, but nothing to consume them?
|
||||
if (decos.value.size() > 0) {
|
||||
return add_error(next(), "expected declaration after decorations");
|
||||
// We have attributes parsed, but nothing to consume them?
|
||||
if (attrs.value.size() > 0) {
|
||||
return add_error(next(), "expected declaration after attributes");
|
||||
}
|
||||
|
||||
// We have a statement outside of a function?
|
||||
|
@ -460,10 +460,10 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||
}
|
||||
|
||||
// global_variable_decl
|
||||
// : variable_decoration_list* variable_decl
|
||||
// | variable_decoration_list* variable_decl EQUAL const_expr
|
||||
// : variable_attribute_list* variable_decl
|
||||
// | variable_attribute_list* variable_decl EQUAL const_expr
|
||||
Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
|
||||
ast::DecorationList& decos) {
|
||||
ast::AttributeList& attrs) {
|
||||
auto decl = variable_decl();
|
||||
if (decl.errored)
|
||||
return Failure::kErrored;
|
||||
|
@ -486,7 +486,7 @@ Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
|
|||
decl->type, // type
|
||||
false, // is_const
|
||||
constructor, // constructor
|
||||
std::move(decos)); // decorations
|
||||
std::move(attrs)); // attributes
|
||||
}
|
||||
|
||||
// global_constant_decl
|
||||
|
@ -494,7 +494,7 @@ Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
|
|||
// global_const_initializer
|
||||
// : EQUAL const_expr
|
||||
Maybe<const ast::Variable*> ParserImpl::global_constant_decl(
|
||||
ast::DecorationList& decos) {
|
||||
ast::AttributeList& attrs) {
|
||||
if (!match(Token::Type::kLet)) {
|
||||
return Failure::kNoMatch;
|
||||
}
|
||||
|
@ -522,7 +522,7 @@ Maybe<const ast::Variable*> ParserImpl::global_constant_decl(
|
|||
decl->type, // type
|
||||
true, // is_const
|
||||
initializer, // constructor
|
||||
std::move(decos)); // decorations
|
||||
std::move(attrs)); // attributes
|
||||
}
|
||||
|
||||
// variable_decl
|
||||
|
@ -807,7 +807,7 @@ Expect<ast::TexelFormat> ParserImpl::expect_texel_format(std::string_view use) {
|
|||
}
|
||||
|
||||
// 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(
|
||||
std::string_view use,
|
||||
bool allow_inferred) {
|
||||
|
@ -822,18 +822,18 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
|
|||
if (!expect(use, Token::Type::kColon))
|
||||
return Failure::kErrored;
|
||||
|
||||
auto decos = decoration_list();
|
||||
if (decos.errored)
|
||||
auto attrs = attribute_list();
|
||||
if (attrs.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
auto t = peek();
|
||||
auto type = type_decl(decos.value);
|
||||
auto type = type_decl(attrs.value);
|
||||
if (type.errored)
|
||||
return Failure::kErrored;
|
||||
if (!type.matched)
|
||||
return add_error(t.source(), "invalid type", use);
|
||||
|
||||
if (!expect_decorations_consumed(decos.value))
|
||||
if (!expect_attributes_consumed(attrs.value))
|
||||
return Failure::kErrored;
|
||||
|
||||
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
|
||||
// | VEC4 LESS_THAN type_decl 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
|
||||
// | array_decoration_list* ARRAY LESS_THAN type_decl
|
||||
// | array_attribute_list* ARRAY LESS_THAN type_decl
|
||||
// GREATER_THAN
|
||||
// | MAT2x2 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
|
||||
// | texture_sampler_types
|
||||
Maybe<const ast::Type*> ParserImpl::type_decl() {
|
||||
auto decos = decoration_list();
|
||||
if (decos.errored)
|
||||
auto attrs = attribute_list();
|
||||
if (attrs.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
auto type = type_decl(decos.value);
|
||||
auto type = type_decl(attrs.value);
|
||||
if (type.errored) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
if (!expect_decorations_consumed(decos.value)) {
|
||||
if (!expect_attributes_consumed(attrs.value)) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
if (!type.matched) {
|
||||
|
@ -955,7 +955,7 @@ Maybe<const ast::Type*> ParserImpl::type_decl() {
|
|||
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();
|
||||
Source 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)) {
|
||||
return expect_type_decl_array(t, std::move(decos));
|
||||
return expect_type_decl_array(t, std::move(attrs));
|
||||
}
|
||||
|
||||
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(
|
||||
Token t,
|
||||
ast::DecorationList decos) {
|
||||
ast::AttributeList attrs) {
|
||||
const char* use = "array declaration";
|
||||
|
||||
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,
|
||||
size, std::move(decos));
|
||||
size, std::move(attrs));
|
||||
}
|
||||
|
||||
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_decoration_decl* STRUCT IDENT struct_body_decl
|
||||
Maybe<const ast::Struct*> ParserImpl::struct_decl(ast::DecorationList& decos) {
|
||||
// : struct_attribute_decl* STRUCT IDENT struct_body_decl
|
||||
Maybe<const ast::Struct*> ParserImpl::struct_decl(ast::AttributeList& attrs) {
|
||||
auto t = peek();
|
||||
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);
|
||||
return create<ast::Struct>(source, sym, std::move(body.value),
|
||||
std::move(decos));
|
||||
std::move(attrs));
|
||||
}
|
||||
|
||||
// struct_body_decl
|
||||
|
@ -1215,14 +1215,14 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
|
|||
!peek_is(Token::Type::kEOF)) {
|
||||
auto member = sync(Token::Type::kSemicolon,
|
||||
[&]() -> Expect<ast::StructMember*> {
|
||||
auto decos = decoration_list();
|
||||
if (decos.errored) {
|
||||
auto attrs = attribute_list();
|
||||
if (attrs.errored) {
|
||||
errored = true;
|
||||
}
|
||||
if (!synchronized_) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
return expect_struct_member(decos.value);
|
||||
return expect_struct_member(attrs.value);
|
||||
});
|
||||
|
||||
if (member.errored) {
|
||||
|
@ -1240,9 +1240,9 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
|
|||
}
|
||||
|
||||
// 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(
|
||||
ast::DecorationList& decos) {
|
||||
ast::AttributeList& attrs) {
|
||||
auto decl = expect_variable_ident_decl("struct member");
|
||||
if (decl.errored)
|
||||
return Failure::kErrored;
|
||||
|
@ -1252,13 +1252,13 @@ Expect<ast::StructMember*> ParserImpl::expect_struct_member(
|
|||
|
||||
return create<ast::StructMember>(decl->source,
|
||||
builder_.Symbols().Register(decl->name),
|
||||
decl->type, std::move(decos));
|
||||
decl->type, std::move(attrs));
|
||||
}
|
||||
|
||||
// function_decl
|
||||
// : function_header body_stmt
|
||||
Maybe<const ast::Function*> ParserImpl::function_decl(
|
||||
ast::DecorationList& decos) {
|
||||
ast::AttributeList& attrs) {
|
||||
auto header = function_header();
|
||||
if (header.errored) {
|
||||
if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) {
|
||||
|
@ -1286,7 +1286,7 @@ Maybe<const ast::Function*> ParserImpl::function_decl(
|
|||
|
||||
return create<ast::Function>(
|
||||
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
|
||||
|
@ -1320,28 +1320,28 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
|
|||
}
|
||||
|
||||
const ast::Type* return_type = nullptr;
|
||||
ast::DecorationList return_decorations;
|
||||
ast::AttributeList return_attributes;
|
||||
|
||||
if (match(Token::Type::kArrow)) {
|
||||
auto decos = decoration_list();
|
||||
if (decos.errored) {
|
||||
auto attrs = attribute_list();
|
||||
if (attrs.errored) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
return_decorations = decos.value;
|
||||
return_attributes = attrs.value;
|
||||
|
||||
// Apply stride decorations to the type node instead of the function.
|
||||
ast::DecorationList type_decorations;
|
||||
auto itr = std::find_if(
|
||||
return_decorations.begin(), return_decorations.end(),
|
||||
[](auto* deco) { return Is<ast::StrideDecoration>(deco); });
|
||||
if (itr != return_decorations.end()) {
|
||||
type_decorations.emplace_back(*itr);
|
||||
return_decorations.erase(itr);
|
||||
// Apply stride attributes to the type node instead of the function.
|
||||
ast::AttributeList type_attributes;
|
||||
auto itr =
|
||||
std::find_if(return_attributes.begin(), return_attributes.end(),
|
||||
[](auto* attr) { return Is<ast::StrideAttribute>(attr); });
|
||||
if (itr != return_attributes.end()) {
|
||||
type_attributes.emplace_back(*itr);
|
||||
return_attributes.erase(itr);
|
||||
}
|
||||
|
||||
auto tok = peek();
|
||||
|
||||
auto type = type_decl(type_decorations);
|
||||
auto type = type_decl(type_attributes);
|
||||
if (type.errored) {
|
||||
errored = true;
|
||||
} else if (!type.matched) {
|
||||
|
@ -1358,7 +1358,7 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
|
|||
}
|
||||
|
||||
return FunctionHeader{source, name.value, std::move(params.value),
|
||||
return_type, std::move(return_decorations)};
|
||||
return_type, std::move(return_attributes)};
|
||||
}
|
||||
|
||||
// param_list
|
||||
|
@ -1387,9 +1387,9 @@ Expect<ast::VariableList> ParserImpl::expect_param_list() {
|
|||
}
|
||||
|
||||
// param
|
||||
// : decoration_list* variable_ident_decl
|
||||
// : attribute_list* variable_ident_decl
|
||||
Expect<ast::Variable*> ParserImpl::expect_param() {
|
||||
auto decos = decoration_list();
|
||||
auto attrs = attribute_list();
|
||||
|
||||
auto decl = expect_variable_ident_decl("parameter");
|
||||
if (decl.errored)
|
||||
|
@ -1403,7 +1403,7 @@ Expect<ast::Variable*> ParserImpl::expect_param() {
|
|||
decl->type, // type
|
||||
true, // is_const
|
||||
nullptr, // constructor
|
||||
std::move(decos.value)); // decorations
|
||||
std::move(attrs.value)); // attributes
|
||||
// Formal parameters are treated like a const declaration where the
|
||||
// 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
|
||||
|
@ -1430,7 +1430,7 @@ Expect<ast::PipelineStage> ParserImpl::expect_pipeline_stage() {
|
|||
next(); // Consume the peek
|
||||
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() {
|
||||
|
@ -1440,7 +1440,7 @@ Expect<ast::Builtin> ParserImpl::expect_builtin() {
|
|||
|
||||
ast::Builtin builtin = ident_to_builtin(ident.value);
|
||||
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};
|
||||
}
|
||||
|
@ -1661,7 +1661,7 @@ Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
|
|||
decl->type, // type
|
||||
true, // is_const
|
||||
constructor.value, // constructor
|
||||
ast::DecorationList{}); // decorations
|
||||
ast::AttributeList{}); // attributes
|
||||
|
||||
return create<ast::VariableDeclStatement>(decl->source, var);
|
||||
}
|
||||
|
@ -1691,7 +1691,7 @@ Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
|
|||
decl->type, // type
|
||||
false, // is_const
|
||||
constructor, // constructor
|
||||
ast::DecorationList{}); // decorations
|
||||
ast::AttributeList{}); // attributes
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
Maybe<ast::DecorationList> ParserImpl::decoration_list() {
|
||||
Maybe<ast::AttributeList> ParserImpl::attribute_list() {
|
||||
bool errored = false;
|
||||
bool matched = false;
|
||||
ast::DecorationList decos;
|
||||
ast::AttributeList attrs;
|
||||
|
||||
while (continue_parsing()) {
|
||||
if (match(Token::Type::kAttr)) {
|
||||
if (auto deco = expect_decoration(); deco.errored) {
|
||||
if (auto attr = expect_attribute(); attr.errored) {
|
||||
errored = true;
|
||||
} else {
|
||||
decos.emplace_back(deco.value);
|
||||
attrs.emplace_back(attr.value);
|
||||
}
|
||||
} else { // [DEPRECATED] - old [[decoration]] style
|
||||
auto list = decoration_bracketed_list(decos);
|
||||
} else { // [DEPRECATED] - old [[attribute]] style
|
||||
auto list = attribute_bracketed_list(attrs);
|
||||
if (list.errored) {
|
||||
errored = true;
|
||||
}
|
||||
|
@ -2840,11 +2840,11 @@ Maybe<ast::DecorationList> ParserImpl::decoration_list() {
|
|||
if (!matched)
|
||||
return Failure::kNoMatch;
|
||||
|
||||
return decos;
|
||||
return attrs;
|
||||
}
|
||||
|
||||
Maybe<bool> ParserImpl::decoration_bracketed_list(ast::DecorationList& decos) {
|
||||
const char* use = "decoration list";
|
||||
Maybe<bool> ParserImpl::attribute_bracketed_list(ast::AttributeList& attrs) {
|
||||
const char* use = "attribute list";
|
||||
|
||||
Source source;
|
||||
if (!match(Token::Type::kAttrLeft, &source)) {
|
||||
|
@ -2852,28 +2852,28 @@ Maybe<bool> ParserImpl::decoration_bracketed_list(ast::DecorationList& decos) {
|
|||
}
|
||||
|
||||
deprecated(source,
|
||||
"[[decoration]] style decorations have been replaced with "
|
||||
"@decoration style");
|
||||
"[[attribute]] style attributes have been replaced with "
|
||||
"@attribute style");
|
||||
|
||||
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> {
|
||||
bool errored = false;
|
||||
|
||||
while (continue_parsing()) {
|
||||
auto deco = expect_decoration();
|
||||
if (deco.errored) {
|
||||
auto attr = expect_attribute();
|
||||
if (attr.errored) {
|
||||
errored = true;
|
||||
}
|
||||
decos.emplace_back(deco.value);
|
||||
attrs.emplace_back(attr.value);
|
||||
|
||||
if (match(Token::Type::kComma)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_decoration(peek())) {
|
||||
// We have two decorations in a bracket without a separating comma.
|
||||
if (is_attribute(peek())) {
|
||||
// We have two attributes in a bracket without a separating comma.
|
||||
// e.g. @location(1) group(2)
|
||||
// ^^^ expected comma
|
||||
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 deco = decoration();
|
||||
if (deco.errored)
|
||||
auto attr = attribute();
|
||||
if (attr.errored)
|
||||
return Failure::kErrored;
|
||||
if (deco.matched)
|
||||
return deco.value;
|
||||
return add_error(t, "expected decoration");
|
||||
if (attr.matched)
|
||||
return attr.value;
|
||||
return add_error(t, "expected attribute");
|
||||
}
|
||||
|
||||
Maybe<const ast::Decoration*> ParserImpl::decoration() {
|
||||
using Result = Maybe<const ast::Decoration*>;
|
||||
Maybe<const ast::Attribute*> ParserImpl::attribute() {
|
||||
using Result = Maybe<const ast::Attribute*>;
|
||||
auto t = next();
|
||||
|
||||
if (!t.IsIdentifier()) {
|
||||
return Failure::kNoMatch;
|
||||
}
|
||||
|
||||
if (t == kLocationDecoration) {
|
||||
const char* use = "location decoration";
|
||||
if (t == kLocationAttribute) {
|
||||
const char* use = "location attribute";
|
||||
return expect_paren_block(use, [&]() -> Result {
|
||||
auto val = expect_positive_sint(use);
|
||||
if (val.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::LocationDecoration>(t.source(), val.value);
|
||||
return create<ast::LocationAttribute>(t.source(), val.value);
|
||||
});
|
||||
}
|
||||
|
||||
if (t == kBindingDecoration) {
|
||||
const char* use = "binding decoration";
|
||||
if (t == kBindingAttribute) {
|
||||
const char* use = "binding attribute";
|
||||
return expect_paren_block(use, [&]() -> Result {
|
||||
auto val = expect_positive_sint(use);
|
||||
if (val.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::BindingDecoration>(t.source(), val.value);
|
||||
return create<ast::BindingAttribute>(t.source(), val.value);
|
||||
});
|
||||
}
|
||||
|
||||
if (t == kGroupDecoration) {
|
||||
const char* use = "group decoration";
|
||||
if (t == kGroupAttribute) {
|
||||
const char* use = "group attribute";
|
||||
return expect_paren_block(use, [&]() -> Result {
|
||||
auto val = expect_positive_sint(use);
|
||||
if (val.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::GroupDecoration>(t.source(), val.value);
|
||||
return create<ast::GroupAttribute>(t.source(), val.value);
|
||||
});
|
||||
}
|
||||
|
||||
if (t == kInterpolateDecoration) {
|
||||
return expect_paren_block("interpolate decoration", [&]() -> Result {
|
||||
if (t == kInterpolateAttribute) {
|
||||
return expect_paren_block("interpolate attribute", [&]() -> Result {
|
||||
ast::InterpolationType type;
|
||||
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) {
|
||||
return create<ast::InvariantDecoration>(t.source());
|
||||
if (t == kInvariantAttribute) {
|
||||
return create<ast::InvariantAttribute>(t.source());
|
||||
}
|
||||
|
||||
if (t == kBuiltinDecoration) {
|
||||
return expect_paren_block("builtin decoration", [&]() -> Result {
|
||||
if (t == kBuiltinAttribute) {
|
||||
return expect_paren_block("builtin attribute", [&]() -> Result {
|
||||
auto builtin = expect_builtin();
|
||||
if (builtin.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::BuiltinDecoration>(t.source(), builtin.value);
|
||||
return create<ast::BuiltinAttribute>(t.source(), builtin.value);
|
||||
});
|
||||
}
|
||||
|
||||
if (t == kWorkgroupSizeDecoration) {
|
||||
return expect_paren_block("workgroup_size decoration", [&]() -> Result {
|
||||
if (t == kWorkgroupSizeAttribute) {
|
||||
return expect_paren_block("workgroup_size attribute", [&]() -> Result {
|
||||
const ast::Expression* x = nullptr;
|
||||
const ast::Expression* y = 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) {
|
||||
return expect_paren_block("stage decoration", [&]() -> Result {
|
||||
if (t == kStageAttribute) {
|
||||
return expect_paren_block("stage attribute", [&]() -> Result {
|
||||
auto stage = expect_pipeline_stage();
|
||||
if (stage.errored)
|
||||
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");
|
||||
return create<ast::StructBlockDecoration>(t.source());
|
||||
return create<ast::StructBlockAttribute>(t.source());
|
||||
}
|
||||
|
||||
if (t == kStrideDecoration) {
|
||||
const char* use = "stride decoration";
|
||||
if (t == kStrideAttribute) {
|
||||
const char* use = "stride attribute";
|
||||
return expect_paren_block(use, [&]() -> Result {
|
||||
auto val = expect_nonzero_positive_sint(use);
|
||||
if (val.errored)
|
||||
|
@ -3055,34 +3055,34 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
|
|||
deprecated(t.source(),
|
||||
"the @stride attribute is deprecated; use a larger type if "
|
||||
"necessary");
|
||||
return create<ast::StrideDecoration>(t.source(), val.value);
|
||||
return create<ast::StrideAttribute>(t.source(), val.value);
|
||||
});
|
||||
}
|
||||
|
||||
if (t == kSizeDecoration) {
|
||||
const char* use = "size decoration";
|
||||
if (t == kSizeAttribute) {
|
||||
const char* use = "size attribute";
|
||||
return expect_paren_block(use, [&]() -> Result {
|
||||
auto val = expect_positive_sint(use);
|
||||
if (val.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::StructMemberSizeDecoration>(t.source(), val.value);
|
||||
return create<ast::StructMemberSizeAttribute>(t.source(), val.value);
|
||||
});
|
||||
}
|
||||
|
||||
if (t == kAlignDecoration) {
|
||||
const char* use = "align decoration";
|
||||
if (t == kAlignAttribute) {
|
||||
const char* use = "align attribute";
|
||||
return expect_paren_block(use, [&]() -> Result {
|
||||
auto val = expect_positive_sint(use);
|
||||
if (val.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::StructMemberAlignDecoration>(t.source(), val.value);
|
||||
return create<ast::StructMemberAlignAttribute>(t.source(), val.value);
|
||||
});
|
||||
}
|
||||
|
||||
if (t == kOverrideDecoration) {
|
||||
const char* use = "override decoration";
|
||||
if (t == kOverrideAttribute) {
|
||||
const char* use = "override attribute";
|
||||
|
||||
if (peek_is(Token::Type::kParenLeft)) {
|
||||
// @override(x)
|
||||
|
@ -3091,22 +3091,22 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
|
|||
if (val.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::OverrideDecoration>(t.source(), val.value);
|
||||
return create<ast::OverrideAttribute>(t.source(), val.value);
|
||||
});
|
||||
} else {
|
||||
// [[override]]
|
||||
return create<ast::OverrideDecoration>(t.source());
|
||||
return create<ast::OverrideAttribute>(t.source());
|
||||
}
|
||||
}
|
||||
|
||||
return Failure::kNoMatch;
|
||||
}
|
||||
|
||||
bool ParserImpl::expect_decorations_consumed(ast::DecorationList& in) {
|
||||
bool ParserImpl::expect_attributes_consumed(ast::AttributeList& in) {
|
||||
if (in.empty()) {
|
||||
return true;
|
||||
}
|
||||
add_error(in[0]->source, "unexpected decorations");
|
||||
add_error(in[0]->source, "unexpected attributes");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -239,12 +239,12 @@ class ParserImpl {
|
|||
/// @param n function name
|
||||
/// @param p function parameters
|
||||
/// @param ret_ty function return type
|
||||
/// @param ret_decos return type decorations
|
||||
/// @param ret_attrs return type attributes
|
||||
FunctionHeader(Source src,
|
||||
std::string n,
|
||||
ast::VariableList p,
|
||||
const ast::Type* ret_ty,
|
||||
ast::DecorationList ret_decos);
|
||||
ast::AttributeList ret_attrs);
|
||||
/// Destructor
|
||||
~FunctionHeader();
|
||||
/// Assignment operator
|
||||
|
@ -260,8 +260,8 @@ class ParserImpl {
|
|||
ast::VariableList params;
|
||||
/// Function return type
|
||||
const ast::Type* return_type = nullptr;
|
||||
/// Function return type decorations
|
||||
ast::DecorationList return_type_decorations;
|
||||
/// Function return type attributes
|
||||
ast::AttributeList return_type_attributes;
|
||||
};
|
||||
|
||||
/// VarDeclInfo contains the parsed information for variable declaration.
|
||||
|
@ -387,15 +387,15 @@ class ParserImpl {
|
|||
/// @return true on parse success, otherwise an error.
|
||||
Expect<bool> expect_global_decl();
|
||||
/// 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
|
||||
/// @param decos the list of decorations for the variable declaration.
|
||||
Maybe<const ast::Variable*> global_variable_decl(ast::DecorationList& decos);
|
||||
/// @param attrs the list of attributes for the variable declaration.
|
||||
Maybe<const ast::Variable*> global_variable_decl(ast::AttributeList& attrs);
|
||||
/// 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
|
||||
/// @param decos the list of decorations for the constant declaration.
|
||||
Maybe<const ast::Variable*> global_constant_decl(ast::DecorationList& decos);
|
||||
/// @param attrs the list of attributes for the constant declaration.
|
||||
Maybe<const ast::Variable*> global_constant_decl(ast::AttributeList& attrs);
|
||||
/// Parses a `variable_decl` grammar element
|
||||
/// @param allow_inferred if true, do not fail if variable decl does not
|
||||
/// specify type
|
||||
|
@ -420,33 +420,33 @@ class ParserImpl {
|
|||
/// @returns the parsed Type or nullptr if none matched.
|
||||
Maybe<const ast::Type*> type_decl();
|
||||
/// Parses a `type_decl` grammar element with the given pre-parsed
|
||||
/// decorations.
|
||||
/// @param decos the list of decorations for the type.
|
||||
/// attributes.
|
||||
/// @param attrs the list of attributes for the type.
|
||||
/// @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.
|
||||
/// @param use a description of what was being parsed if an error was raised.
|
||||
/// @returns the storage class or StorageClass::kNone if none matched
|
||||
Expect<ast::StorageClass> expect_storage_class(std::string_view use);
|
||||
/// 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
|
||||
/// @param decos the list of decorations for the struct declaration.
|
||||
Maybe<const ast::Struct*> struct_decl(ast::DecorationList& decos);
|
||||
/// @param attrs the list of attributes for the struct declaration.
|
||||
Maybe<const ast::Struct*> struct_decl(ast::AttributeList& attrs);
|
||||
/// Parses a `struct_body_decl` grammar element, erroring on parse failure.
|
||||
/// @returns the struct members
|
||||
Expect<ast::StructMemberList> expect_struct_body_decl();
|
||||
/// 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.
|
||||
/// @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
|
||||
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
|
||||
/// `function_decoration_decl*` provided as `decos`.
|
||||
/// @param decos the list of decorations for the function declaration.
|
||||
/// `function_attribute_decl*` provided as `attrs`.
|
||||
/// @param attrs the list of attributes for the function declaration.
|
||||
/// @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
|
||||
/// @returns the parsed Type or nullptr if none matched.
|
||||
Maybe<const ast::Type*> texture_sampler_types();
|
||||
|
@ -670,28 +670,28 @@ class ParserImpl {
|
|||
/// Parses a `assignment_stmt` grammar element
|
||||
/// @returns the parsed assignment or nullptr
|
||||
Maybe<const ast::AssignmentStatement*> assignment_stmt();
|
||||
/// Parses one or more decoration lists.
|
||||
/// @return the parsed decoration list, or an empty list on error.
|
||||
Maybe<ast::DecorationList> decoration_list();
|
||||
/// Parses a list of decorations between `ATTR_LEFT` and `ATTR_RIGHT`
|
||||
/// Parses one or more attribute lists.
|
||||
/// @return the parsed attribute list, or an empty list on error.
|
||||
Maybe<ast::AttributeList> attribute_list();
|
||||
/// Parses a list of attributes between `ATTR_LEFT` and `ATTR_RIGHT`
|
||||
/// brackets.
|
||||
/// @param decos the list to append newly parsed decorations to.
|
||||
/// @return true if any decorations were be parsed, otherwise false.
|
||||
Maybe<bool> decoration_bracketed_list(ast::DecorationList& decos);
|
||||
/// Parses a single decoration of the following types:
|
||||
/// * `struct_decoration`
|
||||
/// * `struct_member_decoration`
|
||||
/// * `array_decoration`
|
||||
/// * `variable_decoration`
|
||||
/// * `global_const_decoration`
|
||||
/// * `function_decoration`
|
||||
/// @return the parsed decoration, or nullptr.
|
||||
Maybe<const ast::Decoration*> decoration();
|
||||
/// Parses a single decoration, reporting an error if the next token does not
|
||||
/// represent a decoration.
|
||||
/// @see #decoration for the full list of decorations this method parses.
|
||||
/// @return the parsed decoration, or nullptr on error.
|
||||
Expect<const ast::Decoration*> expect_decoration();
|
||||
/// @param attrs the list to append newly parsed attributes to.
|
||||
/// @return true if any attributes were be parsed, otherwise false.
|
||||
Maybe<bool> attribute_bracketed_list(ast::AttributeList& attrs);
|
||||
/// Parses a single attribute of the following types:
|
||||
/// * `struct_attribute`
|
||||
/// * `struct_member_attribute`
|
||||
/// * `array_attribute`
|
||||
/// * `variable_attribute`
|
||||
/// * `global_const_attribute`
|
||||
/// * `function_attribute`
|
||||
/// @return the parsed attribute, or nullptr.
|
||||
Maybe<const ast::Attribute*> attribute();
|
||||
/// Parses a single attribute, reporting an error if the next token does not
|
||||
/// represent a attribute.
|
||||
/// @see #attribute for the full list of attributes this method parses.
|
||||
/// @return the parsed attribute, or nullptr on error.
|
||||
Expect<const ast::Attribute*> expect_attribute();
|
||||
|
||||
private:
|
||||
/// 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>>
|
||||
T without_error(F&& func);
|
||||
|
||||
/// Reports an error if the decoration list `list` is not empty.
|
||||
/// Used to ensure that all decorations are consumed.
|
||||
bool expect_decorations_consumed(ast::DecorationList& list);
|
||||
/// Reports an error if the attribute list `list` is not empty.
|
||||
/// Used to ensure that all attributes are consumed.
|
||||
bool expect_attributes_consumed(ast::AttributeList& list);
|
||||
|
||||
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_vector(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(std::string_view use);
|
||||
|
|
|
@ -53,23 +53,23 @@ fn f() { return 1 & >; }
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, AliasDeclInvalidDeco) {
|
||||
TEST_F(ParserImplErrorTest, AliasDeclInvalidAttribute) {
|
||||
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;
|
||||
^^^^^^^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_AliasDeclInvalidDeco) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_AliasDeclInvalidAttribute) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:3 error: unexpected decorations
|
||||
test.wgsl:1:3 error: unexpected attributes
|
||||
[[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() {}",
|
||||
R"(test.wgsl:1:8 error: expected '(' for stage decoration
|
||||
R"(test.wgsl:1:8 error: expected '(' for stage attribute
|
||||
@stage vertex) fn f() {}
|
||||
^^^^^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, FunctionDeclStageMissingRParen) {
|
||||
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() {}
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclDecoStageMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStageMissingLParen) {
|
||||
EXPECT(
|
||||
"[[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() {}
|
||||
^^
|
||||
|
||||
test.wgsl:1:9 error: expected '(' for stage decoration
|
||||
test.wgsl:1:9 error: expected '(' for stage attribute
|
||||
[[stage vertex]] fn f() {}
|
||||
^^^^^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclDecoStageMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStageMissingRParen) {
|
||||
EXPECT(
|
||||
"[[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() {}
|
||||
^^
|
||||
|
||||
test.wgsl:1:15 error: expected ')' for stage decoration
|
||||
test.wgsl:1:15 error: expected ')' for stage attribute
|
||||
[[stage(vertex]] fn f() {}
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageInvalid) {
|
||||
TEST_F(ParserImplErrorTest, FunctionDeclStageInvalid) {
|
||||
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() {}
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageTypeInvalid) {
|
||||
TEST_F(ParserImplErrorTest, FunctionDeclStageTypeInvalid) {
|
||||
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() {}
|
||||
^^^^^^
|
||||
|
||||
|
@ -387,36 +387,34 @@ test.wgsl:1:8 error: unexpected token
|
|||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest,
|
||||
DEPRECATED_FunctionDeclDecoWorkgroupSizeMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclWorkgroupSizeMissingLParen) {
|
||||
EXPECT(
|
||||
"[[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() {}
|
||||
^^
|
||||
|
||||
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() {}
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest,
|
||||
DEPRECATED_FunctionDeclDecoWorkgroupSizeMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclWorkgroupSizeMissingRParen) {
|
||||
EXPECT(
|
||||
"[[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() {}
|
||||
^^
|
||||
|
||||
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() {}
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeXInvalid) {
|
||||
TEST_F(ParserImplErrorTest, FunctionDeclWorkgroupSizeXInvalid) {
|
||||
EXPECT("@workgroup_size() fn f() {}",
|
||||
R"(test.wgsl:1:17 error: expected workgroup_size x parameter
|
||||
@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() {}",
|
||||
R"(test.wgsl:1:20 error: expected workgroup_size y parameter
|
||||
@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() {}",
|
||||
R"(test.wgsl:1:23 error: expected workgroup_size z parameter
|
||||
@workgroup_size(1, 2, ) fn f() {}
|
||||
|
@ -517,7 +515,7 @@ fn f() {
|
|||
|
||||
TEST_F(ParserImplErrorTest, FunctionScopeUnusedDecl) {
|
||||
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)}
|
||||
^^^^
|
||||
)");
|
||||
|
@ -639,9 +637,9 @@ let i : vec2<i32> = vec2<i32>(1, 2;
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclInvalidDeco) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclInvalidAttribute) {
|
||||
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;
|
||||
^
|
||||
)");
|
||||
|
@ -728,10 +726,10 @@ var x : texture_storage_2d<1>;
|
|||
}
|
||||
|
||||
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructDecoMissingStruct) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructAttrMissingStruct) {
|
||||
EXPECT(
|
||||
"[[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]];
|
||||
^^
|
||||
|
||||
|
@ -739,17 +737,17 @@ test.wgsl:1:3 warning: use of deprecated language feature: [[block]] attributes
|
|||
[[block]];
|
||||
^^^^^
|
||||
|
||||
test.wgsl:1:10 error: expected declaration after decorations
|
||||
test.wgsl:1:10 error: expected declaration after attributes
|
||||
[[block]];
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructDecoMissingEnd) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructAttrMissingEnd) {
|
||||
EXPECT(
|
||||
"[[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 {};
|
||||
^^
|
||||
|
||||
|
@ -757,7 +755,7 @@ test.wgsl:1:3 warning: use of deprecated language feature: [[block]] attributes
|
|||
[[block struct {};
|
||||
^^^^^
|
||||
|
||||
test.wgsl:1:9 error: expected ']]' for decoration list
|
||||
test.wgsl:1:9 error: expected ']]' for attribute list
|
||||
[[block struct {};
|
||||
^^^^^^
|
||||
)");
|
||||
|
@ -788,28 +786,28 @@ struct S { i : i32;
|
|||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberDecoEmpty) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberAttrEmpty) {
|
||||
EXPECT(
|
||||
"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; };
|
||||
^^
|
||||
|
||||
test.wgsl:1:14 error: empty decoration list
|
||||
test.wgsl:1:14 error: empty attribute list
|
||||
struct S { [[]] i : i32; };
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberDecoMissingEnd) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberAttrMissingEnd) {
|
||||
EXPECT(
|
||||
"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; };
|
||||
^^
|
||||
|
||||
test.wgsl:1:15 error: expected decoration
|
||||
test.wgsl:1:15 error: expected attribute
|
||||
struct S { [[ i : i32; };
|
||||
^
|
||||
)");
|
||||
|
@ -836,11 +834,11 @@ TEST_F(ParserImplErrorTest,
|
|||
DEPRECATED_GlobalDeclStructMemberAlignMissingLParen) {
|
||||
EXPECT(
|
||||
"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; };
|
||||
^^
|
||||
|
||||
test.wgsl:1:20 error: expected '(' for align decoration
|
||||
test.wgsl:1:20 error: expected '(' for align attribute
|
||||
struct S { [[align 1)]] i : i32; };
|
||||
^
|
||||
)");
|
||||
|
@ -851,11 +849,11 @@ TEST_F(ParserImplErrorTest,
|
|||
DEPRECATED_GlobalDeclStructMemberAlignMissingRParen) {
|
||||
EXPECT(
|
||||
"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; };
|
||||
^^
|
||||
|
||||
test.wgsl:1:21 error: expected ')' for align decoration
|
||||
test.wgsl:1:21 error: expected ')' for align attribute
|
||||
struct S { [[align(1]] i : i32; };
|
||||
^^
|
||||
)");
|
||||
|
@ -864,7 +862,7 @@ struct S { [[align(1]] i : i32; };
|
|||
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignInvaldValue) {
|
||||
EXPECT(
|
||||
"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; };
|
||||
^
|
||||
)");
|
||||
|
@ -872,7 +870,7 @@ struct S { @align(x) i : i32; };
|
|||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignNegativeValue) {
|
||||
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; };
|
||||
^^
|
||||
)");
|
||||
|
@ -883,11 +881,11 @@ TEST_F(ParserImplErrorTest,
|
|||
DEPRECATED_GlobalDeclStructMemberSizeMissingLParen) {
|
||||
EXPECT(
|
||||
"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; };
|
||||
^^
|
||||
|
||||
test.wgsl:1:19 error: expected '(' for size decoration
|
||||
test.wgsl:1:19 error: expected '(' for size attribute
|
||||
struct S { [[size 1)]] i : i32; };
|
||||
^
|
||||
)");
|
||||
|
@ -898,11 +896,11 @@ TEST_F(ParserImplErrorTest,
|
|||
DEPRECATED_GlobalDeclStructMemberSizeMissingRParen) {
|
||||
EXPECT(
|
||||
"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; };
|
||||
^^
|
||||
|
||||
test.wgsl:1:20 error: expected ')' for size decoration
|
||||
test.wgsl:1:20 error: expected ')' for size attribute
|
||||
struct S { [[size(1]] i : i32; };
|
||||
^^
|
||||
)");
|
||||
|
@ -911,7 +909,7 @@ struct S { [[size(1]] i : i32; };
|
|||
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeInvaldValue) {
|
||||
EXPECT(
|
||||
"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; };
|
||||
^
|
||||
)");
|
||||
|
@ -919,7 +917,7 @@ struct S { @size(x) i : i32; };
|
|||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeNegativeValue) {
|
||||
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; };
|
||||
^^
|
||||
)");
|
||||
|
@ -955,14 +953,14 @@ type meow = f32
|
|||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclTypeDecoInvalid) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclTypeAttrInvalid) {
|
||||
EXPECT(
|
||||
"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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:11 error: empty decoration list
|
||||
test.wgsl:1:11 error: empty attribute list
|
||||
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;",
|
||||
R"(test.wgsl:1:10 error: unexpected decorations
|
||||
R"(test.wgsl:1:10 error: unexpected attributes
|
||||
var i : @location(1) i32;
|
||||
^^^^^^^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayDecoMissingEnd) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayAttrMissingEnd) {
|
||||
EXPECT(
|
||||
"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>;
|
||||
^^
|
||||
|
||||
test.wgsl:1:23 error: expected ']]' for decoration list
|
||||
test.wgsl:1:23 error: expected ']]' for attribute list
|
||||
var i : [[location(1) array<i32>;
|
||||
^^^^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest,
|
||||
DEPRECATED_GlobalDeclVarArrayDecoStrideMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayStrideMissingLParen) {
|
||||
EXPECT(
|
||||
"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>;
|
||||
^^
|
||||
|
||||
test.wgsl:1:18 error: expected '(' for stride decoration
|
||||
test.wgsl:1:18 error: expected '(' for stride attribute
|
||||
var i : [[stride 1)]] array<i32>;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest,
|
||||
DEPRECATED_GlobalDeclVarArrayDecoStrideMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayStrideMissingRParen) {
|
||||
EXPECT(
|
||||
"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>;
|
||||
^^
|
||||
|
||||
test.wgsl:1:21 error: expected ')' for location decoration
|
||||
test.wgsl:1:21 error: expected ')' for location attribute
|
||||
var i : [[location(1]] array<i32>;
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoStrideInvalid) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayStrideInvalid) {
|
||||
EXPECT(
|
||||
"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>;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoStrideNegative) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayStrideNegative) {
|
||||
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>;
|
||||
^^
|
||||
)");
|
||||
|
@ -1078,36 +1074,36 @@ var i : array<u32, !>;
|
|||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoListEmpty) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrListEmpty) {
|
||||
EXPECT(
|
||||
"[[]] 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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:3 error: empty decoration list
|
||||
test.wgsl:1:3 error: empty attribute list
|
||||
[[]] var i : i32;
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoListInvalid) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrListInvalid) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:16 error: expected decoration
|
||||
test.wgsl:1:16 error: expected attribute
|
||||
[[location(1), meow]] var i : i32;
|
||||
^^^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoListMissingComma) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrListMissingComma) {
|
||||
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;
|
||||
^^^^^
|
||||
|
||||
|
@ -1118,117 +1114,117 @@ test.wgsl:1:19 error: unexpected token
|
|||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoListMissingEnd) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrListMissingEnd) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:15 error: expected ']]' for decoration list
|
||||
test.wgsl:1:15 error: expected ']]' for attribute list
|
||||
[[location(1) meow]] var i : i32;
|
||||
^^^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrLocationMissingLParen) {
|
||||
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;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrLocationMissingRParen) {
|
||||
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;
|
||||
^^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoLocationMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrLocationMissingLParen) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:12 error: expected '(' for location decoration
|
||||
test.wgsl:1:12 error: expected '(' for location attribute
|
||||
[[location 1]] var i : i32;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoLocationMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrLocationMissingRParen) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:14 error: expected ')' for location decoration
|
||||
test.wgsl:1:14 error: expected ')' for location attribute
|
||||
[[location (1]] var i : i32;
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationInvalidValue) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrLocationInvalidValue) {
|
||||
EXPECT(
|
||||
"@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;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinMissingLParen) {
|
||||
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;
|
||||
^^^^^^^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinMissingRParen) {
|
||||
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;
|
||||
^^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBuiltinMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBuiltinMissingLParen) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:11 error: expected '(' for builtin decoration
|
||||
test.wgsl:1:11 error: expected '(' for builtin attribute
|
||||
[[builtin position]] var i : i32;
|
||||
^^^^^^^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBuiltinMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBuiltinMissingRParen) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:19 error: expected ')' for builtin decoration
|
||||
test.wgsl:1:19 error: expected ')' for builtin attribute
|
||||
[[builtin(position]] var i : i32;
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinInvalidIdentifer) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinInvalidIdentifer) {
|
||||
EXPECT("@builtin(1) var i : i32;",
|
||||
R"(test.wgsl:1:10 error: expected identifier for builtin
|
||||
@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;",
|
||||
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;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingMissingLParen) {
|
||||
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;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingMissingRParen) {
|
||||
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;
|
||||
^^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBindingMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBindingMissingLParen) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:11 error: expected '(' for binding decoration
|
||||
test.wgsl:1:11 error: expected '(' for binding attribute
|
||||
[[binding 1]] var i : i32;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBindingMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBindingMissingRParen) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:12 error: expected ')' for binding decoration
|
||||
test.wgsl:1:12 error: expected ')' for binding attribute
|
||||
[[binding(1]] var i : i32;
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingInvalidValue) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingInvalidValue) {
|
||||
EXPECT(
|
||||
"@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;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoGroupMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrGroupMissingLParen) {
|
||||
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;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoGroupMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrGroupMissingRParen) {
|
||||
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;
|
||||
^^^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoGroupMissingLParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrGroupMissingLParen) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:9 error: expected '(' for group decoration
|
||||
test.wgsl:1:9 error: expected '(' for group attribute
|
||||
[[group 1]] var i : i32;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1382): Remove
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoGroupMissingRParen) {
|
||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrGroupMissingRParen) {
|
||||
EXPECT(
|
||||
"[[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;
|
||||
^^
|
||||
|
||||
test.wgsl:1:10 error: expected ')' for group decoration
|
||||
test.wgsl:1:10 error: expected ')' for group attribute
|
||||
[[group(1]] var i : i32;
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingGroupValue) {
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingGroupValue) {
|
||||
EXPECT(
|
||||
"@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;
|
||||
^
|
||||
)");
|
||||
|
|
|
@ -55,7 +55,7 @@ test.wgsl:3:6 error: expected ')' for function declaration
|
|||
fn x(.) {}
|
||||
^
|
||||
|
||||
test.wgsl:4:2 error: expected decoration
|
||||
test.wgsl:4:2 error: expected attribute
|
||||
@_ fn -> {}
|
||||
^
|
||||
|
||||
|
@ -126,7 +126,7 @@ test.wgsl:5:10 error: expected ':' for struct member
|
|||
blah blah blah;
|
||||
^^^^
|
||||
|
||||
test.wgsl:7:6 error: expected decoration
|
||||
test.wgsl:7:6 error: expected attribute
|
||||
@- x : i32;
|
||||
^
|
||||
)");
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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"
|
||||
|
||||
namespace tint {
|
||||
|
@ -22,11 +22,11 @@ namespace {
|
|||
|
||||
TEST_F(ParserImplTest, FunctionDecl) {
|
||||
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();
|
||||
ASSERT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto f = p->function_decl(decos.value);
|
||||
ASSERT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto f = p->function_decl(attrs.value);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_FALSE(f.errored);
|
||||
EXPECT_TRUE(f.matched);
|
||||
|
@ -48,13 +48,13 @@ TEST_F(ParserImplTest, FunctionDecl) {
|
|||
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 decos = p->decoration_list();
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_FALSE(decos.errored);
|
||||
ASSERT_TRUE(decos.matched);
|
||||
auto f = p->function_decl(decos.value);
|
||||
ASSERT_FALSE(attrs.errored);
|
||||
ASSERT_TRUE(attrs.matched);
|
||||
auto f = p->function_decl(attrs.value);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_FALSE(f.errored);
|
||||
EXPECT_TRUE(f.matched);
|
||||
|
@ -65,11 +65,11 @@ TEST_F(ParserImplTest, FunctionDecl_DecorationList) {
|
|||
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||
ASSERT_EQ(f->params.size(), 0u);
|
||||
|
||||
auto& decorations = f->decorations;
|
||||
ASSERT_EQ(decorations.size(), 1u);
|
||||
ASSERT_TRUE(decorations[0]->Is<ast::WorkgroupDecoration>());
|
||||
auto& attributes = f->attributes;
|
||||
ASSERT_EQ(attributes.size(), 1u);
|
||||
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>());
|
||||
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>());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, FunctionDecl_DecorationList_MultipleEntries) {
|
||||
TEST_F(ParserImplTest, FunctionDecl_AttributeList_MultipleEntries) {
|
||||
auto p = parser(R"(
|
||||
@workgroup_size(2, 3, 4) @stage(compute)
|
||||
fn main() { return; })");
|
||||
auto decos = p->decoration_list();
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_FALSE(decos.errored);
|
||||
ASSERT_TRUE(decos.matched);
|
||||
auto f = p->function_decl(decos.value);
|
||||
ASSERT_FALSE(attrs.errored);
|
||||
ASSERT_TRUE(attrs.matched);
|
||||
auto f = p->function_decl(attrs.value);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_FALSE(f.errored);
|
||||
EXPECT_TRUE(f.matched);
|
||||
|
@ -104,11 +104,11 @@ fn main() { return; })");
|
|||
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||
ASSERT_EQ(f->params.size(), 0u);
|
||||
|
||||
auto& decorations = f->decorations;
|
||||
ASSERT_EQ(decorations.size(), 2u);
|
||||
auto& attributes = f->attributes;
|
||||
ASSERT_EQ(attributes.size(), 2u);
|
||||
|
||||
ASSERT_TRUE(decorations[0]->Is<ast::WorkgroupDecoration>());
|
||||
auto values = decorations[0]->As<ast::WorkgroupDecoration>()->Values();
|
||||
ASSERT_TRUE(attributes[0]->Is<ast::WorkgroupAttribute>());
|
||||
auto values = attributes[0]->As<ast::WorkgroupAttribute>()->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
|
@ -119,8 +119,8 @@ fn main() { return; })");
|
|||
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
|
||||
ASSERT_TRUE(decorations[1]->Is<ast::StageDecoration>());
|
||||
EXPECT_EQ(decorations[1]->As<ast::StageDecoration>()->stage,
|
||||
ASSERT_TRUE(attributes[1]->Is<ast::StageAttribute>());
|
||||
EXPECT_EQ(attributes[1]->As<ast::StageAttribute>()->stage,
|
||||
ast::PipelineStage::kCompute);
|
||||
|
||||
auto* body = f->body;
|
||||
|
@ -128,16 +128,16 @@ fn main() { return; })");
|
|||
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, FunctionDecl_DecorationList_MultipleLists) {
|
||||
TEST_F(ParserImplTest, FunctionDecl_AttributeList_MultipleLists) {
|
||||
auto p = parser(R"(
|
||||
@workgroup_size(2, 3, 4)
|
||||
@stage(compute)
|
||||
fn main() { return; })");
|
||||
auto decorations = p->decoration_list();
|
||||
auto attributes = p->attribute_list();
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_FALSE(decorations.errored);
|
||||
ASSERT_TRUE(decorations.matched);
|
||||
auto f = p->function_decl(decorations.value);
|
||||
ASSERT_FALSE(attributes.errored);
|
||||
ASSERT_TRUE(attributes.matched);
|
||||
auto f = p->function_decl(attributes.value);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_FALSE(f.errored);
|
||||
EXPECT_TRUE(f.matched);
|
||||
|
@ -148,11 +148,11 @@ fn main() { return; })");
|
|||
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||
ASSERT_EQ(f->params.size(), 0u);
|
||||
|
||||
auto& decos = f->decorations;
|
||||
ASSERT_EQ(decos.size(), 2u);
|
||||
auto& attrs = f->attributes;
|
||||
ASSERT_EQ(attrs.size(), 2u);
|
||||
|
||||
ASSERT_TRUE(decos[0]->Is<ast::WorkgroupDecoration>());
|
||||
auto values = decos[0]->As<ast::WorkgroupDecoration>()->Values();
|
||||
ASSERT_TRUE(attrs[0]->Is<ast::WorkgroupAttribute>());
|
||||
auto values = attrs[0]->As<ast::WorkgroupAttribute>()->Values();
|
||||
|
||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||
|
@ -163,8 +163,8 @@ fn main() { return; })");
|
|||
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||
|
||||
ASSERT_TRUE(decos[1]->Is<ast::StageDecoration>());
|
||||
EXPECT_EQ(decos[1]->As<ast::StageDecoration>()->stage,
|
||||
ASSERT_TRUE(attrs[1]->Is<ast::StageAttribute>());
|
||||
EXPECT_EQ(attrs[1]->As<ast::StageAttribute>()->stage,
|
||||
ast::PipelineStage::kCompute);
|
||||
|
||||
auto* body = f->body;
|
||||
|
@ -172,13 +172,13 @@ fn main() { return; })");
|
|||
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 decos = p->decoration_list();
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto f = p->function_decl(decos.value);
|
||||
ASSERT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto f = p->function_decl(attrs.value);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_FALSE(f.errored);
|
||||
EXPECT_TRUE(f.matched);
|
||||
|
@ -189,12 +189,12 @@ TEST_F(ParserImplTest, FunctionDecl_ReturnTypeDecorationList) {
|
|||
EXPECT_TRUE(f->return_type->Is<ast::F32>());
|
||||
ASSERT_EQ(f->params.size(), 0u);
|
||||
|
||||
auto& decorations = f->decorations;
|
||||
EXPECT_EQ(decorations.size(), 0u);
|
||||
auto& attributes = f->attributes;
|
||||
EXPECT_EQ(attributes.size(), 0u);
|
||||
|
||||
auto& ret_type_decorations = f->return_type_decorations;
|
||||
ASSERT_EQ(ret_type_decorations.size(), 1u);
|
||||
auto* loc = ret_type_decorations[0]->As<ast::LocationDecoration>();
|
||||
auto& ret_type_attributes = f->return_type_attributes;
|
||||
ASSERT_EQ(ret_type_attributes.size(), 1u);
|
||||
auto* loc = ret_type_attributes[0]->As<ast::LocationAttribute>();
|
||||
ASSERT_TRUE(loc != nullptr);
|
||||
EXPECT_EQ(loc->value, 1u);
|
||||
|
||||
|
@ -205,11 +205,11 @@ TEST_F(ParserImplTest, FunctionDecl_ReturnTypeDecorationList) {
|
|||
|
||||
TEST_F(ParserImplTest, FunctionDecl_InvalidHeader) {
|
||||
auto p = parser("fn main() -> { }");
|
||||
auto decos = p->decoration_list();
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto f = p->function_decl(decos.value);
|
||||
ASSERT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto f = p->function_decl(attrs.value);
|
||||
EXPECT_TRUE(f.errored);
|
||||
EXPECT_FALSE(f.matched);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
|
@ -219,11 +219,11 @@ TEST_F(ParserImplTest, FunctionDecl_InvalidHeader) {
|
|||
|
||||
TEST_F(ParserImplTest, FunctionDecl_InvalidBody) {
|
||||
auto p = parser("fn main() { return }");
|
||||
auto decos = p->decoration_list();
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto f = p->function_decl(decos.value);
|
||||
ASSERT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto f = p->function_decl(attrs.value);
|
||||
EXPECT_TRUE(f.errored);
|
||||
EXPECT_FALSE(f.matched);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
|
@ -233,11 +233,11 @@ TEST_F(ParserImplTest, FunctionDecl_InvalidBody) {
|
|||
|
||||
TEST_F(ParserImplTest, FunctionDecl_MissingLeftBrace) {
|
||||
auto p = parser("fn main() return; }");
|
||||
auto decos = p->decoration_list();
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto f = p->function_decl(decos.value);
|
||||
ASSERT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto f = p->function_decl(attrs.value);
|
||||
EXPECT_TRUE(f.errored);
|
||||
EXPECT_FALSE(f.matched);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -45,7 +45,7 @@ TEST_F(ParserImplTest, FunctionHeader_TrailingComma) {
|
|||
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 f = p->function_header();
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
@ -55,8 +55,8 @@ TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType) {
|
|||
EXPECT_EQ(f->name, "main");
|
||||
EXPECT_EQ(f->params.size(), 0u);
|
||||
EXPECT_TRUE(f->return_type->Is<ast::F32>());
|
||||
ASSERT_EQ(f->return_type_decorations.size(), 1u);
|
||||
auto* loc = f->return_type_decorations[0]->As<ast::LocationDecoration>();
|
||||
ASSERT_EQ(f->return_type_attributes.size(), 1u);
|
||||
auto* loc = f->return_type_attributes[0]->As<ast::LocationAttribute>();
|
||||
ASSERT_TRUE(loc != nullptr);
|
||||
EXPECT_EQ(loc->value, 1u);
|
||||
}
|
||||
|
@ -71,11 +71,11 @@ TEST_F(ParserImplTest, FunctionHeader_InvariantReturnType) {
|
|||
EXPECT_EQ(f->name, "main");
|
||||
EXPECT_EQ(f->params.size(), 0u);
|
||||
EXPECT_TRUE(f->return_type->Is<ast::F32>());
|
||||
ASSERT_EQ(f->return_type_decorations.size(), 1u);
|
||||
EXPECT_TRUE(f->return_type_decorations[0]->Is<ast::InvariantDecoration>());
|
||||
ASSERT_EQ(f->return_type_attributes.size(), 1u);
|
||||
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 f = p->function_header();
|
||||
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->params.size(), 0u);
|
||||
ASSERT_EQ(f->return_type_decorations.size(), 1u);
|
||||
auto* loc = f->return_type_decorations[0]->As<ast::LocationDecoration>();
|
||||
ASSERT_EQ(f->return_type_attributes.size(), 1u);
|
||||
auto* loc = f->return_type_attributes[0]->As<ast::LocationAttribute>();
|
||||
ASSERT_TRUE(loc != nullptr);
|
||||
EXPECT_EQ(loc->value, 1u);
|
||||
|
||||
auto* array_type = f->return_type->As<ast::Array>();
|
||||
ASSERT_EQ(array_type->decorations.size(), 1u);
|
||||
auto* stride = array_type->decorations[0]->As<ast::StrideDecoration>();
|
||||
ASSERT_EQ(array_type->attributes.size(), 1u);
|
||||
auto* stride = array_type->attributes[0]->As<ast::StrideAttribute>();
|
||||
ASSERT_TRUE(stride != nullptr);
|
||||
EXPECT_EQ(stride->stride, 16u);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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"
|
||||
|
||||
namespace tint {
|
||||
|
@ -22,10 +22,10 @@ namespace {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl) {
|
||||
auto p = parser("let a : f32 = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto e = p->global_constant_decl(attrs.value);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -44,16 +44,15 @@ TEST_F(ParserImplTest, GlobalConstantDecl) {
|
|||
ASSERT_NE(e->constructor, nullptr);
|
||||
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
||||
|
||||
EXPECT_FALSE(
|
||||
ast::HasDecoration<ast::OverrideDecoration>(e.value->decorations));
|
||||
EXPECT_FALSE(ast::HasAttribute<ast::OverrideAttribute>(e.value->attributes));
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl_Inferred) {
|
||||
auto p = parser("let a = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto e = p->global_constant_decl(attrs.value);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -71,16 +70,15 @@ TEST_F(ParserImplTest, GlobalConstantDecl_Inferred) {
|
|||
ASSERT_NE(e->constructor, nullptr);
|
||||
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
||||
|
||||
EXPECT_FALSE(
|
||||
ast::HasDecoration<ast::OverrideDecoration>(e.value->decorations));
|
||||
EXPECT_FALSE(ast::HasAttribute<ast::OverrideAttribute>(e.value->attributes));
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
|
||||
auto p = parser("let a : f32 = if (a) {}");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto e = p->global_constant_decl(attrs.value);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
|
@ -90,10 +88,10 @@ TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
|
||||
auto p = parser("let a : f32 =");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto e = p->global_constant_decl(attrs.value);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
|
@ -103,11 +101,11 @@ TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalConstantDec_Override_WithId) {
|
||||
auto p = parser("@override(7) let a : f32 = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_TRUE(decos.matched);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
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_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -126,20 +124,20 @@ TEST_F(ParserImplTest, GlobalConstantDec_Override_WithId) {
|
|||
ASSERT_NE(e->constructor, nullptr);
|
||||
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
||||
|
||||
auto* override_deco =
|
||||
ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations);
|
||||
ASSERT_NE(override_deco, nullptr);
|
||||
EXPECT_TRUE(override_deco->has_value);
|
||||
EXPECT_EQ(override_deco->value, 7u);
|
||||
auto* override_attr =
|
||||
ast::GetAttribute<ast::OverrideAttribute>(e.value->attributes);
|
||||
ASSERT_NE(override_attr, nullptr);
|
||||
EXPECT_TRUE(override_attr->has_value);
|
||||
EXPECT_EQ(override_attr->value, 7u);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) {
|
||||
auto p = parser("[[override]] let a : f32 = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_TRUE(decos.matched);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
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_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -158,41 +156,41 @@ TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) {
|
|||
ASSERT_NE(e->constructor, nullptr);
|
||||
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
||||
|
||||
auto* override_deco =
|
||||
ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations);
|
||||
ASSERT_NE(override_deco, nullptr);
|
||||
EXPECT_FALSE(override_deco->has_value);
|
||||
auto* override_attr =
|
||||
ast::GetAttribute<ast::OverrideAttribute>(e.value->attributes);
|
||||
ASSERT_NE(override_attr, nullptr);
|
||||
EXPECT_FALSE(override_attr->has_value);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalConstantDec_Override_MissingId) {
|
||||
auto p = parser("@override() let a : f32 = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_TRUE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_TRUE(attrs.errored);
|
||||
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_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
|
||||
EXPECT_TRUE(p->has_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) {
|
||||
auto p = parser("@override(-7) let a : f32 = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_TRUE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_TRUE(attrs.errored);
|
||||
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_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
|
||||
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
|
||||
|
|
|
@ -131,7 +131,7 @@ TEST_F(ParserImplTest, GlobalDecl_Function) {
|
|||
"main");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_Function_WithDecoration) {
|
||||
TEST_F(ParserImplTest, GlobalDecl_Function_WithAttribute) {
|
||||
auto p = parser("@workgroup_size(2) fn main() { return; }");
|
||||
p->expect_global_decl();
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
@ -187,14 +187,14 @@ TEST_F(ParserImplTest, GlobalDecl_Struct_WithStride) {
|
|||
ASSERT_TRUE(ty->Is<ast::Array>());
|
||||
const auto* arr = ty->As<ast::Array>();
|
||||
|
||||
ASSERT_EQ(arr->decorations.size(), 1u);
|
||||
auto* stride = arr->decorations[0];
|
||||
ASSERT_TRUE(stride->Is<ast::StrideDecoration>());
|
||||
ASSERT_EQ(stride->As<ast::StrideDecoration>()->stride, 4u);
|
||||
ASSERT_EQ(arr->attributes.size(), 1u);
|
||||
auto* stride = arr->attributes[0];
|
||||
ASSERT_TRUE(stride->Is<ast::StrideAttribute>());
|
||||
ASSERT_EQ(stride->As<ast::StrideAttribute>()->stride, 4u);
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
|
||||
TEST_F(ParserImplTest, GlobalDecl_Struct_WithDecoration) {
|
||||
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when @block is removed.
|
||||
TEST_F(ParserImplTest, GlobalDecl_Struct_WithAttribute) {
|
||||
auto p = parser("[[block]] struct A { data: f32; }");
|
||||
p->expect_global_decl();
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
|
|
@ -21,10 +21,10 @@ namespace {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
|
||||
auto p = parser("var<private> a : f32");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_variable_decl(decos.value);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto e = p->global_variable_decl(attrs.value);
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -44,10 +44,10 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
|
||||
auto p = parser("var<private> a : f32 = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_variable_decl(decos.value);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto e = p->global_variable_decl(attrs.value);
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -66,12 +66,12 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
|
|||
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 decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_TRUE(decos.matched);
|
||||
auto e = p->global_variable_decl(decos.value);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
EXPECT_TRUE(attrs.matched);
|
||||
auto e = p->global_variable_decl(attrs.value);
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -89,19 +89,19 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
|||
|
||||
ASSERT_EQ(e->constructor, nullptr);
|
||||
|
||||
auto& decorations = e->decorations;
|
||||
ASSERT_EQ(decorations.size(), 2u);
|
||||
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
|
||||
ASSERT_TRUE(decorations[1]->Is<ast::GroupDecoration>());
|
||||
auto& attributes = e->attributes;
|
||||
ASSERT_EQ(attributes.size(), 2u);
|
||||
ASSERT_TRUE(attributes[0]->Is<ast::BindingAttribute>());
|
||||
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 decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_TRUE(decos.matched);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
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();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -119,34 +119,34 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
|
|||
|
||||
ASSERT_EQ(e->constructor, nullptr);
|
||||
|
||||
auto& decorations = e->decorations;
|
||||
ASSERT_EQ(decorations.size(), 2u);
|
||||
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
|
||||
ASSERT_TRUE(decorations[1]->Is<ast::GroupDecoration>());
|
||||
auto& attributes = e->attributes;
|
||||
ASSERT_EQ(attributes.size(), 2u);
|
||||
ASSERT_TRUE(attributes[0]->Is<ast::BindingAttribute>());
|
||||
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 decos = p->decoration_list();
|
||||
EXPECT_TRUE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_TRUE(attrs.errored);
|
||||
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_TRUE(e.matched);
|
||||
EXPECT_NE(e.value, nullptr);
|
||||
|
||||
EXPECT_TRUE(p->has_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) {
|
||||
auto p = parser("var<private> a : f32 = if (a) {}");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_variable_decl(decos.value);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto e = p->global_variable_decl(attrs.value);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
|
@ -156,10 +156,10 @@ TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
|
||||
auto p = parser("var<invalid> a : f32;");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_variable_decl(decos.value);
|
||||
auto attrs = p->attribute_list();
|
||||
EXPECT_FALSE(attrs.errored);
|
||||
EXPECT_FALSE(attrs.matched);
|
||||
auto e = p->global_variable_decl(attrs.value);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
|
|
|
@ -91,7 +91,7 @@ TEST_F(ParserImplTest, ParamList_TrailingComma) {
|
|||
EXPECT_EQ(e.value.size(), 1u);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, ParamList_Decorations) {
|
||||
TEST_F(ParserImplTest, ParamList_Attributes) {
|
||||
auto p =
|
||||
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_EQ(e.value[0]->type->As<ast::Vector>()->width, 4u);
|
||||
EXPECT_TRUE(e.value[0]->is_const);
|
||||
auto decos0 = e.value[0]->decorations;
|
||||
ASSERT_EQ(decos0.size(), 1u);
|
||||
EXPECT_TRUE(decos0[0]->Is<ast::BuiltinDecoration>());
|
||||
EXPECT_EQ(decos0[0]->As<ast::BuiltinDecoration>()->builtin,
|
||||
auto attrs_0 = e.value[0]->attributes;
|
||||
ASSERT_EQ(attrs_0.size(), 1u);
|
||||
EXPECT_TRUE(attrs_0[0]->Is<ast::BuiltinAttribute>());
|
||||
EXPECT_EQ(attrs_0[0]->As<ast::BuiltinAttribute>()->builtin,
|
||||
ast::Builtin::kPosition);
|
||||
|
||||
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_TRUE(e.value[1]->type->Is<ast::F32>());
|
||||
EXPECT_TRUE(e.value[1]->is_const);
|
||||
auto decos1 = e.value[1]->decorations;
|
||||
ASSERT_EQ(decos1.size(), 1u);
|
||||
EXPECT_TRUE(decos1[0]->Is<ast::LocationDecoration>());
|
||||
EXPECT_EQ(decos1[0]->As<ast::LocationDecoration>()->value, 1u);
|
||||
auto attrs_1 = e.value[1]->attributes;
|
||||
ASSERT_EQ(attrs_1.size(), 1u);
|
||||
EXPECT_TRUE(attrs_1[0]->Is<ast::LocationAttribute>());
|
||||
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.column, 52u);
|
||||
|
|
|
@ -58,7 +58,7 @@ TEST_F(ParserImplTest, PipelineStage_NoMatch) {
|
|||
auto stage = p->expect_pipeline_stage();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
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
|
||||
|
|
|
@ -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
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// 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"
|
||||
|
||||
namespace tint {
|
||||
|
@ -20,40 +20,40 @@ namespace reader {
|
|||
namespace wgsl {
|
||||
namespace {
|
||||
|
||||
struct DecorationData {
|
||||
struct AttributeData {
|
||||
const char* input;
|
||||
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);
|
||||
return out;
|
||||
}
|
||||
|
||||
class DecorationTest : public ParserImplTestWithParam<DecorationData> {};
|
||||
class AttributeTest : public ParserImplTestWithParam<AttributeData> {};
|
||||
|
||||
TEST_P(DecorationTest, Parses) {
|
||||
TEST_P(AttributeTest, Parses) {
|
||||
auto params = GetParam();
|
||||
auto p = parser(params.input);
|
||||
|
||||
auto deco = p->decoration();
|
||||
auto attr = p->attribute();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
EXPECT_TRUE(deco.matched);
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr);
|
||||
auto* struct_deco = deco.value->As<ast::Decoration>();
|
||||
ASSERT_NE(struct_deco, nullptr);
|
||||
EXPECT_EQ(struct_deco->Is<ast::StructBlockDecoration>(), params.is_block);
|
||||
EXPECT_TRUE(attr.matched);
|
||||
EXPECT_FALSE(attr.errored);
|
||||
ASSERT_NE(attr.value, nullptr);
|
||||
auto* struct_attr = attr.value->As<ast::Attribute>();
|
||||
ASSERT_NE(struct_attr, nullptr);
|
||||
EXPECT_EQ(struct_attr->Is<ast::StructBlockAttribute>(), params.is_block);
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||
DecorationTest,
|
||||
testing::Values(DecorationData{"block", true}));
|
||||
AttributeTest,
|
||||
testing::Values(AttributeData{"block", true}));
|
||||
|
||||
TEST_F(ParserImplTest, Decoration_NoMatch) {
|
||||
TEST_F(ParserImplTest, Attribute_NoMatch) {
|
||||
auto p = parser("not-a-stage");
|
||||
auto deco = p->decoration();
|
||||
EXPECT_FALSE(deco.matched);
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_EQ(deco.value, nullptr);
|
||||
auto attr = p->attribute();
|
||||
EXPECT_FALSE(attr.matched);
|
||||
EXPECT_FALSE(attr.errored);
|
||||
ASSERT_EQ(attr.value, nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
|
@ -32,7 +32,7 @@ TEST_F(ParserImplTest, StructBodyDecl_Parses) {
|
|||
const auto* mem = m.value[0];
|
||||
EXPECT_EQ(mem->symbol, builder.Symbols().Get("a"));
|
||||
EXPECT_TRUE(mem->type->Is<ast::I32>());
|
||||
EXPECT_EQ(mem->decorations.size(), 0u);
|
||||
EXPECT_EQ(mem->attributes.size(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructBodyDecl_ParsesEmpty) {
|
||||
|
@ -52,7 +52,7 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidAlign) {
|
|||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_TRUE(m.errored);
|
||||
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) {
|
||||
|
@ -64,7 +64,7 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidSize) {
|
|||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_TRUE(m.errored);
|
||||
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) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue