mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-13 19:01:24 +00:00
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.
|
`ast::Node`s are not shared.
|
||||||
|
|
||||||
The AST does not perform any verification of its content. For example, the
|
The AST does not perform any verification of its content. For example, the
|
||||||
`ast::StrideDecoration` node has numeric stride parameter, which is a count of
|
`ast::StrideAttribute` node has numeric stride parameter, which is a count of
|
||||||
the number of bytes from the start of one array element to the start of the
|
the number of bytes from the start of one array element to the start of the
|
||||||
next. The AST node itself does not constrain the set of stride values that you
|
next. The AST node itself does not constrain the set of stride values that you
|
||||||
can set, aside from storing it as an unsigned integer.
|
can set, aside from storing it as an unsigned integer.
|
||||||
|
72
src/BUILD.gn
72
src/BUILD.gn
@ -186,8 +186,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||||||
"ast/atomic.h",
|
"ast/atomic.h",
|
||||||
"ast/binary_expression.cc",
|
"ast/binary_expression.cc",
|
||||||
"ast/binary_expression.h",
|
"ast/binary_expression.h",
|
||||||
"ast/binding_decoration.cc",
|
"ast/binding_attribute.cc",
|
||||||
"ast/binding_decoration.h",
|
"ast/binding_attribute.h",
|
||||||
"ast/bitcast_expression.cc",
|
"ast/bitcast_expression.cc",
|
||||||
"ast/bitcast_expression.h",
|
"ast/bitcast_expression.h",
|
||||||
"ast/block_statement.cc",
|
"ast/block_statement.cc",
|
||||||
@ -200,8 +200,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||||||
"ast/break_statement.h",
|
"ast/break_statement.h",
|
||||||
"ast/builtin.cc",
|
"ast/builtin.cc",
|
||||||
"ast/builtin.h",
|
"ast/builtin.h",
|
||||||
"ast/builtin_decoration.cc",
|
"ast/builtin_attribute.cc",
|
||||||
"ast/builtin_decoration.h",
|
"ast/builtin_attribute.h",
|
||||||
"ast/call_expression.cc",
|
"ast/call_expression.cc",
|
||||||
"ast/call_expression.h",
|
"ast/call_expression.h",
|
||||||
"ast/call_statement.cc",
|
"ast/call_statement.cc",
|
||||||
@ -210,14 +210,14 @@ libtint_source_set("libtint_core_all_src") {
|
|||||||
"ast/case_statement.h",
|
"ast/case_statement.h",
|
||||||
"ast/continue_statement.cc",
|
"ast/continue_statement.cc",
|
||||||
"ast/continue_statement.h",
|
"ast/continue_statement.h",
|
||||||
"ast/decoration.cc",
|
"ast/attribute.cc",
|
||||||
"ast/decoration.h",
|
"ast/attribute.h",
|
||||||
"ast/depth_multisampled_texture.cc",
|
"ast/depth_multisampled_texture.cc",
|
||||||
"ast/depth_multisampled_texture.h",
|
"ast/depth_multisampled_texture.h",
|
||||||
"ast/depth_texture.cc",
|
"ast/depth_texture.cc",
|
||||||
"ast/depth_texture.h",
|
"ast/depth_texture.h",
|
||||||
"ast/disable_validation_decoration.cc",
|
"ast/disable_validation_attribute.cc",
|
||||||
"ast/disable_validation_decoration.h",
|
"ast/disable_validation_attribute.h",
|
||||||
"ast/discard_statement.cc",
|
"ast/discard_statement.cc",
|
||||||
"ast/discard_statement.h",
|
"ast/discard_statement.h",
|
||||||
"ast/else_statement.cc",
|
"ast/else_statement.cc",
|
||||||
@ -236,8 +236,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||||||
"ast/for_loop_statement.h",
|
"ast/for_loop_statement.h",
|
||||||
"ast/function.cc",
|
"ast/function.cc",
|
||||||
"ast/function.h",
|
"ast/function.h",
|
||||||
"ast/group_decoration.cc",
|
"ast/group_attribute.cc",
|
||||||
"ast/group_decoration.h",
|
"ast/group_attribute.h",
|
||||||
"ast/i32.cc",
|
"ast/i32.cc",
|
||||||
"ast/i32.h",
|
"ast/i32.h",
|
||||||
"ast/identifier_expression.cc",
|
"ast/identifier_expression.cc",
|
||||||
@ -248,16 +248,16 @@ libtint_source_set("libtint_core_all_src") {
|
|||||||
"ast/index_accessor_expression.h",
|
"ast/index_accessor_expression.h",
|
||||||
"ast/int_literal_expression.cc",
|
"ast/int_literal_expression.cc",
|
||||||
"ast/int_literal_expression.h",
|
"ast/int_literal_expression.h",
|
||||||
"ast/internal_decoration.cc",
|
"ast/internal_attribute.cc",
|
||||||
"ast/internal_decoration.h",
|
"ast/internal_attribute.h",
|
||||||
"ast/interpolate_decoration.cc",
|
"ast/interpolate_attribute.cc",
|
||||||
"ast/interpolate_decoration.h",
|
"ast/interpolate_attribute.h",
|
||||||
"ast/invariant_decoration.cc",
|
"ast/invariant_attribute.cc",
|
||||||
"ast/invariant_decoration.h",
|
"ast/invariant_attribute.h",
|
||||||
"ast/literal_expression.cc",
|
"ast/literal_expression.cc",
|
||||||
"ast/literal_expression.h",
|
"ast/literal_expression.h",
|
||||||
"ast/location_decoration.cc",
|
"ast/location_attribute.cc",
|
||||||
"ast/location_decoration.h",
|
"ast/location_attribute.h",
|
||||||
"ast/loop_statement.cc",
|
"ast/loop_statement.cc",
|
||||||
"ast/loop_statement.h",
|
"ast/loop_statement.h",
|
||||||
"ast/matrix.cc",
|
"ast/matrix.cc",
|
||||||
@ -270,8 +270,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||||||
"ast/multisampled_texture.h",
|
"ast/multisampled_texture.h",
|
||||||
"ast/node.cc",
|
"ast/node.cc",
|
||||||
"ast/node.h",
|
"ast/node.h",
|
||||||
"ast/override_decoration.cc",
|
"ast/override_attribute.cc",
|
||||||
"ast/override_decoration.h",
|
"ast/override_attribute.h",
|
||||||
"ast/phony_expression.cc",
|
"ast/phony_expression.cc",
|
||||||
"ast/phony_expression.h",
|
"ast/phony_expression.h",
|
||||||
"ast/pipeline_stage.cc",
|
"ast/pipeline_stage.cc",
|
||||||
@ -286,28 +286,28 @@ libtint_source_set("libtint_core_all_src") {
|
|||||||
"ast/sampler.h",
|
"ast/sampler.h",
|
||||||
"ast/sint_literal_expression.cc",
|
"ast/sint_literal_expression.cc",
|
||||||
"ast/sint_literal_expression.h",
|
"ast/sint_literal_expression.h",
|
||||||
"ast/stage_decoration.cc",
|
"ast/stage_attribute.cc",
|
||||||
"ast/stage_decoration.h",
|
"ast/stage_attribute.h",
|
||||||
"ast/statement.cc",
|
"ast/statement.cc",
|
||||||
"ast/statement.h",
|
"ast/statement.h",
|
||||||
"ast/storage_class.cc",
|
"ast/storage_class.cc",
|
||||||
"ast/storage_class.h",
|
"ast/storage_class.h",
|
||||||
"ast/storage_texture.cc",
|
"ast/storage_texture.cc",
|
||||||
"ast/storage_texture.h",
|
"ast/storage_texture.h",
|
||||||
"ast/stride_decoration.cc",
|
"ast/stride_attribute.cc",
|
||||||
"ast/stride_decoration.h",
|
"ast/stride_attribute.h",
|
||||||
"ast/struct.cc",
|
"ast/struct.cc",
|
||||||
"ast/struct.h",
|
"ast/struct.h",
|
||||||
"ast/struct_block_decoration.cc",
|
"ast/struct_block_attribute.cc",
|
||||||
"ast/struct_block_decoration.h",
|
"ast/struct_block_attribute.h",
|
||||||
"ast/struct_member.cc",
|
"ast/struct_member.cc",
|
||||||
"ast/struct_member.h",
|
"ast/struct_member.h",
|
||||||
"ast/struct_member_align_decoration.cc",
|
"ast/struct_member_align_attribute.cc",
|
||||||
"ast/struct_member_align_decoration.h",
|
"ast/struct_member_align_attribute.h",
|
||||||
"ast/struct_member_offset_decoration.cc",
|
"ast/struct_member_offset_attribute.cc",
|
||||||
"ast/struct_member_offset_decoration.h",
|
"ast/struct_member_offset_attribute.h",
|
||||||
"ast/struct_member_size_decoration.cc",
|
"ast/struct_member_size_attribute.cc",
|
||||||
"ast/struct_member_size_decoration.h",
|
"ast/struct_member_size_attribute.h",
|
||||||
"ast/switch_statement.cc",
|
"ast/switch_statement.cc",
|
||||||
"ast/switch_statement.h",
|
"ast/switch_statement.h",
|
||||||
"ast/texture.cc",
|
"ast/texture.cc",
|
||||||
@ -334,8 +334,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||||||
"ast/vector.h",
|
"ast/vector.h",
|
||||||
"ast/void.cc",
|
"ast/void.cc",
|
||||||
"ast/void.h",
|
"ast/void.h",
|
||||||
"ast/workgroup_decoration.cc",
|
"ast/workgroup_attribute.cc",
|
||||||
"ast/workgroup_decoration.h",
|
"ast/workgroup_attribute.h",
|
||||||
"block_allocator.h",
|
"block_allocator.h",
|
||||||
"castable.cc",
|
"castable.cc",
|
||||||
"castable.h",
|
"castable.h",
|
||||||
@ -427,8 +427,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||||||
"traits.h",
|
"traits.h",
|
||||||
"transform/add_empty_entry_point.cc",
|
"transform/add_empty_entry_point.cc",
|
||||||
"transform/add_empty_entry_point.h",
|
"transform/add_empty_entry_point.h",
|
||||||
"transform/add_spirv_block_decoration.cc",
|
"transform/add_spirv_block_attribute.cc",
|
||||||
"transform/add_spirv_block_decoration.h",
|
"transform/add_spirv_block_attribute.h",
|
||||||
"transform/array_length_from_uniform.cc",
|
"transform/array_length_from_uniform.cc",
|
||||||
"transform/array_length_from_uniform.h",
|
"transform/array_length_from_uniform.h",
|
||||||
"transform/binding_remapper.cc",
|
"transform/binding_remapper.cc",
|
||||||
|
@ -55,6 +55,8 @@ set(TINT_LIB_SRCS
|
|||||||
../include/tint/tint.h
|
../include/tint/tint.h
|
||||||
ast/access.cc
|
ast/access.cc
|
||||||
ast/access.h
|
ast/access.h
|
||||||
|
ast/attribute.cc
|
||||||
|
ast/attribute.h
|
||||||
ast/alias.cc
|
ast/alias.cc
|
||||||
ast/alias.h
|
ast/alias.h
|
||||||
ast/index_accessor_expression.cc
|
ast/index_accessor_expression.cc
|
||||||
@ -67,8 +69,8 @@ set(TINT_LIB_SRCS
|
|||||||
ast/atomic.h
|
ast/atomic.h
|
||||||
ast/binary_expression.cc
|
ast/binary_expression.cc
|
||||||
ast/binary_expression.h
|
ast/binary_expression.h
|
||||||
ast/binding_decoration.cc
|
ast/binding_attribute.cc
|
||||||
ast/binding_decoration.h
|
ast/binding_attribute.h
|
||||||
ast/bitcast_expression.cc
|
ast/bitcast_expression.cc
|
||||||
ast/bitcast_expression.h
|
ast/bitcast_expression.h
|
||||||
ast/block_statement.cc
|
ast/block_statement.cc
|
||||||
@ -79,8 +81,8 @@ set(TINT_LIB_SRCS
|
|||||||
ast/bool.h
|
ast/bool.h
|
||||||
ast/break_statement.cc
|
ast/break_statement.cc
|
||||||
ast/break_statement.h
|
ast/break_statement.h
|
||||||
ast/builtin_decoration.cc
|
ast/builtin_attribute.cc
|
||||||
ast/builtin_decoration.h
|
ast/builtin_attribute.h
|
||||||
ast/builtin.cc
|
ast/builtin.cc
|
||||||
ast/builtin.h
|
ast/builtin.h
|
||||||
ast/call_expression.cc
|
ast/call_expression.cc
|
||||||
@ -91,12 +93,10 @@ set(TINT_LIB_SRCS
|
|||||||
ast/case_statement.h
|
ast/case_statement.h
|
||||||
ast/continue_statement.cc
|
ast/continue_statement.cc
|
||||||
ast/continue_statement.h
|
ast/continue_statement.h
|
||||||
ast/decoration.cc
|
|
||||||
ast/decoration.h
|
|
||||||
ast/depth_multisampled_texture.cc
|
ast/depth_multisampled_texture.cc
|
||||||
ast/depth_multisampled_texture.h
|
ast/depth_multisampled_texture.h
|
||||||
ast/disable_validation_decoration.cc
|
ast/disable_validation_attribute.cc
|
||||||
ast/disable_validation_decoration.h
|
ast/disable_validation_attribute.h
|
||||||
ast/depth_texture.cc
|
ast/depth_texture.cc
|
||||||
ast/depth_texture.h
|
ast/depth_texture.h
|
||||||
ast/discard_statement.cc
|
ast/discard_statement.cc
|
||||||
@ -117,8 +117,8 @@ set(TINT_LIB_SRCS
|
|||||||
ast/for_loop_statement.h
|
ast/for_loop_statement.h
|
||||||
ast/function.cc
|
ast/function.cc
|
||||||
ast/function.h
|
ast/function.h
|
||||||
ast/group_decoration.cc
|
ast/group_attribute.cc
|
||||||
ast/group_decoration.h
|
ast/group_attribute.h
|
||||||
ast/i32.cc
|
ast/i32.cc
|
||||||
ast/i32.h
|
ast/i32.h
|
||||||
ast/identifier_expression.cc
|
ast/identifier_expression.cc
|
||||||
@ -127,16 +127,16 @@ set(TINT_LIB_SRCS
|
|||||||
ast/if_statement.h
|
ast/if_statement.h
|
||||||
ast/int_literal_expression.cc
|
ast/int_literal_expression.cc
|
||||||
ast/int_literal_expression.h
|
ast/int_literal_expression.h
|
||||||
ast/internal_decoration.cc
|
ast/internal_attribute.cc
|
||||||
ast/internal_decoration.h
|
ast/internal_attribute.h
|
||||||
ast/interpolate_decoration.cc
|
ast/interpolate_attribute.cc
|
||||||
ast/interpolate_decoration.h
|
ast/interpolate_attribute.h
|
||||||
ast/invariant_decoration.cc
|
ast/invariant_attribute.cc
|
||||||
ast/invariant_decoration.h
|
ast/invariant_attribute.h
|
||||||
ast/literal_expression.cc
|
ast/literal_expression.cc
|
||||||
ast/literal_expression.h
|
ast/literal_expression.h
|
||||||
ast/location_decoration.cc
|
ast/location_attribute.cc
|
||||||
ast/location_decoration.h
|
ast/location_attribute.h
|
||||||
ast/loop_statement.cc
|
ast/loop_statement.cc
|
||||||
ast/loop_statement.h
|
ast/loop_statement.h
|
||||||
ast/matrix.cc
|
ast/matrix.cc
|
||||||
@ -149,8 +149,8 @@ set(TINT_LIB_SRCS
|
|||||||
ast/multisampled_texture.h
|
ast/multisampled_texture.h
|
||||||
ast/node.cc
|
ast/node.cc
|
||||||
ast/node.h
|
ast/node.h
|
||||||
ast/override_decoration.cc
|
ast/override_attribute.cc
|
||||||
ast/override_decoration.h
|
ast/override_attribute.h
|
||||||
ast/phony_expression.cc
|
ast/phony_expression.cc
|
||||||
ast/phony_expression.h
|
ast/phony_expression.h
|
||||||
ast/pipeline_stage.cc
|
ast/pipeline_stage.cc
|
||||||
@ -165,24 +165,24 @@ set(TINT_LIB_SRCS
|
|||||||
ast/sampler.h
|
ast/sampler.h
|
||||||
ast/sint_literal_expression.cc
|
ast/sint_literal_expression.cc
|
||||||
ast/sint_literal_expression.h
|
ast/sint_literal_expression.h
|
||||||
ast/stage_decoration.cc
|
ast/stage_attribute.cc
|
||||||
ast/stage_decoration.h
|
ast/stage_attribute.h
|
||||||
ast/statement.cc
|
ast/statement.cc
|
||||||
ast/statement.h
|
ast/statement.h
|
||||||
ast/storage_class.cc
|
ast/storage_class.cc
|
||||||
ast/storage_class.h
|
ast/storage_class.h
|
||||||
ast/storage_texture.cc
|
ast/storage_texture.cc
|
||||||
ast/storage_texture.h
|
ast/storage_texture.h
|
||||||
ast/stride_decoration.cc
|
ast/stride_attribute.cc
|
||||||
ast/stride_decoration.h
|
ast/stride_attribute.h
|
||||||
ast/struct_block_decoration.cc
|
ast/struct_block_attribute.cc
|
||||||
ast/struct_block_decoration.h
|
ast/struct_block_attribute.h
|
||||||
ast/struct_member_align_decoration.cc
|
ast/struct_member_align_attribute.cc
|
||||||
ast/struct_member_align_decoration.h
|
ast/struct_member_align_attribute.h
|
||||||
ast/struct_member_offset_decoration.cc
|
ast/struct_member_offset_attribute.cc
|
||||||
ast/struct_member_offset_decoration.h
|
ast/struct_member_offset_attribute.h
|
||||||
ast/struct_member_size_decoration.cc
|
ast/struct_member_size_attribute.cc
|
||||||
ast/struct_member_size_decoration.h
|
ast/struct_member_size_attribute.h
|
||||||
ast/struct_member.cc
|
ast/struct_member.cc
|
||||||
ast/struct_member.h
|
ast/struct_member.h
|
||||||
ast/struct.cc
|
ast/struct.cc
|
||||||
@ -216,8 +216,8 @@ set(TINT_LIB_SRCS
|
|||||||
ast/vector.h
|
ast/vector.h
|
||||||
ast/void.cc
|
ast/void.cc
|
||||||
ast/void.h
|
ast/void.h
|
||||||
ast/workgroup_decoration.cc
|
ast/workgroup_attribute.cc
|
||||||
ast/workgroup_decoration.h
|
ast/workgroup_attribute.h
|
||||||
block_allocator.h
|
block_allocator.h
|
||||||
castable.cc
|
castable.cc
|
||||||
castable.h
|
castable.h
|
||||||
@ -295,8 +295,8 @@ set(TINT_LIB_SRCS
|
|||||||
traits.h
|
traits.h
|
||||||
transform/add_empty_entry_point.cc
|
transform/add_empty_entry_point.cc
|
||||||
transform/add_empty_entry_point.h
|
transform/add_empty_entry_point.h
|
||||||
transform/add_spirv_block_decoration.cc
|
transform/add_spirv_block_attribute.cc
|
||||||
transform/add_spirv_block_decoration.h
|
transform/add_spirv_block_attribute.h
|
||||||
transform/array_length_from_uniform.cc
|
transform/array_length_from_uniform.cc
|
||||||
transform/array_length_from_uniform.h
|
transform/array_length_from_uniform.h
|
||||||
transform/binding_remapper.cc
|
transform/binding_remapper.cc
|
||||||
@ -617,13 +617,13 @@ if(TINT_BUILD_TESTS)
|
|||||||
ast/assignment_statement_test.cc
|
ast/assignment_statement_test.cc
|
||||||
ast/atomic_test.cc
|
ast/atomic_test.cc
|
||||||
ast/binary_expression_test.cc
|
ast/binary_expression_test.cc
|
||||||
ast/binding_decoration_test.cc
|
ast/binding_attribute_test.cc
|
||||||
ast/bitcast_expression_test.cc
|
ast/bitcast_expression_test.cc
|
||||||
ast/block_statement_test.cc
|
ast/block_statement_test.cc
|
||||||
ast/bool_literal_expression_test.cc
|
ast/bool_literal_expression_test.cc
|
||||||
ast/bool_test.cc
|
ast/bool_test.cc
|
||||||
ast/break_statement_test.cc
|
ast/break_statement_test.cc
|
||||||
ast/builtin_decoration_test.cc
|
ast/builtin_attribute_test.cc
|
||||||
ast/call_expression_test.cc
|
ast/call_expression_test.cc
|
||||||
ast/call_statement_test.cc
|
ast/call_statement_test.cc
|
||||||
ast/case_statement_test.cc
|
ast/case_statement_test.cc
|
||||||
@ -638,36 +638,36 @@ if(TINT_BUILD_TESTS)
|
|||||||
ast/float_literal_expression_test.cc
|
ast/float_literal_expression_test.cc
|
||||||
ast/for_loop_statement_test.cc
|
ast/for_loop_statement_test.cc
|
||||||
ast/function_test.cc
|
ast/function_test.cc
|
||||||
ast/group_decoration_test.cc
|
ast/group_attribute_test.cc
|
||||||
ast/i32_test.cc
|
ast/i32_test.cc
|
||||||
ast/identifier_expression_test.cc
|
ast/identifier_expression_test.cc
|
||||||
ast/if_statement_test.cc
|
ast/if_statement_test.cc
|
||||||
ast/index_accessor_expression_test.cc
|
ast/index_accessor_expression_test.cc
|
||||||
ast/int_literal_expression_test.cc
|
ast/int_literal_expression_test.cc
|
||||||
ast/interpolate_decoration_test.cc
|
ast/interpolate_attribute_test.cc
|
||||||
ast/intrinsic_texture_helper_test.cc
|
ast/intrinsic_texture_helper_test.cc
|
||||||
ast/intrinsic_texture_helper_test.h
|
ast/intrinsic_texture_helper_test.h
|
||||||
ast/invariant_decoration_test.cc
|
ast/invariant_attribute_test.cc
|
||||||
ast/location_decoration_test.cc
|
ast/location_attribute_test.cc
|
||||||
ast/loop_statement_test.cc
|
ast/loop_statement_test.cc
|
||||||
ast/matrix_test.cc
|
ast/matrix_test.cc
|
||||||
ast/member_accessor_expression_test.cc
|
ast/member_accessor_expression_test.cc
|
||||||
ast/module_clone_test.cc
|
ast/module_clone_test.cc
|
||||||
ast/module_test.cc
|
ast/module_test.cc
|
||||||
ast/multisampled_texture_test.cc
|
ast/multisampled_texture_test.cc
|
||||||
ast/override_decoration_test.cc
|
ast/override_attribute_test.cc
|
||||||
ast/phony_expression_test.cc
|
ast/phony_expression_test.cc
|
||||||
ast/pointer_test.cc
|
ast/pointer_test.cc
|
||||||
ast/return_statement_test.cc
|
ast/return_statement_test.cc
|
||||||
ast/sampled_texture_test.cc
|
ast/sampled_texture_test.cc
|
||||||
ast/sampler_test.cc
|
ast/sampler_test.cc
|
||||||
ast/sint_literal_expression_test.cc
|
ast/sint_literal_expression_test.cc
|
||||||
ast/stage_decoration_test.cc
|
ast/stage_attribute_test.cc
|
||||||
ast/storage_texture_test.cc
|
ast/storage_texture_test.cc
|
||||||
ast/stride_decoration_test.cc
|
ast/stride_attribute_test.cc
|
||||||
ast/struct_member_align_decoration_test.cc
|
ast/struct_member_align_attribute_test.cc
|
||||||
ast/struct_member_offset_decoration_test.cc
|
ast/struct_member_offset_attribute_test.cc
|
||||||
ast/struct_member_size_decoration_test.cc
|
ast/struct_member_size_attribute_test.cc
|
||||||
ast/struct_member_test.cc
|
ast/struct_member_test.cc
|
||||||
ast/struct_test.cc
|
ast/struct_test.cc
|
||||||
ast/switch_statement_test.cc
|
ast/switch_statement_test.cc
|
||||||
@ -680,7 +680,7 @@ if(TINT_BUILD_TESTS)
|
|||||||
ast/variable_decl_statement_test.cc
|
ast/variable_decl_statement_test.cc
|
||||||
ast/variable_test.cc
|
ast/variable_test.cc
|
||||||
ast/vector_test.cc
|
ast/vector_test.cc
|
||||||
ast/workgroup_decoration_test.cc
|
ast/workgroup_attribute_test.cc
|
||||||
block_allocator_test.cc
|
block_allocator_test.cc
|
||||||
castable_test.cc
|
castable_test.cc
|
||||||
clone_context_test.cc
|
clone_context_test.cc
|
||||||
@ -701,7 +701,7 @@ if(TINT_BUILD_TESTS)
|
|||||||
resolver/call_validation_test.cc
|
resolver/call_validation_test.cc
|
||||||
resolver/compound_statement_test.cc
|
resolver/compound_statement_test.cc
|
||||||
resolver/control_block_validation_test.cc
|
resolver/control_block_validation_test.cc
|
||||||
resolver/decoration_validation_test.cc
|
resolver/attribute_validation_test.cc
|
||||||
resolver/dependency_graph_test.cc
|
resolver/dependency_graph_test.cc
|
||||||
resolver/entry_point_validation_test.cc
|
resolver/entry_point_validation_test.cc
|
||||||
resolver/function_validation_test.cc
|
resolver/function_validation_test.cc
|
||||||
@ -850,8 +850,8 @@ if(TINT_BUILD_TESTS)
|
|||||||
reader/wgsl/parser_impl_exclusive_or_expression_test.cc
|
reader/wgsl/parser_impl_exclusive_or_expression_test.cc
|
||||||
reader/wgsl/parser_impl_for_stmt_test.cc
|
reader/wgsl/parser_impl_for_stmt_test.cc
|
||||||
reader/wgsl/parser_impl_function_decl_test.cc
|
reader/wgsl/parser_impl_function_decl_test.cc
|
||||||
reader/wgsl/parser_impl_function_decoration_list_test.cc
|
reader/wgsl/parser_impl_function_attribute_list_test.cc
|
||||||
reader/wgsl/parser_impl_function_decoration_test.cc
|
reader/wgsl/parser_impl_function_attribute_test.cc
|
||||||
reader/wgsl/parser_impl_function_header_test.cc
|
reader/wgsl/parser_impl_function_header_test.cc
|
||||||
reader/wgsl/parser_impl_global_constant_decl_test.cc
|
reader/wgsl/parser_impl_global_constant_decl_test.cc
|
||||||
reader/wgsl/parser_impl_global_decl_test.cc
|
reader/wgsl/parser_impl_global_decl_test.cc
|
||||||
@ -878,10 +878,10 @@ if(TINT_BUILD_TESTS)
|
|||||||
reader/wgsl/parser_impl_storage_texture_type_test.cc
|
reader/wgsl/parser_impl_storage_texture_type_test.cc
|
||||||
reader/wgsl/parser_impl_struct_body_decl_test.cc
|
reader/wgsl/parser_impl_struct_body_decl_test.cc
|
||||||
reader/wgsl/parser_impl_struct_decl_test.cc
|
reader/wgsl/parser_impl_struct_decl_test.cc
|
||||||
reader/wgsl/parser_impl_struct_decoration_decl_test.cc
|
reader/wgsl/parser_impl_struct_attribute_decl_test.cc
|
||||||
reader/wgsl/parser_impl_struct_decoration_test.cc
|
reader/wgsl/parser_impl_struct_attribute_test.cc
|
||||||
reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc
|
reader/wgsl/parser_impl_struct_member_attribute_decl_test.cc
|
||||||
reader/wgsl/parser_impl_struct_member_decoration_test.cc
|
reader/wgsl/parser_impl_struct_member_attribute_test.cc
|
||||||
reader/wgsl/parser_impl_struct_member_test.cc
|
reader/wgsl/parser_impl_struct_member_test.cc
|
||||||
reader/wgsl/parser_impl_switch_body_test.cc
|
reader/wgsl/parser_impl_switch_body_test.cc
|
||||||
reader/wgsl/parser_impl_switch_stmt_test.cc
|
reader/wgsl/parser_impl_switch_stmt_test.cc
|
||||||
@ -894,8 +894,8 @@ if(TINT_BUILD_TESTS)
|
|||||||
reader/wgsl/parser_impl_type_decl_test.cc
|
reader/wgsl/parser_impl_type_decl_test.cc
|
||||||
reader/wgsl/parser_impl_unary_expression_test.cc
|
reader/wgsl/parser_impl_unary_expression_test.cc
|
||||||
reader/wgsl/parser_impl_variable_decl_test.cc
|
reader/wgsl/parser_impl_variable_decl_test.cc
|
||||||
reader/wgsl/parser_impl_variable_decoration_list_test.cc
|
reader/wgsl/parser_impl_variable_attribute_list_test.cc
|
||||||
reader/wgsl/parser_impl_variable_decoration_test.cc
|
reader/wgsl/parser_impl_variable_attribute_test.cc
|
||||||
reader/wgsl/parser_impl_variable_ident_decl_test.cc
|
reader/wgsl/parser_impl_variable_ident_decl_test.cc
|
||||||
reader/wgsl/parser_impl_variable_stmt_test.cc
|
reader/wgsl/parser_impl_variable_stmt_test.cc
|
||||||
reader/wgsl/parser_impl_variable_qualifier_test.cc
|
reader/wgsl/parser_impl_variable_qualifier_test.cc
|
||||||
@ -916,7 +916,7 @@ if(TINT_BUILD_TESTS)
|
|||||||
writer/spirv/builder_discard_test.cc
|
writer/spirv/builder_discard_test.cc
|
||||||
writer/spirv/builder_entry_point_test.cc
|
writer/spirv/builder_entry_point_test.cc
|
||||||
writer/spirv/builder_format_conversion_test.cc
|
writer/spirv/builder_format_conversion_test.cc
|
||||||
writer/spirv/builder_function_decoration_test.cc
|
writer/spirv/builder_function_attribute_test.cc
|
||||||
writer/spirv/builder_function_test.cc
|
writer/spirv/builder_function_test.cc
|
||||||
writer/spirv/builder_function_variable_test.cc
|
writer/spirv/builder_function_variable_test.cc
|
||||||
writer/spirv/builder_global_variable_test.cc
|
writer/spirv/builder_global_variable_test.cc
|
||||||
@ -977,7 +977,7 @@ if(TINT_BUILD_TESTS)
|
|||||||
if(${TINT_BUILD_WGSL_READER} AND ${TINT_BUILD_WGSL_WRITER})
|
if(${TINT_BUILD_WGSL_READER} AND ${TINT_BUILD_WGSL_WRITER})
|
||||||
list(APPEND TINT_TEST_SRCS
|
list(APPEND TINT_TEST_SRCS
|
||||||
transform/add_empty_entry_point_test.cc
|
transform/add_empty_entry_point_test.cc
|
||||||
transform/add_spirv_block_decoration_test.cc
|
transform/add_spirv_block_attribute_test.cc
|
||||||
transform/array_length_from_uniform_test.cc
|
transform/array_length_from_uniform_test.cc
|
||||||
transform/binding_remapper_test.cc
|
transform/binding_remapper_test.cc
|
||||||
transform/calculate_array_length_test.cc
|
transform/calculate_array_length_test.cc
|
||||||
|
@ -43,8 +43,8 @@ Array::Array(ProgramID pid,
|
|||||||
const Source& src,
|
const Source& src,
|
||||||
const Type* subtype,
|
const Type* subtype,
|
||||||
const Expression* cnt,
|
const Expression* cnt,
|
||||||
DecorationList decos)
|
AttributeList attrs)
|
||||||
: Base(pid, src), type(subtype), count(cnt), decorations(decos) {}
|
: Base(pid, src), type(subtype), count(cnt), attributes(attrs) {}
|
||||||
|
|
||||||
Array::Array(Array&&) = default;
|
Array::Array(Array&&) = default;
|
||||||
|
|
||||||
@ -52,8 +52,8 @@ Array::~Array() = default;
|
|||||||
|
|
||||||
std::string Array::FriendlyName(const SymbolTable& symbols) const {
|
std::string Array::FriendlyName(const SymbolTable& symbols) const {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
for (auto* deco : decorations) {
|
for (auto* attr : attributes) {
|
||||||
if (auto* stride = deco->As<ast::StrideDecoration>()) {
|
if (auto* stride = attr->As<ast::StrideAttribute>()) {
|
||||||
out << "@stride(" << stride->stride << ") ";
|
out << "@stride(" << stride->stride << ") ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,8 +70,8 @@ const Array* Array::Clone(CloneContext* ctx) const {
|
|||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
auto* ty = ctx->Clone(type);
|
auto* ty = ctx->Clone(type);
|
||||||
auto* cnt = ctx->Clone(count);
|
auto* cnt = ctx->Clone(count);
|
||||||
auto decos = ctx->Clone(decorations);
|
auto attrs = ctx->Clone(attributes);
|
||||||
return ctx->dst->create<Array>(src, ty, cnt, decos);
|
return ctx->dst->create<Array>(src, ty, cnt, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
#include "src/ast/type.h"
|
#include "src/ast/type.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
@ -35,12 +35,12 @@ class Array : public Castable<Array, Type> {
|
|||||||
/// @param subtype the type of the array elements
|
/// @param subtype the type of the array elements
|
||||||
/// @param count the number of elements in the array. nullptr represents a
|
/// @param count the number of elements in the array. nullptr represents a
|
||||||
/// runtime-sized array.
|
/// runtime-sized array.
|
||||||
/// @param decorations the array decorations
|
/// @param attributes the array attributes
|
||||||
Array(ProgramID pid,
|
Array(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
const Type* subtype,
|
const Type* subtype,
|
||||||
const Expression* count,
|
const Expression* count,
|
||||||
DecorationList decorations);
|
AttributeList attributes);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
Array(Array&&);
|
Array(Array&&);
|
||||||
~Array() override;
|
~Array() override;
|
||||||
@ -65,8 +65,8 @@ class Array : public Castable<Array, Type> {
|
|||||||
/// the array size in elements, or nullptr for a runtime array
|
/// the array size in elements, or nullptr for a runtime array
|
||||||
const Expression* const count;
|
const Expression* const count;
|
||||||
|
|
||||||
/// the array decorations
|
/// the array attributes
|
||||||
const DecorationList decorations;
|
const AttributeList attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
@ -25,7 +25,7 @@ using AstArrayTest = TestHelper;
|
|||||||
TEST_F(AstArrayTest, CreateSizedArray) {
|
TEST_F(AstArrayTest, CreateSizedArray) {
|
||||||
auto* u32 = create<U32>();
|
auto* u32 = create<U32>();
|
||||||
auto* count = Expr(3);
|
auto* count = Expr(3);
|
||||||
auto* arr = create<Array>(u32, count, DecorationList{});
|
auto* arr = create<Array>(u32, count, AttributeList{});
|
||||||
EXPECT_EQ(arr->type, u32);
|
EXPECT_EQ(arr->type, u32);
|
||||||
EXPECT_EQ(arr->count, count);
|
EXPECT_EQ(arr->count, count);
|
||||||
EXPECT_TRUE(arr->Is<Array>());
|
EXPECT_TRUE(arr->Is<Array>());
|
||||||
@ -34,7 +34,7 @@ TEST_F(AstArrayTest, CreateSizedArray) {
|
|||||||
|
|
||||||
TEST_F(AstArrayTest, CreateRuntimeArray) {
|
TEST_F(AstArrayTest, CreateRuntimeArray) {
|
||||||
auto* u32 = create<U32>();
|
auto* u32 = create<U32>();
|
||||||
auto* arr = create<Array>(u32, nullptr, DecorationList{});
|
auto* arr = create<Array>(u32, nullptr, AttributeList{});
|
||||||
EXPECT_EQ(arr->type, u32);
|
EXPECT_EQ(arr->type, u32);
|
||||||
EXPECT_EQ(arr->count, nullptr);
|
EXPECT_EQ(arr->count, nullptr);
|
||||||
EXPECT_TRUE(arr->Is<Array>());
|
EXPECT_TRUE(arr->Is<Array>());
|
||||||
@ -43,26 +43,26 @@ TEST_F(AstArrayTest, CreateRuntimeArray) {
|
|||||||
|
|
||||||
TEST_F(AstArrayTest, FriendlyName_RuntimeSized) {
|
TEST_F(AstArrayTest, FriendlyName_RuntimeSized) {
|
||||||
auto* i32 = create<I32>();
|
auto* i32 = create<I32>();
|
||||||
auto* arr = create<Array>(i32, nullptr, DecorationList{});
|
auto* arr = create<Array>(i32, nullptr, AttributeList{});
|
||||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
|
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AstArrayTest, FriendlyName_LiteralSized) {
|
TEST_F(AstArrayTest, FriendlyName_LiteralSized) {
|
||||||
auto* i32 = create<I32>();
|
auto* i32 = create<I32>();
|
||||||
auto* arr = create<Array>(i32, Expr(5), DecorationList{});
|
auto* arr = create<Array>(i32, Expr(5), AttributeList{});
|
||||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
|
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AstArrayTest, FriendlyName_ConstantSized) {
|
TEST_F(AstArrayTest, FriendlyName_ConstantSized) {
|
||||||
auto* i32 = create<I32>();
|
auto* i32 = create<I32>();
|
||||||
auto* arr = create<Array>(i32, Expr("size"), DecorationList{});
|
auto* arr = create<Array>(i32, Expr("size"), AttributeList{});
|
||||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, size>");
|
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, size>");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AstArrayTest, FriendlyName_WithStride) {
|
TEST_F(AstArrayTest, FriendlyName_WithStride) {
|
||||||
auto* i32 = create<I32>();
|
auto* i32 = create<I32>();
|
||||||
auto* arr =
|
auto* arr =
|
||||||
create<Array>(i32, Expr(5), DecorationList{create<StrideDecoration>(32)});
|
create<Array>(i32, Expr(5), AttributeList{create<StrideAttribute>(32)});
|
||||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>");
|
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,14 +12,14 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::Decoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::Attribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
Decoration::~Decoration() = default;
|
Attribute::~Attribute() = default;
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
@ -12,8 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_DECORATION_H_
|
#ifndef SRC_AST_ATTRIBUTE_H_
|
||||||
#define SRC_AST_DECORATION_H_
|
#define SRC_AST_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -23,43 +23,43 @@
|
|||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// The base class for all decorations
|
/// The base class for all attributes
|
||||||
class Decoration : public Castable<Decoration, Node> {
|
class Attribute : public Castable<Attribute, Node> {
|
||||||
public:
|
public:
|
||||||
~Decoration() override;
|
~Attribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
virtual std::string Name() const = 0;
|
virtual std::string Name() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
Decoration(ProgramID pid, const Source& src) : Base(pid, src) {}
|
Attribute(ProgramID pid, const Source& src) : Base(pid, src) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A list of decorations
|
/// A list of attributes
|
||||||
using DecorationList = std::vector<const Decoration*>;
|
using AttributeList = std::vector<const Attribute*>;
|
||||||
|
|
||||||
/// @param decorations the list of decorations to search
|
/// @param attributes the list of attributes to search
|
||||||
/// @returns true if `decorations` includes a decoration of type `T`
|
/// @returns true if `attributes` includes a attribute of type `T`
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool HasDecoration(const DecorationList& decorations) {
|
bool HasAttribute(const AttributeList& attributes) {
|
||||||
for (auto* deco : decorations) {
|
for (auto* attr : attributes) {
|
||||||
if (deco->Is<T>()) {
|
if (attr->Is<T>()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param decorations the list of decorations to search
|
/// @param attributes the list of attributes to search
|
||||||
/// @returns a pointer to `T` from `decorations` if found, otherwise nullptr.
|
/// @returns a pointer to `T` from `attributes` if found, otherwise nullptr.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const T* GetDecoration(const DecorationList& decorations) {
|
const T* GetAttribute(const AttributeList& attributes) {
|
||||||
for (auto* deco : decorations) {
|
for (auto* attr : attributes) {
|
||||||
if (deco->Is<T>()) {
|
if (attr->Is<T>()) {
|
||||||
return deco->As<T>();
|
return attr->As<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -68,4 +68,4 @@ const T* GetDecoration(const DecorationList& decorations) {
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_DECORATION_H_
|
#endif // SRC_AST_ATTRIBUTE_H_
|
@ -12,32 +12,32 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/binding_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::LocationDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::BindingAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
LocationDecoration::LocationDecoration(ProgramID pid,
|
BindingAttribute::BindingAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
uint32_t val)
|
uint32_t val)
|
||||||
: Base(pid, src), value(val) {}
|
: Base(pid, src), value(val) {}
|
||||||
|
|
||||||
LocationDecoration::~LocationDecoration() = default;
|
BindingAttribute::~BindingAttribute() = default;
|
||||||
|
|
||||||
std::string LocationDecoration::Name() const {
|
std::string BindingAttribute::Name() const {
|
||||||
return "location";
|
return "binding";
|
||||||
}
|
}
|
||||||
|
|
||||||
const LocationDecoration* LocationDecoration::Clone(CloneContext* ctx) const {
|
const BindingAttribute* BindingAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<LocationDecoration>(src, value);
|
return ctx->dst->create<BindingAttribute>(src, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,34 +12,34 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_BINDING_DECORATION_H_
|
#ifndef SRC_AST_BINDING_ATTRIBUTE_H_
|
||||||
#define SRC_AST_BINDING_DECORATION_H_
|
#define SRC_AST_BINDING_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A binding decoration
|
/// A binding attribute
|
||||||
class BindingDecoration : public Castable<BindingDecoration, Decoration> {
|
class BindingAttribute : public Castable<BindingAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// Constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param value the binding value
|
/// @param value the binding value
|
||||||
BindingDecoration(ProgramID pid, const Source& src, uint32_t value);
|
BindingAttribute(ProgramID pid, const Source& src, uint32_t value);
|
||||||
~BindingDecoration() override;
|
~BindingAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const BindingDecoration* Clone(CloneContext* ctx) const override;
|
const BindingAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// the binding value
|
/// the binding value
|
||||||
const uint32_t value;
|
const uint32_t value;
|
||||||
@ -48,4 +48,4 @@ class BindingDecoration : public Castable<BindingDecoration, Decoration> {
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_BINDING_DECORATION_H_
|
#endif // SRC_AST_BINDING_ATTRIBUTE_H_
|
@ -12,17 +12,16 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/override_decoration.h"
|
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using GroupDecorationTest = TestHelper;
|
using BindingAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(GroupDecorationTest, Creation) {
|
TEST_F(BindingAttributeTest, Creation) {
|
||||||
auto* d = create<GroupDecoration>(2);
|
auto* d = create<BindingAttribute>(2);
|
||||||
EXPECT_EQ(2u, d->value);
|
EXPECT_EQ(2u, d->value);
|
||||||
}
|
}
|
||||||
|
|
@ -12,32 +12,30 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
BuiltinDecoration::BuiltinDecoration(ProgramID pid,
|
BuiltinAttribute::BuiltinAttribute(ProgramID pid, const Source& src, Builtin b)
|
||||||
const Source& src,
|
|
||||||
Builtin b)
|
|
||||||
: Base(pid, src), builtin(b) {}
|
: Base(pid, src), builtin(b) {}
|
||||||
|
|
||||||
BuiltinDecoration::~BuiltinDecoration() = default;
|
BuiltinAttribute::~BuiltinAttribute() = default;
|
||||||
|
|
||||||
std::string BuiltinDecoration::Name() const {
|
std::string BuiltinAttribute::Name() const {
|
||||||
return "builtin";
|
return "builtin";
|
||||||
}
|
}
|
||||||
|
|
||||||
const BuiltinDecoration* BuiltinDecoration::Clone(CloneContext* ctx) const {
|
const BuiltinAttribute* BuiltinAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<BuiltinDecoration>(src, builtin);
|
return ctx->dst->create<BuiltinAttribute>(src, builtin);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,35 +12,35 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_BUILTIN_DECORATION_H_
|
#ifndef SRC_AST_BUILTIN_ATTRIBUTE_H_
|
||||||
#define SRC_AST_BUILTIN_DECORATION_H_
|
#define SRC_AST_BUILTIN_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "src/ast/attribute.h"
|
||||||
#include "src/ast/builtin.h"
|
#include "src/ast/builtin.h"
|
||||||
#include "src/ast/decoration.h"
|
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A builtin decoration
|
/// A builtin attribute
|
||||||
class BuiltinDecoration : public Castable<BuiltinDecoration, Decoration> {
|
class BuiltinAttribute : public Castable<BuiltinAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param builtin the builtin value
|
/// @param builtin the builtin value
|
||||||
BuiltinDecoration(ProgramID pid, const Source& src, Builtin builtin);
|
BuiltinAttribute(ProgramID pid, const Source& src, Builtin builtin);
|
||||||
~BuiltinDecoration() override;
|
~BuiltinAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const BuiltinDecoration* Clone(CloneContext* ctx) const override;
|
const BuiltinAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The builtin value
|
/// The builtin value
|
||||||
const Builtin builtin;
|
const Builtin builtin;
|
||||||
@ -49,4 +49,4 @@ class BuiltinDecoration : public Castable<BuiltinDecoration, Decoration> {
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_BUILTIN_DECORATION_H_
|
#endif // SRC_AST_BUILTIN_ATTRIBUTE_H_
|
@ -12,17 +12,16 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/override_decoration.h"
|
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using BuiltinDecorationTest = TestHelper;
|
using BuiltinAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(BuiltinDecorationTest, Creation) {
|
TEST_F(BuiltinAttributeTest, Creation) {
|
||||||
auto* d = create<BuiltinDecoration>(Builtin::kFragDepth);
|
auto* d = create<BuiltinAttribute>(Builtin::kFragDepth);
|
||||||
EXPECT_EQ(Builtin::kFragDepth, d->builtin);
|
EXPECT_EQ(Builtin::kFragDepth, d->builtin);
|
||||||
}
|
}
|
||||||
|
|
@ -12,22 +12,22 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/disable_validation_decoration.h"
|
#include "src/ast/disable_validation_attribute.h"
|
||||||
#include "src/clone_context.h"
|
#include "src/clone_context.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::DisableValidationDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::DisableValidationAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
DisableValidationDecoration::DisableValidationDecoration(ProgramID pid,
|
DisableValidationAttribute::DisableValidationAttribute(ProgramID pid,
|
||||||
DisabledValidation val)
|
DisabledValidation val)
|
||||||
: Base(pid), validation(val) {}
|
: Base(pid), validation(val) {}
|
||||||
|
|
||||||
DisableValidationDecoration::~DisableValidationDecoration() = default;
|
DisableValidationAttribute::~DisableValidationAttribute() = default;
|
||||||
|
|
||||||
std::string DisableValidationDecoration::InternalName() const {
|
std::string DisableValidationAttribute::InternalName() const {
|
||||||
switch (validation) {
|
switch (validation) {
|
||||||
case DisabledValidation::kFunctionHasNoBody:
|
case DisabledValidation::kFunctionHasNoBody:
|
||||||
return "disable_validation__function_has_no_body";
|
return "disable_validation__function_has_no_body";
|
||||||
@ -39,7 +39,7 @@ std::string DisableValidationDecoration::InternalName() const {
|
|||||||
return "disable_validation__entry_point_parameter";
|
return "disable_validation__entry_point_parameter";
|
||||||
case DisabledValidation::kIgnoreConstructibleFunctionParameter:
|
case DisabledValidation::kIgnoreConstructibleFunctionParameter:
|
||||||
return "disable_validation__ignore_constructible_function_parameter";
|
return "disable_validation__ignore_constructible_function_parameter";
|
||||||
case DisabledValidation::kIgnoreStrideDecoration:
|
case DisabledValidation::kIgnoreStrideAttribute:
|
||||||
return "disable_validation__ignore_stride";
|
return "disable_validation__ignore_stride";
|
||||||
case DisabledValidation::kIgnoreInvalidPointerArgument:
|
case DisabledValidation::kIgnoreInvalidPointerArgument:
|
||||||
return "disable_validation__ignore_invalid_pointer_argument";
|
return "disable_validation__ignore_invalid_pointer_argument";
|
||||||
@ -47,10 +47,10 @@ std::string DisableValidationDecoration::InternalName() const {
|
|||||||
return "<invalid>";
|
return "<invalid>";
|
||||||
}
|
}
|
||||||
|
|
||||||
const DisableValidationDecoration* DisableValidationDecoration::Clone(
|
const DisableValidationAttribute* DisableValidationAttribute::Clone(
|
||||||
CloneContext* ctx) const {
|
CloneContext* ctx) const {
|
||||||
return ctx->dst->ASTNodes().Create<DisableValidationDecoration>(
|
return ctx->dst->ASTNodes().Create<DisableValidationAttribute>(ctx->dst->ID(),
|
||||||
ctx->dst->ID(), validation);
|
validation);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,18 +12,18 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_DISABLE_VALIDATION_DECORATION_H_
|
#ifndef SRC_AST_DISABLE_VALIDATION_ATTRIBUTE_H_
|
||||||
#define SRC_AST_DISABLE_VALIDATION_DECORATION_H_
|
#define SRC_AST_DISABLE_VALIDATION_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/internal_decoration.h"
|
#include "src/ast/internal_attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// Enumerator of validation features that can be disabled with a
|
/// Enumerator of validation features that can be disabled with a
|
||||||
/// DisableValidationDecoration decoration.
|
/// DisableValidationAttribute attribute.
|
||||||
enum class DisabledValidation {
|
enum class DisabledValidation {
|
||||||
/// When applied to a function, the validator will not complain there is no
|
/// When applied to a function, the validator will not complain there is no
|
||||||
/// body to a function.
|
/// body to a function.
|
||||||
@ -35,49 +35,49 @@ enum class DisabledValidation {
|
|||||||
/// declared storage class.
|
/// declared storage class.
|
||||||
kIgnoreStorageClass,
|
kIgnoreStorageClass,
|
||||||
/// When applied to an entry-point function parameter, the validator will not
|
/// When applied to an entry-point function parameter, the validator will not
|
||||||
/// check for entry IO decorations.
|
/// check for entry IO attributes.
|
||||||
kEntryPointParameter,
|
kEntryPointParameter,
|
||||||
/// When applied to a function parameter, the validator will not
|
/// When applied to a function parameter, the validator will not
|
||||||
/// check if parameter type is constructible
|
/// check if parameter type is constructible
|
||||||
kIgnoreConstructibleFunctionParameter,
|
kIgnoreConstructibleFunctionParameter,
|
||||||
/// When applied to a member decoration, a stride decoration may be applied to
|
/// When applied to a member attribute, a stride attribute may be applied to
|
||||||
/// non-array types.
|
/// non-array types.
|
||||||
kIgnoreStrideDecoration,
|
kIgnoreStrideAttribute,
|
||||||
/// When applied to a pointer function parameter, the validator will not
|
/// When applied to a pointer function parameter, the validator will not
|
||||||
/// require a function call argument passed for that parameter to have a
|
/// require a function call argument passed for that parameter to have a
|
||||||
/// certain form.
|
/// certain form.
|
||||||
kIgnoreInvalidPointerArgument,
|
kIgnoreInvalidPointerArgument,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An internal decoration used to tell the validator to ignore specific
|
/// An internal attribute used to tell the validator to ignore specific
|
||||||
/// violations. Typically generated by transforms that need to produce ASTs that
|
/// violations. Typically generated by transforms that need to produce ASTs that
|
||||||
/// would otherwise cause validation errors.
|
/// would otherwise cause validation errors.
|
||||||
class DisableValidationDecoration
|
class DisableValidationAttribute
|
||||||
: public Castable<DisableValidationDecoration, InternalDecoration> {
|
: public Castable<DisableValidationAttribute, InternalAttribute> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param program_id the identifier of the program that owns this node
|
/// @param program_id the identifier of the program that owns this node
|
||||||
/// @param validation the validation to disable
|
/// @param validation the validation to disable
|
||||||
explicit DisableValidationDecoration(ProgramID program_id,
|
explicit DisableValidationAttribute(ProgramID program_id,
|
||||||
DisabledValidation validation);
|
DisabledValidation validation);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~DisableValidationDecoration() override;
|
~DisableValidationAttribute() override;
|
||||||
|
|
||||||
/// @return a short description of the internal decoration which will be
|
/// @return a short description of the internal attribute which will be
|
||||||
/// displayed in WGSL as `@internal(<name>)` (but is not parsable).
|
/// displayed in WGSL as `@internal(<name>)` (but is not parsable).
|
||||||
std::string InternalName() const override;
|
std::string InternalName() const override;
|
||||||
|
|
||||||
/// Performs a deep clone of this object using the CloneContext `ctx`.
|
/// Performs a deep clone of this object using the CloneContext `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned object
|
/// @return the newly cloned object
|
||||||
const DisableValidationDecoration* Clone(CloneContext* ctx) const override;
|
const DisableValidationAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The validation that this decoration disables
|
/// The validation that this attribute disables
|
||||||
const DisabledValidation validation;
|
const DisabledValidation validation;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_DISABLE_VALIDATION_DECORATION_H_
|
#endif // SRC_AST_DISABLE_VALIDATION_ATTRIBUTE_H_
|
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
|
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::Function);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::Function);
|
||||||
@ -29,15 +29,15 @@ Function::Function(ProgramID pid,
|
|||||||
VariableList parameters,
|
VariableList parameters,
|
||||||
const Type* return_ty,
|
const Type* return_ty,
|
||||||
const BlockStatement* b,
|
const BlockStatement* b,
|
||||||
DecorationList decos,
|
AttributeList attrs,
|
||||||
DecorationList return_type_decos)
|
AttributeList return_type_attrs)
|
||||||
: Base(pid, src),
|
: Base(pid, src),
|
||||||
symbol(sym),
|
symbol(sym),
|
||||||
params(std::move(parameters)),
|
params(std::move(parameters)),
|
||||||
return_type(return_ty),
|
return_type(return_ty),
|
||||||
body(b),
|
body(b),
|
||||||
decorations(std::move(decos)),
|
attributes(std::move(attrs)),
|
||||||
return_type_decorations(std::move(return_type_decos)) {
|
return_type_attributes(std::move(return_type_attrs)) {
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
|
||||||
for (auto* param : params) {
|
for (auto* param : params) {
|
||||||
@ -46,11 +46,11 @@ Function::Function(ProgramID pid,
|
|||||||
}
|
}
|
||||||
TINT_ASSERT(AST, symbol.IsValid());
|
TINT_ASSERT(AST, symbol.IsValid());
|
||||||
TINT_ASSERT(AST, return_type);
|
TINT_ASSERT(AST, return_type);
|
||||||
for (auto* deco : decorations) {
|
for (auto* attr : attributes) {
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
|
||||||
}
|
}
|
||||||
for (auto* deco : return_type_decorations) {
|
for (auto* attr : return_type_attributes) {
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ Function::Function(Function&&) = default;
|
|||||||
Function::~Function() = default;
|
Function::~Function() = default;
|
||||||
|
|
||||||
PipelineStage Function::PipelineStage() const {
|
PipelineStage Function::PipelineStage() const {
|
||||||
if (auto* stage = GetDecoration<StageDecoration>(decorations)) {
|
if (auto* stage = GetAttribute<StageAttribute>(attributes)) {
|
||||||
return stage->stage;
|
return stage->stage;
|
||||||
}
|
}
|
||||||
return PipelineStage::kNone;
|
return PipelineStage::kNone;
|
||||||
@ -72,9 +72,9 @@ const Function* Function::Clone(CloneContext* ctx) const {
|
|||||||
auto p = ctx->Clone(params);
|
auto p = ctx->Clone(params);
|
||||||
auto* ret = ctx->Clone(return_type);
|
auto* ret = ctx->Clone(return_type);
|
||||||
auto* b = ctx->Clone(body);
|
auto* b = ctx->Clone(body);
|
||||||
auto decos = ctx->Clone(decorations);
|
auto attrs = ctx->Clone(attributes);
|
||||||
auto ret_decos = ctx->Clone(return_type_decorations);
|
auto ret_attrs = ctx->Clone(return_type_attributes);
|
||||||
return ctx->dst->create<Function>(src, sym, p, ret, b, decos, ret_decos);
|
return ctx->dst->create<Function>(src, sym, p, ret, b, attrs, ret_attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Function* FunctionList::Find(Symbol sym) const {
|
const Function* FunctionList::Find(Symbol sym) const {
|
||||||
|
@ -20,12 +20,12 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/binding_decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
#include "src/ast/binding_attribute.h"
|
||||||
#include "src/ast/block_statement.h"
|
#include "src/ast/block_statement.h"
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_attribute.h"
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/group_attribute.h"
|
||||||
#include "src/ast/group_decoration.h"
|
#include "src/ast/location_attribute.h"
|
||||||
#include "src/ast/location_decoration.h"
|
|
||||||
#include "src/ast/pipeline_stage.h"
|
#include "src/ast/pipeline_stage.h"
|
||||||
#include "src/ast/variable.h"
|
#include "src/ast/variable.h"
|
||||||
|
|
||||||
@ -42,16 +42,16 @@ class Function : public Castable<Function, Node> {
|
|||||||
/// @param params the function parameters
|
/// @param params the function parameters
|
||||||
/// @param return_type the return type
|
/// @param return_type the return type
|
||||||
/// @param body the function body
|
/// @param body the function body
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
/// @param return_type_decorations the return type decorations
|
/// @param return_type_attributes the return type attributes
|
||||||
Function(ProgramID program_id,
|
Function(ProgramID program_id,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
Symbol symbol,
|
Symbol symbol,
|
||||||
VariableList params,
|
VariableList params,
|
||||||
const Type* return_type,
|
const Type* return_type,
|
||||||
const BlockStatement* body,
|
const BlockStatement* body,
|
||||||
DecorationList decorations,
|
AttributeList attributes,
|
||||||
DecorationList return_type_decorations);
|
AttributeList return_type_attributes);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
Function(Function&&);
|
Function(Function&&);
|
||||||
|
|
||||||
@ -81,11 +81,11 @@ class Function : public Castable<Function, Node> {
|
|||||||
/// The function body
|
/// The function body
|
||||||
const BlockStatement* const body;
|
const BlockStatement* const body;
|
||||||
|
|
||||||
/// The decorations attached to this function
|
/// The attributes attached to this function
|
||||||
const DecorationList decorations;
|
const AttributeList attributes;
|
||||||
|
|
||||||
/// The decorations attached to the function return type.
|
/// The attributes attached to the function return type.
|
||||||
const DecorationList return_type_decorations;
|
const AttributeList return_type_attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A list of functions
|
/// A list of functions
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
#include "gtest/gtest-spi.h"
|
#include "gtest/gtest-spi.h"
|
||||||
#include "src/ast/discard_statement.h"
|
#include "src/ast/discard_statement.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
@ -29,7 +29,7 @@ TEST_F(FunctionTest, Creation) {
|
|||||||
params.push_back(Param("var", ty.i32()));
|
params.push_back(Param("var", ty.i32()));
|
||||||
auto* var = params[0];
|
auto* var = params[0];
|
||||||
|
|
||||||
auto* f = Func("func", params, ty.void_(), StatementList{}, DecorationList{});
|
auto* f = Func("func", params, ty.void_(), StatementList{}, AttributeList{});
|
||||||
EXPECT_EQ(f->symbol, Symbols().Get("func"));
|
EXPECT_EQ(f->symbol, Symbols().Get("func"));
|
||||||
ASSERT_EQ(f->params.size(), 1u);
|
ASSERT_EQ(f->params.size(), 1u);
|
||||||
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||||
@ -41,7 +41,7 @@ TEST_F(FunctionTest, Creation_WithSource) {
|
|||||||
params.push_back(Param("var", ty.i32()));
|
params.push_back(Param("var", ty.i32()));
|
||||||
|
|
||||||
auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(),
|
auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(),
|
||||||
StatementList{}, DecorationList{});
|
StatementList{}, AttributeList{});
|
||||||
auto src = f->source;
|
auto src = f->source;
|
||||||
EXPECT_EQ(src.range.begin.line, 20u);
|
EXPECT_EQ(src.range.begin.line, 20u);
|
||||||
EXPECT_EQ(src.range.begin.column, 2u);
|
EXPECT_EQ(src.range.begin.column, 2u);
|
||||||
@ -52,7 +52,7 @@ TEST_F(FunctionTest, Assert_InvalidName) {
|
|||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.Func("", VariableList{}, b.ty.void_(), StatementList{},
|
b.Func("", VariableList{}, b.ty.void_(), StatementList{},
|
||||||
DecorationList{});
|
AttributeList{});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ TEST_F(FunctionTest, Assert_Null_ReturnType) {
|
|||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.Func("f", VariableList{}, nullptr, StatementList{}, DecorationList{});
|
b.Func("f", VariableList{}, nullptr, StatementList{}, AttributeList{});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ TEST_F(FunctionTest, Assert_Null_Param) {
|
|||||||
params.push_back(b.Param("var", b.ty.i32()));
|
params.push_back(b.Param("var", b.ty.i32()));
|
||||||
params.push_back(nullptr);
|
params.push_back(nullptr);
|
||||||
|
|
||||||
b.Func("f", params, b.ty.void_(), StatementList{}, DecorationList{});
|
b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
@ -100,27 +100,27 @@ TEST_F(FunctionTest, Assert_DifferentProgramID_Param) {
|
|||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(FunctionTest, Assert_DifferentProgramID_Deco) {
|
TEST_F(FunctionTest, Assert_DifferentProgramID_Attr) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
|
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
|
||||||
DecorationList{
|
AttributeList{
|
||||||
b2.WorkgroupSize(2, 4, 6),
|
b2.WorkgroupSize(2, 4, 6),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnDeco) {
|
TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnAttr) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
|
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
|
||||||
DecorationList{},
|
AttributeList{},
|
||||||
DecorationList{
|
AttributeList{
|
||||||
b2.WorkgroupSize(2, 4, 6),
|
b2.WorkgroupSize(2, 4, 6),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -134,7 +134,7 @@ TEST_F(FunctionTest, Assert_NonConstParam) {
|
|||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(b.Var("var", b.ty.i32(), ast::StorageClass::kNone));
|
params.push_back(b.Var("var", b.ty.i32(), ast::StorageClass::kNone));
|
||||||
|
|
||||||
b.Func("f", params, b.ty.void_(), StatementList{}, DecorationList{});
|
b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ using FunctionListTest = TestHelper;
|
|||||||
|
|
||||||
TEST_F(FunctionListTest, FindSymbol) {
|
TEST_F(FunctionListTest, FindSymbol) {
|
||||||
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
|
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||||
ast::DecorationList{});
|
ast::AttributeList{});
|
||||||
FunctionList list;
|
FunctionList list;
|
||||||
list.Add(func);
|
list.Add(func);
|
||||||
EXPECT_EQ(func, list.Find(Symbols().Register("main")));
|
EXPECT_EQ(func, list.Find(Symbols().Register("main")));
|
||||||
@ -156,11 +156,11 @@ TEST_F(FunctionListTest, FindSymbolMissing) {
|
|||||||
|
|
||||||
TEST_F(FunctionListTest, FindSymbolStage) {
|
TEST_F(FunctionListTest, FindSymbolStage) {
|
||||||
auto* fs = Func("main", VariableList{}, ty.f32(), StatementList{},
|
auto* fs = Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(PipelineStage::kFragment),
|
Stage(PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
auto* vs = Func("main", VariableList{}, ty.f32(), StatementList{},
|
auto* vs = Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(PipelineStage::kVertex),
|
Stage(PipelineStage::kVertex),
|
||||||
});
|
});
|
||||||
FunctionList list;
|
FunctionList list;
|
||||||
@ -174,7 +174,7 @@ TEST_F(FunctionListTest, FindSymbolStage) {
|
|||||||
TEST_F(FunctionListTest, FindSymbolStageMissing) {
|
TEST_F(FunctionListTest, FindSymbolStageMissing) {
|
||||||
FunctionList list;
|
FunctionList list;
|
||||||
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
|
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(PipelineStage::kFragment),
|
Stage(PipelineStage::kFragment),
|
||||||
}));
|
}));
|
||||||
EXPECT_EQ(nullptr,
|
EXPECT_EQ(nullptr,
|
||||||
@ -184,7 +184,7 @@ TEST_F(FunctionListTest, FindSymbolStageMissing) {
|
|||||||
TEST_F(FunctionListTest, HasStage) {
|
TEST_F(FunctionListTest, HasStage) {
|
||||||
FunctionList list;
|
FunctionList list;
|
||||||
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
|
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(PipelineStage::kFragment),
|
Stage(PipelineStage::kFragment),
|
||||||
}));
|
}));
|
||||||
EXPECT_TRUE(list.HasStage(PipelineStage::kFragment));
|
EXPECT_TRUE(list.HasStage(PipelineStage::kFragment));
|
||||||
|
@ -12,30 +12,30 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/group_decoration.h"
|
#include "src/ast/group_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::GroupDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::GroupAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
GroupDecoration::GroupDecoration(ProgramID pid, const Source& src, uint32_t val)
|
GroupAttribute::GroupAttribute(ProgramID pid, const Source& src, uint32_t val)
|
||||||
: Base(pid, src), value(val) {}
|
: Base(pid, src), value(val) {}
|
||||||
|
|
||||||
GroupDecoration::~GroupDecoration() = default;
|
GroupAttribute::~GroupAttribute() = default;
|
||||||
|
|
||||||
std::string GroupDecoration::Name() const {
|
std::string GroupAttribute::Name() const {
|
||||||
return "group";
|
return "group";
|
||||||
}
|
}
|
||||||
|
|
||||||
const GroupDecoration* GroupDecoration::Clone(CloneContext* ctx) const {
|
const GroupAttribute* GroupAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<GroupDecoration>(src, value);
|
return ctx->dst->create<GroupAttribute>(src, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,34 +12,34 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_GROUP_DECORATION_H_
|
#ifndef SRC_AST_GROUP_ATTRIBUTE_H_
|
||||||
#define SRC_AST_GROUP_DECORATION_H_
|
#define SRC_AST_GROUP_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A group decoration
|
/// A group attribute
|
||||||
class GroupDecoration : public Castable<GroupDecoration, Decoration> {
|
class GroupAttribute : public Castable<GroupAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param value the group value
|
/// @param value the group value
|
||||||
GroupDecoration(ProgramID pid, const Source& src, uint32_t value);
|
GroupAttribute(ProgramID pid, const Source& src, uint32_t value);
|
||||||
~GroupDecoration() override;
|
~GroupAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const GroupDecoration* Clone(CloneContext* ctx) const override;
|
const GroupAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The group value
|
/// The group value
|
||||||
const uint32_t value;
|
const uint32_t value;
|
||||||
@ -48,4 +48,4 @@ class GroupDecoration : public Castable<GroupDecoration, Decoration> {
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_GROUP_DECORATION_H_
|
#endif // SRC_AST_GROUP_ATTRIBUTE_H_
|
@ -12,17 +12,17 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using BindingDecorationTest = TestHelper;
|
using GroupAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(BindingDecorationTest, Creation) {
|
TEST_F(GroupAttributeTest, Creation) {
|
||||||
auto* d = create<BindingDecoration>(2);
|
auto* d = create<GroupAttribute>(2);
|
||||||
EXPECT_EQ(2u, d->value);
|
EXPECT_EQ(2u, d->value);
|
||||||
}
|
}
|
||||||
|
|
@ -12,18 +12,18 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/internal_decoration.h"
|
#include "src/ast/internal_attribute.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::InternalDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::InternalAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
InternalDecoration::InternalDecoration(ProgramID pid) : Base(pid, Source{}) {}
|
InternalAttribute::InternalAttribute(ProgramID pid) : Base(pid, Source{}) {}
|
||||||
|
|
||||||
InternalDecoration::~InternalDecoration() = default;
|
InternalAttribute::~InternalAttribute() = default;
|
||||||
|
|
||||||
std::string InternalDecoration::Name() const {
|
std::string InternalAttribute::Name() const {
|
||||||
return "internal";
|
return "internal";
|
||||||
}
|
}
|
||||||
|
|
@ -12,37 +12,37 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_INTERNAL_DECORATION_H_
|
#ifndef SRC_AST_INTERNAL_ATTRIBUTE_H_
|
||||||
#define SRC_AST_INTERNAL_DECORATION_H_
|
#define SRC_AST_INTERNAL_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A decoration used to indicate that a function is tint-internal.
|
/// An attribute used to indicate that a function is tint-internal.
|
||||||
/// These decorations are not produced by generators, but instead are usually
|
/// These attributes are not produced by generators, but instead are usually
|
||||||
/// created by transforms for consumption by a particular backend.
|
/// created by transforms for consumption by a particular backend.
|
||||||
class InternalDecoration : public Castable<InternalDecoration, Decoration> {
|
class InternalAttribute : public Castable<InternalAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param program_id the identifier of the program that owns this node
|
/// @param program_id the identifier of the program that owns this node
|
||||||
explicit InternalDecoration(ProgramID program_id);
|
explicit InternalAttribute(ProgramID program_id);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~InternalDecoration() override;
|
~InternalAttribute() override;
|
||||||
|
|
||||||
/// @return a short description of the internal decoration which will be
|
/// @return a short description of the internal attribute which will be
|
||||||
/// displayed in WGSL as `@internal(<name>)` (but is not parsable).
|
/// displayed in WGSL as `@internal(<name>)` (but is not parsable).
|
||||||
virtual std::string InternalName() const = 0;
|
virtual std::string InternalName() const = 0;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_INTERNAL_DECORATION_H_
|
#endif // SRC_AST_INTERNAL_ATTRIBUTE_H_
|
@ -12,34 +12,34 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/interpolate_decoration.h"
|
#include "src/ast/interpolate_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::InterpolateDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::InterpolateAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
InterpolateDecoration::InterpolateDecoration(ProgramID pid,
|
InterpolateAttribute::InterpolateAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
InterpolationType ty,
|
InterpolationType ty,
|
||||||
InterpolationSampling smpl)
|
InterpolationSampling smpl)
|
||||||
: Base(pid, src), type(ty), sampling(smpl) {}
|
: Base(pid, src), type(ty), sampling(smpl) {}
|
||||||
|
|
||||||
InterpolateDecoration::~InterpolateDecoration() = default;
|
InterpolateAttribute::~InterpolateAttribute() = default;
|
||||||
|
|
||||||
std::string InterpolateDecoration::Name() const {
|
std::string InterpolateAttribute::Name() const {
|
||||||
return "interpolate";
|
return "interpolate";
|
||||||
}
|
}
|
||||||
|
|
||||||
const InterpolateDecoration* InterpolateDecoration::Clone(
|
const InterpolateAttribute* InterpolateAttribute::Clone(
|
||||||
CloneContext* ctx) const {
|
CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<InterpolateDecoration>(src, type, sampling);
|
return ctx->dst->create<InterpolateAttribute>(src, type, sampling);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, InterpolationType type) {
|
std::ostream& operator<<(std::ostream& out, InterpolationType type) {
|
@ -12,13 +12,13 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_INTERPOLATE_DECORATION_H_
|
#ifndef SRC_AST_INTERPOLATE_ATTRIBUTE_H_
|
||||||
#define SRC_AST_INTERPOLATE_DECORATION_H_
|
#define SRC_AST_INTERPOLATE_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
@ -29,29 +29,28 @@ enum class InterpolationType { kPerspective, kLinear, kFlat };
|
|||||||
/// The interpolation sampling.
|
/// The interpolation sampling.
|
||||||
enum class InterpolationSampling { kNone = -1, kCenter, kCentroid, kSample };
|
enum class InterpolationSampling { kNone = -1, kCenter, kCentroid, kSample };
|
||||||
|
|
||||||
/// An interpolate decoration
|
/// An interpolate attribute
|
||||||
class InterpolateDecoration
|
class InterpolateAttribute : public Castable<InterpolateAttribute, Attribute> {
|
||||||
: public Castable<InterpolateDecoration, Decoration> {
|
|
||||||
public:
|
public:
|
||||||
/// Create an interpolate decoration.
|
/// Create an interpolate attribute.
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param type the interpolation type
|
/// @param type the interpolation type
|
||||||
/// @param sampling the interpolation sampling
|
/// @param sampling the interpolation sampling
|
||||||
InterpolateDecoration(ProgramID pid,
|
InterpolateAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
InterpolationType type,
|
InterpolationType type,
|
||||||
InterpolationSampling sampling);
|
InterpolationSampling sampling);
|
||||||
~InterpolateDecoration() override;
|
~InterpolateAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const InterpolateDecoration* Clone(CloneContext* ctx) const override;
|
const InterpolateAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The interpolation type
|
/// The interpolation type
|
||||||
const InterpolationType type;
|
const InterpolationType type;
|
||||||
@ -73,4 +72,4 @@ std::ostream& operator<<(std::ostream& out, InterpolationSampling sampling);
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_INTERPOLATE_DECORATION_H_
|
#endif // SRC_AST_INTERPOLATE_ATTRIBUTE_H_
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/interpolate_decoration.h"
|
#include "src/ast/interpolate_attribute.h"
|
||||||
|
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
@ -20,11 +20,11 @@ namespace tint {
|
|||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using InterpolateDecorationTest = TestHelper;
|
using InterpolateAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(InterpolateDecorationTest, Creation) {
|
TEST_F(InterpolateAttributeTest, Creation) {
|
||||||
auto* d = create<InterpolateDecoration>(InterpolationType::kLinear,
|
auto* d = create<InterpolateAttribute>(InterpolationType::kLinear,
|
||||||
InterpolationSampling::kCenter);
|
InterpolationSampling::kCenter);
|
||||||
EXPECT_EQ(InterpolationType::kLinear, d->type);
|
EXPECT_EQ(InterpolationType::kLinear, d->type);
|
||||||
EXPECT_EQ(InterpolationSampling::kCenter, d->sampling);
|
EXPECT_EQ(InterpolationSampling::kCenter, d->sampling);
|
||||||
}
|
}
|
@ -151,36 +151,36 @@ const ast::Type* TextureOverloadCase::BuildResultVectorComponentType(
|
|||||||
|
|
||||||
const ast::Variable* TextureOverloadCase::BuildTextureVariable(
|
const ast::Variable* TextureOverloadCase::BuildTextureVariable(
|
||||||
ProgramBuilder* b) const {
|
ProgramBuilder* b) const {
|
||||||
DecorationList decos = {
|
AttributeList attrs = {
|
||||||
b->create<ast::GroupDecoration>(0),
|
b->create<ast::GroupAttribute>(0),
|
||||||
b->create<ast::BindingDecoration>(0),
|
b->create<ast::BindingAttribute>(0),
|
||||||
};
|
};
|
||||||
switch (texture_kind) {
|
switch (texture_kind) {
|
||||||
case ast::intrinsic::test::TextureKind::kRegular:
|
case ast::intrinsic::test::TextureKind::kRegular:
|
||||||
return b->Global("texture",
|
return b->Global("texture",
|
||||||
b->ty.sampled_texture(texture_dimension,
|
b->ty.sampled_texture(texture_dimension,
|
||||||
BuildResultVectorComponentType(b)),
|
BuildResultVectorComponentType(b)),
|
||||||
decos);
|
attrs);
|
||||||
|
|
||||||
case ast::intrinsic::test::TextureKind::kDepth:
|
case ast::intrinsic::test::TextureKind::kDepth:
|
||||||
return b->Global("texture", b->ty.depth_texture(texture_dimension),
|
return b->Global("texture", b->ty.depth_texture(texture_dimension),
|
||||||
decos);
|
attrs);
|
||||||
|
|
||||||
case ast::intrinsic::test::TextureKind::kDepthMultisampled:
|
case ast::intrinsic::test::TextureKind::kDepthMultisampled:
|
||||||
return b->Global("texture",
|
return b->Global("texture",
|
||||||
b->ty.depth_multisampled_texture(texture_dimension),
|
b->ty.depth_multisampled_texture(texture_dimension),
|
||||||
decos);
|
attrs);
|
||||||
|
|
||||||
case ast::intrinsic::test::TextureKind::kMultisampled:
|
case ast::intrinsic::test::TextureKind::kMultisampled:
|
||||||
return b->Global(
|
return b->Global(
|
||||||
"texture",
|
"texture",
|
||||||
b->ty.multisampled_texture(texture_dimension,
|
b->ty.multisampled_texture(texture_dimension,
|
||||||
BuildResultVectorComponentType(b)),
|
BuildResultVectorComponentType(b)),
|
||||||
decos);
|
attrs);
|
||||||
|
|
||||||
case ast::intrinsic::test::TextureKind::kStorage: {
|
case ast::intrinsic::test::TextureKind::kStorage: {
|
||||||
auto* st = b->ty.storage_texture(texture_dimension, texel_format, access);
|
auto* st = b->ty.storage_texture(texture_dimension, texel_format, access);
|
||||||
return b->Global("texture", st, decos);
|
return b->Global("texture", st, attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,11 +190,11 @@ const ast::Variable* TextureOverloadCase::BuildTextureVariable(
|
|||||||
|
|
||||||
const ast::Variable* TextureOverloadCase::BuildSamplerVariable(
|
const ast::Variable* TextureOverloadCase::BuildSamplerVariable(
|
||||||
ProgramBuilder* b) const {
|
ProgramBuilder* b) const {
|
||||||
DecorationList decos = {
|
AttributeList attrs = {
|
||||||
b->create<ast::GroupDecoration>(0),
|
b->create<ast::GroupAttribute>(0),
|
||||||
b->create<ast::BindingDecoration>(1),
|
b->create<ast::BindingAttribute>(1),
|
||||||
};
|
};
|
||||||
return b->Global("sampler", b->ty.sampler(sampler_kind), decos);
|
return b->Global("sampler", b->ty.sampler(sampler_kind), attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
|
std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
|
||||||
|
@ -12,28 +12,28 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/invariant_decoration.h"
|
#include "src/ast/invariant_attribute.h"
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::InvariantDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::InvariantAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
InvariantDecoration::InvariantDecoration(ProgramID pid, const Source& src)
|
InvariantAttribute::InvariantAttribute(ProgramID pid, const Source& src)
|
||||||
: Base(pid, src) {}
|
: Base(pid, src) {}
|
||||||
|
|
||||||
InvariantDecoration::~InvariantDecoration() = default;
|
InvariantAttribute::~InvariantAttribute() = default;
|
||||||
|
|
||||||
std::string InvariantDecoration::Name() const {
|
std::string InvariantAttribute::Name() const {
|
||||||
return "invariant";
|
return "invariant";
|
||||||
}
|
}
|
||||||
|
|
||||||
const InvariantDecoration* InvariantDecoration::Clone(CloneContext* ctx) const {
|
const InvariantAttribute* InvariantAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<InvariantDecoration>(src);
|
return ctx->dst->create<InvariantAttribute>(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,36 +12,36 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_INVARIANT_DECORATION_H_
|
#ifndef SRC_AST_INVARIANT_ATTRIBUTE_H_
|
||||||
#define SRC_AST_INVARIANT_DECORATION_H_
|
#define SRC_AST_INVARIANT_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// The invariant attribute
|
/// The invariant attribute
|
||||||
class InvariantDecoration : public Castable<InvariantDecoration, Decoration> {
|
class InvariantAttribute : public Castable<InvariantAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
InvariantDecoration(ProgramID pid, const Source& src);
|
InvariantAttribute(ProgramID pid, const Source& src);
|
||||||
~InvariantDecoration() override;
|
~InvariantAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const InvariantDecoration* Clone(CloneContext* ctx) const override;
|
const InvariantAttribute* Clone(CloneContext* ctx) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_INVARIANT_DECORATION_H_
|
#endif // SRC_AST_INVARIANT_ATTRIBUTE_H_
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/invariant_decoration.h"
|
#include "src/ast/invariant_attribute.h"
|
||||||
|
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ namespace tint {
|
|||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using InvariantDecorationTest = TestHelper;
|
using InvariantAttributeTest = TestHelper;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,32 +12,32 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/binding_decoration.h"
|
#include "src/ast/location_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::BindingDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::LocationAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
BindingDecoration::BindingDecoration(ProgramID pid,
|
LocationAttribute::LocationAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
uint32_t val)
|
uint32_t val)
|
||||||
: Base(pid, src), value(val) {}
|
: Base(pid, src), value(val) {}
|
||||||
|
|
||||||
BindingDecoration::~BindingDecoration() = default;
|
LocationAttribute::~LocationAttribute() = default;
|
||||||
|
|
||||||
std::string BindingDecoration::Name() const {
|
std::string LocationAttribute::Name() const {
|
||||||
return "binding";
|
return "location";
|
||||||
}
|
}
|
||||||
|
|
||||||
const BindingDecoration* BindingDecoration::Clone(CloneContext* ctx) const {
|
const LocationAttribute* LocationAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<BindingDecoration>(src, value);
|
return ctx->dst->create<LocationAttribute>(src, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,34 +12,34 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_LOCATION_DECORATION_H_
|
#ifndef SRC_AST_LOCATION_ATTRIBUTE_H_
|
||||||
#define SRC_AST_LOCATION_DECORATION_H_
|
#define SRC_AST_LOCATION_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A location decoration
|
/// A location attribute
|
||||||
class LocationDecoration : public Castable<LocationDecoration, Decoration> {
|
class LocationAttribute : public Castable<LocationAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param value the location value
|
/// @param value the location value
|
||||||
LocationDecoration(ProgramID pid, const Source& src, uint32_t value);
|
LocationAttribute(ProgramID pid, const Source& src, uint32_t value);
|
||||||
~LocationDecoration() override;
|
~LocationAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const LocationDecoration* Clone(CloneContext* ctx) const override;
|
const LocationAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The location value
|
/// The location value
|
||||||
const uint32_t value;
|
const uint32_t value;
|
||||||
@ -48,4 +48,4 @@ class LocationDecoration : public Castable<LocationDecoration, Decoration> {
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_LOCATION_DECORATION_H_
|
#endif // SRC_AST_LOCATION_ATTRIBUTE_H_
|
@ -12,17 +12,17 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using LocationDecorationTest = TestHelper;
|
using LocationAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(LocationDecorationTest, Creation) {
|
TEST_F(LocationAttributeTest, Creation) {
|
||||||
auto* d = create<LocationDecoration>(2);
|
auto* d = create<LocationAttribute>(2);
|
||||||
EXPECT_EQ(2u, d->value);
|
EXPECT_EQ(2u, d->value);
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ TEST_F(ModuleTest, Creation) {
|
|||||||
|
|
||||||
TEST_F(ModuleTest, LookupFunction) {
|
TEST_F(ModuleTest, LookupFunction) {
|
||||||
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
|
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
|
||||||
ast::DecorationList{});
|
ast::AttributeList{});
|
||||||
|
|
||||||
Program program(std::move(*this));
|
Program program(std::move(*this));
|
||||||
EXPECT_EQ(func,
|
EXPECT_EQ(func,
|
||||||
@ -66,7 +66,7 @@ TEST_F(ModuleTest, Assert_DifferentProgramID_Function) {
|
|||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.AST().AddFunction(b2.create<ast::Function>(
|
b1.AST().AddFunction(b2.create<ast::Function>(
|
||||||
b2.Symbols().Register("func"), VariableList{}, b2.ty.f32(),
|
b2.Symbols().Register("func"), VariableList{}, b2.ty.f32(),
|
||||||
b2.Block(), DecorationList{}, DecorationList{}));
|
b2.Block(), AttributeList{}, AttributeList{}));
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -12,38 +12,38 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::OverrideDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::OverrideAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
OverrideDecoration::OverrideDecoration(ProgramID pid, const Source& src)
|
OverrideAttribute::OverrideAttribute(ProgramID pid, const Source& src)
|
||||||
: Base(pid, src), has_value(false), value(0) {}
|
: Base(pid, src), has_value(false), value(0) {}
|
||||||
|
|
||||||
OverrideDecoration::OverrideDecoration(ProgramID pid,
|
OverrideAttribute::OverrideAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
uint32_t val)
|
uint32_t val)
|
||||||
: Base(pid, src), has_value(true), value(val) {}
|
: Base(pid, src), has_value(true), value(val) {}
|
||||||
|
|
||||||
OverrideDecoration::~OverrideDecoration() = default;
|
OverrideAttribute::~OverrideAttribute() = default;
|
||||||
|
|
||||||
std::string OverrideDecoration::Name() const {
|
std::string OverrideAttribute::Name() const {
|
||||||
return "override";
|
return "override";
|
||||||
}
|
}
|
||||||
|
|
||||||
const OverrideDecoration* OverrideDecoration::Clone(CloneContext* ctx) const {
|
const OverrideAttribute* OverrideAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
if (has_value) {
|
if (has_value) {
|
||||||
return ctx->dst->create<OverrideDecoration>(src, value);
|
return ctx->dst->create<OverrideAttribute>(src, value);
|
||||||
} else {
|
} else {
|
||||||
return ctx->dst->create<OverrideDecoration>(src);
|
return ctx->dst->create<OverrideAttribute>(src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -12,38 +12,38 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_OVERRIDE_DECORATION_H_
|
#ifndef SRC_AST_OVERRIDE_ATTRIBUTE_H_
|
||||||
#define SRC_AST_OVERRIDE_DECORATION_H_
|
#define SRC_AST_OVERRIDE_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// An override decoration
|
/// An override attribute
|
||||||
class OverrideDecoration : public Castable<OverrideDecoration, Decoration> {
|
class OverrideAttribute : public Castable<OverrideAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// Create an override decoration with no specified id.
|
/// Create an override attribute with no specified id.
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
OverrideDecoration(ProgramID pid, const Source& src);
|
OverrideAttribute(ProgramID pid, const Source& src);
|
||||||
/// Create an override decoration with a specific id value.
|
/// Create an override attribute with a specific id value.
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param val the override value
|
/// @param val the override value
|
||||||
OverrideDecoration(ProgramID pid, const Source& src, uint32_t val);
|
OverrideAttribute(ProgramID pid, const Source& src, uint32_t val);
|
||||||
~OverrideDecoration() override;
|
~OverrideAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const OverrideDecoration* Clone(CloneContext* ctx) const override;
|
const OverrideAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// True if an override id was specified
|
/// True if an override id was specified
|
||||||
const bool has_value;
|
const bool has_value;
|
||||||
@ -55,4 +55,4 @@ class OverrideDecoration : public Castable<OverrideDecoration, Decoration> {
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_OVERRIDE_DECORATION_H_
|
#endif // SRC_AST_OVERRIDE_ATTRIBUTE_H_
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
|
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
@ -20,16 +20,16 @@ namespace tint {
|
|||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using OverrideDecorationTest = TestHelper;
|
using OverrideAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(OverrideDecorationTest, Creation_WithValue) {
|
TEST_F(OverrideAttributeTest, Creation_WithValue) {
|
||||||
auto* d = create<OverrideDecoration>(12);
|
auto* d = create<OverrideAttribute>(12);
|
||||||
EXPECT_TRUE(d->has_value);
|
EXPECT_TRUE(d->has_value);
|
||||||
EXPECT_EQ(12u, d->value);
|
EXPECT_EQ(12u, d->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OverrideDecorationTest, Creation_WithoutValue) {
|
TEST_F(OverrideAttributeTest, Creation_WithoutValue) {
|
||||||
auto* d = create<OverrideDecoration>();
|
auto* d = create<OverrideAttribute>();
|
||||||
EXPECT_FALSE(d->has_value);
|
EXPECT_FALSE(d->has_value);
|
||||||
}
|
}
|
||||||
|
|
@ -12,32 +12,32 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StageDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StageAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
StageDecoration::StageDecoration(ProgramID pid,
|
StageAttribute::StageAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
PipelineStage s)
|
PipelineStage s)
|
||||||
: Base(pid, src), stage(s) {}
|
: Base(pid, src), stage(s) {}
|
||||||
|
|
||||||
StageDecoration::~StageDecoration() = default;
|
StageAttribute::~StageAttribute() = default;
|
||||||
|
|
||||||
std::string StageDecoration::Name() const {
|
std::string StageAttribute::Name() const {
|
||||||
return "stage";
|
return "stage";
|
||||||
}
|
}
|
||||||
|
|
||||||
const StageDecoration* StageDecoration::Clone(CloneContext* ctx) const {
|
const StageAttribute* StageAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<StageDecoration>(src, stage);
|
return ctx->dst->create<StageAttribute>(src, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,37 +12,37 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_STAGE_DECORATION_H_
|
#ifndef SRC_AST_STAGE_ATTRIBUTE_H_
|
||||||
#define SRC_AST_STAGE_DECORATION_H_
|
#define SRC_AST_STAGE_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
#include "src/ast/pipeline_stage.h"
|
#include "src/ast/pipeline_stage.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A workgroup decoration
|
/// A workgroup attribute
|
||||||
class StageDecoration : public Castable<StageDecoration, Decoration> {
|
class StageAttribute : public Castable<StageAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param program_id the identifier of the program that owns this node
|
/// @param program_id the identifier of the program that owns this node
|
||||||
/// @param stage the pipeline stage
|
/// @param stage the pipeline stage
|
||||||
/// @param source the source of this decoration
|
/// @param source the source of this attribute
|
||||||
StageDecoration(ProgramID program_id,
|
StageAttribute(ProgramID program_id,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
PipelineStage stage);
|
PipelineStage stage);
|
||||||
~StageDecoration() override;
|
~StageAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const StageDecoration* Clone(CloneContext* ctx) const override;
|
const StageAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The pipeline stage
|
/// The pipeline stage
|
||||||
const PipelineStage stage;
|
const PipelineStage stage;
|
||||||
@ -51,4 +51,4 @@ class StageDecoration : public Castable<StageDecoration, Decoration> {
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_STAGE_DECORATION_H_
|
#endif // SRC_AST_STAGE_ATTRIBUTE_H_
|
@ -12,19 +12,19 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
|
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using StageDecorationTest = TestHelper;
|
using StageAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(StageDecorationTest, Creation_1param) {
|
TEST_F(StageAttributeTest, Creation_1param) {
|
||||||
auto* d = create<StageDecoration>(PipelineStage::kFragment);
|
auto* d = create<StageAttribute>(PipelineStage::kFragment);
|
||||||
EXPECT_EQ(d->stage, PipelineStage::kFragment);
|
EXPECT_EQ(d->stage, PipelineStage::kFragment);
|
||||||
}
|
}
|
||||||
|
|
@ -12,30 +12,30 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/stride_decoration.h"
|
#include "src/ast/stride_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StrideDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StrideAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
StrideDecoration::StrideDecoration(ProgramID pid, const Source& src, uint32_t s)
|
StrideAttribute::StrideAttribute(ProgramID pid, const Source& src, uint32_t s)
|
||||||
: Base(pid, src), stride(s) {}
|
: Base(pid, src), stride(s) {}
|
||||||
|
|
||||||
StrideDecoration::~StrideDecoration() = default;
|
StrideAttribute::~StrideAttribute() = default;
|
||||||
|
|
||||||
std::string StrideDecoration::Name() const {
|
std::string StrideAttribute::Name() const {
|
||||||
return "stride";
|
return "stride";
|
||||||
}
|
}
|
||||||
|
|
||||||
const StrideDecoration* StrideDecoration::Clone(CloneContext* ctx) const {
|
const StrideAttribute* StrideAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<StrideDecoration>(src, stride);
|
return ctx->dst->create<StrideAttribute>(src, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,34 +12,34 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_STRIDE_DECORATION_H_
|
#ifndef SRC_AST_STRIDE_ATTRIBUTE_H_
|
||||||
#define SRC_AST_STRIDE_DECORATION_H_
|
#define SRC_AST_STRIDE_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A stride decoration
|
/// A stride attribute
|
||||||
class StrideDecoration : public Castable<StrideDecoration, Decoration> {
|
class StrideAttribute : public Castable<StrideAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param stride the stride value
|
/// @param stride the stride value
|
||||||
StrideDecoration(ProgramID pid, const Source& src, uint32_t stride);
|
StrideAttribute(ProgramID pid, const Source& src, uint32_t stride);
|
||||||
~StrideDecoration() override;
|
~StrideAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const StrideDecoration* Clone(CloneContext* ctx) const override;
|
const StrideAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The stride value
|
/// The stride value
|
||||||
const uint32_t stride;
|
const uint32_t stride;
|
||||||
@ -48,4 +48,4 @@ class StrideDecoration : public Castable<StrideDecoration, Decoration> {
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_STRIDE_DECORATION_H_
|
#endif // SRC_AST_STRIDE_ATTRIBUTE_H_
|
@ -18,15 +18,15 @@ namespace tint {
|
|||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using StrideDecorationTest = TestHelper;
|
using StrideAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(StrideDecorationTest, Creation) {
|
TEST_F(StrideAttributeTest, Creation) {
|
||||||
auto* d = create<StrideDecoration>(2);
|
auto* d = create<StrideAttribute>(2);
|
||||||
EXPECT_EQ(2u, d->stride);
|
EXPECT_EQ(2u, d->stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StrideDecorationTest, Source) {
|
TEST_F(StrideAttributeTest, Source) {
|
||||||
auto* d = create<StrideDecoration>(
|
auto* d = create<StrideAttribute>(
|
||||||
Source{Source::Range{Source::Location{1, 2}, Source::Location{3, 4}}}, 2);
|
Source{Source::Range{Source::Location{1, 2}, Source::Location{3, 4}}}, 2);
|
||||||
EXPECT_EQ(d->source.range.begin.line, 1u);
|
EXPECT_EQ(d->source.range.begin.line, 1u);
|
||||||
EXPECT_EQ(d->source.range.begin.column, 2u);
|
EXPECT_EQ(d->source.range.begin.column, 2u);
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/struct_block_decoration.h"
|
#include "src/ast/struct_block_attribute.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::Struct);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::Struct);
|
||||||
@ -28,15 +28,15 @@ Struct::Struct(ProgramID pid,
|
|||||||
const Source& src,
|
const Source& src,
|
||||||
Symbol n,
|
Symbol n,
|
||||||
StructMemberList m,
|
StructMemberList m,
|
||||||
DecorationList decos)
|
AttributeList attrs)
|
||||||
: Base(pid, src, n), members(std::move(m)), decorations(std::move(decos)) {
|
: Base(pid, src, n), members(std::move(m)), attributes(std::move(attrs)) {
|
||||||
for (auto* mem : members) {
|
for (auto* mem : members) {
|
||||||
TINT_ASSERT(AST, mem);
|
TINT_ASSERT(AST, mem);
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, mem, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, mem, program_id);
|
||||||
}
|
}
|
||||||
for (auto* deco : decorations) {
|
for (auto* attr : attributes) {
|
||||||
TINT_ASSERT(AST, deco);
|
TINT_ASSERT(AST, attr);
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +49,8 @@ const Struct* Struct::Clone(CloneContext* ctx) const {
|
|||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
auto n = ctx->Clone(name);
|
auto n = ctx->Clone(name);
|
||||||
auto mem = ctx->Clone(members);
|
auto mem = ctx->Clone(members);
|
||||||
auto decos = ctx->Clone(decorations);
|
auto attrs = ctx->Clone(attributes);
|
||||||
return ctx->dst->create<Struct>(src, n, mem, decos);
|
return ctx->dst->create<Struct>(src, n, mem, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
#include "src/ast/struct_member.h"
|
#include "src/ast/struct_member.h"
|
||||||
#include "src/ast/type_decl.h"
|
#include "src/ast/type_decl.h"
|
||||||
|
|
||||||
@ -33,12 +33,12 @@ class Struct : public Castable<Struct, TypeDecl> {
|
|||||||
/// @param src the source of this node for the import statement
|
/// @param src the source of this node for the import statement
|
||||||
/// @param name The name of the structure
|
/// @param name The name of the structure
|
||||||
/// @param members The struct members
|
/// @param members The struct members
|
||||||
/// @param decorations The struct decorations
|
/// @param attributes The struct attributes
|
||||||
Struct(ProgramID pid,
|
Struct(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
Symbol name,
|
Symbol name,
|
||||||
StructMemberList members,
|
StructMemberList members,
|
||||||
DecorationList decorations);
|
AttributeList attributes);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
Struct(Struct&&);
|
Struct(Struct&&);
|
||||||
|
|
||||||
@ -53,8 +53,8 @@ class Struct : public Castable<Struct, TypeDecl> {
|
|||||||
/// The members
|
/// The members
|
||||||
const StructMemberList members;
|
const StructMemberList members;
|
||||||
|
|
||||||
/// The struct decorations
|
/// The struct attributes
|
||||||
const DecorationList decorations;
|
const AttributeList attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
@ -12,31 +12,31 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/struct_block_decoration.h"
|
#include "src/ast/struct_block_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructBlockDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructBlockAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
StructBlockDecoration::StructBlockDecoration(ProgramID pid, const Source& src)
|
StructBlockAttribute::StructBlockAttribute(ProgramID pid, const Source& src)
|
||||||
: Base(pid, src) {}
|
: Base(pid, src) {}
|
||||||
|
|
||||||
StructBlockDecoration::~StructBlockDecoration() = default;
|
StructBlockAttribute::~StructBlockAttribute() = default;
|
||||||
|
|
||||||
std::string StructBlockDecoration::Name() const {
|
std::string StructBlockAttribute::Name() const {
|
||||||
return "block";
|
return "block";
|
||||||
}
|
}
|
||||||
|
|
||||||
const StructBlockDecoration* StructBlockDecoration::Clone(
|
const StructBlockAttribute* StructBlockAttribute::Clone(
|
||||||
CloneContext* ctx) const {
|
CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<StructBlockDecoration>(src);
|
return ctx->dst->create<StructBlockAttribute>(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,38 +12,37 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
#ifndef SRC_AST_STRUCT_BLOCK_ATTRIBUTE_H_
|
||||||
#define SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
#define SRC_AST_STRUCT_BLOCK_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// The struct decorations
|
/// The struct block attribute
|
||||||
class StructBlockDecoration
|
class StructBlockAttribute : public Castable<StructBlockAttribute, Attribute> {
|
||||||
: public Castable<StructBlockDecoration, Decoration> {
|
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// Constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
StructBlockDecoration(ProgramID pid, const Source& src);
|
StructBlockAttribute(ProgramID pid, const Source& src);
|
||||||
~StructBlockDecoration() override;
|
~StructBlockAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const StructBlockDecoration* Clone(CloneContext* ctx) const override;
|
const StructBlockAttribute* Clone(CloneContext* ctx) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
#endif // SRC_AST_STRUCT_BLOCK_ATTRIBUTE_H_
|
@ -25,14 +25,14 @@ StructMember::StructMember(ProgramID pid,
|
|||||||
const Source& src,
|
const Source& src,
|
||||||
const Symbol& sym,
|
const Symbol& sym,
|
||||||
const ast::Type* ty,
|
const ast::Type* ty,
|
||||||
DecorationList decos)
|
AttributeList attrs)
|
||||||
: Base(pid, src), symbol(sym), type(ty), decorations(std::move(decos)) {
|
: Base(pid, src), symbol(sym), type(ty), attributes(std::move(attrs)) {
|
||||||
TINT_ASSERT(AST, type);
|
TINT_ASSERT(AST, type);
|
||||||
TINT_ASSERT(AST, symbol.IsValid());
|
TINT_ASSERT(AST, symbol.IsValid());
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
|
||||||
for (auto* deco : decorations) {
|
for (auto* attr : attributes) {
|
||||||
TINT_ASSERT(AST, deco);
|
TINT_ASSERT(AST, attr);
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, deco, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,8 +45,8 @@ const StructMember* StructMember::Clone(CloneContext* ctx) const {
|
|||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
auto sym = ctx->Clone(symbol);
|
auto sym = ctx->Clone(symbol);
|
||||||
auto* ty = ctx->Clone(type);
|
auto* ty = ctx->Clone(type);
|
||||||
auto decos = ctx->Clone(decorations);
|
auto attrs = ctx->Clone(attributes);
|
||||||
return ctx->dst->create<StructMember>(src, sym, ty, decos);
|
return ctx->dst->create<StructMember>(src, sym, ty, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
@ -34,12 +34,12 @@ class StructMember : public Castable<StructMember, Node> {
|
|||||||
/// @param src the source of this node for the struct member statement
|
/// @param src the source of this node for the struct member statement
|
||||||
/// @param sym The struct member symbol
|
/// @param sym The struct member symbol
|
||||||
/// @param type The struct member type
|
/// @param type The struct member type
|
||||||
/// @param decorations The struct member decorations
|
/// @param attributes The struct member attributes
|
||||||
StructMember(ProgramID pid,
|
StructMember(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
const Symbol& sym,
|
const Symbol& sym,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
DecorationList decorations);
|
AttributeList attributes);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
StructMember(StructMember&&);
|
StructMember(StructMember&&);
|
||||||
|
|
||||||
@ -57,8 +57,8 @@ class StructMember : public Castable<StructMember, Node> {
|
|||||||
/// The type
|
/// The type
|
||||||
const ast::Type* const type;
|
const ast::Type* const type;
|
||||||
|
|
||||||
/// The decorations
|
/// The attributes
|
||||||
const DecorationList decorations;
|
const AttributeList attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A list of struct members
|
/// A list of struct members
|
||||||
|
@ -12,34 +12,34 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/struct_member_size_decoration.h"
|
#include "src/ast/struct_member_align_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/clone_context.h"
|
#include "src/clone_context.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberSizeDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberAlignAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
StructMemberSizeDecoration::StructMemberSizeDecoration(ProgramID pid,
|
StructMemberAlignAttribute::StructMemberAlignAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
uint32_t sz)
|
uint32_t a)
|
||||||
: Base(pid, src), size(sz) {}
|
: Base(pid, src), align(a) {}
|
||||||
|
|
||||||
StructMemberSizeDecoration::~StructMemberSizeDecoration() = default;
|
StructMemberAlignAttribute::~StructMemberAlignAttribute() = default;
|
||||||
|
|
||||||
std::string StructMemberSizeDecoration::Name() const {
|
std::string StructMemberAlignAttribute::Name() const {
|
||||||
return "size";
|
return "align";
|
||||||
}
|
}
|
||||||
|
|
||||||
const StructMemberSizeDecoration* StructMemberSizeDecoration::Clone(
|
const StructMemberAlignAttribute* StructMemberAlignAttribute::Clone(
|
||||||
CloneContext* ctx) const {
|
CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<StructMemberSizeDecoration>(src, size);
|
return ctx->dst->create<StructMemberAlignAttribute>(src, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,36 +12,36 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
|
#ifndef SRC_AST_STRUCT_MEMBER_ALIGN_ATTRIBUTE_H_
|
||||||
#define SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
|
#define SRC_AST_STRUCT_MEMBER_ALIGN_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A struct member align decoration
|
/// A struct member align attribute
|
||||||
class StructMemberAlignDecoration
|
class StructMemberAlignAttribute
|
||||||
: public Castable<StructMemberAlignDecoration, Decoration> {
|
: public Castable<StructMemberAlignAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param align the align value
|
/// @param align the align value
|
||||||
StructMemberAlignDecoration(ProgramID pid, const Source& src, uint32_t align);
|
StructMemberAlignAttribute(ProgramID pid, const Source& src, uint32_t align);
|
||||||
~StructMemberAlignDecoration() override;
|
~StructMemberAlignAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const StructMemberAlignDecoration* Clone(CloneContext* ctx) const override;
|
const StructMemberAlignAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The align value
|
/// The align value
|
||||||
const uint32_t align;
|
const uint32_t align;
|
||||||
@ -50,4 +50,4 @@ class StructMemberAlignDecoration
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
|
#endif // SRC_AST_STRUCT_MEMBER_ALIGN_ATTRIBUTE_H_
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/struct_member_align_decoration.h"
|
#include "src/ast/struct_member_align_attribute.h"
|
||||||
|
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
@ -20,10 +20,10 @@ namespace tint {
|
|||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using StructMemberAlignDecorationTest = TestHelper;
|
using StructMemberAlignAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(StructMemberAlignDecorationTest, Creation) {
|
TEST_F(StructMemberAlignAttributeTest, Creation) {
|
||||||
auto* d = create<StructMemberAlignDecoration>(2);
|
auto* d = create<StructMemberAlignAttribute>(2);
|
||||||
EXPECT_EQ(2u, d->align);
|
EXPECT_EQ(2u, d->align);
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021 The Tint Authors.
|
// Copyright 2020 The Tint Authors.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@ -12,34 +12,33 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/struct_member_align_decoration.h"
|
#include "src/ast/struct_member_offset_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/clone_context.h"
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberAlignDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberOffsetAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
StructMemberAlignDecoration::StructMemberAlignDecoration(ProgramID pid,
|
StructMemberOffsetAttribute::StructMemberOffsetAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
uint32_t a)
|
uint32_t o)
|
||||||
: Base(pid, src), align(a) {}
|
: Base(pid, src), offset(o) {}
|
||||||
|
|
||||||
StructMemberAlignDecoration::~StructMemberAlignDecoration() = default;
|
StructMemberOffsetAttribute::~StructMemberOffsetAttribute() = default;
|
||||||
|
|
||||||
std::string StructMemberAlignDecoration::Name() const {
|
std::string StructMemberOffsetAttribute::Name() const {
|
||||||
return "align";
|
return "offset";
|
||||||
}
|
}
|
||||||
|
|
||||||
const StructMemberAlignDecoration* StructMemberAlignDecoration::Clone(
|
const StructMemberOffsetAttribute* StructMemberOffsetAttribute::Clone(
|
||||||
CloneContext* ctx) const {
|
CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<StructMemberAlignDecoration>(src, align);
|
return ctx->dst->create<StructMemberOffsetAttribute>(src, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,46 +12,46 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
#ifndef SRC_AST_STRUCT_MEMBER_OFFSET_ATTRIBUTE_H_
|
||||||
#define SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
#define SRC_AST_STRUCT_MEMBER_OFFSET_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A struct member offset decoration
|
/// A struct member offset attribute
|
||||||
/// @note The WGSL spec removed the `@offset(n)` decoration for `@size(n)`
|
/// @note The WGSL spec removed the `@offset(n)` attribute for `@size(n)`
|
||||||
/// and `@align(n)` in https://github.com/gpuweb/gpuweb/pull/1447. However
|
/// and `@align(n)` in https://github.com/gpuweb/gpuweb/pull/1447. However
|
||||||
/// this decoration is kept because the SPIR-V reader has to deal with absolute
|
/// this attribute is kept because the SPIR-V reader has to deal with absolute
|
||||||
/// offsets, and transforming these to size / align is complex and can be done
|
/// offsets, and transforming these to size / align is complex and can be done
|
||||||
/// in a number of ways. The Resolver is responsible for consuming the size and
|
/// in a number of ways. The Resolver is responsible for consuming the size and
|
||||||
/// align decorations and transforming these into absolute offsets. It is
|
/// align attributes and transforming these into absolute offsets. It is
|
||||||
/// trivial for the Resolver to handle `@offset(n)` or `@size(n)` /
|
/// trivial for the Resolver to handle `@offset(n)` or `@size(n)` /
|
||||||
/// `@align(n)` decorations, so this is what we do, keeping all the layout
|
/// `@align(n)` attributes, so this is what we do, keeping all the layout
|
||||||
/// logic in one place.
|
/// logic in one place.
|
||||||
class StructMemberOffsetDecoration
|
class StructMemberOffsetAttribute
|
||||||
: public Castable<StructMemberOffsetDecoration, Decoration> {
|
: public Castable<StructMemberOffsetAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param offset the offset value
|
/// @param offset the offset value
|
||||||
StructMemberOffsetDecoration(ProgramID pid,
|
StructMemberOffsetAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
uint32_t offset);
|
uint32_t offset);
|
||||||
~StructMemberOffsetDecoration() override;
|
~StructMemberOffsetAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const StructMemberOffsetDecoration* Clone(CloneContext* ctx) const override;
|
const StructMemberOffsetAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The offset value
|
/// The offset value
|
||||||
const uint32_t offset;
|
const uint32_t offset;
|
||||||
@ -60,4 +60,4 @@ class StructMemberOffsetDecoration
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
#endif // SRC_AST_STRUCT_MEMBER_OFFSET_ATTRIBUTE_H_
|
@ -18,10 +18,10 @@ namespace tint {
|
|||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using StructMemberOffsetDecorationTest = TestHelper;
|
using StructMemberOffsetAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(StructMemberOffsetDecorationTest, Creation) {
|
TEST_F(StructMemberOffsetAttributeTest, Creation) {
|
||||||
auto* d = create<StructMemberOffsetDecoration>(2);
|
auto* d = create<StructMemberOffsetAttribute>(2);
|
||||||
EXPECT_EQ(2u, d->offset);
|
EXPECT_EQ(2u, d->offset);
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 The Tint Authors.
|
// Copyright 2021 The Tint Authors.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@ -12,33 +12,34 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/struct_member_offset_decoration.h"
|
#include "src/ast/struct_member_size_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "src/clone_context.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberOffsetDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberSizeAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
StructMemberOffsetDecoration::StructMemberOffsetDecoration(ProgramID pid,
|
StructMemberSizeAttribute::StructMemberSizeAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
uint32_t o)
|
uint32_t sz)
|
||||||
: Base(pid, src), offset(o) {}
|
: Base(pid, src), size(sz) {}
|
||||||
|
|
||||||
StructMemberOffsetDecoration::~StructMemberOffsetDecoration() = default;
|
StructMemberSizeAttribute::~StructMemberSizeAttribute() = default;
|
||||||
|
|
||||||
std::string StructMemberOffsetDecoration::Name() const {
|
std::string StructMemberSizeAttribute::Name() const {
|
||||||
return "offset";
|
return "size";
|
||||||
}
|
}
|
||||||
|
|
||||||
const StructMemberOffsetDecoration* StructMemberOffsetDecoration::Clone(
|
const StructMemberSizeAttribute* StructMemberSizeAttribute::Clone(
|
||||||
CloneContext* ctx) const {
|
CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<StructMemberOffsetDecoration>(src, offset);
|
return ctx->dst->create<StructMemberSizeAttribute>(src, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,36 +12,36 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
|
#ifndef SRC_AST_STRUCT_MEMBER_SIZE_ATTRIBUTE_H_
|
||||||
#define SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
|
#define SRC_AST_STRUCT_MEMBER_SIZE_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
/// A struct member size decoration
|
/// A struct member size attribute
|
||||||
class StructMemberSizeDecoration
|
class StructMemberSizeAttribute
|
||||||
: public Castable<StructMemberSizeDecoration, Decoration> {
|
: public Castable<StructMemberSizeAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param size the size value
|
/// @param size the size value
|
||||||
StructMemberSizeDecoration(ProgramID pid, const Source& src, uint32_t size);
|
StructMemberSizeAttribute(ProgramID pid, const Source& src, uint32_t size);
|
||||||
~StructMemberSizeDecoration() override;
|
~StructMemberSizeAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const StructMemberSizeDecoration* Clone(CloneContext* ctx) const override;
|
const StructMemberSizeAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The size value
|
/// The size value
|
||||||
const uint32_t size;
|
const uint32_t size;
|
||||||
@ -50,4 +50,4 @@ class StructMemberSizeDecoration
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
|
#endif // SRC_AST_STRUCT_MEMBER_SIZE_ATTRIBUTE_H_
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/struct_member_size_decoration.h"
|
#include "src/ast/struct_member_size_attribute.h"
|
||||||
|
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
@ -20,10 +20,10 @@ namespace tint {
|
|||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using StructMemberOffsetDecorationTest = TestHelper;
|
using StructMemberSizeAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(StructMemberOffsetDecorationTest, Creation) {
|
TEST_F(StructMemberSizeAttributeTest, Creation) {
|
||||||
auto* d = create<StructMemberSizeDecoration>(2);
|
auto* d = create<StructMemberSizeAttribute>(2);
|
||||||
EXPECT_EQ(2u, d->size);
|
EXPECT_EQ(2u, d->size);
|
||||||
}
|
}
|
||||||
|
|
@ -25,8 +25,8 @@ TEST_F(StructMemberTest, Creation) {
|
|||||||
auto* st = Member("a", ty.i32(), {MemberSize(4)});
|
auto* st = Member("a", ty.i32(), {MemberSize(4)});
|
||||||
EXPECT_EQ(st->symbol, Symbol(1, ID()));
|
EXPECT_EQ(st->symbol, Symbol(1, ID()));
|
||||||
EXPECT_TRUE(st->type->Is<ast::I32>());
|
EXPECT_TRUE(st->type->Is<ast::I32>());
|
||||||
EXPECT_EQ(st->decorations.size(), 1u);
|
EXPECT_EQ(st->attributes.size(), 1u);
|
||||||
EXPECT_TRUE(st->decorations[0]->Is<StructMemberSizeDecoration>());
|
EXPECT_TRUE(st->attributes[0]->Is<StructMemberSizeAttribute>());
|
||||||
EXPECT_EQ(st->source.range.begin.line, 0u);
|
EXPECT_EQ(st->source.range.begin.line, 0u);
|
||||||
EXPECT_EQ(st->source.range.begin.column, 0u);
|
EXPECT_EQ(st->source.range.begin.column, 0u);
|
||||||
EXPECT_EQ(st->source.range.end.line, 0u);
|
EXPECT_EQ(st->source.range.end.line, 0u);
|
||||||
@ -39,7 +39,7 @@ TEST_F(StructMemberTest, CreationWithSource) {
|
|||||||
"a", ty.i32());
|
"a", ty.i32());
|
||||||
EXPECT_EQ(st->symbol, Symbol(1, ID()));
|
EXPECT_EQ(st->symbol, Symbol(1, ID()));
|
||||||
EXPECT_TRUE(st->type->Is<ast::I32>());
|
EXPECT_TRUE(st->type->Is<ast::I32>());
|
||||||
EXPECT_EQ(st->decorations.size(), 0u);
|
EXPECT_EQ(st->attributes.size(), 0u);
|
||||||
EXPECT_EQ(st->source.range.begin.line, 27u);
|
EXPECT_EQ(st->source.range.begin.line, 27u);
|
||||||
EXPECT_EQ(st->source.range.begin.column, 4u);
|
EXPECT_EQ(st->source.range.begin.column, 4u);
|
||||||
EXPECT_EQ(st->source.range.end.line, 27u);
|
EXPECT_EQ(st->source.range.end.line, 27u);
|
||||||
@ -64,7 +64,7 @@ TEST_F(StructMemberTest, Assert_Null_Type) {
|
|||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StructMemberTest, Assert_Null_Decoration) {
|
TEST_F(StructMemberTest, Assert_Null_Attribute) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
@ -83,7 +83,7 @@ TEST_F(StructMemberTest, Assert_DifferentProgramID_Symbol) {
|
|||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StructMemberTest, Assert_DifferentProgramID_Decoration) {
|
TEST_F(StructMemberTest, Assert_DifferentProgramID_Attribute) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "src/ast/matrix.h"
|
#include "src/ast/matrix.h"
|
||||||
#include "src/ast/pointer.h"
|
#include "src/ast/pointer.h"
|
||||||
#include "src/ast/sampler.h"
|
#include "src/ast/sampler.h"
|
||||||
#include "src/ast/struct_block_decoration.h"
|
#include "src/ast/struct_block_attribute.h"
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
#include "src/ast/texture.h"
|
#include "src/ast/texture.h"
|
||||||
#include "src/ast/u32.h"
|
#include "src/ast/u32.h"
|
||||||
@ -37,43 +37,43 @@ using AstStructTest = TestHelper;
|
|||||||
TEST_F(AstStructTest, Creation) {
|
TEST_F(AstStructTest, Creation) {
|
||||||
auto name = Sym("s");
|
auto name = Sym("s");
|
||||||
auto* s = create<Struct>(name, StructMemberList{Member("a", ty.i32())},
|
auto* s = create<Struct>(name, StructMemberList{Member("a", ty.i32())},
|
||||||
DecorationList{});
|
AttributeList{});
|
||||||
EXPECT_EQ(s->name, name);
|
EXPECT_EQ(s->name, name);
|
||||||
EXPECT_EQ(s->members.size(), 1u);
|
EXPECT_EQ(s->members.size(), 1u);
|
||||||
EXPECT_TRUE(s->decorations.empty());
|
EXPECT_TRUE(s->attributes.empty());
|
||||||
EXPECT_EQ(s->source.range.begin.line, 0u);
|
EXPECT_EQ(s->source.range.begin.line, 0u);
|
||||||
EXPECT_EQ(s->source.range.begin.column, 0u);
|
EXPECT_EQ(s->source.range.begin.column, 0u);
|
||||||
EXPECT_EQ(s->source.range.end.line, 0u);
|
EXPECT_EQ(s->source.range.end.line, 0u);
|
||||||
EXPECT_EQ(s->source.range.end.column, 0u);
|
EXPECT_EQ(s->source.range.end.column, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AstStructTest, Creation_WithDecorations) {
|
TEST_F(AstStructTest, Creation_WithAttributes) {
|
||||||
auto name = Sym("s");
|
auto name = Sym("s");
|
||||||
DecorationList decos;
|
AttributeList attrs;
|
||||||
decos.push_back(create<StructBlockDecoration>());
|
attrs.push_back(create<StructBlockAttribute>());
|
||||||
|
|
||||||
auto* s =
|
auto* s =
|
||||||
create<Struct>(name, StructMemberList{Member("a", ty.i32())}, decos);
|
create<Struct>(name, StructMemberList{Member("a", ty.i32())}, attrs);
|
||||||
EXPECT_EQ(s->name, name);
|
EXPECT_EQ(s->name, name);
|
||||||
EXPECT_EQ(s->members.size(), 1u);
|
EXPECT_EQ(s->members.size(), 1u);
|
||||||
ASSERT_EQ(s->decorations.size(), 1u);
|
ASSERT_EQ(s->attributes.size(), 1u);
|
||||||
EXPECT_TRUE(s->decorations[0]->Is<StructBlockDecoration>());
|
EXPECT_TRUE(s->attributes[0]->Is<StructBlockAttribute>());
|
||||||
EXPECT_EQ(s->source.range.begin.line, 0u);
|
EXPECT_EQ(s->source.range.begin.line, 0u);
|
||||||
EXPECT_EQ(s->source.range.begin.column, 0u);
|
EXPECT_EQ(s->source.range.begin.column, 0u);
|
||||||
EXPECT_EQ(s->source.range.end.line, 0u);
|
EXPECT_EQ(s->source.range.end.line, 0u);
|
||||||
EXPECT_EQ(s->source.range.end.column, 0u);
|
EXPECT_EQ(s->source.range.end.column, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AstStructTest, CreationWithSourceAndDecorations) {
|
TEST_F(AstStructTest, CreationWithSourceAndAttributes) {
|
||||||
auto name = Sym("s");
|
auto name = Sym("s");
|
||||||
auto* s = create<Struct>(
|
auto* s = create<Struct>(
|
||||||
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
|
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
|
||||||
name, StructMemberList{Member("a", ty.i32())},
|
name, StructMemberList{Member("a", ty.i32())},
|
||||||
DecorationList{create<StructBlockDecoration>()});
|
AttributeList{create<StructBlockAttribute>()});
|
||||||
EXPECT_EQ(s->name, name);
|
EXPECT_EQ(s->name, name);
|
||||||
EXPECT_EQ(s->members.size(), 1u);
|
EXPECT_EQ(s->members.size(), 1u);
|
||||||
ASSERT_EQ(s->decorations.size(), 1u);
|
ASSERT_EQ(s->attributes.size(), 1u);
|
||||||
EXPECT_TRUE(s->decorations[0]->Is<StructBlockDecoration>());
|
EXPECT_TRUE(s->attributes[0]->Is<StructBlockAttribute>());
|
||||||
EXPECT_EQ(s->source.range.begin.line, 27u);
|
EXPECT_EQ(s->source.range.begin.line, 27u);
|
||||||
EXPECT_EQ(s->source.range.begin.column, 4u);
|
EXPECT_EQ(s->source.range.begin.column, 4u);
|
||||||
EXPECT_EQ(s->source.range.end.line, 27u);
|
EXPECT_EQ(s->source.range.end.line, 27u);
|
||||||
@ -86,18 +86,18 @@ TEST_F(AstStructTest, Assert_Null_StructMember) {
|
|||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.create<Struct>(b.Sym("S"),
|
b.create<Struct>(b.Sym("S"),
|
||||||
StructMemberList{b.Member("a", b.ty.i32()), nullptr},
|
StructMemberList{b.Member("a", b.ty.i32()), nullptr},
|
||||||
DecorationList{});
|
AttributeList{});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AstStructTest, Assert_Null_Decoration) {
|
TEST_F(AstStructTest, Assert_Null_Attribute) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.create<Struct>(b.Sym("S"),
|
b.create<Struct>(b.Sym("S"),
|
||||||
StructMemberList{b.Member("a", b.ty.i32())},
|
StructMemberList{b.Member("a", b.ty.i32())},
|
||||||
DecorationList{nullptr});
|
AttributeList{nullptr});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
@ -109,19 +109,19 @@ TEST_F(AstStructTest, Assert_DifferentProgramID_StructMember) {
|
|||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.create<Struct>(b1.Sym("S"),
|
b1.create<Struct>(b1.Sym("S"),
|
||||||
StructMemberList{b2.Member("a", b2.ty.i32())},
|
StructMemberList{b2.Member("a", b2.ty.i32())},
|
||||||
DecorationList{});
|
AttributeList{});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AstStructTest, Assert_DifferentProgramID_Decoration) {
|
TEST_F(AstStructTest, Assert_DifferentProgramID_Attribute) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.create<Struct>(b1.Sym("S"),
|
b1.create<Struct>(b1.Sym("S"),
|
||||||
StructMemberList{b1.Member("a", b1.ty.i32())},
|
StructMemberList{b1.Member("a", b1.ty.i32())},
|
||||||
DecorationList{b2.create<StructBlockDecoration>()});
|
AttributeList{b2.create<StructBlockAttribute>()});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include "src/ast/variable.h"
|
#include "src/ast/variable.h"
|
||||||
|
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
#include "src/sem/variable.h"
|
#include "src/sem/variable.h"
|
||||||
|
|
||||||
@ -31,13 +31,13 @@ Variable::Variable(ProgramID pid,
|
|||||||
const ast::Type* ty,
|
const ast::Type* ty,
|
||||||
bool constant,
|
bool constant,
|
||||||
const Expression* ctor,
|
const Expression* ctor,
|
||||||
DecorationList decos)
|
AttributeList attrs)
|
||||||
: Base(pid, src),
|
: Base(pid, src),
|
||||||
symbol(sym),
|
symbol(sym),
|
||||||
type(ty),
|
type(ty),
|
||||||
is_const(constant),
|
is_const(constant),
|
||||||
constructor(ctor),
|
constructor(ctor),
|
||||||
decorations(std::move(decos)),
|
attributes(std::move(attrs)),
|
||||||
declared_storage_class(dsc),
|
declared_storage_class(dsc),
|
||||||
declared_access(da) {
|
declared_access(da) {
|
||||||
TINT_ASSERT(AST, symbol.IsValid());
|
TINT_ASSERT(AST, symbol.IsValid());
|
||||||
@ -50,12 +50,12 @@ Variable::Variable(Variable&&) = default;
|
|||||||
Variable::~Variable() = default;
|
Variable::~Variable() = default;
|
||||||
|
|
||||||
VariableBindingPoint Variable::BindingPoint() const {
|
VariableBindingPoint Variable::BindingPoint() const {
|
||||||
const GroupDecoration* group = nullptr;
|
const GroupAttribute* group = nullptr;
|
||||||
const BindingDecoration* binding = nullptr;
|
const BindingAttribute* binding = nullptr;
|
||||||
for (auto* deco : decorations) {
|
for (auto* attr : attributes) {
|
||||||
if (auto* g = deco->As<GroupDecoration>()) {
|
if (auto* g = attr->As<GroupAttribute>()) {
|
||||||
group = g;
|
group = g;
|
||||||
} else if (auto* b = deco->As<BindingDecoration>()) {
|
} else if (auto* b = attr->As<BindingAttribute>()) {
|
||||||
binding = b;
|
binding = b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,9 +67,9 @@ const Variable* Variable::Clone(CloneContext* ctx) const {
|
|||||||
auto sym = ctx->Clone(symbol);
|
auto sym = ctx->Clone(symbol);
|
||||||
auto* ty = ctx->Clone(type);
|
auto* ty = ctx->Clone(type);
|
||||||
auto* ctor = ctx->Clone(constructor);
|
auto* ctor = ctx->Clone(constructor);
|
||||||
auto decos = ctx->Clone(decorations);
|
auto attrs = ctx->Clone(attributes);
|
||||||
return ctx->dst->create<Variable>(src, sym, declared_storage_class,
|
return ctx->dst->create<Variable>(src, sym, declared_storage_class,
|
||||||
declared_access, ty, is_const, ctor, decos);
|
declared_access, ty, is_const, ctor, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/access.h"
|
#include "src/ast/access.h"
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
#include "src/ast/expression.h"
|
#include "src/ast/expression.h"
|
||||||
#include "src/ast/storage_class.h"
|
#include "src/ast/storage_class.h"
|
||||||
|
|
||||||
@ -27,20 +27,20 @@ namespace tint {
|
|||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class BindingDecoration;
|
class BindingAttribute;
|
||||||
class GroupDecoration;
|
class GroupAttribute;
|
||||||
class LocationDecoration;
|
class LocationAttribute;
|
||||||
class Type;
|
class Type;
|
||||||
|
|
||||||
/// VariableBindingPoint holds a group and binding decoration.
|
/// VariableBindingPoint holds a group and binding attribute.
|
||||||
struct VariableBindingPoint {
|
struct VariableBindingPoint {
|
||||||
/// The `[[group]]` part of the binding point
|
/// The `@group` part of the binding point
|
||||||
const GroupDecoration* group = nullptr;
|
const GroupAttribute* group = nullptr;
|
||||||
/// The `[[binding]]` part of the binding point
|
/// The `@binding` part of the binding point
|
||||||
const BindingDecoration* binding = nullptr;
|
const BindingAttribute* binding = nullptr;
|
||||||
|
|
||||||
/// @returns true if the BindingPoint has a valid group and binding
|
/// @returns true if the BindingPoint has a valid group and binding
|
||||||
/// decoration.
|
/// attribute.
|
||||||
inline operator bool() const { return group && binding; }
|
inline operator bool() const { return group && binding; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ class Variable : public Castable<Variable, Node> {
|
|||||||
/// @param type the declared variable type
|
/// @param type the declared variable type
|
||||||
/// @param is_const true if the variable is const
|
/// @param is_const true if the variable is const
|
||||||
/// @param constructor the constructor expression
|
/// @param constructor the constructor expression
|
||||||
/// @param decorations the variable decorations
|
/// @param attributes the variable attributes
|
||||||
Variable(ProgramID program_id,
|
Variable(ProgramID program_id,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
const Symbol& sym,
|
const Symbol& sym,
|
||||||
@ -117,7 +117,7 @@ class Variable : public Castable<Variable, Node> {
|
|||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
bool is_const,
|
bool is_const,
|
||||||
const Expression* constructor,
|
const Expression* constructor,
|
||||||
DecorationList decorations);
|
AttributeList attributes);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
Variable(Variable&&);
|
Variable(Variable&&);
|
||||||
|
|
||||||
@ -146,8 +146,8 @@ class Variable : public Castable<Variable, Node> {
|
|||||||
/// The constructor expression or nullptr if none set
|
/// The constructor expression or nullptr if none set
|
||||||
const Expression* const constructor;
|
const Expression* const constructor;
|
||||||
|
|
||||||
/// The decorations attached to this variable
|
/// The attributes attached to this variable
|
||||||
const DecorationList decorations;
|
const AttributeList attributes;
|
||||||
|
|
||||||
/// The declared storage class
|
/// The declared storage class
|
||||||
const StorageClass declared_storage_class;
|
const StorageClass declared_storage_class;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "gtest/gtest-spi.h"
|
#include "gtest/gtest-spi.h"
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
@ -37,7 +37,7 @@ TEST_F(VariableTest, Creation) {
|
|||||||
TEST_F(VariableTest, CreationWithSource) {
|
TEST_F(VariableTest, CreationWithSource) {
|
||||||
auto* v = Var(
|
auto* v = Var(
|
||||||
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}},
|
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}},
|
||||||
"i", ty.f32(), StorageClass::kPrivate, nullptr, DecorationList{});
|
"i", ty.f32(), StorageClass::kPrivate, nullptr, AttributeList{});
|
||||||
|
|
||||||
EXPECT_EQ(v->symbol, Symbol(1, ID()));
|
EXPECT_EQ(v->symbol, Symbol(1, ID()));
|
||||||
EXPECT_EQ(v->declared_storage_class, StorageClass::kPrivate);
|
EXPECT_EQ(v->declared_storage_class, StorageClass::kPrivate);
|
||||||
@ -51,7 +51,7 @@ TEST_F(VariableTest, CreationWithSource) {
|
|||||||
TEST_F(VariableTest, CreationEmpty) {
|
TEST_F(VariableTest, CreationEmpty) {
|
||||||
auto* v = Var(
|
auto* v = Var(
|
||||||
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}},
|
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}},
|
||||||
"a_var", ty.i32(), StorageClass::kWorkgroup, nullptr, DecorationList{});
|
"a_var", ty.i32(), StorageClass::kWorkgroup, nullptr, AttributeList{});
|
||||||
|
|
||||||
EXPECT_EQ(v->symbol, Symbol(1, ID()));
|
EXPECT_EQ(v->symbol, Symbol(1, ID()));
|
||||||
EXPECT_EQ(v->declared_storage_class, StorageClass::kWorkgroup);
|
EXPECT_EQ(v->declared_storage_class, StorageClass::kWorkgroup);
|
||||||
@ -91,29 +91,29 @@ TEST_F(VariableTest, Assert_DifferentProgramID_Constructor) {
|
|||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, WithDecorations) {
|
TEST_F(VariableTest, WithAttributes) {
|
||||||
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
||||||
DecorationList{
|
AttributeList{
|
||||||
create<LocationDecoration>(1),
|
create<LocationAttribute>(1),
|
||||||
create<BuiltinDecoration>(Builtin::kPosition),
|
create<BuiltinAttribute>(Builtin::kPosition),
|
||||||
create<OverrideDecoration>(1200),
|
create<OverrideAttribute>(1200),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto& decorations = var->decorations;
|
auto& attributes = var->attributes;
|
||||||
EXPECT_TRUE(ast::HasDecoration<ast::LocationDecoration>(decorations));
|
EXPECT_TRUE(ast::HasAttribute<ast::LocationAttribute>(attributes));
|
||||||
EXPECT_TRUE(ast::HasDecoration<ast::BuiltinDecoration>(decorations));
|
EXPECT_TRUE(ast::HasAttribute<ast::BuiltinAttribute>(attributes));
|
||||||
EXPECT_TRUE(ast::HasDecoration<ast::OverrideDecoration>(decorations));
|
EXPECT_TRUE(ast::HasAttribute<ast::OverrideAttribute>(attributes));
|
||||||
|
|
||||||
auto* location = ast::GetDecoration<ast::LocationDecoration>(decorations);
|
auto* location = ast::GetAttribute<ast::LocationAttribute>(attributes);
|
||||||
ASSERT_NE(nullptr, location);
|
ASSERT_NE(nullptr, location);
|
||||||
EXPECT_EQ(1u, location->value);
|
EXPECT_EQ(1u, location->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, BindingPoint) {
|
TEST_F(VariableTest, BindingPoint) {
|
||||||
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
||||||
DecorationList{
|
AttributeList{
|
||||||
create<BindingDecoration>(2),
|
create<BindingAttribute>(2),
|
||||||
create<GroupDecoration>(1),
|
create<GroupAttribute>(1),
|
||||||
});
|
});
|
||||||
EXPECT_TRUE(var->BindingPoint());
|
EXPECT_TRUE(var->BindingPoint());
|
||||||
ASSERT_NE(var->BindingPoint().binding, nullptr);
|
ASSERT_NE(var->BindingPoint().binding, nullptr);
|
||||||
@ -122,18 +122,18 @@ TEST_F(VariableTest, BindingPoint) {
|
|||||||
EXPECT_EQ(var->BindingPoint().group->value, 1u);
|
EXPECT_EQ(var->BindingPoint().group->value, 1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, BindingPointoDecorations) {
|
TEST_F(VariableTest, BindingPointAttributes) {
|
||||||
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
||||||
DecorationList{});
|
AttributeList{});
|
||||||
EXPECT_FALSE(var->BindingPoint());
|
EXPECT_FALSE(var->BindingPoint());
|
||||||
EXPECT_EQ(var->BindingPoint().group, nullptr);
|
EXPECT_EQ(var->BindingPoint().group, nullptr);
|
||||||
EXPECT_EQ(var->BindingPoint().binding, nullptr);
|
EXPECT_EQ(var->BindingPoint().binding, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, BindingPointMissingGroupDecoration) {
|
TEST_F(VariableTest, BindingPointMissingGroupAttribute) {
|
||||||
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
||||||
DecorationList{
|
AttributeList{
|
||||||
create<BindingDecoration>(2),
|
create<BindingAttribute>(2),
|
||||||
});
|
});
|
||||||
EXPECT_FALSE(var->BindingPoint());
|
EXPECT_FALSE(var->BindingPoint());
|
||||||
ASSERT_NE(var->BindingPoint().binding, nullptr);
|
ASSERT_NE(var->BindingPoint().binding, nullptr);
|
||||||
@ -141,9 +141,9 @@ TEST_F(VariableTest, BindingPointMissingGroupDecoration) {
|
|||||||
EXPECT_EQ(var->BindingPoint().group, nullptr);
|
EXPECT_EQ(var->BindingPoint().group, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, BindingPointMissingBindingDecoration) {
|
TEST_F(VariableTest, BindingPointMissingBindingAttribute) {
|
||||||
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
||||||
DecorationList{create<GroupDecoration>(1)});
|
AttributeList{create<GroupAttribute>(1)});
|
||||||
EXPECT_FALSE(var->BindingPoint());
|
EXPECT_FALSE(var->BindingPoint());
|
||||||
ASSERT_NE(var->BindingPoint().group, nullptr);
|
ASSERT_NE(var->BindingPoint().group, nullptr);
|
||||||
EXPECT_EQ(var->BindingPoint().group->value, 1u);
|
EXPECT_EQ(var->BindingPoint().group->value, 1u);
|
||||||
|
@ -12,37 +12,37 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::WorkgroupDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::WorkgroupAttribute);
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
WorkgroupDecoration::WorkgroupDecoration(ProgramID pid,
|
WorkgroupAttribute::WorkgroupAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
const ast::Expression* x_,
|
const ast::Expression* x_,
|
||||||
const ast::Expression* y_,
|
const ast::Expression* y_,
|
||||||
const ast::Expression* z_)
|
const ast::Expression* z_)
|
||||||
: Base(pid, src), x(x_), y(y_), z(z_) {}
|
: Base(pid, src), x(x_), y(y_), z(z_) {}
|
||||||
|
|
||||||
WorkgroupDecoration::~WorkgroupDecoration() = default;
|
WorkgroupAttribute::~WorkgroupAttribute() = default;
|
||||||
|
|
||||||
std::string WorkgroupDecoration::Name() const {
|
std::string WorkgroupAttribute::Name() const {
|
||||||
return "workgroup_size";
|
return "workgroup_size";
|
||||||
}
|
}
|
||||||
|
|
||||||
const WorkgroupDecoration* WorkgroupDecoration::Clone(CloneContext* ctx) const {
|
const WorkgroupAttribute* WorkgroupAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
auto* x_ = ctx->Clone(x);
|
auto* x_ = ctx->Clone(x);
|
||||||
auto* y_ = ctx->Clone(y);
|
auto* y_ = ctx->Clone(y);
|
||||||
auto* z_ = ctx->Clone(z);
|
auto* z_ = ctx->Clone(z);
|
||||||
return ctx->dst->create<WorkgroupDecoration>(src, x_, y_, z_);
|
return ctx->dst->create<WorkgroupAttribute>(src, x_, y_, z_);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
@ -12,13 +12,13 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_AST_WORKGROUP_DECORATION_H_
|
#ifndef SRC_AST_WORKGROUP_ATTRIBUTE_H_
|
||||||
#define SRC_AST_WORKGROUP_DECORATION_H_
|
#define SRC_AST_WORKGROUP_ATTRIBUTE_H_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/attribute.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
@ -26,8 +26,8 @@ namespace ast {
|
|||||||
// Forward declaration
|
// Forward declaration
|
||||||
class Expression;
|
class Expression;
|
||||||
|
|
||||||
/// A workgroup decoration
|
/// A workgroup attribute
|
||||||
class WorkgroupDecoration : public Castable<WorkgroupDecoration, Decoration> {
|
class WorkgroupAttribute : public Castable<WorkgroupAttribute, Attribute> {
|
||||||
public:
|
public:
|
||||||
/// constructor
|
/// constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
/// @param pid the identifier of the program that owns this node
|
||||||
@ -35,25 +35,25 @@ class WorkgroupDecoration : public Castable<WorkgroupDecoration, Decoration> {
|
|||||||
/// @param x the workgroup x dimension expression
|
/// @param x the workgroup x dimension expression
|
||||||
/// @param y the optional workgroup y dimension expression
|
/// @param y the optional workgroup y dimension expression
|
||||||
/// @param z the optional workgroup z dimension expression
|
/// @param z the optional workgroup z dimension expression
|
||||||
WorkgroupDecoration(ProgramID pid,
|
WorkgroupAttribute(ProgramID pid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
const ast::Expression* x,
|
const ast::Expression* x,
|
||||||
const ast::Expression* y = nullptr,
|
const ast::Expression* y = nullptr,
|
||||||
const ast::Expression* z = nullptr);
|
const ast::Expression* z = nullptr);
|
||||||
|
|
||||||
~WorkgroupDecoration() override;
|
~WorkgroupAttribute() override;
|
||||||
|
|
||||||
/// @returns the workgroup dimensions
|
/// @returns the workgroup dimensions
|
||||||
std::array<const ast::Expression*, 3> Values() const { return {x, y, z}; }
|
std::array<const ast::Expression*, 3> Values() const { return {x, y, z}; }
|
||||||
|
|
||||||
/// @returns the WGSL name for the decoration
|
/// @returns the WGSL name for the attribute
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||||
/// `ctx`.
|
/// `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const WorkgroupDecoration* Clone(CloneContext* ctx) const override;
|
const WorkgroupAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The workgroup x dimension.
|
/// The workgroup x dimension.
|
||||||
const ast::Expression* const x;
|
const ast::Expression* const x;
|
||||||
@ -66,4 +66,4 @@ class WorkgroupDecoration : public Castable<WorkgroupDecoration, Decoration> {
|
|||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_WORKGROUP_DECORATION_H_
|
#endif // SRC_AST_WORKGROUP_ATTRIBUTE_H_
|
@ -12,18 +12,18 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
|
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using WorkgroupDecorationTest = TestHelper;
|
using WorkgroupAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(WorkgroupDecorationTest, Creation_1param) {
|
TEST_F(WorkgroupAttributeTest, Creation_1param) {
|
||||||
auto* d = WorkgroupSize(2);
|
auto* d = WorkgroupSize(2);
|
||||||
auto values = d->Values();
|
auto values = d->Values();
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ TEST_F(WorkgroupDecorationTest, Creation_1param) {
|
|||||||
EXPECT_EQ(values[1], nullptr);
|
EXPECT_EQ(values[1], nullptr);
|
||||||
EXPECT_EQ(values[2], nullptr);
|
EXPECT_EQ(values[2], nullptr);
|
||||||
}
|
}
|
||||||
TEST_F(WorkgroupDecorationTest, Creation_2param) {
|
TEST_F(WorkgroupAttributeTest, Creation_2param) {
|
||||||
auto* d = WorkgroupSize(2, 4);
|
auto* d = WorkgroupSize(2, 4);
|
||||||
auto values = d->Values();
|
auto values = d->Values();
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ TEST_F(WorkgroupDecorationTest, Creation_2param) {
|
|||||||
EXPECT_EQ(values[2], nullptr);
|
EXPECT_EQ(values[2], nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WorkgroupDecorationTest, Creation_3param) {
|
TEST_F(WorkgroupAttributeTest, Creation_3param) {
|
||||||
auto* d = WorkgroupSize(2, 4, 6);
|
auto* d = WorkgroupSize(2, 4, 6);
|
||||||
auto values = d->Values();
|
auto values = d->Values();
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ TEST_F(WorkgroupDecorationTest, Creation_3param) {
|
|||||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
|
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WorkgroupDecorationTest, Creation_WithIdentifier) {
|
TEST_F(WorkgroupAttributeTest, Creation_WithIdentifier) {
|
||||||
auto* d = WorkgroupSize(2, 4, "depth");
|
auto* d = WorkgroupSize(2, 4, "depth");
|
||||||
auto values = d->Values();
|
auto values = d->Values();
|
||||||
|
|
@ -17,6 +17,10 @@
|
|||||||
namespace tint {
|
namespace tint {
|
||||||
namespace inspector {
|
namespace inspector {
|
||||||
|
|
||||||
|
StageVariable::StageVariable() = default;
|
||||||
|
StageVariable::StageVariable(const StageVariable&) = default;
|
||||||
|
StageVariable::~StageVariable() = default;
|
||||||
|
|
||||||
EntryPoint::EntryPoint() = default;
|
EntryPoint::EntryPoint() = default;
|
||||||
EntryPoint::EntryPoint(EntryPoint&) = default;
|
EntryPoint::EntryPoint(EntryPoint&) = default;
|
||||||
EntryPoint::EntryPoint(EntryPoint&&) = default;
|
EntryPoint::EntryPoint(EntryPoint&&) = default;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/interpolate_decoration.h"
|
#include "src/ast/interpolate_attribute.h"
|
||||||
#include "src/ast/pipeline_stage.h"
|
#include "src/ast/pipeline_stage.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
@ -56,13 +56,27 @@ enum class InterpolationSampling {
|
|||||||
|
|
||||||
/// Reflection data about an entry point input or output.
|
/// Reflection data about an entry point input or output.
|
||||||
struct StageVariable {
|
struct StageVariable {
|
||||||
|
/// Constructor
|
||||||
|
StageVariable();
|
||||||
|
/// Copy constructor
|
||||||
|
StageVariable(const StageVariable&);
|
||||||
|
/// Destructor
|
||||||
|
~StageVariable();
|
||||||
|
|
||||||
/// Name of the variable in the shader.
|
/// Name of the variable in the shader.
|
||||||
std::string name;
|
std::string name;
|
||||||
/// Is Location Decoration present
|
/// Is location attribute present
|
||||||
bool has_location_decoration = false;
|
bool has_location_attribute = false;
|
||||||
/// Value of Location Decoration, only valid if |has_location_decoration| is
|
/// Value of the location attribute, only valid if #has_location_attribute is
|
||||||
/// true.
|
/// true.
|
||||||
uint32_t location_decoration;
|
uint32_t location_attribute;
|
||||||
|
/// Is Location attribute present
|
||||||
|
/// [DEPRECATED]: Use #has_location_attribute
|
||||||
|
bool& has_location_decoration = has_location_attribute;
|
||||||
|
/// Value of Location Decoration, only valid if #has_location_decoration is
|
||||||
|
/// true.
|
||||||
|
/// [DEPRECATED]: Use #location_attribute
|
||||||
|
uint32_t& location_decoration = location_attribute;
|
||||||
/// Scalar type that the variable is composed of.
|
/// Scalar type that the variable is composed of.
|
||||||
ComponentType component_type = ComponentType::kUnknown;
|
ComponentType component_type = ComponentType::kUnknown;
|
||||||
/// How the scalars are composed for the variable.
|
/// How the scalars are composed for the variable.
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
#include "src/ast/bool_literal_expression.h"
|
#include "src/ast/bool_literal_expression.h"
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
#include "src/ast/float_literal_expression.h"
|
#include "src/ast/float_literal_expression.h"
|
||||||
#include "src/ast/interpolate_decoration.h"
|
#include "src/ast/interpolate_attribute.h"
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_attribute.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/ast/sint_literal_expression.h"
|
#include "src/ast/sint_literal_expression.h"
|
||||||
#include "src/ast/uint_literal_expression.h"
|
#include "src/ast/uint_literal_expression.h"
|
||||||
#include "src/sem/array.h"
|
#include "src/sem/array.h"
|
||||||
@ -102,19 +102,19 @@ std::tuple<ComponentType, CompositionType> CalculateComponentAndComposition(
|
|||||||
|
|
||||||
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
|
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
const ast::DecorationList& decorations) {
|
const ast::AttributeList& attributes) {
|
||||||
auto* interpolation_decoration =
|
auto* interpolation_attribute =
|
||||||
ast::GetDecoration<ast::InterpolateDecoration>(decorations);
|
ast::GetAttribute<ast::InterpolateAttribute>(attributes);
|
||||||
if (type->is_integer_scalar_or_vector()) {
|
if (type->is_integer_scalar_or_vector()) {
|
||||||
return {InterpolationType::kFlat, InterpolationSampling::kNone};
|
return {InterpolationType::kFlat, InterpolationSampling::kNone};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!interpolation_decoration) {
|
if (!interpolation_attribute) {
|
||||||
return {InterpolationType::kPerspective, InterpolationSampling::kCenter};
|
return {InterpolationType::kPerspective, InterpolationSampling::kCenter};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto interpolation_type = interpolation_decoration->type;
|
auto interpolation_type = interpolation_attribute->type;
|
||||||
auto sampling = interpolation_decoration->sampling;
|
auto sampling = interpolation_attribute->sampling;
|
||||||
if (interpolation_type != ast::InterpolationType::kFlat &&
|
if (interpolation_type != ast::InterpolationType::kFlat &&
|
||||||
sampling == ast::InterpolationSampling::kNone) {
|
sampling == ast::InterpolationSampling::kNone) {
|
||||||
sampling = ast::InterpolationSampling::kCenter;
|
sampling = ast::InterpolationSampling::kCenter;
|
||||||
@ -157,34 +157,34 @@ std::vector<EntryPoint> Inspector::GetEntryPoints() {
|
|||||||
for (auto* param : sem->Parameters()) {
|
for (auto* param : sem->Parameters()) {
|
||||||
AddEntryPointInOutVariables(
|
AddEntryPointInOutVariables(
|
||||||
program_->Symbols().NameFor(param->Declaration()->symbol),
|
program_->Symbols().NameFor(param->Declaration()->symbol),
|
||||||
param->Type(), param->Declaration()->decorations,
|
param->Type(), param->Declaration()->attributes,
|
||||||
entry_point.input_variables);
|
entry_point.input_variables);
|
||||||
|
|
||||||
entry_point.input_position_used |=
|
entry_point.input_position_used |=
|
||||||
ContainsBuiltin(ast::Builtin::kPosition, param->Type(),
|
ContainsBuiltin(ast::Builtin::kPosition, param->Type(),
|
||||||
param->Declaration()->decorations);
|
param->Declaration()->attributes);
|
||||||
entry_point.front_facing_used |=
|
entry_point.front_facing_used |=
|
||||||
ContainsBuiltin(ast::Builtin::kFrontFacing, param->Type(),
|
ContainsBuiltin(ast::Builtin::kFrontFacing, param->Type(),
|
||||||
param->Declaration()->decorations);
|
param->Declaration()->attributes);
|
||||||
entry_point.sample_index_used |=
|
entry_point.sample_index_used |=
|
||||||
ContainsBuiltin(ast::Builtin::kSampleIndex, param->Type(),
|
ContainsBuiltin(ast::Builtin::kSampleIndex, param->Type(),
|
||||||
param->Declaration()->decorations);
|
param->Declaration()->attributes);
|
||||||
entry_point.input_sample_mask_used |=
|
entry_point.input_sample_mask_used |=
|
||||||
ContainsBuiltin(ast::Builtin::kSampleMask, param->Type(),
|
ContainsBuiltin(ast::Builtin::kSampleMask, param->Type(),
|
||||||
param->Declaration()->decorations);
|
param->Declaration()->attributes);
|
||||||
entry_point.num_workgroups_used |=
|
entry_point.num_workgroups_used |=
|
||||||
ContainsBuiltin(ast::Builtin::kNumWorkgroups, param->Type(),
|
ContainsBuiltin(ast::Builtin::kNumWorkgroups, param->Type(),
|
||||||
param->Declaration()->decorations);
|
param->Declaration()->attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sem->ReturnType()->Is<sem::Void>()) {
|
if (!sem->ReturnType()->Is<sem::Void>()) {
|
||||||
AddEntryPointInOutVariables("<retval>", sem->ReturnType(),
|
AddEntryPointInOutVariables("<retval>", sem->ReturnType(),
|
||||||
func->return_type_decorations,
|
func->return_type_attributes,
|
||||||
entry_point.output_variables);
|
entry_point.output_variables);
|
||||||
|
|
||||||
entry_point.output_sample_mask_used =
|
entry_point.output_sample_mask_used =
|
||||||
ContainsBuiltin(ast::Builtin::kSampleMask, sem->ReturnType(),
|
ContainsBuiltin(ast::Builtin::kSampleMask, sem->ReturnType(),
|
||||||
func->return_type_decorations);
|
func->return_type_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* var : sem->TransitivelyReferencedGlobals()) {
|
for (auto* var : sem->TransitivelyReferencedGlobals()) {
|
||||||
@ -213,10 +213,10 @@ std::vector<EntryPoint> Inspector::GetEntryPoints() {
|
|||||||
|
|
||||||
overridable_constant.is_initialized =
|
overridable_constant.is_initialized =
|
||||||
global->Declaration()->constructor;
|
global->Declaration()->constructor;
|
||||||
auto* override_deco = ast::GetDecoration<ast::OverrideDecoration>(
|
auto* override_attr = ast::GetAttribute<ast::OverrideAttribute>(
|
||||||
global->Declaration()->decorations);
|
global->Declaration()->attributes);
|
||||||
overridable_constant.is_numeric_id_specified =
|
overridable_constant.is_numeric_id_specified =
|
||||||
override_deco ? override_deco->has_value : false;
|
override_attr ? override_attr->has_value : false;
|
||||||
|
|
||||||
entry_point.overridable_constants.push_back(overridable_constant);
|
entry_point.overridable_constants.push_back(overridable_constant);
|
||||||
}
|
}
|
||||||
@ -579,10 +579,10 @@ const ast::Function* Inspector::FindEntryPointByName(const std::string& name) {
|
|||||||
void Inspector::AddEntryPointInOutVariables(
|
void Inspector::AddEntryPointInOutVariables(
|
||||||
std::string name,
|
std::string name,
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
const ast::DecorationList& decorations,
|
const ast::AttributeList& attributes,
|
||||||
std::vector<StageVariable>& variables) const {
|
std::vector<StageVariable>& variables) const {
|
||||||
// Skip builtins.
|
// Skip builtins.
|
||||||
if (ast::HasDecoration<ast::BuiltinDecoration>(decorations)) {
|
if (ast::HasAttribute<ast::BuiltinAttribute>(attributes)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,7 +594,7 @@ void Inspector::AddEntryPointInOutVariables(
|
|||||||
AddEntryPointInOutVariables(
|
AddEntryPointInOutVariables(
|
||||||
name + "." +
|
name + "." +
|
||||||
program_->Symbols().NameFor(member->Declaration()->symbol),
|
program_->Symbols().NameFor(member->Declaration()->symbol),
|
||||||
member->Type(), member->Declaration()->decorations, variables);
|
member->Type(), member->Declaration()->attributes, variables);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -606,28 +606,28 @@ void Inspector::AddEntryPointInOutVariables(
|
|||||||
std::tie(stage_variable.component_type, stage_variable.composition_type) =
|
std::tie(stage_variable.component_type, stage_variable.composition_type) =
|
||||||
CalculateComponentAndComposition(type);
|
CalculateComponentAndComposition(type);
|
||||||
|
|
||||||
auto* location = ast::GetDecoration<ast::LocationDecoration>(decorations);
|
auto* location = ast::GetAttribute<ast::LocationAttribute>(attributes);
|
||||||
TINT_ASSERT(Inspector, location != nullptr);
|
TINT_ASSERT(Inspector, location != nullptr);
|
||||||
stage_variable.has_location_decoration = true;
|
stage_variable.has_location_attribute = true;
|
||||||
stage_variable.location_decoration = location->value;
|
stage_variable.location_attribute = location->value;
|
||||||
|
|
||||||
std::tie(stage_variable.interpolation_type,
|
std::tie(stage_variable.interpolation_type,
|
||||||
stage_variable.interpolation_sampling) =
|
stage_variable.interpolation_sampling) =
|
||||||
CalculateInterpolationData(type, decorations);
|
CalculateInterpolationData(type, attributes);
|
||||||
|
|
||||||
variables.push_back(stage_variable);
|
variables.push_back(stage_variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Inspector::ContainsBuiltin(ast::Builtin builtin,
|
bool Inspector::ContainsBuiltin(ast::Builtin builtin,
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
const ast::DecorationList& decorations) const {
|
const ast::AttributeList& attributes) const {
|
||||||
auto* unwrapped_type = type->UnwrapRef();
|
auto* unwrapped_type = type->UnwrapRef();
|
||||||
|
|
||||||
if (auto* struct_ty = unwrapped_type->As<sem::Struct>()) {
|
if (auto* struct_ty = unwrapped_type->As<sem::Struct>()) {
|
||||||
// Recurse into members.
|
// Recurse into members.
|
||||||
for (auto* member : struct_ty->Members()) {
|
for (auto* member : struct_ty->Members()) {
|
||||||
if (ContainsBuiltin(builtin, member->Type(),
|
if (ContainsBuiltin(builtin, member->Type(),
|
||||||
member->Declaration()->decorations)) {
|
member->Declaration()->attributes)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -636,7 +636,7 @@ bool Inspector::ContainsBuiltin(ast::Builtin builtin,
|
|||||||
|
|
||||||
// Base case: check for builtin
|
// Base case: check for builtin
|
||||||
auto* builtin_declaration =
|
auto* builtin_declaration =
|
||||||
ast::GetDecoration<ast::BuiltinDecoration>(decorations);
|
ast::GetAttribute<ast::BuiltinAttribute>(attributes);
|
||||||
if (!builtin_declaration || builtin_declaration->builtin != builtin) {
|
if (!builtin_declaration || builtin_declaration->builtin != builtin) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -158,19 +158,19 @@ class Inspector {
|
|||||||
/// Otherwise, add the variable unless it is a builtin.
|
/// Otherwise, add the variable unless it is a builtin.
|
||||||
/// @param name the name of the variable being added
|
/// @param name the name of the variable being added
|
||||||
/// @param type the type of the variable
|
/// @param type the type of the variable
|
||||||
/// @param decorations the variable decorations
|
/// @param attributes the variable attributes
|
||||||
/// @param variables the list to add the variables to
|
/// @param variables the list to add the variables to
|
||||||
void AddEntryPointInOutVariables(std::string name,
|
void AddEntryPointInOutVariables(std::string name,
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
const ast::DecorationList& decorations,
|
const ast::AttributeList& attributes,
|
||||||
std::vector<StageVariable>& variables) const;
|
std::vector<StageVariable>& variables) const;
|
||||||
|
|
||||||
/// Recursively determine if the type contains builtin.
|
/// Recursively determine if the type contains builtin.
|
||||||
/// If `type` is a struct, recurse into members to check for the decoration.
|
/// If `type` is a struct, recurse into members to check for the attribute.
|
||||||
/// Otherwise, check `decorations` for the decoration.
|
/// Otherwise, check `attributes` for the attribute.
|
||||||
bool ContainsBuiltin(ast::Builtin builtin,
|
bool ContainsBuiltin(ast::Builtin builtin,
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
const ast::DecorationList& decorations) const;
|
const ast::AttributeList& attributes) const;
|
||||||
|
|
||||||
/// Gathers all the texture resource bindings of the given type for the given
|
/// Gathers all the texture resource bindings of the given type for the given
|
||||||
/// entry point.
|
/// entry point.
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/call_statement.h"
|
#include "src/ast/call_statement.h"
|
||||||
#include "src/ast/disable_validation_decoration.h"
|
#include "src/ast/disable_validation_attribute.h"
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
#include "src/ast/struct_block_decoration.h"
|
#include "src/ast/struct_block_attribute.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
#include "src/inspector/test_inspector_builder.h"
|
#include "src/inspector/test_inspector_builder.h"
|
||||||
#include "src/inspector/test_inspector_runner.h"
|
#include "src/inspector/test_inspector_runner.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
@ -172,7 +172,7 @@ TEST_F(InspectorGetEntryPointTest, NoEntryPoints) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
|
TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
|
||||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -190,13 +190,13 @@ TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
|
TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
|
||||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
MakeEmptyBodyFunction("bar",
|
MakeEmptyBodyFunction("bar",
|
||||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1)});
|
WorkgroupSize(1)});
|
||||||
|
|
||||||
// TODO(dsinclair): Update to run the namer transform when available.
|
// TODO(dsinclair): Update to run the namer transform when available.
|
||||||
|
|
||||||
@ -217,13 +217,12 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
|
|||||||
TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
|
TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
|
||||||
MakeEmptyBodyFunction("func", {});
|
MakeEmptyBodyFunction("func", {});
|
||||||
|
|
||||||
MakeCallerBodyFunction(
|
MakeCallerBodyFunction("foo", {"func"},
|
||||||
"foo", {"func"},
|
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
WorkgroupSize(1)});
|
||||||
WorkgroupSize(1)});
|
|
||||||
|
|
||||||
MakeCallerBodyFunction("bar", {"func"},
|
MakeCallerBodyFunction("bar", {"func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -245,8 +244,8 @@ TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
|
|||||||
|
|
||||||
TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
|
TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
|
||||||
MakeEmptyBodyFunction("foo",
|
MakeEmptyBodyFunction("foo",
|
||||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(8, 2, 1)});
|
WorkgroupSize(8, 2, 1)});
|
||||||
|
|
||||||
Inspector& inspector = Build();
|
Inspector& inspector = Build();
|
||||||
|
|
||||||
@ -282,7 +281,7 @@ TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
|
|||||||
MakeEmptyBodyFunction("func", {});
|
MakeEmptyBodyFunction("func", {});
|
||||||
|
|
||||||
MakeCallerBodyFunction("foo", {"func"},
|
MakeCallerBodyFunction("foo", {"func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -315,14 +314,14 @@ TEST_P(InspectorGetEntryPointComponentAndCompositionTest, Test) {
|
|||||||
|
|
||||||
ASSERT_EQ(1u, result[0].input_variables.size());
|
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||||
EXPECT_EQ("in_var", result[0].input_variables[0].name);
|
EXPECT_EQ("in_var", result[0].input_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||||
EXPECT_EQ(component, result[0].input_variables[0].component_type);
|
EXPECT_EQ(component, result[0].input_variables[0].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(1u, result[0].output_variables.size());
|
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||||
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||||
EXPECT_EQ(component, result[0].output_variables[0].component_type);
|
EXPECT_EQ(component, result[0].output_variables[0].component_type);
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
@ -351,28 +350,28 @@ TEST_F(InspectorGetEntryPointTest, MultipleInOutVariables) {
|
|||||||
|
|
||||||
ASSERT_EQ(3u, result[0].input_variables.size());
|
ASSERT_EQ(3u, result[0].input_variables.size());
|
||||||
EXPECT_EQ("in_var0", result[0].input_variables[0].name);
|
EXPECT_EQ("in_var0", result[0].input_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||||
EXPECT_EQ(InterpolationType::kFlat,
|
EXPECT_EQ(InterpolationType::kFlat,
|
||||||
result[0].input_variables[0].interpolation_type);
|
result[0].input_variables[0].interpolation_type);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
||||||
EXPECT_EQ("in_var1", result[0].input_variables[1].name);
|
EXPECT_EQ("in_var1", result[0].input_variables[1].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[1].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[1].has_location_attribute);
|
||||||
EXPECT_EQ(1u, result[0].input_variables[1].location_decoration);
|
EXPECT_EQ(1u, result[0].input_variables[1].location_attribute);
|
||||||
EXPECT_EQ(InterpolationType::kFlat,
|
EXPECT_EQ(InterpolationType::kFlat,
|
||||||
result[0].input_variables[1].interpolation_type);
|
result[0].input_variables[1].interpolation_type);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
|
||||||
EXPECT_EQ("in_var4", result[0].input_variables[2].name);
|
EXPECT_EQ("in_var4", result[0].input_variables[2].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[2].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[2].has_location_attribute);
|
||||||
EXPECT_EQ(4u, result[0].input_variables[2].location_decoration);
|
EXPECT_EQ(4u, result[0].input_variables[2].location_attribute);
|
||||||
EXPECT_EQ(InterpolationType::kFlat,
|
EXPECT_EQ(InterpolationType::kFlat,
|
||||||
result[0].input_variables[2].interpolation_type);
|
result[0].input_variables[2].interpolation_type);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(1u, result[0].output_variables.size());
|
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||||
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,30 +393,30 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutVariables) {
|
|||||||
|
|
||||||
ASSERT_EQ(1u, result[0].input_variables.size());
|
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||||
EXPECT_EQ("in_var_foo", result[0].input_variables[0].name);
|
EXPECT_EQ("in_var_foo", result[0].input_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||||
EXPECT_EQ(InterpolationType::kFlat,
|
EXPECT_EQ(InterpolationType::kFlat,
|
||||||
result[0].input_variables[0].interpolation_type);
|
result[0].input_variables[0].interpolation_type);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(1u, result[0].output_variables.size());
|
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||||
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(1u, result[1].input_variables.size());
|
ASSERT_EQ(1u, result[1].input_variables.size());
|
||||||
EXPECT_EQ("in_var_bar", result[1].input_variables[0].name);
|
EXPECT_EQ("in_var_bar", result[1].input_variables[0].name);
|
||||||
EXPECT_TRUE(result[1].input_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[1].input_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[1].input_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[1].input_variables[0].location_attribute);
|
||||||
EXPECT_EQ(InterpolationType::kFlat,
|
EXPECT_EQ(InterpolationType::kFlat,
|
||||||
result[1].input_variables[0].interpolation_type);
|
result[1].input_variables[0].interpolation_type);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(1u, result[1].output_variables.size());
|
ASSERT_EQ(1u, result[1].output_variables.size());
|
||||||
EXPECT_EQ("<retval>", result[1].output_variables[0].name);
|
EXPECT_EQ("<retval>", result[1].output_variables[0].name);
|
||||||
EXPECT_TRUE(result[1].output_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[1].output_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(1u, result[1].output_variables[0].location_decoration);
|
EXPECT_EQ(1u, result[1].output_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[1].output_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[1].output_variables[0].component_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,8 +436,8 @@ TEST_F(InspectorGetEntryPointTest, BuiltInsNotStageVariables) {
|
|||||||
|
|
||||||
ASSERT_EQ(1u, result[0].input_variables.size());
|
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||||
EXPECT_EQ("in_var1", result[0].input_variables[0].name);
|
EXPECT_EQ("in_var1", result[0].input_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[0].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(0u, result[0].output_variables.size());
|
ASSERT_EQ(0u, result[0].output_variables.size());
|
||||||
@ -457,22 +456,22 @@ TEST_F(InspectorGetEntryPointTest, InOutStruct) {
|
|||||||
|
|
||||||
ASSERT_EQ(2u, result[0].input_variables.size());
|
ASSERT_EQ(2u, result[0].input_variables.size());
|
||||||
EXPECT_EQ("param.a", result[0].input_variables[0].name);
|
EXPECT_EQ("param.a", result[0].input_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
||||||
EXPECT_EQ("param.b", result[0].input_variables[1].name);
|
EXPECT_EQ("param.b", result[0].input_variables[1].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[1].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[1].has_location_attribute);
|
||||||
EXPECT_EQ(1u, result[0].input_variables[1].location_decoration);
|
EXPECT_EQ(1u, result[0].input_variables[1].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(2u, result[0].output_variables.size());
|
ASSERT_EQ(2u, result[0].output_variables.size());
|
||||||
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
|
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
||||||
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
|
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
|
||||||
EXPECT_TRUE(result[0].output_variables[1].has_location_decoration);
|
EXPECT_TRUE(result[0].output_variables[1].has_location_attribute);
|
||||||
EXPECT_EQ(1u, result[0].output_variables[1].location_decoration);
|
EXPECT_EQ(1u, result[0].output_variables[1].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,22 +492,22 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutSharedStruct) {
|
|||||||
|
|
||||||
ASSERT_EQ(2u, result[0].output_variables.size());
|
ASSERT_EQ(2u, result[0].output_variables.size());
|
||||||
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
|
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
||||||
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
|
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
|
||||||
EXPECT_TRUE(result[0].output_variables[1].has_location_decoration);
|
EXPECT_TRUE(result[0].output_variables[1].has_location_attribute);
|
||||||
EXPECT_EQ(1u, result[0].output_variables[1].location_decoration);
|
EXPECT_EQ(1u, result[0].output_variables[1].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(2u, result[1].input_variables.size());
|
ASSERT_EQ(2u, result[1].input_variables.size());
|
||||||
EXPECT_EQ("param.a", result[1].input_variables[0].name);
|
EXPECT_EQ("param.a", result[1].input_variables[0].name);
|
||||||
EXPECT_TRUE(result[1].input_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[1].input_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[1].input_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[1].input_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[0].component_type);
|
||||||
EXPECT_EQ("param.b", result[1].input_variables[1].name);
|
EXPECT_EQ("param.b", result[1].input_variables[1].name);
|
||||||
EXPECT_TRUE(result[1].input_variables[1].has_location_decoration);
|
EXPECT_TRUE(result[1].input_variables[1].has_location_attribute);
|
||||||
EXPECT_EQ(1u, result[1].input_variables[1].location_decoration);
|
EXPECT_EQ(1u, result[1].input_variables[1].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[1].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[1].input_variables[1].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(0u, result[1].output_variables.size());
|
ASSERT_EQ(0u, result[1].output_variables.size());
|
||||||
@ -532,34 +531,34 @@ TEST_F(InspectorGetEntryPointTest, MixInOutVariablesAndStruct) {
|
|||||||
|
|
||||||
ASSERT_EQ(5u, result[0].input_variables.size());
|
ASSERT_EQ(5u, result[0].input_variables.size());
|
||||||
EXPECT_EQ("param_a.a", result[0].input_variables[0].name);
|
EXPECT_EQ("param_a.a", result[0].input_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].input_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[0].component_type);
|
||||||
EXPECT_EQ("param_a.b", result[0].input_variables[1].name);
|
EXPECT_EQ("param_a.b", result[0].input_variables[1].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[1].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[1].has_location_attribute);
|
||||||
EXPECT_EQ(1u, result[0].input_variables[1].location_decoration);
|
EXPECT_EQ(1u, result[0].input_variables[1].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[1].component_type);
|
||||||
EXPECT_EQ("param_b.a", result[0].input_variables[2].name);
|
EXPECT_EQ("param_b.a", result[0].input_variables[2].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[2].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[2].has_location_attribute);
|
||||||
EXPECT_EQ(2u, result[0].input_variables[2].location_decoration);
|
EXPECT_EQ(2u, result[0].input_variables[2].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].input_variables[2].component_type);
|
||||||
EXPECT_EQ("param_c", result[0].input_variables[3].name);
|
EXPECT_EQ("param_c", result[0].input_variables[3].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[3].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[3].has_location_attribute);
|
||||||
EXPECT_EQ(3u, result[0].input_variables[3].location_decoration);
|
EXPECT_EQ(3u, result[0].input_variables[3].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[3].component_type);
|
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[3].component_type);
|
||||||
EXPECT_EQ("param_d", result[0].input_variables[4].name);
|
EXPECT_EQ("param_d", result[0].input_variables[4].name);
|
||||||
EXPECT_TRUE(result[0].input_variables[4].has_location_decoration);
|
EXPECT_TRUE(result[0].input_variables[4].has_location_attribute);
|
||||||
EXPECT_EQ(4u, result[0].input_variables[4].location_decoration);
|
EXPECT_EQ(4u, result[0].input_variables[4].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[4].component_type);
|
EXPECT_EQ(ComponentType::kFloat, result[0].input_variables[4].component_type);
|
||||||
|
|
||||||
ASSERT_EQ(2u, result[0].output_variables.size());
|
ASSERT_EQ(2u, result[0].output_variables.size());
|
||||||
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
|
EXPECT_EQ("<retval>.a", result[0].output_variables[0].name);
|
||||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
EXPECT_TRUE(result[0].output_variables[0].has_location_attribute);
|
||||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
EXPECT_EQ(0u, result[0].output_variables[0].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[0].component_type);
|
||||||
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
|
EXPECT_EQ("<retval>.b", result[0].output_variables[1].name);
|
||||||
EXPECT_TRUE(result[0].output_variables[1].has_location_decoration);
|
EXPECT_TRUE(result[0].output_variables[1].has_location_attribute);
|
||||||
EXPECT_EQ(1u, result[0].output_variables[1].location_decoration);
|
EXPECT_EQ(1u, result[0].output_variables[1].location_attribute);
|
||||||
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
|
EXPECT_EQ(ComponentType::kUInt, result[0].output_variables[1].component_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1050,7 +1049,7 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_NoEntryPoints) {
|
|||||||
// TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass
|
// TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass
|
||||||
// through
|
// through
|
||||||
TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
|
TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
|
||||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kVertex),
|
Stage(ast::PipelineStage::kVertex),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1069,7 +1068,7 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
|
|||||||
// through
|
// through
|
||||||
TEST_F(InspectorGetRemappedNameForEntryPointTest,
|
TEST_F(InspectorGetRemappedNameForEntryPointTest,
|
||||||
DISABLED_MultipleEntryPoints) {
|
DISABLED_MultipleEntryPoints) {
|
||||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kVertex),
|
Stage(ast::PipelineStage::kVertex),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1077,8 +1076,8 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest,
|
|||||||
// available.
|
// available.
|
||||||
|
|
||||||
MakeEmptyBodyFunction("bar",
|
MakeEmptyBodyFunction("bar",
|
||||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1)});
|
WorkgroupSize(1)});
|
||||||
|
|
||||||
Inspector& inspector = Build();
|
Inspector& inspector = Build();
|
||||||
|
|
||||||
@ -1222,8 +1221,8 @@ TEST_F(InspectorGetConstantNameToIdMapTest, WithAndWithoutIds) {
|
|||||||
|
|
||||||
TEST_F(InspectorGetStorageSizeTest, Empty) {
|
TEST_F(InspectorGetStorageSizeTest, Empty) {
|
||||||
MakeEmptyBodyFunction("ep_func",
|
MakeEmptyBodyFunction("ep_func",
|
||||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1)});
|
WorkgroupSize(1)});
|
||||||
Inspector& inspector = Build();
|
Inspector& inspector = Build();
|
||||||
EXPECT_EQ(0u, inspector.GetStorageSize("ep_func"));
|
EXPECT_EQ(0u, inspector.GetStorageSize("ep_func"));
|
||||||
}
|
}
|
||||||
@ -1260,7 +1259,7 @@ TEST_F(InspectorGetStorageSizeTest, Simple_Struct) {
|
|||||||
{{0, ty.i32()}});
|
{{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"ub_func", "sb_func", "rosb_func"},
|
MakeCallerBodyFunction("ep_func", {"ub_func", "sb_func", "rosb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1),
|
WorkgroupSize(1),
|
||||||
});
|
});
|
||||||
@ -1299,7 +1298,7 @@ TEST_F(InspectorGetStorageSizeTest, StructVec3) {
|
|||||||
|
|
||||||
TEST_F(InspectorGetResourceBindingsTest, Empty) {
|
TEST_F(InspectorGetResourceBindingsTest, Empty) {
|
||||||
MakeCallerBodyFunction("ep_func", {},
|
MakeCallerBodyFunction("ep_func", {},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1353,7 +1352,7 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
|
|||||||
MakeCallerBodyFunction("ep_func",
|
MakeCallerBodyFunction("ep_func",
|
||||||
{"ub_func", "sb_func", "rosb_func", "s_func",
|
{"ub_func", "sb_func", "rosb_func", "s_func",
|
||||||
"cs_func", "depth_ms_func", "st_func"},
|
"cs_func", "depth_ms_func", "st_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1424,7 +1423,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonEntryPointFunc) {
|
|||||||
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1440,7 +1439,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple_NonStruct) {
|
|||||||
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.i32(), {});
|
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.i32(), {});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1465,7 +1464,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple_Struct) {
|
|||||||
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1492,7 +1491,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleMembers) {
|
|||||||
"ub_func", "foo_ub", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
|
"ub_func", "foo_ub", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1518,7 +1517,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingPadding) {
|
|||||||
{{0, ty.vec3<f32>()}});
|
{{0, ty.vec3<f32>()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1541,7 +1540,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonStructVec3) {
|
|||||||
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
|
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1582,7 +1581,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) {
|
|||||||
Func("ep_func", ast::VariableList(), ty.void_(),
|
Func("ep_func", ast::VariableList(), ty.void_(),
|
||||||
ast::StatementList{FuncCall("ub_foo_func"), FuncCall("ub_bar_func"),
|
ast::StatementList{FuncCall("ub_foo_func"), FuncCall("ub_bar_func"),
|
||||||
FuncCall("ub_baz_func"), Return()},
|
FuncCall("ub_baz_func"), Return()},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1621,14 +1620,14 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingArray) {
|
|||||||
"foo_type",
|
"foo_type",
|
||||||
{Member("0i32", ty.i32()),
|
{Member("0i32", ty.i32()),
|
||||||
Member("b", ty.array(ty.u32(), 4, /*stride*/ 16), {MemberAlign(16)})},
|
Member("b", ty.array(ty.u32(), 4, /*stride*/ 16), {MemberAlign(16)})},
|
||||||
{create<ast::StructBlockDecoration>()});
|
{create<ast::StructBlockAttribute>()});
|
||||||
|
|
||||||
AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
|
AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
|
||||||
|
|
||||||
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1651,7 +1650,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple_NonStruct) {
|
|||||||
MakePlainGlobalReferenceBodyFunction("sb_func", "foo_sb", ty.i32(), {});
|
MakePlainGlobalReferenceBodyFunction("sb_func", "foo_sb", ty.i32(), {});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1676,7 +1675,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple_Struct) {
|
|||||||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1706,7 +1705,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) {
|
|||||||
"sb_func", "foo_sb", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
|
"sb_func", "foo_sb", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1754,7 +1753,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
|
|||||||
FuncCall("sb_baz_func"),
|
FuncCall("sb_baz_func"),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1794,7 +1793,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
|
|||||||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1822,7 +1821,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
|
|||||||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1848,7 +1847,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) {
|
|||||||
{{0, ty.vec3<f32>()}});
|
{{0, ty.vec3<f32>()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1871,7 +1870,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, NonStructVec3) {
|
|||||||
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
|
MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
MakeCallerBodyFunction("ep_func", {"ub_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1896,7 +1895,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
|
|||||||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1914,7 +1913,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
|
|||||||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1963,7 +1962,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
|
|||||||
FuncCall("sb_baz_func"),
|
FuncCall("sb_baz_func"),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2006,7 +2005,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
|
|||||||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2035,7 +2034,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
|
|||||||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2060,7 +2059,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
|
|||||||
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
MakeCallerBodyFunction("ep_func", {"sb_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2080,7 +2079,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
|
|||||||
|
|
||||||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||||
"foo_coords", ty.f32(),
|
"foo_coords", ty.f32(),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2096,7 +2095,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
|
TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
|
||||||
MakeEmptyBodyFunction("ep_func", ast::DecorationList{
|
MakeEmptyBodyFunction("ep_func", ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2119,7 +2118,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
|
|||||||
"foo_coords", ty.f32(), {});
|
"foo_coords", ty.f32(), {});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"foo_func"},
|
MakeCallerBodyFunction("ep_func", {"foo_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2143,7 +2142,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
|
|||||||
|
|
||||||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||||
"foo_coords", ty.f32(),
|
"foo_coords", ty.f32(),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2162,7 +2161,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
|
|||||||
|
|
||||||
MakeComparisonSamplerReferenceBodyFunction(
|
MakeComparisonSamplerReferenceBodyFunction(
|
||||||
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
|
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2183,7 +2182,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
|
|||||||
|
|
||||||
MakeComparisonSamplerReferenceBodyFunction(
|
MakeComparisonSamplerReferenceBodyFunction(
|
||||||
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
|
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2200,7 +2199,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
|
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
|
||||||
MakeEmptyBodyFunction("ep_func", ast::DecorationList{
|
MakeEmptyBodyFunction("ep_func", ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2224,7 +2223,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
|
|||||||
"foo_depth", ty.f32(), {});
|
"foo_depth", ty.f32(), {});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"foo_func"},
|
MakeCallerBodyFunction("ep_func", {"foo_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2249,7 +2248,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
|
|||||||
|
|
||||||
MakeComparisonSamplerReferenceBodyFunction(
|
MakeComparisonSamplerReferenceBodyFunction(
|
||||||
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
|
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", ty.f32(),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2268,7 +2267,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
|
|||||||
|
|
||||||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||||
"foo_coords", ty.f32(),
|
"foo_coords", ty.f32(),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2281,7 +2280,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
|
TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
|
||||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2304,7 +2303,7 @@ TEST_P(InspectorGetSampledTextureResourceBindingsTestWithParam, textureSample) {
|
|||||||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||||
"foo_coords",
|
"foo_coords",
|
||||||
GetBaseType(GetParam().sampled_kind),
|
GetBaseType(GetParam().sampled_kind),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2363,7 +2362,7 @@ TEST_P(InspectorGetSampledArrayTextureResourceBindingsTestWithParam,
|
|||||||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||||
"foo_coords", "foo_array_index",
|
"foo_coords", "foo_array_index",
|
||||||
GetBaseType(GetParam().sampled_kind),
|
GetBaseType(GetParam().sampled_kind),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2408,7 +2407,7 @@ TEST_P(InspectorGetMultisampledTextureResourceBindingsTestWithParam,
|
|||||||
CallStmt(Call("textureLoad", "foo_texture", "foo_coords",
|
CallStmt(Call("textureLoad", "foo_texture", "foo_coords",
|
||||||
"foo_sample_index")),
|
"foo_sample_index")),
|
||||||
},
|
},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2451,7 +2450,7 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
inspector::ResourceBinding::SampledKind::kUInt}));
|
inspector::ResourceBinding::SampledKind::kUInt}));
|
||||||
|
|
||||||
TEST_F(InspectorGetMultisampledArrayTextureResourceBindingsTest, Empty) {
|
TEST_F(InspectorGetMultisampledArrayTextureResourceBindingsTest, Empty) {
|
||||||
MakeEmptyBodyFunction("foo", ast::DecorationList{
|
MakeEmptyBodyFunction("foo", ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2476,7 +2475,7 @@ TEST_P(InspectorGetMultisampledArrayTextureResourceBindingsTestWithParam,
|
|||||||
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
|
||||||
"foo_coords", "foo_array_index",
|
"foo_coords", "foo_array_index",
|
||||||
GetBaseType(GetParam().sampled_kind),
|
GetBaseType(GetParam().sampled_kind),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2512,7 +2511,7 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
inspector::ResourceBinding::SampledKind::kUInt}));
|
inspector::ResourceBinding::SampledKind::kUInt}));
|
||||||
|
|
||||||
TEST_F(InspectorGetStorageTextureResourceBindingsTest, Empty) {
|
TEST_F(InspectorGetStorageTextureResourceBindingsTest, Empty) {
|
||||||
MakeEmptyBodyFunction("ep", ast::DecorationList{
|
MakeEmptyBodyFunction("ep", ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2560,7 +2559,7 @@ TEST_P(InspectorGetStorageTextureResourceBindingsTestWithParam, Simple) {
|
|||||||
|
|
||||||
MakeStorageTextureBodyFunction(
|
MakeStorageTextureBodyFunction(
|
||||||
"ep", "st_var", dim_type,
|
"ep", "st_var", dim_type,
|
||||||
ast::DecorationList{Stage(ast::PipelineStage::kFragment)});
|
ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
|
||||||
|
|
||||||
Inspector& inspector = Build();
|
Inspector& inspector = Build();
|
||||||
|
|
||||||
@ -2649,7 +2648,7 @@ TEST_P(InspectorGetDepthTextureResourceBindingsTestWithParam,
|
|||||||
ast::StatementList{
|
ast::StatementList{
|
||||||
CallStmt(Call("textureDimensions", "dt")),
|
CallStmt(Call("textureDimensions", "dt")),
|
||||||
},
|
},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2693,7 +2692,7 @@ TEST_F(InspectorGetDepthMultisampledTextureResourceBindingsTest,
|
|||||||
ast::StatementList{
|
ast::StatementList{
|
||||||
CallStmt(Call("textureDimensions", "tex")),
|
CallStmt(Call("textureDimensions", "tex")),
|
||||||
},
|
},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2718,7 +2717,7 @@ TEST_F(InspectorGetExternalTextureResourceBindingsTest, Simple) {
|
|||||||
ast::StatementList{
|
ast::StatementList{
|
||||||
CallStmt(Call("textureDimensions", "et")),
|
CallStmt(Call("textureDimensions", "et")),
|
||||||
},
|
},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2996,8 +2995,8 @@ fn direct(@location(0) fragUV: vec2<f32>,
|
|||||||
|
|
||||||
TEST_F(InspectorGetWorkgroupStorageSizeTest, Empty) {
|
TEST_F(InspectorGetWorkgroupStorageSizeTest, Empty) {
|
||||||
MakeEmptyBodyFunction("ep_func",
|
MakeEmptyBodyFunction("ep_func",
|
||||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1)});
|
WorkgroupSize(1)});
|
||||||
Inspector& inspector = Build();
|
Inspector& inspector = Build();
|
||||||
EXPECT_EQ(0u, inspector.GetWorkgroupStorageSize("ep_func"));
|
EXPECT_EQ(0u, inspector.GetWorkgroupStorageSize("ep_func"));
|
||||||
}
|
}
|
||||||
@ -3007,7 +3006,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, Simple) {
|
|||||||
MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
|
MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"f32_func"},
|
MakeCallerBodyFunction("ep_func", {"f32_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1),
|
WorkgroupSize(1),
|
||||||
});
|
});
|
||||||
@ -3031,7 +3030,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, CompoundTypes) {
|
|||||||
MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
|
MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"wg_struct_func", "f32_func"},
|
MakeCallerBodyFunction("ep_func", {"wg_struct_func", "f32_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1),
|
WorkgroupSize(1),
|
||||||
});
|
});
|
||||||
@ -3048,7 +3047,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, AlignmentPadding) {
|
|||||||
{});
|
{});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"wg_func"},
|
MakeCallerBodyFunction("ep_func", {"wg_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1),
|
WorkgroupSize(1),
|
||||||
});
|
});
|
||||||
@ -3064,7 +3063,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, StructAlignment) {
|
|||||||
const auto* wg_struct_type = MakeStructTypeFromMembers(
|
const auto* wg_struct_type = MakeStructTypeFromMembers(
|
||||||
"WgStruct",
|
"WgStruct",
|
||||||
{MakeStructMember(0, ty.f32(),
|
{MakeStructMember(0, ty.f32(),
|
||||||
{create<ast::StructMemberAlignDecoration>(1024)})},
|
{create<ast::StructMemberAlignAttribute>(1024)})},
|
||||||
/*is_block=*/false);
|
/*is_block=*/false);
|
||||||
|
|
||||||
AddWorkgroupStorage("wg_struct_var", ty.Of(wg_struct_type));
|
AddWorkgroupStorage("wg_struct_var", ty.Of(wg_struct_type));
|
||||||
@ -3072,7 +3071,7 @@ TEST_F(InspectorGetWorkgroupStorageSizeTest, StructAlignment) {
|
|||||||
{{0, ty.f32()}});
|
{{0, ty.f32()}});
|
||||||
|
|
||||||
MakeCallerBodyFunction("ep_func", {"wg_struct_func"},
|
MakeCallerBodyFunction("ep_func", {"wg_struct_func"},
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1),
|
WorkgroupSize(1),
|
||||||
});
|
});
|
||||||
|
@ -29,14 +29,14 @@ InspectorBuilder::InspectorBuilder() = default;
|
|||||||
InspectorBuilder::~InspectorBuilder() = default;
|
InspectorBuilder::~InspectorBuilder() = default;
|
||||||
|
|
||||||
void InspectorBuilder::MakeEmptyBodyFunction(std::string name,
|
void InspectorBuilder::MakeEmptyBodyFunction(std::string name,
|
||||||
ast::DecorationList decorations) {
|
ast::AttributeList attributes) {
|
||||||
Func(name, ast::VariableList(), ty.void_(), ast::StatementList{Return()},
|
Func(name, ast::VariableList(), ty.void_(), ast::StatementList{Return()},
|
||||||
decorations);
|
attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
|
void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
|
||||||
std::vector<std::string> callees,
|
std::vector<std::string> callees,
|
||||||
ast::DecorationList decorations) {
|
ast::AttributeList attributes) {
|
||||||
ast::StatementList body;
|
ast::StatementList body;
|
||||||
body.reserve(callees.size() + 1);
|
body.reserve(callees.size() + 1);
|
||||||
for (auto callee : callees) {
|
for (auto callee : callees) {
|
||||||
@ -44,7 +44,7 @@ void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
|
|||||||
}
|
}
|
||||||
body.push_back(Return());
|
body.push_back(Return());
|
||||||
|
|
||||||
Func(caller, ast::VariableList(), ty.void_(), body, decorations);
|
Func(caller, ast::VariableList(), ty.void_(), body, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Struct* InspectorBuilder::MakeInOutStruct(
|
const ast::Struct* InspectorBuilder::MakeInOutStruct(
|
||||||
@ -65,13 +65,13 @@ const ast::Function* InspectorBuilder::MakePlainGlobalReferenceBodyFunction(
|
|||||||
std::string func,
|
std::string func,
|
||||||
std::string var,
|
std::string var,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::DecorationList decorations) {
|
ast::AttributeList attributes) {
|
||||||
ast::StatementList stmts;
|
ast::StatementList stmts;
|
||||||
stmts.emplace_back(Decl(Var("local_" + var, type)));
|
stmts.emplace_back(Decl(Var("local_" + var, type)));
|
||||||
stmts.emplace_back(Assign("local_" + var, var));
|
stmts.emplace_back(Assign("local_" + var, var));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func, ast::VariableList(), ty.void_(), stmts, decorations);
|
return Func(func, ast::VariableList(), ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InspectorBuilder::ContainsName(const std::vector<StageVariable>& vec,
|
bool InspectorBuilder::ContainsName(const std::vector<StageVariable>& vec,
|
||||||
@ -104,18 +104,18 @@ const ast::Struct* InspectorBuilder::MakeStructTypeFromMembers(
|
|||||||
const std::string& name,
|
const std::string& name,
|
||||||
ast::StructMemberList members,
|
ast::StructMemberList members,
|
||||||
bool is_block) {
|
bool is_block) {
|
||||||
ast::DecorationList decos;
|
ast::AttributeList attrs;
|
||||||
if (is_block) {
|
if (is_block) {
|
||||||
decos.push_back(create<ast::StructBlockDecoration>());
|
attrs.push_back(create<ast::StructBlockAttribute>());
|
||||||
}
|
}
|
||||||
return Structure(name, std::move(members), decos);
|
return Structure(name, std::move(members), attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::StructMember* InspectorBuilder::MakeStructMember(
|
const ast::StructMember* InspectorBuilder::MakeStructMember(
|
||||||
size_t index,
|
size_t index,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::DecorationList decorations) {
|
ast::AttributeList attributes) {
|
||||||
return Member(StructMemberName(index, type), type, std::move(decorations));
|
return Member(StructMemberName(index, type), type, std::move(attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Struct* InspectorBuilder::MakeUniformBufferType(
|
const ast::Struct* InspectorBuilder::MakeUniformBufferType(
|
||||||
@ -136,9 +136,9 @@ void InspectorBuilder::AddUniformBuffer(const std::string& name,
|
|||||||
uint32_t group,
|
uint32_t group,
|
||||||
uint32_t binding) {
|
uint32_t binding) {
|
||||||
Global(name, type, ast::StorageClass::kUniform,
|
Global(name, type, ast::StorageClass::kUniform,
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
create<ast::BindingDecoration>(binding),
|
create<ast::BindingAttribute>(binding),
|
||||||
create<ast::GroupDecoration>(group),
|
create<ast::GroupAttribute>(group),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,9 +153,9 @@ void InspectorBuilder::AddStorageBuffer(const std::string& name,
|
|||||||
uint32_t group,
|
uint32_t group,
|
||||||
uint32_t binding) {
|
uint32_t binding) {
|
||||||
Global(name, type, ast::StorageClass::kStorage, access,
|
Global(name, type, ast::StorageClass::kStorage, access,
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
create<ast::BindingDecoration>(binding),
|
create<ast::BindingAttribute>(binding),
|
||||||
create<ast::GroupDecoration>(group),
|
create<ast::GroupAttribute>(group),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,17 +185,16 @@ void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
|
|||||||
|
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
Func(func_name, ast::VariableList(), ty.void_(), stmts,
|
Func(func_name, ast::VariableList(), ty.void_(), stmts, ast::AttributeList{});
|
||||||
ast::DecorationList{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorBuilder::AddSampler(const std::string& name,
|
void InspectorBuilder::AddSampler(const std::string& name,
|
||||||
uint32_t group,
|
uint32_t group,
|
||||||
uint32_t binding) {
|
uint32_t binding) {
|
||||||
Global(name, sampler_type(),
|
Global(name, sampler_type(),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
create<ast::BindingDecoration>(binding),
|
create<ast::BindingAttribute>(binding),
|
||||||
create<ast::GroupDecoration>(group),
|
create<ast::GroupAttribute>(group),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,9 +202,9 @@ void InspectorBuilder::AddComparisonSampler(const std::string& name,
|
|||||||
uint32_t group,
|
uint32_t group,
|
||||||
uint32_t binding) {
|
uint32_t binding) {
|
||||||
Global(name, comparison_sampler_type(),
|
Global(name, comparison_sampler_type(),
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
create<ast::BindingDecoration>(binding),
|
create<ast::BindingAttribute>(binding),
|
||||||
create<ast::GroupDecoration>(group),
|
create<ast::GroupAttribute>(group),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,9 +213,9 @@ void InspectorBuilder::AddResource(const std::string& name,
|
|||||||
uint32_t group,
|
uint32_t group,
|
||||||
uint32_t binding) {
|
uint32_t binding) {
|
||||||
Global(name, type,
|
Global(name, type,
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
create<ast::BindingDecoration>(binding),
|
create<ast::BindingAttribute>(binding),
|
||||||
create<ast::GroupDecoration>(group),
|
create<ast::GroupAttribute>(group),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +230,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
|||||||
const std::string& sampler_name,
|
const std::string& sampler_name,
|
||||||
const std::string& coords_name,
|
const std::string& coords_name,
|
||||||
const ast::Type* base_type,
|
const ast::Type* base_type,
|
||||||
ast::DecorationList decorations) {
|
ast::AttributeList attributes) {
|
||||||
std::string result_name = "sampler_result";
|
std::string result_name = "sampler_result";
|
||||||
|
|
||||||
ast::StatementList stmts;
|
ast::StatementList stmts;
|
||||||
@ -241,7 +240,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
|||||||
sampler_name, coords_name)));
|
sampler_name, coords_name)));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations);
|
return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
||||||
@ -251,7 +250,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
|||||||
const std::string& coords_name,
|
const std::string& coords_name,
|
||||||
const std::string& array_index,
|
const std::string& array_index,
|
||||||
const ast::Type* base_type,
|
const ast::Type* base_type,
|
||||||
ast::DecorationList decorations) {
|
ast::AttributeList attributes) {
|
||||||
std::string result_name = "sampler_result";
|
std::string result_name = "sampler_result";
|
||||||
|
|
||||||
ast::StatementList stmts;
|
ast::StatementList stmts;
|
||||||
@ -263,7 +262,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
|||||||
coords_name, array_index)));
|
coords_name, array_index)));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations);
|
return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Function*
|
const ast::Function*
|
||||||
@ -274,7 +273,7 @@ InspectorBuilder::MakeComparisonSamplerReferenceBodyFunction(
|
|||||||
const std::string& coords_name,
|
const std::string& coords_name,
|
||||||
const std::string& depth_name,
|
const std::string& depth_name,
|
||||||
const ast::Type* base_type,
|
const ast::Type* base_type,
|
||||||
ast::DecorationList decorations) {
|
ast::AttributeList attributes) {
|
||||||
std::string result_name = "sampler_result";
|
std::string result_name = "sampler_result";
|
||||||
|
|
||||||
ast::StatementList stmts;
|
ast::StatementList stmts;
|
||||||
@ -285,7 +284,7 @@ InspectorBuilder::MakeComparisonSamplerReferenceBodyFunction(
|
|||||||
sampler_name, coords_name, depth_name)));
|
sampler_name, coords_name, depth_name)));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations);
|
return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Type* InspectorBuilder::GetBaseType(
|
const ast::Type* InspectorBuilder::GetBaseType(
|
||||||
@ -331,9 +330,9 @@ void InspectorBuilder::AddStorageTexture(const std::string& name,
|
|||||||
uint32_t group,
|
uint32_t group,
|
||||||
uint32_t binding) {
|
uint32_t binding) {
|
||||||
Global(name, type,
|
Global(name, type,
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
create<ast::BindingDecoration>(binding),
|
create<ast::BindingAttribute>(binding),
|
||||||
create<ast::GroupDecoration>(group),
|
create<ast::GroupAttribute>(group),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,14 +340,14 @@ const ast::Function* InspectorBuilder::MakeStorageTextureBodyFunction(
|
|||||||
const std::string& func_name,
|
const std::string& func_name,
|
||||||
const std::string& st_name,
|
const std::string& st_name,
|
||||||
const ast::Type* dim_type,
|
const ast::Type* dim_type,
|
||||||
ast::DecorationList decorations) {
|
ast::AttributeList attributes) {
|
||||||
ast::StatementList stmts;
|
ast::StatementList stmts;
|
||||||
|
|
||||||
stmts.emplace_back(Decl(Var("dim", dim_type)));
|
stmts.emplace_back(Decl(Var("dim", dim_type)));
|
||||||
stmts.emplace_back(Assign("dim", Call("textureDimensions", st_name)));
|
stmts.emplace_back(Assign("dim", Call("textureDimensions", st_name)));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations);
|
return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction(
|
std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction(
|
||||||
|
@ -21,11 +21,11 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/call_statement.h"
|
#include "src/ast/call_statement.h"
|
||||||
#include "src/ast/disable_validation_decoration.h"
|
#include "src/ast/disable_validation_attribute.h"
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
#include "src/ast/struct_block_decoration.h"
|
#include "src/ast/struct_block_attribute.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
#include "src/sem/depth_texture_type.h"
|
#include "src/sem/depth_texture_type.h"
|
||||||
#include "src/sem/external_texture_type.h"
|
#include "src/sem/external_texture_type.h"
|
||||||
@ -45,16 +45,16 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
|
|
||||||
/// Generates an empty function
|
/// Generates an empty function
|
||||||
/// @param name name of the function created
|
/// @param name name of the function created
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
void MakeEmptyBodyFunction(std::string name, ast::DecorationList decorations);
|
void MakeEmptyBodyFunction(std::string name, ast::AttributeList attributes);
|
||||||
|
|
||||||
/// Generates a function that calls other functions
|
/// Generates a function that calls other functions
|
||||||
/// @param caller name of the function created
|
/// @param caller name of the function created
|
||||||
/// @param callees names of the functions to be called
|
/// @param callees names of the functions to be called
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
void MakeCallerBodyFunction(std::string caller,
|
void MakeCallerBodyFunction(std::string caller,
|
||||||
std::vector<std::string> callees,
|
std::vector<std::string> callees,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList attributes);
|
||||||
|
|
||||||
/// Generates a struct that contains user-defined IO members
|
/// Generates a struct that contains user-defined IO members
|
||||||
/// @param name the name of the generated struct
|
/// @param name the name of the generated struct
|
||||||
@ -76,11 +76,11 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
/// @param name name of the function created
|
/// @param name name of the function created
|
||||||
/// @param inout_vars tuples of {in, out} that will be converted into out = in
|
/// @param inout_vars tuples of {in, out} that will be converted into out = in
|
||||||
/// calls in the function body
|
/// calls in the function body
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
void MakeInOutVariableBodyFunction(
|
void MakeInOutVariableBodyFunction(
|
||||||
std::string name,
|
std::string name,
|
||||||
std::vector<std::tuple<std::string, std::string>> inout_vars,
|
std::vector<std::tuple<std::string, std::string>> inout_vars,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList attributes);
|
||||||
|
|
||||||
// TODO(crbug.com/tint/697): Remove this.
|
// TODO(crbug.com/tint/697): Remove this.
|
||||||
/// Generates a function that references in/out variables and calls another
|
/// Generates a function that references in/out variables and calls another
|
||||||
@ -89,13 +89,13 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
/// @param callee name of the function to be called
|
/// @param callee name of the function to be called
|
||||||
/// @param inout_vars tuples of {in, out} that will be converted into out = in
|
/// @param inout_vars tuples of {in, out} that will be converted into out = in
|
||||||
/// calls in the function body
|
/// calls in the function body
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
/// @returns a function object
|
/// @returns a function object
|
||||||
const ast::Function* MakeInOutVariableCallerBodyFunction(
|
const ast::Function* MakeInOutVariableCallerBodyFunction(
|
||||||
std::string caller,
|
std::string caller,
|
||||||
std::string callee,
|
std::string callee,
|
||||||
std::vector<std::tuple<std::string, std::string>> inout_vars,
|
std::vector<std::tuple<std::string, std::string>> inout_vars,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList attributes);
|
||||||
|
|
||||||
/// Add a pipeline constant to the global variables, with a specific ID.
|
/// Add a pipeline constant to the global variables, with a specific ID.
|
||||||
/// @param name name of the variable to add
|
/// @param name name of the variable to add
|
||||||
@ -110,7 +110,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
const ast::Expression* constructor) {
|
const ast::Expression* constructor) {
|
||||||
return GlobalConst(name, type, constructor,
|
return GlobalConst(name, type, constructor,
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Override(id),
|
Override(id),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
const ast::Expression* constructor) {
|
const ast::Expression* constructor) {
|
||||||
return GlobalConst(name, type, constructor,
|
return GlobalConst(name, type, constructor,
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
Override(),
|
Override(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -136,13 +136,13 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
/// @param func name of the function created
|
/// @param func name of the function created
|
||||||
/// @param var name of the constant to be reference
|
/// @param var name of the constant to be reference
|
||||||
/// @param type type of the const being referenced
|
/// @param type type of the const being referenced
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
/// @returns a function object
|
/// @returns a function object
|
||||||
const ast::Function* MakePlainGlobalReferenceBodyFunction(
|
const ast::Function* MakePlainGlobalReferenceBodyFunction(
|
||||||
std::string func,
|
std::string func,
|
||||||
std::string var,
|
std::string var,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList attributes);
|
||||||
|
|
||||||
/// @param vec Vector of StageVariable to be searched
|
/// @param vec Vector of StageVariable to be searched
|
||||||
/// @param name Name to be searching for
|
/// @param name Name to be searching for
|
||||||
@ -177,11 +177,11 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
/// Generates a struct member with a specified index and type.
|
/// Generates a struct member with a specified index and type.
|
||||||
/// @param index index of the field within the struct
|
/// @param index index of the field within the struct
|
||||||
/// @param type the type of the member field
|
/// @param type the type of the member field
|
||||||
/// @param decorations a list of decorations to apply to the member field
|
/// @param attributes a list of attributes to apply to the member field
|
||||||
/// @returns a struct member
|
/// @returns a struct member
|
||||||
const ast::StructMember* MakeStructMember(size_t index,
|
const ast::StructMember* MakeStructMember(size_t index,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList attributes);
|
||||||
|
|
||||||
/// Generates types appropriate for using in an uniform buffer
|
/// Generates types appropriate for using in an uniform buffer
|
||||||
/// @param name name for the type
|
/// @param name name for the type
|
||||||
@ -270,7 +270,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
/// @param sampler_name name of the sampler to use
|
/// @param sampler_name name of the sampler to use
|
||||||
/// @param coords_name name of the coords variable to use
|
/// @param coords_name name of the coords variable to use
|
||||||
/// @param base_type sampler base type
|
/// @param base_type sampler base type
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
/// @returns a function that references all of the values specified
|
/// @returns a function that references all of the values specified
|
||||||
const ast::Function* MakeSamplerReferenceBodyFunction(
|
const ast::Function* MakeSamplerReferenceBodyFunction(
|
||||||
const std::string& func_name,
|
const std::string& func_name,
|
||||||
@ -278,7 +278,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
const std::string& sampler_name,
|
const std::string& sampler_name,
|
||||||
const std::string& coords_name,
|
const std::string& coords_name,
|
||||||
const ast::Type* base_type,
|
const ast::Type* base_type,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList attributes);
|
||||||
|
|
||||||
/// Generates a function that references a specific sampler variable
|
/// Generates a function that references a specific sampler variable
|
||||||
/// @param func_name name of the function created
|
/// @param func_name name of the function created
|
||||||
@ -287,7 +287,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
/// @param coords_name name of the coords variable to use
|
/// @param coords_name name of the coords variable to use
|
||||||
/// @param array_index name of the array index variable to use
|
/// @param array_index name of the array index variable to use
|
||||||
/// @param base_type sampler base type
|
/// @param base_type sampler base type
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
/// @returns a function that references all of the values specified
|
/// @returns a function that references all of the values specified
|
||||||
const ast::Function* MakeSamplerReferenceBodyFunction(
|
const ast::Function* MakeSamplerReferenceBodyFunction(
|
||||||
const std::string& func_name,
|
const std::string& func_name,
|
||||||
@ -296,7 +296,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
const std::string& coords_name,
|
const std::string& coords_name,
|
||||||
const std::string& array_index,
|
const std::string& array_index,
|
||||||
const ast::Type* base_type,
|
const ast::Type* base_type,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList attributes);
|
||||||
|
|
||||||
/// Generates a function that references a specific comparison sampler
|
/// Generates a function that references a specific comparison sampler
|
||||||
/// variable.
|
/// variable.
|
||||||
@ -306,7 +306,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
/// @param coords_name name of the coords variable to use
|
/// @param coords_name name of the coords variable to use
|
||||||
/// @param depth_name name of the depth reference to use
|
/// @param depth_name name of the depth reference to use
|
||||||
/// @param base_type sampler base type
|
/// @param base_type sampler base type
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
/// @returns a function that references all of the values specified
|
/// @returns a function that references all of the values specified
|
||||||
const ast::Function* MakeComparisonSamplerReferenceBodyFunction(
|
const ast::Function* MakeComparisonSamplerReferenceBodyFunction(
|
||||||
const std::string& func_name,
|
const std::string& func_name,
|
||||||
@ -315,7 +315,7 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
const std::string& coords_name,
|
const std::string& coords_name,
|
||||||
const std::string& depth_name,
|
const std::string& depth_name,
|
||||||
const ast::Type* base_type,
|
const ast::Type* base_type,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList attributes);
|
||||||
|
|
||||||
/// Gets an appropriate type for the data in a given texture type.
|
/// Gets an appropriate type for the data in a given texture type.
|
||||||
/// @param sampled_kind type of in the texture
|
/// @param sampled_kind type of in the texture
|
||||||
@ -351,13 +351,13 @@ class InspectorBuilder : public ProgramBuilder {
|
|||||||
/// @param func_name name of the function created
|
/// @param func_name name of the function created
|
||||||
/// @param st_name name of the storage texture to use
|
/// @param st_name name of the storage texture to use
|
||||||
/// @param dim_type type expected by textureDimensons to return
|
/// @param dim_type type expected by textureDimensons to return
|
||||||
/// @param decorations the function decorations
|
/// @param attributes the function attributes
|
||||||
/// @returns a function that references all of the values specified
|
/// @returns a function that references all of the values specified
|
||||||
const ast::Function* MakeStorageTextureBodyFunction(
|
const ast::Function* MakeStorageTextureBodyFunction(
|
||||||
const std::string& func_name,
|
const std::string& func_name,
|
||||||
const std::string& st_name,
|
const std::string& st_name,
|
||||||
const ast::Type* dim_type,
|
const ast::Type* dim_type,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList attributes);
|
||||||
|
|
||||||
/// Get a generator function that returns a type appropriate for a stage
|
/// Get a generator function that returns a type appropriate for a stage
|
||||||
/// variable with the given combination of component and composition type.
|
/// variable with the given combination of component and composition type.
|
||||||
|
@ -131,7 +131,7 @@ const ast::Statement* ProgramBuilder::WrapInStatement(
|
|||||||
const ast::Function* ProgramBuilder::WrapInFunction(
|
const ast::Function* ProgramBuilder::WrapInFunction(
|
||||||
const ast::StatementList stmts) {
|
const ast::StatementList stmts) {
|
||||||
return Func("test_function", {}, ty.void_(), std::move(stmts),
|
return Func("test_function", {}, ty.void_(), std::move(stmts),
|
||||||
{create<ast::StageDecoration>(ast::PipelineStage::kCompute),
|
{create<ast::StageAttribute>(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1, 1, 1)});
|
WorkgroupSize(1, 1, 1)});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/atomic.h"
|
#include "src/ast/atomic.h"
|
||||||
#include "src/ast/binary_expression.h"
|
#include "src/ast/binary_expression.h"
|
||||||
#include "src/ast/binding_decoration.h"
|
#include "src/ast/binding_attribute.h"
|
||||||
#include "src/ast/bitcast_expression.h"
|
#include "src/ast/bitcast_expression.h"
|
||||||
#include "src/ast/bool.h"
|
#include "src/ast/bool.h"
|
||||||
#include "src/ast/bool_literal_expression.h"
|
#include "src/ast/bool_literal_expression.h"
|
||||||
@ -35,7 +35,7 @@
|
|||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/depth_multisampled_texture.h"
|
#include "src/ast/depth_multisampled_texture.h"
|
||||||
#include "src/ast/depth_texture.h"
|
#include "src/ast/depth_texture.h"
|
||||||
#include "src/ast/disable_validation_decoration.h"
|
#include "src/ast/disable_validation_attribute.h"
|
||||||
#include "src/ast/discard_statement.h"
|
#include "src/ast/discard_statement.h"
|
||||||
#include "src/ast/external_texture.h"
|
#include "src/ast/external_texture.h"
|
||||||
#include "src/ast/f32.h"
|
#include "src/ast/f32.h"
|
||||||
@ -45,27 +45,27 @@
|
|||||||
#include "src/ast/i32.h"
|
#include "src/ast/i32.h"
|
||||||
#include "src/ast/if_statement.h"
|
#include "src/ast/if_statement.h"
|
||||||
#include "src/ast/index_accessor_expression.h"
|
#include "src/ast/index_accessor_expression.h"
|
||||||
#include "src/ast/interpolate_decoration.h"
|
#include "src/ast/interpolate_attribute.h"
|
||||||
#include "src/ast/invariant_decoration.h"
|
#include "src/ast/invariant_attribute.h"
|
||||||
#include "src/ast/loop_statement.h"
|
#include "src/ast/loop_statement.h"
|
||||||
#include "src/ast/matrix.h"
|
#include "src/ast/matrix.h"
|
||||||
#include "src/ast/member_accessor_expression.h"
|
#include "src/ast/member_accessor_expression.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
#include "src/ast/multisampled_texture.h"
|
#include "src/ast/multisampled_texture.h"
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/ast/phony_expression.h"
|
#include "src/ast/phony_expression.h"
|
||||||
#include "src/ast/pointer.h"
|
#include "src/ast/pointer.h"
|
||||||
#include "src/ast/return_statement.h"
|
#include "src/ast/return_statement.h"
|
||||||
#include "src/ast/sampled_texture.h"
|
#include "src/ast/sampled_texture.h"
|
||||||
#include "src/ast/sampler.h"
|
#include "src/ast/sampler.h"
|
||||||
#include "src/ast/sint_literal_expression.h"
|
#include "src/ast/sint_literal_expression.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
#include "src/ast/storage_texture.h"
|
#include "src/ast/storage_texture.h"
|
||||||
#include "src/ast/stride_decoration.h"
|
#include "src/ast/stride_attribute.h"
|
||||||
#include "src/ast/struct_block_decoration.h"
|
#include "src/ast/struct_block_attribute.h"
|
||||||
#include "src/ast/struct_member_align_decoration.h"
|
#include "src/ast/struct_member_align_attribute.h"
|
||||||
#include "src/ast/struct_member_offset_decoration.h"
|
#include "src/ast/struct_member_offset_attribute.h"
|
||||||
#include "src/ast/struct_member_size_decoration.h"
|
#include "src/ast/struct_member_size_attribute.h"
|
||||||
#include "src/ast/switch_statement.h"
|
#include "src/ast/switch_statement.h"
|
||||||
#include "src/ast/type_name.h"
|
#include "src/ast/type_name.h"
|
||||||
#include "src/ast/u32.h"
|
#include "src/ast/u32.h"
|
||||||
@ -74,7 +74,7 @@
|
|||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
#include "src/ast/vector.h"
|
#include "src/ast/vector.h"
|
||||||
#include "src/ast/void.h"
|
#include "src/ast/void.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
#include "src/program.h"
|
#include "src/program.h"
|
||||||
#include "src/program_id.h"
|
#include "src/program_id.h"
|
||||||
#include "src/sem/array.h"
|
#include "src/sem/array.h"
|
||||||
@ -131,13 +131,13 @@ class ProgramBuilder {
|
|||||||
ast::StorageClass storage = ast::StorageClass::kNone;
|
ast::StorageClass storage = ast::StorageClass::kNone;
|
||||||
ast::Access access = ast::Access::kUndefined;
|
ast::Access access = ast::Access::kUndefined;
|
||||||
const ast::Expression* constructor = nullptr;
|
const ast::Expression* constructor = nullptr;
|
||||||
ast::DecorationList decorations = {};
|
ast::AttributeList attributes = {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Set(ast::StorageClass sc) { storage = sc; }
|
void Set(ast::StorageClass sc) { storage = sc; }
|
||||||
void Set(ast::Access ac) { access = ac; }
|
void Set(ast::Access ac) { access = ac; }
|
||||||
void Set(const ast::Expression* c) { constructor = c; }
|
void Set(const ast::Expression* c) { constructor = c; }
|
||||||
void Set(const ast::DecorationList& l) { decorations = l; }
|
void Set(const ast::AttributeList& l) { attributes = l; }
|
||||||
|
|
||||||
template <typename FIRST, typename... ARGS>
|
template <typename FIRST, typename... ARGS>
|
||||||
void Apply(FIRST&& first, ARGS&&... args) {
|
void Apply(FIRST&& first, ARGS&&... args) {
|
||||||
@ -640,28 +640,28 @@ class ProgramBuilder {
|
|||||||
|
|
||||||
/// @param subtype the array element type
|
/// @param subtype the array element type
|
||||||
/// @param n the array size. nullptr represents a runtime-array
|
/// @param n the array size. nullptr represents a runtime-array
|
||||||
/// @param decos the optional decorations for the array
|
/// @param attrs the optional attributes for the array
|
||||||
/// @return the tint AST type for a array of size `n` of type `T`
|
/// @return the tint AST type for a array of size `n` of type `T`
|
||||||
template <typename EXPR = ast::Expression*>
|
template <typename EXPR = ast::Expression*>
|
||||||
const ast::Array* array(const ast::Type* subtype,
|
const ast::Array* array(const ast::Type* subtype,
|
||||||
EXPR&& n = nullptr,
|
EXPR&& n = nullptr,
|
||||||
ast::DecorationList decos = {}) const {
|
ast::AttributeList attrs = {}) const {
|
||||||
return builder->create<ast::Array>(
|
return builder->create<ast::Array>(
|
||||||
subtype, builder->Expr(std::forward<EXPR>(n)), decos);
|
subtype, builder->Expr(std::forward<EXPR>(n)), attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param source the Source of the node
|
/// @param source the Source of the node
|
||||||
/// @param subtype the array element type
|
/// @param subtype the array element type
|
||||||
/// @param n the array size. nullptr represents a runtime-array
|
/// @param n the array size. nullptr represents a runtime-array
|
||||||
/// @param decos the optional decorations for the array
|
/// @param attrs the optional attributes for the array
|
||||||
/// @return the tint AST type for a array of size `n` of type `T`
|
/// @return the tint AST type for a array of size `n` of type `T`
|
||||||
template <typename EXPR = ast::Expression*>
|
template <typename EXPR = ast::Expression*>
|
||||||
const ast::Array* array(const Source& source,
|
const ast::Array* array(const Source& source,
|
||||||
const ast::Type* subtype,
|
const ast::Type* subtype,
|
||||||
EXPR&& n = nullptr,
|
EXPR&& n = nullptr,
|
||||||
ast::DecorationList decos = {}) const {
|
ast::AttributeList attrs = {}) const {
|
||||||
return builder->create<ast::Array>(
|
return builder->create<ast::Array>(
|
||||||
source, subtype, builder->Expr(std::forward<EXPR>(n)), decos);
|
source, subtype, builder->Expr(std::forward<EXPR>(n)), attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param subtype the array element type
|
/// @param subtype the array element type
|
||||||
@ -672,11 +672,11 @@ class ProgramBuilder {
|
|||||||
const ast::Array* array(const ast::Type* subtype,
|
const ast::Array* array(const ast::Type* subtype,
|
||||||
EXPR&& n,
|
EXPR&& n,
|
||||||
uint32_t stride) const {
|
uint32_t stride) const {
|
||||||
ast::DecorationList decos;
|
ast::AttributeList attrs;
|
||||||
if (stride) {
|
if (stride) {
|
||||||
decos.emplace_back(builder->create<ast::StrideDecoration>(stride));
|
attrs.emplace_back(builder->create<ast::StrideAttribute>(stride));
|
||||||
}
|
}
|
||||||
return array(subtype, std::forward<EXPR>(n), std::move(decos));
|
return array(subtype, std::forward<EXPR>(n), std::move(attrs));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param source the Source of the node
|
/// @param source the Source of the node
|
||||||
@ -689,11 +689,11 @@ class ProgramBuilder {
|
|||||||
const ast::Type* subtype,
|
const ast::Type* subtype,
|
||||||
EXPR&& n,
|
EXPR&& n,
|
||||||
uint32_t stride) const {
|
uint32_t stride) const {
|
||||||
ast::DecorationList decos;
|
ast::AttributeList attrs;
|
||||||
if (stride) {
|
if (stride) {
|
||||||
decos.emplace_back(builder->create<ast::StrideDecoration>(stride));
|
attrs.emplace_back(builder->create<ast::StrideAttribute>(stride));
|
||||||
}
|
}
|
||||||
return array(source, subtype, std::forward<EXPR>(n), std::move(decos));
|
return array(source, subtype, std::forward<EXPR>(n), std::move(attrs));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @return the tint AST type for a runtime-sized array of type `T`
|
/// @return the tint AST type for a runtime-sized array of type `T`
|
||||||
@ -1322,7 +1322,7 @@ class ProgramBuilder {
|
|||||||
/// * ast::StorageClass - specifies the variable storage class
|
/// * ast::StorageClass - specifies the variable storage class
|
||||||
/// * ast::Access - specifies the variable's access control
|
/// * ast::Access - specifies the variable's access control
|
||||||
/// * ast::Expression* - specifies the variable's initializer expression
|
/// * ast::Expression* - specifies the variable's initializer expression
|
||||||
/// * ast::DecorationList - specifies the variable's decorations
|
/// * ast::AttributeList - specifies the variable's attributes
|
||||||
/// Note that repeated arguments of the same type will use the last argument's
|
/// Note that repeated arguments of the same type will use the last argument's
|
||||||
/// value.
|
/// value.
|
||||||
/// @returns a `ast::Variable` with the given name, type and additional
|
/// @returns a `ast::Variable` with the given name, type and additional
|
||||||
@ -1334,7 +1334,7 @@ class ProgramBuilder {
|
|||||||
VarOptionals opts(std::forward<OPTIONAL>(optional)...);
|
VarOptionals opts(std::forward<OPTIONAL>(optional)...);
|
||||||
return create<ast::Variable>(Sym(std::forward<NAME>(name)), opts.storage,
|
return create<ast::Variable>(Sym(std::forward<NAME>(name)), opts.storage,
|
||||||
opts.access, type, false, opts.constructor,
|
opts.access, type, false, opts.constructor,
|
||||||
std::move(opts.decorations));
|
std::move(opts.attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param source the variable source
|
/// @param source the variable source
|
||||||
@ -1345,7 +1345,7 @@ class ProgramBuilder {
|
|||||||
/// * ast::StorageClass - specifies the variable storage class
|
/// * ast::StorageClass - specifies the variable storage class
|
||||||
/// * ast::Access - specifies the variable's access control
|
/// * ast::Access - specifies the variable's access control
|
||||||
/// * ast::Expression* - specifies the variable's initializer expression
|
/// * ast::Expression* - specifies the variable's initializer expression
|
||||||
/// * ast::DecorationList - specifies the variable's decorations
|
/// * ast::AttributeList - specifies the variable's attributes
|
||||||
/// Note that repeated arguments of the same type will use the last argument's
|
/// Note that repeated arguments of the same type will use the last argument's
|
||||||
/// value.
|
/// value.
|
||||||
/// @returns a `ast::Variable` with the given name, storage and type
|
/// @returns a `ast::Variable` with the given name, storage and type
|
||||||
@ -1357,67 +1357,67 @@ class ProgramBuilder {
|
|||||||
VarOptionals opts(std::forward<OPTIONAL>(optional)...);
|
VarOptionals opts(std::forward<OPTIONAL>(optional)...);
|
||||||
return create<ast::Variable>(source, Sym(std::forward<NAME>(name)),
|
return create<ast::Variable>(source, Sym(std::forward<NAME>(name)),
|
||||||
opts.storage, opts.access, type, false,
|
opts.storage, opts.access, type, false,
|
||||||
opts.constructor, std::move(opts.decorations));
|
opts.constructor, std::move(opts.attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param name the variable name
|
/// @param name the variable name
|
||||||
/// @param type the variable type
|
/// @param type the variable type
|
||||||
/// @param constructor constructor expression
|
/// @param constructor constructor expression
|
||||||
/// @param decorations optional variable decorations
|
/// @param attributes optional variable attributes
|
||||||
/// @returns a constant `ast::Variable` with the given name and type
|
/// @returns a constant `ast::Variable` with the given name and type
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::Variable* Const(NAME&& name,
|
const ast::Variable* Const(NAME&& name,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
const ast::Expression* constructor,
|
const ast::Expression* constructor,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
return create<ast::Variable>(
|
return create<ast::Variable>(
|
||||||
Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
|
Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
|
||||||
ast::Access::kUndefined, type, true, constructor, decorations);
|
ast::Access::kUndefined, type, true, constructor, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param source the variable source
|
/// @param source the variable source
|
||||||
/// @param name the variable name
|
/// @param name the variable name
|
||||||
/// @param type the variable type
|
/// @param type the variable type
|
||||||
/// @param constructor constructor expression
|
/// @param constructor constructor expression
|
||||||
/// @param decorations optional variable decorations
|
/// @param attributes optional variable attributes
|
||||||
/// @returns a constant `ast::Variable` with the given name and type
|
/// @returns a constant `ast::Variable` with the given name and type
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::Variable* Const(const Source& source,
|
const ast::Variable* Const(const Source& source,
|
||||||
NAME&& name,
|
NAME&& name,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
const ast::Expression* constructor,
|
const ast::Expression* constructor,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
return create<ast::Variable>(
|
return create<ast::Variable>(
|
||||||
source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
|
source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
|
||||||
ast::Access::kUndefined, type, true, constructor, decorations);
|
ast::Access::kUndefined, type, true, constructor, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param name the parameter name
|
/// @param name the parameter name
|
||||||
/// @param type the parameter type
|
/// @param type the parameter type
|
||||||
/// @param decorations optional parameter decorations
|
/// @param attributes optional parameter attributes
|
||||||
/// @returns a constant `ast::Variable` with the given name and type
|
/// @returns a constant `ast::Variable` with the given name and type
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::Variable* Param(NAME&& name,
|
const ast::Variable* Param(NAME&& name,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
return create<ast::Variable>(
|
return create<ast::Variable>(
|
||||||
Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
|
Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
|
||||||
ast::Access::kUndefined, type, true, nullptr, decorations);
|
ast::Access::kUndefined, type, true, nullptr, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param source the parameter source
|
/// @param source the parameter source
|
||||||
/// @param name the parameter name
|
/// @param name the parameter name
|
||||||
/// @param type the parameter type
|
/// @param type the parameter type
|
||||||
/// @param decorations optional parameter decorations
|
/// @param attributes optional parameter attributes
|
||||||
/// @returns a constant `ast::Variable` with the given name and type
|
/// @returns a constant `ast::Variable` with the given name and type
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::Variable* Param(const Source& source,
|
const ast::Variable* Param(const Source& source,
|
||||||
NAME&& name,
|
NAME&& name,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
return create<ast::Variable>(
|
return create<ast::Variable>(
|
||||||
source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
|
source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
|
||||||
ast::Access::kUndefined, type, true, nullptr, decorations);
|
ast::Access::kUndefined, type, true, nullptr, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param name the variable name
|
/// @param name the variable name
|
||||||
@ -1427,7 +1427,7 @@ class ProgramBuilder {
|
|||||||
/// * ast::StorageClass - specifies the variable storage class
|
/// * ast::StorageClass - specifies the variable storage class
|
||||||
/// * ast::Access - specifies the variable's access control
|
/// * ast::Access - specifies the variable's access control
|
||||||
/// * ast::Expression* - specifies the variable's initializer expression
|
/// * ast::Expression* - specifies the variable's initializer expression
|
||||||
/// * ast::DecorationList - specifies the variable's decorations
|
/// * ast::AttributeList - specifies the variable's attributes
|
||||||
/// Note that repeated arguments of the same type will use the last argument's
|
/// Note that repeated arguments of the same type will use the last argument's
|
||||||
/// value.
|
/// value.
|
||||||
/// @returns a new `ast::Variable`, which is automatically registered as a
|
/// @returns a new `ast::Variable`, which is automatically registered as a
|
||||||
@ -1452,7 +1452,7 @@ class ProgramBuilder {
|
|||||||
/// * ast::StorageClass - specifies the variable storage class
|
/// * ast::StorageClass - specifies the variable storage class
|
||||||
/// * ast::Access - specifies the variable's access control
|
/// * ast::Access - specifies the variable's access control
|
||||||
/// * ast::Expression* - specifies the variable's initializer expression
|
/// * ast::Expression* - specifies the variable's initializer expression
|
||||||
/// * ast::DecorationList - specifies the variable's decorations
|
/// * ast::AttributeList - specifies the variable's attributes
|
||||||
/// Note that repeated arguments of the same type will use the last argument's
|
/// Note that repeated arguments of the same type will use the last argument's
|
||||||
/// value.
|
/// value.
|
||||||
/// @returns a new `ast::Variable`, which is automatically registered as a
|
/// @returns a new `ast::Variable`, which is automatically registered as a
|
||||||
@ -1471,7 +1471,7 @@ class ProgramBuilder {
|
|||||||
/// @param name the variable name
|
/// @param name the variable name
|
||||||
/// @param type the variable type
|
/// @param type the variable type
|
||||||
/// @param constructor constructor expression
|
/// @param constructor constructor expression
|
||||||
/// @param decorations optional variable decorations
|
/// @param attributes optional variable attributes
|
||||||
/// @returns a const `ast::Variable` constructed by calling Var() with the
|
/// @returns a const `ast::Variable` constructed by calling Var() with the
|
||||||
/// arguments of `args`, which is automatically registered as a global
|
/// arguments of `args`, which is automatically registered as a global
|
||||||
/// variable with the ast::Module.
|
/// variable with the ast::Module.
|
||||||
@ -1479,9 +1479,9 @@ class ProgramBuilder {
|
|||||||
const ast::Variable* GlobalConst(NAME&& name,
|
const ast::Variable* GlobalConst(NAME&& name,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
const ast::Expression* constructor,
|
const ast::Expression* constructor,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
auto* var = Const(std::forward<NAME>(name), type, constructor,
|
auto* var = Const(std::forward<NAME>(name), type, constructor,
|
||||||
std::move(decorations));
|
std::move(attributes));
|
||||||
AST().AddGlobalVariable(var);
|
AST().AddGlobalVariable(var);
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
@ -1490,7 +1490,7 @@ class ProgramBuilder {
|
|||||||
/// @param name the variable name
|
/// @param name the variable name
|
||||||
/// @param type the variable type
|
/// @param type the variable type
|
||||||
/// @param constructor constructor expression
|
/// @param constructor constructor expression
|
||||||
/// @param decorations optional variable decorations
|
/// @param attributes optional variable attributes
|
||||||
/// @returns a const `ast::Variable` constructed by calling Var() with the
|
/// @returns a const `ast::Variable` constructed by calling Var() with the
|
||||||
/// arguments of `args`, which is automatically registered as a global
|
/// arguments of `args`, which is automatically registered as a global
|
||||||
/// variable with the ast::Module.
|
/// variable with the ast::Module.
|
||||||
@ -1499,9 +1499,9 @@ class ProgramBuilder {
|
|||||||
NAME&& name,
|
NAME&& name,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
const ast::Expression* constructor,
|
const ast::Expression* constructor,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
auto* var = Const(source, std::forward<NAME>(name), type, constructor,
|
auto* var = Const(source, std::forward<NAME>(name), type, constructor,
|
||||||
std::move(decorations));
|
std::move(attributes));
|
||||||
AST().AddGlobalVariable(var);
|
AST().AddGlobalVariable(var);
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
@ -1747,71 +1747,71 @@ class ProgramBuilder {
|
|||||||
Expr(std::forward<IDX>(idx)));
|
Expr(std::forward<IDX>(idx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ast::StructMemberOffsetDecoration
|
/// Creates a ast::StructMemberOffsetAttribute
|
||||||
/// @param val the offset value
|
/// @param val the offset value
|
||||||
/// @returns the offset decoration pointer
|
/// @returns the offset attribute pointer
|
||||||
const ast::StructMemberOffsetDecoration* MemberOffset(uint32_t val) {
|
const ast::StructMemberOffsetAttribute* MemberOffset(uint32_t val) {
|
||||||
return create<ast::StructMemberOffsetDecoration>(source_, val);
|
return create<ast::StructMemberOffsetAttribute>(source_, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ast::StructMemberSizeDecoration
|
/// Creates a ast::StructMemberSizeAttribute
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param val the size value
|
/// @param val the size value
|
||||||
/// @returns the size decoration pointer
|
/// @returns the size attribute pointer
|
||||||
const ast::StructMemberSizeDecoration* MemberSize(const Source& source,
|
const ast::StructMemberSizeAttribute* MemberSize(const Source& source,
|
||||||
uint32_t val) {
|
uint32_t val) {
|
||||||
return create<ast::StructMemberSizeDecoration>(source, val);
|
return create<ast::StructMemberSizeAttribute>(source, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ast::StructMemberSizeDecoration
|
/// Creates a ast::StructMemberSizeAttribute
|
||||||
/// @param val the size value
|
/// @param val the size value
|
||||||
/// @returns the size decoration pointer
|
/// @returns the size attribute pointer
|
||||||
const ast::StructMemberSizeDecoration* MemberSize(uint32_t val) {
|
const ast::StructMemberSizeAttribute* MemberSize(uint32_t val) {
|
||||||
return create<ast::StructMemberSizeDecoration>(source_, val);
|
return create<ast::StructMemberSizeAttribute>(source_, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ast::StructMemberAlignDecoration
|
/// Creates a ast::StructMemberAlignAttribute
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param val the align value
|
/// @param val the align value
|
||||||
/// @returns the align decoration pointer
|
/// @returns the align attribute pointer
|
||||||
const ast::StructMemberAlignDecoration* MemberAlign(const Source& source,
|
const ast::StructMemberAlignAttribute* MemberAlign(const Source& source,
|
||||||
uint32_t val) {
|
uint32_t val) {
|
||||||
return create<ast::StructMemberAlignDecoration>(source, val);
|
return create<ast::StructMemberAlignAttribute>(source, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ast::StructMemberAlignDecoration
|
/// Creates a ast::StructMemberAlignAttribute
|
||||||
/// @param val the align value
|
/// @param val the align value
|
||||||
/// @returns the align decoration pointer
|
/// @returns the align attribute pointer
|
||||||
const ast::StructMemberAlignDecoration* MemberAlign(uint32_t val) {
|
const ast::StructMemberAlignAttribute* MemberAlign(uint32_t val) {
|
||||||
return create<ast::StructMemberAlignDecoration>(source_, val);
|
return create<ast::StructMemberAlignAttribute>(source_, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ast::StructBlockDecoration
|
/// Creates a ast::StructBlockAttribute
|
||||||
/// @returns the struct block decoration pointer
|
/// @returns the struct block attribute pointer
|
||||||
const ast::StructBlockDecoration* StructBlock() {
|
const ast::StructBlockAttribute* StructBlock() {
|
||||||
return create<ast::StructBlockDecoration>();
|
return create<ast::StructBlockAttribute>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the ast::GroupDecoration
|
/// Creates the ast::GroupAttribute
|
||||||
/// @param value group decoration index
|
/// @param value group attribute index
|
||||||
/// @returns the group decoration pointer
|
/// @returns the group attribute pointer
|
||||||
const ast::GroupDecoration* Group(uint32_t value) {
|
const ast::GroupAttribute* Group(uint32_t value) {
|
||||||
return create<ast::GroupDecoration>(value);
|
return create<ast::GroupAttribute>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the ast::BindingDecoration
|
/// Creates the ast::BindingAttribute
|
||||||
/// @param value the binding index
|
/// @param value the binding index
|
||||||
/// @returns the binding deocration pointer
|
/// @returns the binding deocration pointer
|
||||||
const ast::BindingDecoration* Binding(uint32_t value) {
|
const ast::BindingAttribute* Binding(uint32_t value) {
|
||||||
return create<ast::BindingDecoration>(value);
|
return create<ast::BindingAttribute>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function to create both a ast::GroupDecoration and
|
/// Convenience function to create both a ast::GroupAttribute and
|
||||||
/// ast::BindingDecoration
|
/// ast::BindingAttribute
|
||||||
/// @param group the group index
|
/// @param group the group index
|
||||||
/// @param binding the binding index
|
/// @param binding the binding index
|
||||||
/// @returns a decoration list with both the group and binding decorations
|
/// @returns a attribute list with both the group and binding attributes
|
||||||
ast::DecorationList GroupAndBinding(uint32_t group, uint32_t binding) {
|
ast::AttributeList GroupAndBinding(uint32_t group, uint32_t binding) {
|
||||||
return {Group(group), Binding(binding)};
|
return {Group(group), Binding(binding)};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1821,9 +1821,9 @@ class ProgramBuilder {
|
|||||||
/// @param params the function parameters
|
/// @param params the function parameters
|
||||||
/// @param type the function return type
|
/// @param type the function return type
|
||||||
/// @param body the function body
|
/// @param body the function body
|
||||||
/// @param decorations the optional function decorations
|
/// @param attributes the optional function attributes
|
||||||
/// @param return_type_decorations the optional function return type
|
/// @param return_type_attributes the optional function return type
|
||||||
/// decorations
|
/// attributes
|
||||||
/// @returns the function pointer
|
/// @returns the function pointer
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::Function* Func(const Source& source,
|
const ast::Function* Func(const Source& source,
|
||||||
@ -1831,12 +1831,11 @@ class ProgramBuilder {
|
|||||||
ast::VariableList params,
|
ast::VariableList params,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::StatementList body,
|
ast::StatementList body,
|
||||||
ast::DecorationList decorations = {},
|
ast::AttributeList attributes = {},
|
||||||
ast::DecorationList return_type_decorations = {}) {
|
ast::AttributeList return_type_attributes = {}) {
|
||||||
auto* func =
|
auto* func = create<ast::Function>(
|
||||||
create<ast::Function>(source, Sym(std::forward<NAME>(name)), params,
|
source, Sym(std::forward<NAME>(name)), params, type,
|
||||||
type, create<ast::BlockStatement>(body),
|
create<ast::BlockStatement>(body), attributes, return_type_attributes);
|
||||||
decorations, return_type_decorations);
|
|
||||||
AST().AddFunction(func);
|
AST().AddFunction(func);
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
@ -1846,20 +1845,20 @@ class ProgramBuilder {
|
|||||||
/// @param params the function parameters
|
/// @param params the function parameters
|
||||||
/// @param type the function return type
|
/// @param type the function return type
|
||||||
/// @param body the function body
|
/// @param body the function body
|
||||||
/// @param decorations the optional function decorations
|
/// @param attributes the optional function attributes
|
||||||
/// @param return_type_decorations the optional function return type
|
/// @param return_type_attributes the optional function return type
|
||||||
/// decorations
|
/// attributes
|
||||||
/// @returns the function pointer
|
/// @returns the function pointer
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::Function* Func(NAME&& name,
|
const ast::Function* Func(NAME&& name,
|
||||||
ast::VariableList params,
|
ast::VariableList params,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::StatementList body,
|
ast::StatementList body,
|
||||||
ast::DecorationList decorations = {},
|
ast::AttributeList attributes = {},
|
||||||
ast::DecorationList return_type_decorations = {}) {
|
ast::AttributeList return_type_attributes = {}) {
|
||||||
auto* func = create<ast::Function>(Sym(std::forward<NAME>(name)), params,
|
auto* func = create<ast::Function>(Sym(std::forward<NAME>(name)), params,
|
||||||
type, create<ast::BlockStatement>(body),
|
type, create<ast::BlockStatement>(body),
|
||||||
decorations, return_type_decorations);
|
attributes, return_type_attributes);
|
||||||
AST().AddFunction(func);
|
AST().AddFunction(func);
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
@ -1960,16 +1959,16 @@ class ProgramBuilder {
|
|||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param name the struct name
|
/// @param name the struct name
|
||||||
/// @param members the struct members
|
/// @param members the struct members
|
||||||
/// @param decorations the optional struct decorations
|
/// @param attributes the optional struct attributes
|
||||||
/// @returns the struct type
|
/// @returns the struct type
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::Struct* Structure(const Source& source,
|
const ast::Struct* Structure(const Source& source,
|
||||||
NAME&& name,
|
NAME&& name,
|
||||||
ast::StructMemberList members,
|
ast::StructMemberList members,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
auto sym = Sym(std::forward<NAME>(name));
|
auto sym = Sym(std::forward<NAME>(name));
|
||||||
auto* type = create<ast::Struct>(source, sym, std::move(members),
|
auto* type = create<ast::Struct>(source, sym, std::move(members),
|
||||||
std::move(decorations));
|
std::move(attributes));
|
||||||
AST().AddTypeDecl(type);
|
AST().AddTypeDecl(type);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@ -1977,15 +1976,15 @@ class ProgramBuilder {
|
|||||||
/// Creates a ast::Struct registering it with the AST().TypeDecls().
|
/// Creates a ast::Struct registering it with the AST().TypeDecls().
|
||||||
/// @param name the struct name
|
/// @param name the struct name
|
||||||
/// @param members the struct members
|
/// @param members the struct members
|
||||||
/// @param decorations the optional struct decorations
|
/// @param attributes the optional struct attributes
|
||||||
/// @returns the struct type
|
/// @returns the struct type
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::Struct* Structure(NAME&& name,
|
const ast::Struct* Structure(NAME&& name,
|
||||||
ast::StructMemberList members,
|
ast::StructMemberList members,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
auto sym = Sym(std::forward<NAME>(name));
|
auto sym = Sym(std::forward<NAME>(name));
|
||||||
auto* type =
|
auto* type =
|
||||||
create<ast::Struct>(sym, std::move(members), std::move(decorations));
|
create<ast::Struct>(sym, std::move(members), std::move(attributes));
|
||||||
AST().AddTypeDecl(type);
|
AST().AddTypeDecl(type);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@ -1994,32 +1993,32 @@ class ProgramBuilder {
|
|||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param name the struct member name
|
/// @param name the struct member name
|
||||||
/// @param type the struct member type
|
/// @param type the struct member type
|
||||||
/// @param decorations the optional struct member decorations
|
/// @param attributes the optional struct member attributes
|
||||||
/// @returns the struct member pointer
|
/// @returns the struct member pointer
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::StructMember* Member(const Source& source,
|
const ast::StructMember* Member(const Source& source,
|
||||||
NAME&& name,
|
NAME&& name,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
return create<ast::StructMember>(source, Sym(std::forward<NAME>(name)),
|
return create<ast::StructMember>(source, Sym(std::forward<NAME>(name)),
|
||||||
type, std::move(decorations));
|
type, std::move(attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ast::StructMember
|
/// Creates a ast::StructMember
|
||||||
/// @param name the struct member name
|
/// @param name the struct member name
|
||||||
/// @param type the struct member type
|
/// @param type the struct member type
|
||||||
/// @param decorations the optional struct member decorations
|
/// @param attributes the optional struct member attributes
|
||||||
/// @returns the struct member pointer
|
/// @returns the struct member pointer
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::StructMember* Member(NAME&& name,
|
const ast::StructMember* Member(NAME&& name,
|
||||||
const ast::Type* type,
|
const ast::Type* type,
|
||||||
ast::DecorationList decorations = {}) {
|
ast::AttributeList attributes = {}) {
|
||||||
return create<ast::StructMember>(source_, Sym(std::forward<NAME>(name)),
|
return create<ast::StructMember>(source_, Sym(std::forward<NAME>(name)),
|
||||||
type, std::move(decorations));
|
type, std::move(attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ast::StructMember with the given byte offset
|
/// Creates a ast::StructMember with the given byte offset
|
||||||
/// @param offset the offset to use in the StructMemberOffsetDecoration
|
/// @param offset the offset to use in the StructMemberOffsetattribute
|
||||||
/// @param name the struct member name
|
/// @param name the struct member name
|
||||||
/// @param type the struct member type
|
/// @param type the struct member type
|
||||||
/// @returns the struct member pointer
|
/// @returns the struct member pointer
|
||||||
@ -2029,8 +2028,8 @@ class ProgramBuilder {
|
|||||||
const ast::Type* type) {
|
const ast::Type* type) {
|
||||||
return create<ast::StructMember>(
|
return create<ast::StructMember>(
|
||||||
source_, Sym(std::forward<NAME>(name)), type,
|
source_, Sym(std::forward<NAME>(name)), type,
|
||||||
ast::DecorationList{
|
ast::AttributeList{
|
||||||
create<ast::StructMemberOffsetDecoration>(offset),
|
create<ast::StructMemberOffsetAttribute>(offset),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2276,183 +2275,182 @@ class ProgramBuilder {
|
|||||||
return create<ast::FallthroughStatement>();
|
return create<ast::FallthroughStatement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::BuiltinDecoration
|
/// Creates an ast::BuiltinAttribute
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param builtin the builtin value
|
/// @param builtin the builtin value
|
||||||
/// @returns the builtin decoration pointer
|
/// @returns the builtin attribute pointer
|
||||||
const ast::BuiltinDecoration* Builtin(const Source& source,
|
const ast::BuiltinAttribute* Builtin(const Source& source,
|
||||||
ast::Builtin builtin) {
|
ast::Builtin builtin) {
|
||||||
return create<ast::BuiltinDecoration>(source, builtin);
|
return create<ast::BuiltinAttribute>(source, builtin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::BuiltinDecoration
|
/// Creates an ast::BuiltinAttribute
|
||||||
/// @param builtin the builtin value
|
/// @param builtin the builtin value
|
||||||
/// @returns the builtin decoration pointer
|
/// @returns the builtin attribute pointer
|
||||||
const ast::BuiltinDecoration* Builtin(ast::Builtin builtin) {
|
const ast::BuiltinAttribute* Builtin(ast::Builtin builtin) {
|
||||||
return create<ast::BuiltinDecoration>(source_, builtin);
|
return create<ast::BuiltinAttribute>(source_, builtin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::InterpolateDecoration
|
/// Creates an ast::InterpolateAttribute
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param type the interpolation type
|
/// @param type the interpolation type
|
||||||
/// @param sampling the interpolation sampling
|
/// @param sampling the interpolation sampling
|
||||||
/// @returns the interpolate decoration pointer
|
/// @returns the interpolate attribute pointer
|
||||||
const ast::InterpolateDecoration* Interpolate(
|
const ast::InterpolateAttribute* Interpolate(
|
||||||
const Source& source,
|
const Source& source,
|
||||||
ast::InterpolationType type,
|
ast::InterpolationType type,
|
||||||
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone) {
|
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone) {
|
||||||
return create<ast::InterpolateDecoration>(source, type, sampling);
|
return create<ast::InterpolateAttribute>(source, type, sampling);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::InterpolateDecoration
|
/// Creates an ast::InterpolateAttribute
|
||||||
/// @param type the interpolation type
|
/// @param type the interpolation type
|
||||||
/// @param sampling the interpolation sampling
|
/// @param sampling the interpolation sampling
|
||||||
/// @returns the interpolate decoration pointer
|
/// @returns the interpolate attribute pointer
|
||||||
const ast::InterpolateDecoration* Interpolate(
|
const ast::InterpolateAttribute* Interpolate(
|
||||||
ast::InterpolationType type,
|
ast::InterpolationType type,
|
||||||
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone) {
|
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone) {
|
||||||
return create<ast::InterpolateDecoration>(source_, type, sampling);
|
return create<ast::InterpolateAttribute>(source_, type, sampling);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::InterpolateDecoration using flat interpolation
|
/// Creates an ast::InterpolateAttribute using flat interpolation
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @returns the interpolate decoration pointer
|
/// @returns the interpolate attribute pointer
|
||||||
const ast::InterpolateDecoration* Flat(const Source& source) {
|
const ast::InterpolateAttribute* Flat(const Source& source) {
|
||||||
return Interpolate(source, ast::InterpolationType::kFlat);
|
return Interpolate(source, ast::InterpolationType::kFlat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::InterpolateDecoration using flat interpolation
|
/// Creates an ast::InterpolateAttribute using flat interpolation
|
||||||
/// @returns the interpolate decoration pointer
|
/// @returns the interpolate attribute pointer
|
||||||
const ast::InterpolateDecoration* Flat() {
|
const ast::InterpolateAttribute* Flat() {
|
||||||
return Interpolate(ast::InterpolationType::kFlat);
|
return Interpolate(ast::InterpolationType::kFlat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::InvariantDecoration
|
/// Creates an ast::InvariantAttribute
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @returns the invariant decoration pointer
|
/// @returns the invariant attribute pointer
|
||||||
const ast::InvariantDecoration* Invariant(const Source& source) {
|
const ast::InvariantAttribute* Invariant(const Source& source) {
|
||||||
return create<ast::InvariantDecoration>(source);
|
return create<ast::InvariantAttribute>(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::InvariantDecoration
|
/// Creates an ast::InvariantAttribute
|
||||||
/// @returns the invariant decoration pointer
|
/// @returns the invariant attribute pointer
|
||||||
const ast::InvariantDecoration* Invariant() {
|
const ast::InvariantAttribute* Invariant() {
|
||||||
return create<ast::InvariantDecoration>(source_);
|
return create<ast::InvariantAttribute>(source_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::LocationDecoration
|
/// Creates an ast::LocationAttribute
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param location the location value
|
/// @param location the location value
|
||||||
/// @returns the location decoration pointer
|
/// @returns the location attribute pointer
|
||||||
const ast::LocationDecoration* Location(const Source& source,
|
const ast::LocationAttribute* Location(const Source& source,
|
||||||
uint32_t location) {
|
uint32_t location) {
|
||||||
return create<ast::LocationDecoration>(source, location);
|
return create<ast::LocationAttribute>(source, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::LocationDecoration
|
/// Creates an ast::LocationAttribute
|
||||||
/// @param location the location value
|
/// @param location the location value
|
||||||
/// @returns the location decoration pointer
|
/// @returns the location attribute pointer
|
||||||
const ast::LocationDecoration* Location(uint32_t location) {
|
const ast::LocationAttribute* Location(uint32_t location) {
|
||||||
return create<ast::LocationDecoration>(source_, location);
|
return create<ast::LocationAttribute>(source_, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::OverrideDecoration with a specific constant ID
|
/// Creates an ast::OverrideAttribute with a specific constant ID
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param id the id value
|
/// @param id the id value
|
||||||
/// @returns the override decoration pointer
|
/// @returns the override attribute pointer
|
||||||
const ast::OverrideDecoration* Override(const Source& source, uint32_t id) {
|
const ast::OverrideAttribute* Override(const Source& source, uint32_t id) {
|
||||||
return create<ast::OverrideDecoration>(source, id);
|
return create<ast::OverrideAttribute>(source, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::OverrideDecoration with a specific constant ID
|
/// Creates an ast::OverrideAttribute with a specific constant ID
|
||||||
/// @param id the optional id value
|
/// @param id the optional id value
|
||||||
/// @returns the override decoration pointer
|
/// @returns the override attribute pointer
|
||||||
const ast::OverrideDecoration* Override(uint32_t id) {
|
const ast::OverrideAttribute* Override(uint32_t id) {
|
||||||
return Override(source_, id);
|
return Override(source_, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::OverrideDecoration without a constant ID
|
/// Creates an ast::OverrideAttribute without a constant ID
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @returns the override decoration pointer
|
/// @returns the override attribute pointer
|
||||||
const ast::OverrideDecoration* Override(const Source& source) {
|
const ast::OverrideAttribute* Override(const Source& source) {
|
||||||
return create<ast::OverrideDecoration>(source);
|
return create<ast::OverrideAttribute>(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::OverrideDecoration without a constant ID
|
/// Creates an ast::OverrideAttribute without a constant ID
|
||||||
/// @returns the override decoration pointer
|
/// @returns the override attribute pointer
|
||||||
const ast::OverrideDecoration* Override() { return Override(source_); }
|
const ast::OverrideAttribute* Override() { return Override(source_); }
|
||||||
|
|
||||||
/// Creates an ast::StageDecoration
|
/// Creates an ast::StageAttribute
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param stage the pipeline stage
|
/// @param stage the pipeline stage
|
||||||
/// @returns the stage decoration pointer
|
/// @returns the stage attribute pointer
|
||||||
const ast::StageDecoration* Stage(const Source& source,
|
const ast::StageAttribute* Stage(const Source& source,
|
||||||
ast::PipelineStage stage) {
|
ast::PipelineStage stage) {
|
||||||
return create<ast::StageDecoration>(source, stage);
|
return create<ast::StageAttribute>(source, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::StageDecoration
|
/// Creates an ast::StageAttribute
|
||||||
/// @param stage the pipeline stage
|
/// @param stage the pipeline stage
|
||||||
/// @returns the stage decoration pointer
|
/// @returns the stage attribute pointer
|
||||||
const ast::StageDecoration* Stage(ast::PipelineStage stage) {
|
const ast::StageAttribute* Stage(ast::PipelineStage stage) {
|
||||||
return create<ast::StageDecoration>(source_, stage);
|
return create<ast::StageAttribute>(source_, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::WorkgroupDecoration
|
/// Creates an ast::WorkgroupAttribute
|
||||||
/// @param x the x dimension expression
|
/// @param x the x dimension expression
|
||||||
/// @returns the workgroup decoration pointer
|
/// @returns the workgroup attribute pointer
|
||||||
template <typename EXPR_X>
|
template <typename EXPR_X>
|
||||||
const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x) {
|
const ast::WorkgroupAttribute* WorkgroupSize(EXPR_X&& x) {
|
||||||
return WorkgroupSize(std::forward<EXPR_X>(x), nullptr, nullptr);
|
return WorkgroupSize(std::forward<EXPR_X>(x), nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::WorkgroupDecoration
|
/// Creates an ast::WorkgroupAttribute
|
||||||
/// @param x the x dimension expression
|
/// @param x the x dimension expression
|
||||||
/// @param y the y dimension expression
|
/// @param y the y dimension expression
|
||||||
/// @returns the workgroup decoration pointer
|
/// @returns the workgroup attribute pointer
|
||||||
template <typename EXPR_X, typename EXPR_Y>
|
template <typename EXPR_X, typename EXPR_Y>
|
||||||
const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x, EXPR_Y&& y) {
|
const ast::WorkgroupAttribute* WorkgroupSize(EXPR_X&& x, EXPR_Y&& y) {
|
||||||
return WorkgroupSize(std::forward<EXPR_X>(x), std::forward<EXPR_Y>(y),
|
return WorkgroupSize(std::forward<EXPR_X>(x), std::forward<EXPR_Y>(y),
|
||||||
nullptr);
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::WorkgroupDecoration
|
/// Creates an ast::WorkgroupAttribute
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param x the x dimension expression
|
/// @param x the x dimension expression
|
||||||
/// @param y the y dimension expression
|
/// @param y the y dimension expression
|
||||||
/// @param z the z dimension expression
|
/// @param z the z dimension expression
|
||||||
/// @returns the workgroup decoration pointer
|
/// @returns the workgroup attribute pointer
|
||||||
template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
|
template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
|
||||||
const ast::WorkgroupDecoration* WorkgroupSize(const Source& source,
|
const ast::WorkgroupAttribute* WorkgroupSize(const Source& source,
|
||||||
EXPR_X&& x,
|
EXPR_X&& x,
|
||||||
EXPR_Y&& y,
|
EXPR_Y&& y,
|
||||||
EXPR_Z&& z) {
|
EXPR_Z&& z) {
|
||||||
return create<ast::WorkgroupDecoration>(
|
return create<ast::WorkgroupAttribute>(
|
||||||
source, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
|
source, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
|
||||||
Expr(std::forward<EXPR_Z>(z)));
|
Expr(std::forward<EXPR_Z>(z)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::WorkgroupDecoration
|
/// Creates an ast::WorkgroupAttribute
|
||||||
/// @param x the x dimension expression
|
/// @param x the x dimension expression
|
||||||
/// @param y the y dimension expression
|
/// @param y the y dimension expression
|
||||||
/// @param z the z dimension expression
|
/// @param z the z dimension expression
|
||||||
/// @returns the workgroup decoration pointer
|
/// @returns the workgroup attribute pointer
|
||||||
template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
|
template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
|
||||||
const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x,
|
const ast::WorkgroupAttribute* WorkgroupSize(EXPR_X&& x,
|
||||||
EXPR_Y&& y,
|
EXPR_Y&& y,
|
||||||
EXPR_Z&& z) {
|
EXPR_Z&& z) {
|
||||||
return create<ast::WorkgroupDecoration>(
|
return create<ast::WorkgroupAttribute>(
|
||||||
source_, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
|
source_, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
|
||||||
Expr(std::forward<EXPR_Z>(z)));
|
Expr(std::forward<EXPR_Z>(z)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::DisableValidationDecoration
|
/// Creates an ast::DisableValidationAttribute
|
||||||
/// @param validation the validation to disable
|
/// @param validation the validation to disable
|
||||||
/// @returns the disable validation decoration pointer
|
/// @returns the disable validation attribute pointer
|
||||||
const ast::DisableValidationDecoration* Disable(
|
const ast::DisableValidationAttribute* Disable(
|
||||||
ast::DisabledValidation validation) {
|
ast::DisabledValidation validation) {
|
||||||
return ASTNodes().Create<ast::DisableValidationDecoration>(ID(),
|
return ASTNodes().Create<ast::DisableValidationAttribute>(ID(), validation);
|
||||||
validation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current builder source to `src`
|
/// Sets the current builder source to `src`
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "src/ast/bitcast_expression.h"
|
#include "src/ast/bitcast_expression.h"
|
||||||
#include "src/ast/break_statement.h"
|
#include "src/ast/break_statement.h"
|
||||||
#include "src/ast/builtin.h"
|
#include "src/ast/builtin.h"
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_attribute.h"
|
||||||
#include "src/ast/call_statement.h"
|
#include "src/ast/call_statement.h"
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/discard_statement.h"
|
#include "src/ast/discard_statement.h"
|
||||||
@ -29,7 +29,7 @@
|
|||||||
#include "src/ast/if_statement.h"
|
#include "src/ast/if_statement.h"
|
||||||
#include "src/ast/loop_statement.h"
|
#include "src/ast/loop_statement.h"
|
||||||
#include "src/ast/return_statement.h"
|
#include "src/ast/return_statement.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
#include "src/ast/switch_statement.h"
|
#include "src/ast/switch_statement.h"
|
||||||
#include "src/ast/unary_op_expression.h"
|
#include "src/ast/unary_op_expression.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
@ -712,8 +712,8 @@ struct LoopStatementBuilder
|
|||||||
|
|
||||||
/// @param decos a list of parsed decorations
|
/// @param decos a list of parsed decorations
|
||||||
/// @returns true if the decorations include a SampleMask builtin
|
/// @returns true if the decorations include a SampleMask builtin
|
||||||
bool HasBuiltinSampleMask(const ast::DecorationList& decos) {
|
bool HasBuiltinSampleMask(const ast::AttributeList& decos) {
|
||||||
if (auto* builtin = ast::GetDecoration<ast::BuiltinDecoration>(decos)) {
|
if (auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(decos)) {
|
||||||
return builtin->builtin == ast::Builtin::kSampleMask;
|
return builtin->builtin == ast::Builtin::kSampleMask;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -915,7 +915,7 @@ bool FunctionEmitter::Emit() {
|
|||||||
builder_.AST().AddFunction(create<ast::Function>(
|
builder_.AST().AddFunction(create<ast::Function>(
|
||||||
decl.source, builder_.Symbols().Register(decl.name),
|
decl.source, builder_.Symbols().Register(decl.name),
|
||||||
std::move(decl.params), decl.return_type->Build(builder_), body,
|
std::move(decl.params), decl.return_type->Build(builder_), body,
|
||||||
std::move(decl.decorations), ast::DecorationList{}));
|
std::move(decl.attributes), ast::AttributeList{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep_info_ && !ep_info_->inner_name.empty()) {
|
if (ep_info_ && !ep_info_->inner_name.empty()) {
|
||||||
@ -953,7 +953,7 @@ const ast::BlockStatement* FunctionEmitter::MakeFunctionBody() {
|
|||||||
|
|
||||||
bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
||||||
const Type* var_type,
|
const Type* var_type,
|
||||||
ast::DecorationList* decos,
|
ast::AttributeList* decos,
|
||||||
std::vector<int> index_prefix,
|
std::vector<int> index_prefix,
|
||||||
const Type* tip_type,
|
const Type* tip_type,
|
||||||
const Type* forced_param_type,
|
const Type* forced_param_type,
|
||||||
@ -997,7 +997,7 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
|||||||
index_prefix.push_back(0);
|
index_prefix.push_back(0);
|
||||||
for (int i = 0; i < static_cast<int>(members.size()); ++i) {
|
for (int i = 0; i < static_cast<int>(members.size()); ++i) {
|
||||||
index_prefix.back() = i;
|
index_prefix.back() = i;
|
||||||
ast::DecorationList member_decos(*decos);
|
ast::AttributeList member_decos(*decos);
|
||||||
if (!parser_impl_.ConvertPipelineDecorations(
|
if (!parser_impl_.ConvertPipelineDecorations(
|
||||||
struct_type,
|
struct_type,
|
||||||
parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
|
parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
|
||||||
@ -1015,7 +1015,7 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
|||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool is_builtin = ast::HasDecoration<ast::BuiltinDecoration>(*decos);
|
const bool is_builtin = ast::HasAttribute<ast::BuiltinAttribute>(*decos);
|
||||||
|
|
||||||
const Type* param_type = is_builtin ? forced_param_type : tip_type;
|
const Type* param_type = is_builtin ? forced_param_type : tip_type;
|
||||||
|
|
||||||
@ -1067,22 +1067,22 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
|||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionEmitter::IncrementLocation(ast::DecorationList* decos) {
|
void FunctionEmitter::IncrementLocation(ast::AttributeList* attributes) {
|
||||||
for (auto*& deco : *decos) {
|
for (auto*& attr : *attributes) {
|
||||||
if (auto* loc_deco = deco->As<ast::LocationDecoration>()) {
|
if (auto* loc_attr = attr->As<ast::LocationAttribute>()) {
|
||||||
// Replace this location decoration with a new one with one higher index.
|
// Replace this location attribute with a new one with one higher index.
|
||||||
// The old one doesn't leak because it's kept in the builder's AST node
|
// The old one doesn't leak because it's kept in the builder's AST node
|
||||||
// list.
|
// list.
|
||||||
deco = builder_.Location(loc_deco->source, loc_deco->value + 1);
|
attr = builder_.Location(loc_attr->source, loc_attr->value + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Decoration* FunctionEmitter::GetLocation(
|
const ast::Attribute* FunctionEmitter::GetLocation(
|
||||||
const ast::DecorationList& decos) {
|
const ast::AttributeList& attributes) {
|
||||||
for (auto* const& deco : decos) {
|
for (auto* const& attr : attributes) {
|
||||||
if (deco->Is<ast::LocationDecoration>()) {
|
if (attr->Is<ast::LocationAttribute>()) {
|
||||||
return deco;
|
return attr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -1090,7 +1090,7 @@ const ast::Decoration* FunctionEmitter::GetLocation(
|
|||||||
|
|
||||||
bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
|
bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
|
||||||
const Type* var_type,
|
const Type* var_type,
|
||||||
ast::DecorationList* decos,
|
ast::AttributeList* decos,
|
||||||
std::vector<int> index_prefix,
|
std::vector<int> index_prefix,
|
||||||
const Type* tip_type,
|
const Type* tip_type,
|
||||||
const Type* forced_member_type,
|
const Type* forced_member_type,
|
||||||
@ -1135,7 +1135,7 @@ bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
|
|||||||
index_prefix.push_back(0);
|
index_prefix.push_back(0);
|
||||||
for (int i = 0; i < static_cast<int>(members.size()); ++i) {
|
for (int i = 0; i < static_cast<int>(members.size()); ++i) {
|
||||||
index_prefix.back() = i;
|
index_prefix.back() = i;
|
||||||
ast::DecorationList member_decos(*decos);
|
ast::AttributeList member_decos(*decos);
|
||||||
if (!parser_impl_.ConvertPipelineDecorations(
|
if (!parser_impl_.ConvertPipelineDecorations(
|
||||||
struct_type,
|
struct_type,
|
||||||
parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
|
parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
|
||||||
@ -1153,7 +1153,7 @@ bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
|
|||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool is_builtin = ast::HasDecoration<ast::BuiltinDecoration>(*decos);
|
const bool is_builtin = ast::HasAttribute<ast::BuiltinAttribute>(*decos);
|
||||||
|
|
||||||
const Type* member_type = is_builtin ? forced_member_type : tip_type;
|
const Type* member_type = is_builtin ? forced_member_type : tip_type;
|
||||||
// Derive the member name directly from the variable name. They can't
|
// Derive the member name directly from the variable name. They can't
|
||||||
@ -1224,7 +1224,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||||||
TINT_ASSERT(Reader, var->opcode() == SpvOpVariable);
|
TINT_ASSERT(Reader, var->opcode() == SpvOpVariable);
|
||||||
auto* store_type = GetVariableStoreType(*var);
|
auto* store_type = GetVariableStoreType(*var);
|
||||||
auto* forced_param_type = store_type;
|
auto* forced_param_type = store_type;
|
||||||
ast::DecorationList param_decos;
|
ast::AttributeList param_decos;
|
||||||
if (!parser_impl_.ConvertDecorationsForVariable(var_id, &forced_param_type,
|
if (!parser_impl_.ConvertDecorationsForVariable(var_id, &forced_param_type,
|
||||||
¶m_decos, true)) {
|
¶m_decos, true)) {
|
||||||
// This occurs, and is not an error, for the PointSize builtin.
|
// This occurs, and is not an error, for the PointSize builtin.
|
||||||
@ -1293,8 +1293,8 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||||||
// The SPIR-V gl_PerVertex variable has already been remapped to
|
// The SPIR-V gl_PerVertex variable has already been remapped to
|
||||||
// a gl_Position variable. Substitute the type.
|
// a gl_Position variable. Substitute the type.
|
||||||
const Type* param_type = ty_.Vector(ty_.F32(), 4);
|
const Type* param_type = ty_.Vector(ty_.F32(), 4);
|
||||||
ast::DecorationList out_decos{
|
ast::AttributeList out_decos{
|
||||||
create<ast::BuiltinDecoration>(source, ast::Builtin::kPosition)};
|
create<ast::BuiltinAttribute>(source, ast::Builtin::kPosition)};
|
||||||
|
|
||||||
const auto var_name = namer_.GetName(var_id);
|
const auto var_name = namer_.GetName(var_id);
|
||||||
return_members.push_back(
|
return_members.push_back(
|
||||||
@ -1307,7 +1307,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||||||
TINT_ASSERT(Reader, var->opcode() == SpvOpVariable);
|
TINT_ASSERT(Reader, var->opcode() == SpvOpVariable);
|
||||||
const Type* store_type = GetVariableStoreType(*var);
|
const Type* store_type = GetVariableStoreType(*var);
|
||||||
const Type* forced_member_type = store_type;
|
const Type* forced_member_type = store_type;
|
||||||
ast::DecorationList out_decos;
|
ast::AttributeList out_decos;
|
||||||
if (!parser_impl_.ConvertDecorationsForVariable(
|
if (!parser_impl_.ConvertDecorationsForVariable(
|
||||||
var_id, &forced_member_type, &out_decos, true)) {
|
var_id, &forced_member_type, &out_decos, true)) {
|
||||||
// This occurs, and is not an error, for the PointSize builtin.
|
// This occurs, and is not an error, for the PointSize builtin.
|
||||||
@ -1349,7 +1349,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||||||
} else {
|
} else {
|
||||||
// Create and register the result type.
|
// Create and register the result type.
|
||||||
auto* str = create<ast::Struct>(Source{}, return_struct_sym,
|
auto* str = create<ast::Struct>(Source{}, return_struct_sym,
|
||||||
return_members, ast::DecorationList{});
|
return_members, ast::AttributeList{});
|
||||||
parser_impl_.AddTypeDecl(return_struct_sym, str);
|
parser_impl_.AddTypeDecl(return_struct_sym, str);
|
||||||
return_type = builder_.ty.Of(str);
|
return_type = builder_.ty.Of(str);
|
||||||
|
|
||||||
@ -1361,8 +1361,8 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>(source, stmts);
|
auto* body = create<ast::BlockStatement>(source, stmts);
|
||||||
ast::DecorationList fn_decos;
|
ast::AttributeList fn_attrs;
|
||||||
fn_decos.emplace_back(create<ast::StageDecoration>(source, ep_info_->stage));
|
fn_attrs.emplace_back(create<ast::StageAttribute>(source, ep_info_->stage));
|
||||||
|
|
||||||
if (ep_info_->stage == ast::PipelineStage::kCompute) {
|
if (ep_info_->stage == ast::PipelineStage::kCompute) {
|
||||||
auto& size = ep_info_->workgroup_size;
|
auto& size = ep_info_->workgroup_size;
|
||||||
@ -1372,15 +1372,14 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
|
|||||||
size.y ? builder_.Expr(static_cast<int>(size.y)) : nullptr;
|
size.y ? builder_.Expr(static_cast<int>(size.y)) : nullptr;
|
||||||
const ast::Expression* z =
|
const ast::Expression* z =
|
||||||
size.z ? builder_.Expr(static_cast<int>(size.z)) : nullptr;
|
size.z ? builder_.Expr(static_cast<int>(size.z)) : nullptr;
|
||||||
fn_decos.emplace_back(
|
fn_attrs.emplace_back(create<ast::WorkgroupAttribute>(Source{}, x, y, z));
|
||||||
create<ast::WorkgroupDecoration>(Source{}, x, y, z));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder_.AST().AddFunction(
|
builder_.AST().AddFunction(
|
||||||
create<ast::Function>(source, builder_.Symbols().Register(ep_info_->name),
|
create<ast::Function>(source, builder_.Symbols().Register(ep_info_->name),
|
||||||
std::move(decl.params), return_type, body,
|
std::move(decl.params), return_type, body,
|
||||||
std::move(fn_decos), ast::DecorationList{}));
|
std::move(fn_attrs), ast::AttributeList{}));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1412,7 +1411,7 @@ bool FunctionEmitter::ParseFunctionDeclaration(FunctionDeclaration* decl) {
|
|||||||
if (type != nullptr) {
|
if (type != nullptr) {
|
||||||
auto* ast_param = parser_impl_.MakeVariable(
|
auto* ast_param = parser_impl_.MakeVariable(
|
||||||
param->result_id(), ast::StorageClass::kNone, type, true, nullptr,
|
param->result_id(), ast::StorageClass::kNone, type, true, nullptr,
|
||||||
ast::DecorationList{});
|
ast::AttributeList{});
|
||||||
// Parameters are treated as const declarations.
|
// Parameters are treated as const declarations.
|
||||||
ast_params.emplace_back(ast_param);
|
ast_params.emplace_back(ast_param);
|
||||||
// The value is accessible by name.
|
// The value is accessible by name.
|
||||||
@ -1428,7 +1427,7 @@ bool FunctionEmitter::ParseFunctionDeclaration(FunctionDeclaration* decl) {
|
|||||||
decl->name = name;
|
decl->name = name;
|
||||||
decl->params = std::move(ast_params);
|
decl->params = std::move(ast_params);
|
||||||
decl->return_type = ret_ty;
|
decl->return_type = ret_ty;
|
||||||
decl->decorations.clear();
|
decl->attributes.clear();
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
@ -2513,7 +2512,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
|
|||||||
}
|
}
|
||||||
auto* var = parser_impl_.MakeVariable(
|
auto* var = parser_impl_.MakeVariable(
|
||||||
inst.result_id(), ast::StorageClass::kNone, var_store_type, false,
|
inst.result_id(), ast::StorageClass::kNone, var_store_type, false,
|
||||||
constructor, ast::DecorationList{});
|
constructor, ast::AttributeList{});
|
||||||
auto* var_decl_stmt = create<ast::VariableDeclStatement>(Source{}, var);
|
auto* var_decl_stmt = create<ast::VariableDeclStatement>(Source{}, var);
|
||||||
AddStatement(var_decl_stmt);
|
AddStatement(var_decl_stmt);
|
||||||
auto* var_type = ty_.Reference(var_store_type, ast::StorageClass::kNone);
|
auto* var_type = ty_.Reference(var_store_type, ast::StorageClass::kNone);
|
||||||
@ -3417,7 +3416,7 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
|
|||||||
AddStatement(create<ast::VariableDeclStatement>(
|
AddStatement(create<ast::VariableDeclStatement>(
|
||||||
Source{},
|
Source{},
|
||||||
parser_impl_.MakeVariable(id, ast::StorageClass::kNone, storage_type,
|
parser_impl_.MakeVariable(id, ast::StorageClass::kNone, storage_type,
|
||||||
false, nullptr, ast::DecorationList{})));
|
false, nullptr, ast::AttributeList{})));
|
||||||
auto* type = ty_.Reference(storage_type, ast::StorageClass::kNone);
|
auto* type = ty_.Reference(storage_type, ast::StorageClass::kNone);
|
||||||
identifier_types_.emplace(id, type);
|
identifier_types_.emplace(id, type);
|
||||||
}
|
}
|
||||||
@ -3490,7 +3489,7 @@ bool FunctionEmitter::EmitConstDefinition(
|
|||||||
expr = AddressOfIfNeeded(expr, &inst);
|
expr = AddressOfIfNeeded(expr, &inst);
|
||||||
auto* ast_const = parser_impl_.MakeVariable(
|
auto* ast_const = parser_impl_.MakeVariable(
|
||||||
inst.result_id(), ast::StorageClass::kNone, expr.type, true, expr.expr,
|
inst.result_id(), ast::StorageClass::kNone, expr.type, true, expr.expr,
|
||||||
ast::DecorationList{});
|
ast::AttributeList{});
|
||||||
if (!ast_const) {
|
if (!ast_const) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -441,7 +441,7 @@ class FunctionEmitter {
|
|||||||
/// @returns false if emission failed
|
/// @returns false if emission failed
|
||||||
bool EmitPipelineInput(std::string var_name,
|
bool EmitPipelineInput(std::string var_name,
|
||||||
const Type* var_type,
|
const Type* var_type,
|
||||||
ast::DecorationList* decos,
|
ast::AttributeList* decos,
|
||||||
std::vector<int> index_prefix,
|
std::vector<int> index_prefix,
|
||||||
const Type* tip_type,
|
const Type* tip_type,
|
||||||
const Type* forced_param_type,
|
const Type* forced_param_type,
|
||||||
@ -470,24 +470,24 @@ class FunctionEmitter {
|
|||||||
/// @returns false if emission failed
|
/// @returns false if emission failed
|
||||||
bool EmitPipelineOutput(std::string var_name,
|
bool EmitPipelineOutput(std::string var_name,
|
||||||
const Type* var_type,
|
const Type* var_type,
|
||||||
ast::DecorationList* decos,
|
ast::AttributeList* decos,
|
||||||
std::vector<int> index_prefix,
|
std::vector<int> index_prefix,
|
||||||
const Type* tip_type,
|
const Type* tip_type,
|
||||||
const Type* forced_member_type,
|
const Type* forced_member_type,
|
||||||
ast::StructMemberList* return_members,
|
ast::StructMemberList* return_members,
|
||||||
ast::ExpressionList* return_exprs);
|
ast::ExpressionList* return_exprs);
|
||||||
|
|
||||||
/// Updates the decoration list, replacing an existing Location decoration
|
/// Updates the attribute list, replacing an existing Location attribute
|
||||||
/// with another having one higher location value. Does nothing if no
|
/// with another having one higher location value. Does nothing if no
|
||||||
/// location decoration exists.
|
/// location attribute exists.
|
||||||
/// Assumes the list contains at most one Location decoration.
|
/// Assumes the list contains at most one Location attribute.
|
||||||
/// @param decos the decoration list to modify
|
/// @param attributes the attribute list to modify
|
||||||
void IncrementLocation(ast::DecorationList* decos);
|
void IncrementLocation(ast::AttributeList* attributes);
|
||||||
|
|
||||||
/// Returns the Location dcoration, if it exists.
|
/// Returns the Location attribute, if it exists.
|
||||||
/// @param decos the list of decorations to search
|
/// @param attributes the list of attributes to search
|
||||||
/// @returns the Location decoration, or nullptr if it doesn't exist
|
/// @returns the Location attribute, or nullptr if it doesn't exist
|
||||||
const ast::Decoration* GetLocation(const ast::DecorationList& decos);
|
const ast::Attribute* GetLocation(const ast::AttributeList& attributes);
|
||||||
|
|
||||||
/// Create an ast::BlockStatement representing the body of the function.
|
/// Create an ast::BlockStatement representing the body of the function.
|
||||||
/// This creates the statement stack, which is non-empty for the lifetime
|
/// This creates the statement stack, which is non-empty for the lifetime
|
||||||
@ -948,8 +948,8 @@ class FunctionEmitter {
|
|||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
/// Function return type
|
/// Function return type
|
||||||
const Type* return_type;
|
const Type* return_type;
|
||||||
/// Function decorations
|
/// Function attributes
|
||||||
ast::DecorationList decorations;
|
ast::AttributeList attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Parse the function declaration, which comprises the name, parameters, and
|
/// Parse the function declaration, which comprises the name, parameters, and
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
|
|
||||||
#include "source/opt/build_module.h"
|
#include "source/opt/build_module.h"
|
||||||
#include "src/ast/bitcast_expression.h"
|
#include "src/ast/bitcast_expression.h"
|
||||||
#include "src/ast/disable_validation_decoration.h"
|
#include "src/ast/disable_validation_attribute.h"
|
||||||
#include "src/ast/interpolate_decoration.h"
|
#include "src/ast/interpolate_attribute.h"
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/ast/type_name.h"
|
#include "src/ast/type_name.h"
|
||||||
#include "src/ast/unary_op_expression.h"
|
#include "src/ast/unary_op_expression.h"
|
||||||
#include "src/reader/spirv/function.h"
|
#include "src/reader/spirv/function.h"
|
||||||
@ -439,7 +439,7 @@ std::string ParserImpl::ShowType(uint32_t type_id) {
|
|||||||
return "SPIR-V type " + std::to_string(type_id);
|
return "SPIR-V type " + std::to_string(type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::DecorationList ParserImpl::ConvertMemberDecoration(
|
ast::AttributeList ParserImpl::ConvertMemberDecoration(
|
||||||
uint32_t struct_type_id,
|
uint32_t struct_type_id,
|
||||||
uint32_t member_index,
|
uint32_t member_index,
|
||||||
const Type* member_ty,
|
const Type* member_ty,
|
||||||
@ -458,7 +458,7 @@ ast::DecorationList ParserImpl::ConvertMemberDecoration(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
create<ast::StructMemberOffsetDecoration>(Source{}, decoration[1]),
|
create<ast::StructMemberOffsetAttribute>(Source{}, decoration[1]),
|
||||||
};
|
};
|
||||||
case SpvDecorationNonReadable:
|
case SpvDecorationNonReadable:
|
||||||
// WGSL doesn't have a member decoration for this. Silently drop it.
|
// WGSL doesn't have a member decoration for this. Silently drop it.
|
||||||
@ -505,9 +505,9 @@ ast::DecorationList ParserImpl::ConvertMemberDecoration(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
create<ast::StrideDecoration>(Source{}, decoration[1]),
|
create<ast::StrideAttribute>(Source{}, decoration[1]),
|
||||||
builder_.ASTNodes().Create<ast::DisableValidationDecoration>(
|
builder_.ASTNodes().Create<ast::DisableValidationAttribute>(
|
||||||
builder_.ID(), ast::DisabledValidation::kIgnoreStrideDecoration),
|
builder_.ID(), ast::DisabledValidation::kIgnoreStrideAttribute),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1152,7 +1152,7 @@ const Type* ParserImpl::ConvertType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool is_non_writable = false;
|
bool is_non_writable = false;
|
||||||
ast::DecorationList ast_member_decorations;
|
ast::AttributeList ast_member_decorations;
|
||||||
for (auto& decoration : GetDecorationsForMember(type_id, member_index)) {
|
for (auto& decoration : GetDecorationsForMember(type_id, member_index)) {
|
||||||
if (IsPipelineDecoration(decoration)) {
|
if (IsPipelineDecoration(decoration)) {
|
||||||
// IO decorations are handled when emitting the entry point.
|
// IO decorations are handled when emitting the entry point.
|
||||||
@ -1198,7 +1198,7 @@ const Type* ParserImpl::ConvertType(
|
|||||||
// Now make the struct.
|
// Now make the struct.
|
||||||
auto sym = builder_.Symbols().Register(name);
|
auto sym = builder_.Symbols().Register(name);
|
||||||
auto* ast_struct = create<ast::Struct>(Source{}, sym, std::move(ast_members),
|
auto* ast_struct = create<ast::Struct>(Source{}, sym, std::move(ast_members),
|
||||||
ast::DecorationList());
|
ast::AttributeList());
|
||||||
if (num_non_writable_members == members.size()) {
|
if (num_non_writable_members == members.size()) {
|
||||||
read_only_struct_types_.insert(ast_struct->name);
|
read_only_struct_types_.insert(ast_struct->name);
|
||||||
}
|
}
|
||||||
@ -1386,7 +1386,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ast_type && ast_expr) {
|
if (ast_type && ast_expr) {
|
||||||
ast::DecorationList spec_id_decos;
|
ast::AttributeList spec_id_decos;
|
||||||
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
|
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
|
||||||
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
|
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
|
||||||
const uint32_t id = deco[1];
|
const uint32_t id = deco[1];
|
||||||
@ -1395,7 +1395,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
|||||||
"between 0 and 65535: ID %"
|
"between 0 and 65535: ID %"
|
||||||
<< inst.result_id() << " has SpecId " << id;
|
<< inst.result_id() << " has SpecId " << id;
|
||||||
}
|
}
|
||||||
auto* cid = create<ast::OverrideDecoration>(Source{}, id);
|
auto* cid = create<ast::OverrideAttribute>(Source{}, id);
|
||||||
spec_id_decos.push_back(cid);
|
spec_id_decos.push_back(cid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1526,7 +1526,7 @@ bool ParserImpl::EmitModuleScopeVariables() {
|
|||||||
}
|
}
|
||||||
auto* ast_var =
|
auto* ast_var =
|
||||||
MakeVariable(var.result_id(), ast_storage_class, ast_store_type, false,
|
MakeVariable(var.result_id(), ast_storage_class, ast_store_type, false,
|
||||||
ast_constructor, ast::DecorationList{});
|
ast_constructor, ast::AttributeList{});
|
||||||
// TODO(dneto): initializers (a.k.a. constructor expression)
|
// TODO(dneto): initializers (a.k.a. constructor expression)
|
||||||
if (ast_var) {
|
if (ast_var) {
|
||||||
builder_.AST().AddGlobalVariable(ast_var);
|
builder_.AST().AddGlobalVariable(ast_var);
|
||||||
@ -1599,7 +1599,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
|||||||
const Type* storage_type,
|
const Type* storage_type,
|
||||||
bool is_const,
|
bool is_const,
|
||||||
const ast::Expression* constructor,
|
const ast::Expression* constructor,
|
||||||
ast::DecorationList decorations) {
|
ast::AttributeList decorations) {
|
||||||
if (storage_type == nullptr) {
|
if (storage_type == nullptr) {
|
||||||
Fail() << "internal error: can't make ast::Variable for null type";
|
Fail() << "internal error: can't make ast::Variable for null type";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -1640,7 +1640,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
|||||||
|
|
||||||
bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
|
bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
|
||||||
const Type** store_type,
|
const Type** store_type,
|
||||||
ast::DecorationList* decorations,
|
ast::AttributeList* decorations,
|
||||||
bool transfer_pipeline_io) {
|
bool transfer_pipeline_io) {
|
||||||
DecorationList non_builtin_pipeline_decorations;
|
DecorationList non_builtin_pipeline_decorations;
|
||||||
for (auto& deco : GetDecorationsFor(id)) {
|
for (auto& deco : GetDecorationsFor(id)) {
|
||||||
@ -1702,7 +1702,7 @@ bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
|
|||||||
}
|
}
|
||||||
if (transfer_pipeline_io) {
|
if (transfer_pipeline_io) {
|
||||||
decorations->emplace_back(
|
decorations->emplace_back(
|
||||||
create<ast::BuiltinDecoration>(Source{}, ast_builtin));
|
create<ast::BuiltinAttribute>(Source{}, ast_builtin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (transfer_pipeline_io && IsPipelineDecoration(deco)) {
|
if (transfer_pipeline_io && IsPipelineDecoration(deco)) {
|
||||||
@ -1713,8 +1713,7 @@ bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
|
|||||||
return Fail() << "malformed DescriptorSet decoration on ID " << id
|
return Fail() << "malformed DescriptorSet decoration on ID " << id
|
||||||
<< ": has no operand";
|
<< ": has no operand";
|
||||||
}
|
}
|
||||||
decorations->emplace_back(
|
decorations->emplace_back(create<ast::GroupAttribute>(Source{}, deco[1]));
|
||||||
create<ast::GroupDecoration>(Source{}, deco[1]));
|
|
||||||
}
|
}
|
||||||
if (deco[0] == SpvDecorationBinding) {
|
if (deco[0] == SpvDecorationBinding) {
|
||||||
if (deco.size() == 1) {
|
if (deco.size() == 1) {
|
||||||
@ -1722,7 +1721,7 @@ bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
|
|||||||
<< ": has no operand";
|
<< ": has no operand";
|
||||||
}
|
}
|
||||||
decorations->emplace_back(
|
decorations->emplace_back(
|
||||||
create<ast::BindingDecoration>(Source{}, deco[1]));
|
create<ast::BindingAttribute>(Source{}, deco[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1750,31 +1749,31 @@ DecorationList ParserImpl::GetMemberPipelineDecorations(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Decoration* ParserImpl::SetLocation(
|
const ast::Attribute* ParserImpl::SetLocation(
|
||||||
ast::DecorationList* decos,
|
ast::AttributeList* attributes,
|
||||||
const ast::Decoration* replacement) {
|
const ast::Attribute* replacement) {
|
||||||
if (!replacement) {
|
if (!replacement) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
for (auto*& deco : *decos) {
|
for (auto*& attribute : *attributes) {
|
||||||
if (deco->Is<ast::LocationDecoration>()) {
|
if (attribute->Is<ast::LocationAttribute>()) {
|
||||||
// Replace this location decoration with the replacement.
|
// Replace this location attribute with the replacement.
|
||||||
// The old one doesn't leak because it's kept in the builder's AST node
|
// The old one doesn't leak because it's kept in the builder's AST node
|
||||||
// list.
|
// list.
|
||||||
const ast::Decoration* result = nullptr;
|
const ast::Attribute* result = nullptr;
|
||||||
result = deco;
|
result = attribute;
|
||||||
deco = replacement;
|
attribute = replacement;
|
||||||
return result; // Assume there is only one such decoration.
|
return result; // Assume there is only one such decoration.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The list didn't have a location. Add it.
|
// The list didn't have a location. Add it.
|
||||||
decos->push_back(replacement);
|
attributes->push_back(replacement);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
|
bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
|
||||||
const DecorationList& decorations,
|
const DecorationList& decorations,
|
||||||
ast::DecorationList* ast_decos) {
|
ast::AttributeList* attributes) {
|
||||||
// Vulkan defaults to perspective-correct interpolation.
|
// Vulkan defaults to perspective-correct interpolation.
|
||||||
ast::InterpolationType type = ast::InterpolationType::kPerspective;
|
ast::InterpolationType type = ast::InterpolationType::kPerspective;
|
||||||
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
|
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
|
||||||
@ -1787,8 +1786,8 @@ bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
|
|||||||
return Fail() << "malformed Location decoration on ID requires one "
|
return Fail() << "malformed Location decoration on ID requires one "
|
||||||
"literal operand";
|
"literal operand";
|
||||||
}
|
}
|
||||||
SetLocation(ast_decos,
|
SetLocation(attributes,
|
||||||
create<ast::LocationDecoration>(Source{}, deco[1]));
|
create<ast::LocationAttribute>(Source{}, deco[1]));
|
||||||
if (store_type->IsIntegerScalarOrVector()) {
|
if (store_type->IsIntegerScalarOrVector()) {
|
||||||
// Default to flat interpolation for integral user-defined IO types.
|
// Default to flat interpolation for integral user-defined IO types.
|
||||||
type = ast::InterpolationType::kFlat;
|
type = ast::InterpolationType::kFlat;
|
||||||
@ -1830,7 +1829,7 @@ bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
|
|||||||
sampling == ast::InterpolationSampling::kNone) {
|
sampling == ast::InterpolationSampling::kNone) {
|
||||||
// This is the default. Don't add a decoration.
|
// This is the default. Don't add a decoration.
|
||||||
} else {
|
} else {
|
||||||
ast_decos->emplace_back(create<ast::InterpolateDecoration>(type, sampling));
|
attributes->emplace_back(create<ast::InterpolateAttribute>(type, sampling));
|
||||||
}
|
}
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
|
@ -243,34 +243,34 @@ class ParserImpl : Reader {
|
|||||||
/// @param id the ID of the SPIR-V variable
|
/// @param id the ID of the SPIR-V variable
|
||||||
/// @param store_type the WGSL store type for the variable, which should be
|
/// @param store_type the WGSL store type for the variable, which should be
|
||||||
/// prepopulatd
|
/// prepopulatd
|
||||||
/// @param ast_decos the decoration list to populate
|
/// @param attributes the attribute list to populate
|
||||||
/// @param transfer_pipeline_io true if pipeline IO decorations (builtins,
|
/// @param transfer_pipeline_io true if pipeline IO decorations (builtins,
|
||||||
/// or locations) will update the store type and the decorations list
|
/// or locations) will update the store type and the decorations list
|
||||||
/// @returns false when the variable should not be emitted as a variable
|
/// @returns false when the variable should not be emitted as a variable
|
||||||
bool ConvertDecorationsForVariable(uint32_t id,
|
bool ConvertDecorationsForVariable(uint32_t id,
|
||||||
const Type** store_type,
|
const Type** store_type,
|
||||||
ast::DecorationList* ast_decos,
|
ast::AttributeList* attributes,
|
||||||
bool transfer_pipeline_io);
|
bool transfer_pipeline_io);
|
||||||
|
|
||||||
/// Converts SPIR-V decorations for pipeline IO into AST decorations.
|
/// Converts SPIR-V decorations for pipeline IO into AST decorations.
|
||||||
/// @param store_type the store type for the variable or member
|
/// @param store_type the store type for the variable or member
|
||||||
/// @param decorations the SPIR-V interpolation decorations
|
/// @param decorations the SPIR-V interpolation decorations
|
||||||
/// @param ast_decos the decoration list to populate.
|
/// @param attributes the attribute list to populate.
|
||||||
/// @returns false if conversion fails
|
/// @returns false if conversion fails
|
||||||
bool ConvertPipelineDecorations(const Type* store_type,
|
bool ConvertPipelineDecorations(const Type* store_type,
|
||||||
const DecorationList& decorations,
|
const DecorationList& decorations,
|
||||||
ast::DecorationList* ast_decos);
|
ast::AttributeList* attributes);
|
||||||
|
|
||||||
/// Updates the decoration list, placing a non-null location decoration into
|
/// Updates the attribute list, placing a non-null location decoration into
|
||||||
/// the list, replacing an existing one if it exists. Does nothing if the
|
/// the list, replacing an existing one if it exists. Does nothing if the
|
||||||
/// replacement is nullptr.
|
/// replacement is nullptr.
|
||||||
/// Assumes the list contains at most one Location decoration.
|
/// Assumes the list contains at most one Location decoration.
|
||||||
/// @param decos the decoration list to modify
|
/// @param decos the attribute list to modify
|
||||||
/// @param replacement the location decoration to place into the list
|
/// @param replacement the location decoration to place into the list
|
||||||
/// @returns the location decoration that was replaced, if one was replaced,
|
/// @returns the location decoration that was replaced, if one was replaced,
|
||||||
/// or null otherwise.
|
/// or null otherwise.
|
||||||
const ast::Decoration* SetLocation(ast::DecorationList* decos,
|
const ast::Attribute* SetLocation(ast::AttributeList* decos,
|
||||||
const ast::Decoration* replacement);
|
const ast::Attribute* replacement);
|
||||||
|
|
||||||
/// Converts a SPIR-V struct member decoration into a number of AST
|
/// Converts a SPIR-V struct member decoration into a number of AST
|
||||||
/// decorations. If the decoration is recognized but deliberately dropped,
|
/// decorations. If the decoration is recognized but deliberately dropped,
|
||||||
@ -281,10 +281,10 @@ class ParserImpl : Reader {
|
|||||||
/// @param member_ty the type of the member
|
/// @param member_ty the type of the member
|
||||||
/// @param decoration an encoded SPIR-V Decoration
|
/// @param decoration an encoded SPIR-V Decoration
|
||||||
/// @returns the AST decorations
|
/// @returns the AST decorations
|
||||||
ast::DecorationList ConvertMemberDecoration(uint32_t struct_type_id,
|
ast::AttributeList ConvertMemberDecoration(uint32_t struct_type_id,
|
||||||
uint32_t member_index,
|
uint32_t member_index,
|
||||||
const Type* member_ty,
|
const Type* member_ty,
|
||||||
const Decoration& decoration);
|
const Decoration& decoration);
|
||||||
|
|
||||||
/// Returns a string for the given type. If the type ID is invalid,
|
/// Returns a string for the given type. If the type ID is invalid,
|
||||||
/// then the resulting string only names the type ID.
|
/// then the resulting string only names the type ID.
|
||||||
@ -430,7 +430,7 @@ class ParserImpl : Reader {
|
|||||||
const Type* storage_type,
|
const Type* storage_type,
|
||||||
bool is_const,
|
bool is_const,
|
||||||
const ast::Expression* constructor,
|
const ast::Expression* constructor,
|
||||||
ast::DecorationList decorations);
|
ast::AttributeList decorations);
|
||||||
|
|
||||||
/// Returns true if a constant expression can be generated.
|
/// Returns true if a constant expression can be generated.
|
||||||
/// @param id the SPIR-V ID of the value
|
/// @param id the SPIR-V ID of the value
|
||||||
|
@ -56,8 +56,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
|
|||||||
auto result =
|
auto result =
|
||||||
p->ConvertMemberDecoration(1, 1, nullptr, {SpvDecorationOffset, 8});
|
p->ConvertMemberDecoration(1, 1, nullptr, {SpvDecorationOffset, 8});
|
||||||
ASSERT_FALSE(result.empty());
|
ASSERT_FALSE(result.empty());
|
||||||
EXPECT_TRUE(result[0]->Is<ast::StructMemberOffsetDecoration>());
|
EXPECT_TRUE(result[0]->Is<ast::StructMemberOffsetAttribute>());
|
||||||
auto* offset_deco = result[0]->As<ast::StructMemberOffsetDecoration>();
|
auto* offset_deco = result[0]->As<ast::StructMemberOffsetAttribute>();
|
||||||
ASSERT_NE(offset_deco, nullptr);
|
ASSERT_NE(offset_deco, nullptr);
|
||||||
EXPECT_EQ(offset_deco->offset, 8u);
|
EXPECT_EQ(offset_deco->offset, 8u);
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
@ -82,8 +82,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Custom) {
|
|||||||
auto result = p->ConvertMemberDecoration(1, 1, &matrix,
|
auto result = p->ConvertMemberDecoration(1, 1, &matrix,
|
||||||
{SpvDecorationMatrixStride, 16});
|
{SpvDecorationMatrixStride, 16});
|
||||||
ASSERT_FALSE(result.empty());
|
ASSERT_FALSE(result.empty());
|
||||||
EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>());
|
EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
|
||||||
auto* stride_deco = result[0]->As<ast::StrideDecoration>();
|
auto* stride_deco = result[0]->As<ast::StrideAttribute>();
|
||||||
ASSERT_NE(stride_deco, nullptr);
|
ASSERT_NE(stride_deco, nullptr);
|
||||||
EXPECT_EQ(stride_deco->stride, 16u);
|
EXPECT_EQ(stride_deco->stride, 16u);
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
@ -108,8 +108,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Custom) {
|
|||||||
auto result = p->ConvertMemberDecoration(1, 1, &matrix,
|
auto result = p->ConvertMemberDecoration(1, 1, &matrix,
|
||||||
{SpvDecorationMatrixStride, 64});
|
{SpvDecorationMatrixStride, 64});
|
||||||
ASSERT_FALSE(result.empty());
|
ASSERT_FALSE(result.empty());
|
||||||
EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>());
|
EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
|
||||||
auto* stride_deco = result[0]->As<ast::StrideDecoration>();
|
auto* stride_deco = result[0]->As<ast::StrideAttribute>();
|
||||||
ASSERT_NE(stride_deco, nullptr);
|
ASSERT_NE(stride_deco, nullptr);
|
||||||
EXPECT_EQ(stride_deco->stride, 64u);
|
EXPECT_EQ(stride_deco->stride, 64u);
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
@ -123,8 +123,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x3_Stride_Custom) {
|
|||||||
auto result = p->ConvertMemberDecoration(1, 1, &matrix,
|
auto result = p->ConvertMemberDecoration(1, 1, &matrix,
|
||||||
{SpvDecorationMatrixStride, 32});
|
{SpvDecorationMatrixStride, 32});
|
||||||
ASSERT_FALSE(result.empty());
|
ASSERT_FALSE(result.empty());
|
||||||
EXPECT_TRUE(result[0]->Is<ast::StrideDecoration>());
|
EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
|
||||||
auto* stride_deco = result[0]->As<ast::StrideDecoration>();
|
auto* stride_deco = result[0]->As<ast::StrideAttribute>();
|
||||||
ASSERT_NE(stride_deco, nullptr);
|
ASSERT_NE(stride_deco, nullptr);
|
||||||
EXPECT_EQ(stride_deco->stride, 32u);
|
EXPECT_EQ(stride_deco->stride, 32u);
|
||||||
EXPECT_TRUE(p->error().empty());
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
@ -196,10 +196,10 @@ class ParserImplWrapperForTest {
|
|||||||
/// @param member_ty the type of the member
|
/// @param member_ty the type of the member
|
||||||
/// @param decoration an encoded SPIR-V Decoration
|
/// @param decoration an encoded SPIR-V Decoration
|
||||||
/// @returns the AST decorations
|
/// @returns the AST decorations
|
||||||
ast::DecorationList ConvertMemberDecoration(uint32_t struct_type_id,
|
ast::AttributeList ConvertMemberDecoration(uint32_t struct_type_id,
|
||||||
uint32_t member_index,
|
uint32_t member_index,
|
||||||
const Type* member_ty,
|
const Type* member_ty,
|
||||||
const Decoration& decoration) {
|
const Decoration& decoration) {
|
||||||
return impl_.ConvertMemberDecoration(struct_type_id, member_index,
|
return impl_.ConvertMemberDecoration(struct_type_id, member_index,
|
||||||
member_ty, decoration);
|
member_ty, decoration);
|
||||||
}
|
}
|
||||||
|
@ -24,18 +24,18 @@
|
|||||||
#include "src/ast/external_texture.h"
|
#include "src/ast/external_texture.h"
|
||||||
#include "src/ast/fallthrough_statement.h"
|
#include "src/ast/fallthrough_statement.h"
|
||||||
#include "src/ast/if_statement.h"
|
#include "src/ast/if_statement.h"
|
||||||
#include "src/ast/invariant_decoration.h"
|
#include "src/ast/invariant_attribute.h"
|
||||||
#include "src/ast/loop_statement.h"
|
#include "src/ast/loop_statement.h"
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/ast/return_statement.h"
|
#include "src/ast/return_statement.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_attribute.h"
|
||||||
#include "src/ast/struct_block_decoration.h"
|
#include "src/ast/struct_block_attribute.h"
|
||||||
#include "src/ast/switch_statement.h"
|
#include "src/ast/switch_statement.h"
|
||||||
#include "src/ast/type_name.h"
|
#include "src/ast/type_name.h"
|
||||||
#include "src/ast/unary_op_expression.h"
|
#include "src/ast/unary_op_expression.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
#include "src/ast/vector.h"
|
#include "src/ast/vector.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
#include "src/reader/wgsl/lexer.h"
|
#include "src/reader/wgsl/lexer.h"
|
||||||
#include "src/sem/depth_texture_type.h"
|
#include "src/sem/depth_texture_type.h"
|
||||||
#include "src/sem/external_texture_type.h"
|
#include "src/sem/external_texture_type.h"
|
||||||
@ -110,27 +110,27 @@ ast::Builtin ident_to_builtin(std::string_view str) {
|
|||||||
return ast::Builtin::kNone;
|
return ast::Builtin::kNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char kBindingDecoration[] = "binding";
|
const char kBindingAttribute[] = "binding";
|
||||||
const char kBlockDecoration[] = "block";
|
const char kBlockAttribute[] = "block";
|
||||||
const char kBuiltinDecoration[] = "builtin";
|
const char kBuiltinAttribute[] = "builtin";
|
||||||
const char kGroupDecoration[] = "group";
|
const char kGroupAttribute[] = "group";
|
||||||
const char kInterpolateDecoration[] = "interpolate";
|
const char kInterpolateAttribute[] = "interpolate";
|
||||||
const char kInvariantDecoration[] = "invariant";
|
const char kInvariantAttribute[] = "invariant";
|
||||||
const char kLocationDecoration[] = "location";
|
const char kLocationAttribute[] = "location";
|
||||||
const char kOverrideDecoration[] = "override";
|
const char kOverrideAttribute[] = "override";
|
||||||
const char kSizeDecoration[] = "size";
|
const char kSizeAttribute[] = "size";
|
||||||
const char kAlignDecoration[] = "align";
|
const char kAlignAttribute[] = "align";
|
||||||
const char kStageDecoration[] = "stage";
|
const char kStageAttribute[] = "stage";
|
||||||
const char kStrideDecoration[] = "stride";
|
const char kStrideAttribute[] = "stride";
|
||||||
const char kWorkgroupSizeDecoration[] = "workgroup_size";
|
const char kWorkgroupSizeAttribute[] = "workgroup_size";
|
||||||
|
|
||||||
bool is_decoration(Token t) {
|
bool is_attribute(Token t) {
|
||||||
return t == kAlignDecoration || t == kBindingDecoration ||
|
return t == kAlignAttribute || t == kBindingAttribute ||
|
||||||
t == kBlockDecoration || t == kBuiltinDecoration ||
|
t == kBlockAttribute || t == kBuiltinAttribute ||
|
||||||
t == kGroupDecoration || t == kInterpolateDecoration ||
|
t == kGroupAttribute || t == kInterpolateAttribute ||
|
||||||
t == kLocationDecoration || t == kOverrideDecoration ||
|
t == kLocationAttribute || t == kOverrideAttribute ||
|
||||||
t == kSizeDecoration || t == kStageDecoration ||
|
t == kSizeAttribute || t == kStageAttribute || t == kStrideAttribute ||
|
||||||
t == kStrideDecoration || t == kWorkgroupSizeDecoration;
|
t == kWorkgroupSizeAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl.html#reserved-keywords
|
// https://gpuweb.github.io/gpuweb/wgsl.html#reserved-keywords
|
||||||
@ -225,12 +225,12 @@ ParserImpl::FunctionHeader::FunctionHeader(Source src,
|
|||||||
std::string n,
|
std::string n,
|
||||||
ast::VariableList p,
|
ast::VariableList p,
|
||||||
const ast::Type* ret_ty,
|
const ast::Type* ret_ty,
|
||||||
ast::DecorationList ret_decos)
|
ast::AttributeList ret_attrs)
|
||||||
: source(src),
|
: source(src),
|
||||||
name(n),
|
name(n),
|
||||||
params(p),
|
params(p),
|
||||||
return_type(ret_ty),
|
return_type(ret_ty),
|
||||||
return_type_decorations(ret_decos) {}
|
return_type_attributes(ret_attrs) {}
|
||||||
|
|
||||||
ParserImpl::FunctionHeader::~FunctionHeader() = default;
|
ParserImpl::FunctionHeader::~FunctionHeader() = default;
|
||||||
|
|
||||||
@ -351,14 +351,14 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||||||
|
|
||||||
bool errored = false;
|
bool errored = false;
|
||||||
|
|
||||||
auto decos = decoration_list();
|
auto attrs = attribute_list();
|
||||||
if (decos.errored)
|
if (attrs.errored)
|
||||||
errored = true;
|
errored = true;
|
||||||
if (!continue_parsing())
|
if (!continue_parsing())
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
auto decl = sync(Token::Type::kSemicolon, [&]() -> Maybe<bool> {
|
auto decl = sync(Token::Type::kSemicolon, [&]() -> Maybe<bool> {
|
||||||
auto gv = global_variable_decl(decos.value);
|
auto gv = global_variable_decl(attrs.value);
|
||||||
if (gv.errored)
|
if (gv.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
if (gv.matched) {
|
if (gv.matched) {
|
||||||
@ -369,7 +369,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gc = global_constant_decl(decos.value);
|
auto gc = global_constant_decl(attrs.value);
|
||||||
if (gc.errored)
|
if (gc.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
@ -393,7 +393,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto str = struct_decl(decos.value);
|
auto str = struct_decl(attrs.value);
|
||||||
if (str.errored)
|
if (str.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
@ -409,10 +409,10 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||||||
errored = true;
|
errored = true;
|
||||||
}
|
}
|
||||||
if (decl.matched) {
|
if (decl.matched) {
|
||||||
return expect_decorations_consumed(decos.value);
|
return expect_attributes_consumed(attrs.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto func = function_decl(decos.value);
|
auto func = function_decl(attrs.value);
|
||||||
if (func.errored) {
|
if (func.errored) {
|
||||||
errored = true;
|
errored = true;
|
||||||
}
|
}
|
||||||
@ -427,9 +427,9 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||||||
|
|
||||||
// Invalid syntax found - try and determine the best error message
|
// Invalid syntax found - try and determine the best error message
|
||||||
|
|
||||||
// We have decorations parsed, but nothing to consume them?
|
// We have attributes parsed, but nothing to consume them?
|
||||||
if (decos.value.size() > 0) {
|
if (attrs.value.size() > 0) {
|
||||||
return add_error(next(), "expected declaration after decorations");
|
return add_error(next(), "expected declaration after attributes");
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a statement outside of a function?
|
// We have a statement outside of a function?
|
||||||
@ -460,10 +460,10 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// global_variable_decl
|
// global_variable_decl
|
||||||
// : variable_decoration_list* variable_decl
|
// : variable_attribute_list* variable_decl
|
||||||
// | variable_decoration_list* variable_decl EQUAL const_expr
|
// | variable_attribute_list* variable_decl EQUAL const_expr
|
||||||
Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
|
Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
|
||||||
ast::DecorationList& decos) {
|
ast::AttributeList& attrs) {
|
||||||
auto decl = variable_decl();
|
auto decl = variable_decl();
|
||||||
if (decl.errored)
|
if (decl.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -486,7 +486,7 @@ Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
|
|||||||
decl->type, // type
|
decl->type, // type
|
||||||
false, // is_const
|
false, // is_const
|
||||||
constructor, // constructor
|
constructor, // constructor
|
||||||
std::move(decos)); // decorations
|
std::move(attrs)); // attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
// global_constant_decl
|
// global_constant_decl
|
||||||
@ -494,7 +494,7 @@ Maybe<const ast::Variable*> ParserImpl::global_variable_decl(
|
|||||||
// global_const_initializer
|
// global_const_initializer
|
||||||
// : EQUAL const_expr
|
// : EQUAL const_expr
|
||||||
Maybe<const ast::Variable*> ParserImpl::global_constant_decl(
|
Maybe<const ast::Variable*> ParserImpl::global_constant_decl(
|
||||||
ast::DecorationList& decos) {
|
ast::AttributeList& attrs) {
|
||||||
if (!match(Token::Type::kLet)) {
|
if (!match(Token::Type::kLet)) {
|
||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
}
|
}
|
||||||
@ -522,7 +522,7 @@ Maybe<const ast::Variable*> ParserImpl::global_constant_decl(
|
|||||||
decl->type, // type
|
decl->type, // type
|
||||||
true, // is_const
|
true, // is_const
|
||||||
initializer, // constructor
|
initializer, // constructor
|
||||||
std::move(decos)); // decorations
|
std::move(attrs)); // attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
// variable_decl
|
// variable_decl
|
||||||
@ -807,7 +807,7 @@ Expect<ast::TexelFormat> ParserImpl::expect_texel_format(std::string_view use) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// variable_ident_decl
|
// variable_ident_decl
|
||||||
// : IDENT COLON variable_decoration_list* type_decl
|
// : IDENT COLON variable_attribute_list* type_decl
|
||||||
Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
|
Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
|
||||||
std::string_view use,
|
std::string_view use,
|
||||||
bool allow_inferred) {
|
bool allow_inferred) {
|
||||||
@ -822,18 +822,18 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
|
|||||||
if (!expect(use, Token::Type::kColon))
|
if (!expect(use, Token::Type::kColon))
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
auto decos = decoration_list();
|
auto attrs = attribute_list();
|
||||||
if (decos.errored)
|
if (attrs.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
auto type = type_decl(decos.value);
|
auto type = type_decl(attrs.value);
|
||||||
if (type.errored)
|
if (type.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
if (!type.matched)
|
if (!type.matched)
|
||||||
return add_error(t.source(), "invalid type", use);
|
return add_error(t.source(), "invalid type", use);
|
||||||
|
|
||||||
if (!expect_decorations_consumed(decos.value))
|
if (!expect_attributes_consumed(attrs.value))
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return TypedIdentifier{type.value, ident.value, ident.source};
|
return TypedIdentifier{type.value, ident.value, ident.source};
|
||||||
@ -922,9 +922,9 @@ Maybe<const ast::Alias*> ParserImpl::type_alias() {
|
|||||||
// | VEC3 LESS_THAN type_decl GREATER_THAN
|
// | VEC3 LESS_THAN type_decl GREATER_THAN
|
||||||
// | VEC4 LESS_THAN type_decl GREATER_THAN
|
// | VEC4 LESS_THAN type_decl GREATER_THAN
|
||||||
// | PTR LESS_THAN storage_class, type_decl (COMMA access_mode)? GREATER_THAN
|
// | PTR LESS_THAN storage_class, type_decl (COMMA access_mode)? GREATER_THAN
|
||||||
// | array_decoration_list* ARRAY LESS_THAN type_decl COMMA
|
// | array_attribute_list* ARRAY LESS_THAN type_decl COMMA
|
||||||
// INT_LITERAL GREATER_THAN
|
// INT_LITERAL GREATER_THAN
|
||||||
// | array_decoration_list* ARRAY LESS_THAN type_decl
|
// | array_attribute_list* ARRAY LESS_THAN type_decl
|
||||||
// GREATER_THAN
|
// GREATER_THAN
|
||||||
// | MAT2x2 LESS_THAN type_decl GREATER_THAN
|
// | MAT2x2 LESS_THAN type_decl GREATER_THAN
|
||||||
// | MAT2x3 LESS_THAN type_decl GREATER_THAN
|
// | MAT2x3 LESS_THAN type_decl GREATER_THAN
|
||||||
@ -937,15 +937,15 @@ Maybe<const ast::Alias*> ParserImpl::type_alias() {
|
|||||||
// | MAT4x4 LESS_THAN type_decl GREATER_THAN
|
// | MAT4x4 LESS_THAN type_decl GREATER_THAN
|
||||||
// | texture_sampler_types
|
// | texture_sampler_types
|
||||||
Maybe<const ast::Type*> ParserImpl::type_decl() {
|
Maybe<const ast::Type*> ParserImpl::type_decl() {
|
||||||
auto decos = decoration_list();
|
auto attrs = attribute_list();
|
||||||
if (decos.errored)
|
if (attrs.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
auto type = type_decl(decos.value);
|
auto type = type_decl(attrs.value);
|
||||||
if (type.errored) {
|
if (type.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
if (!expect_decorations_consumed(decos.value)) {
|
if (!expect_attributes_consumed(attrs.value)) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
if (!type.matched) {
|
if (!type.matched) {
|
||||||
@ -955,7 +955,7 @@ Maybe<const ast::Type*> ParserImpl::type_decl() {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<const ast::Type*> ParserImpl::type_decl(ast::DecorationList& decos) {
|
Maybe<const ast::Type*> ParserImpl::type_decl(ast::AttributeList& attrs) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
Source source;
|
Source source;
|
||||||
if (match(Token::Type::kIdentifier, &source)) {
|
if (match(Token::Type::kIdentifier, &source)) {
|
||||||
@ -989,7 +989,7 @@ Maybe<const ast::Type*> ParserImpl::type_decl(ast::DecorationList& decos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (match(Token::Type::kArray, &source)) {
|
if (match(Token::Type::kArray, &source)) {
|
||||||
return expect_type_decl_array(t, std::move(decos));
|
return expect_type_decl_array(t, std::move(attrs));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.IsMatrix()) {
|
if (t.IsMatrix()) {
|
||||||
@ -1090,7 +1090,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_decl_vector(Token t) {
|
|||||||
|
|
||||||
Expect<const ast::Type*> ParserImpl::expect_type_decl_array(
|
Expect<const ast::Type*> ParserImpl::expect_type_decl_array(
|
||||||
Token t,
|
Token t,
|
||||||
ast::DecorationList decos) {
|
ast::AttributeList attrs) {
|
||||||
const char* use = "array declaration";
|
const char* use = "array declaration";
|
||||||
|
|
||||||
const ast::Expression* size = nullptr;
|
const ast::Expression* size = nullptr;
|
||||||
@ -1119,7 +1119,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_decl_array(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return builder_.ty.array(make_source_range_from(t.source()), subtype.value,
|
return builder_.ty.array(make_source_range_from(t.source()), subtype.value,
|
||||||
size, std::move(decos));
|
size, std::move(attrs));
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect<const ast::Type*> ParserImpl::expect_type_decl_matrix(Token t) {
|
Expect<const ast::Type*> ParserImpl::expect_type_decl_matrix(Token t) {
|
||||||
@ -1181,8 +1181,8 @@ Expect<ast::StorageClass> ParserImpl::expect_storage_class(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// struct_decl
|
// struct_decl
|
||||||
// : struct_decoration_decl* STRUCT IDENT struct_body_decl
|
// : struct_attribute_decl* STRUCT IDENT struct_body_decl
|
||||||
Maybe<const ast::Struct*> ParserImpl::struct_decl(ast::DecorationList& decos) {
|
Maybe<const ast::Struct*> ParserImpl::struct_decl(ast::AttributeList& attrs) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
auto source = t.source();
|
auto source = t.source();
|
||||||
|
|
||||||
@ -1199,7 +1199,7 @@ Maybe<const ast::Struct*> ParserImpl::struct_decl(ast::DecorationList& decos) {
|
|||||||
|
|
||||||
auto sym = builder_.Symbols().Register(name.value);
|
auto sym = builder_.Symbols().Register(name.value);
|
||||||
return create<ast::Struct>(source, sym, std::move(body.value),
|
return create<ast::Struct>(source, sym, std::move(body.value),
|
||||||
std::move(decos));
|
std::move(attrs));
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct_body_decl
|
// struct_body_decl
|
||||||
@ -1215,14 +1215,14 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
|
|||||||
!peek_is(Token::Type::kEOF)) {
|
!peek_is(Token::Type::kEOF)) {
|
||||||
auto member = sync(Token::Type::kSemicolon,
|
auto member = sync(Token::Type::kSemicolon,
|
||||||
[&]() -> Expect<ast::StructMember*> {
|
[&]() -> Expect<ast::StructMember*> {
|
||||||
auto decos = decoration_list();
|
auto attrs = attribute_list();
|
||||||
if (decos.errored) {
|
if (attrs.errored) {
|
||||||
errored = true;
|
errored = true;
|
||||||
}
|
}
|
||||||
if (!synchronized_) {
|
if (!synchronized_) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
return expect_struct_member(decos.value);
|
return expect_struct_member(attrs.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (member.errored) {
|
if (member.errored) {
|
||||||
@ -1240,9 +1240,9 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// struct_member
|
// struct_member
|
||||||
// : struct_member_decoration_decl+ variable_ident_decl SEMICOLON
|
// : struct_member_attribute_decl+ variable_ident_decl SEMICOLON
|
||||||
Expect<ast::StructMember*> ParserImpl::expect_struct_member(
|
Expect<ast::StructMember*> ParserImpl::expect_struct_member(
|
||||||
ast::DecorationList& decos) {
|
ast::AttributeList& attrs) {
|
||||||
auto decl = expect_variable_ident_decl("struct member");
|
auto decl = expect_variable_ident_decl("struct member");
|
||||||
if (decl.errored)
|
if (decl.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -1252,13 +1252,13 @@ Expect<ast::StructMember*> ParserImpl::expect_struct_member(
|
|||||||
|
|
||||||
return create<ast::StructMember>(decl->source,
|
return create<ast::StructMember>(decl->source,
|
||||||
builder_.Symbols().Register(decl->name),
|
builder_.Symbols().Register(decl->name),
|
||||||
decl->type, std::move(decos));
|
decl->type, std::move(attrs));
|
||||||
}
|
}
|
||||||
|
|
||||||
// function_decl
|
// function_decl
|
||||||
// : function_header body_stmt
|
// : function_header body_stmt
|
||||||
Maybe<const ast::Function*> ParserImpl::function_decl(
|
Maybe<const ast::Function*> ParserImpl::function_decl(
|
||||||
ast::DecorationList& decos) {
|
ast::AttributeList& attrs) {
|
||||||
auto header = function_header();
|
auto header = function_header();
|
||||||
if (header.errored) {
|
if (header.errored) {
|
||||||
if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) {
|
if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) {
|
||||||
@ -1286,7 +1286,7 @@ Maybe<const ast::Function*> ParserImpl::function_decl(
|
|||||||
|
|
||||||
return create<ast::Function>(
|
return create<ast::Function>(
|
||||||
header->source, builder_.Symbols().Register(header->name), header->params,
|
header->source, builder_.Symbols().Register(header->name), header->params,
|
||||||
header->return_type, body.value, decos, header->return_type_decorations);
|
header->return_type, body.value, attrs, header->return_type_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// function_header
|
// function_header
|
||||||
@ -1320,28 +1320,28 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ast::Type* return_type = nullptr;
|
const ast::Type* return_type = nullptr;
|
||||||
ast::DecorationList return_decorations;
|
ast::AttributeList return_attributes;
|
||||||
|
|
||||||
if (match(Token::Type::kArrow)) {
|
if (match(Token::Type::kArrow)) {
|
||||||
auto decos = decoration_list();
|
auto attrs = attribute_list();
|
||||||
if (decos.errored) {
|
if (attrs.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
return_decorations = decos.value;
|
return_attributes = attrs.value;
|
||||||
|
|
||||||
// Apply stride decorations to the type node instead of the function.
|
// Apply stride attributes to the type node instead of the function.
|
||||||
ast::DecorationList type_decorations;
|
ast::AttributeList type_attributes;
|
||||||
auto itr = std::find_if(
|
auto itr =
|
||||||
return_decorations.begin(), return_decorations.end(),
|
std::find_if(return_attributes.begin(), return_attributes.end(),
|
||||||
[](auto* deco) { return Is<ast::StrideDecoration>(deco); });
|
[](auto* attr) { return Is<ast::StrideAttribute>(attr); });
|
||||||
if (itr != return_decorations.end()) {
|
if (itr != return_attributes.end()) {
|
||||||
type_decorations.emplace_back(*itr);
|
type_attributes.emplace_back(*itr);
|
||||||
return_decorations.erase(itr);
|
return_attributes.erase(itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tok = peek();
|
auto tok = peek();
|
||||||
|
|
||||||
auto type = type_decl(type_decorations);
|
auto type = type_decl(type_attributes);
|
||||||
if (type.errored) {
|
if (type.errored) {
|
||||||
errored = true;
|
errored = true;
|
||||||
} else if (!type.matched) {
|
} else if (!type.matched) {
|
||||||
@ -1358,7 +1358,7 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return FunctionHeader{source, name.value, std::move(params.value),
|
return FunctionHeader{source, name.value, std::move(params.value),
|
||||||
return_type, std::move(return_decorations)};
|
return_type, std::move(return_attributes)};
|
||||||
}
|
}
|
||||||
|
|
||||||
// param_list
|
// param_list
|
||||||
@ -1387,9 +1387,9 @@ Expect<ast::VariableList> ParserImpl::expect_param_list() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// param
|
// param
|
||||||
// : decoration_list* variable_ident_decl
|
// : attribute_list* variable_ident_decl
|
||||||
Expect<ast::Variable*> ParserImpl::expect_param() {
|
Expect<ast::Variable*> ParserImpl::expect_param() {
|
||||||
auto decos = decoration_list();
|
auto attrs = attribute_list();
|
||||||
|
|
||||||
auto decl = expect_variable_ident_decl("parameter");
|
auto decl = expect_variable_ident_decl("parameter");
|
||||||
if (decl.errored)
|
if (decl.errored)
|
||||||
@ -1403,7 +1403,7 @@ Expect<ast::Variable*> ParserImpl::expect_param() {
|
|||||||
decl->type, // type
|
decl->type, // type
|
||||||
true, // is_const
|
true, // is_const
|
||||||
nullptr, // constructor
|
nullptr, // constructor
|
||||||
std::move(decos.value)); // decorations
|
std::move(attrs.value)); // attributes
|
||||||
// Formal parameters are treated like a const declaration where the
|
// Formal parameters are treated like a const declaration where the
|
||||||
// initializer value is provided by the call's argument. The key point is
|
// initializer value is provided by the call's argument. The key point is
|
||||||
// that it's not updatable after initially set. This is unlike C or GLSL
|
// that it's not updatable after initially set. This is unlike C or GLSL
|
||||||
@ -1430,7 +1430,7 @@ Expect<ast::PipelineStage> ParserImpl::expect_pipeline_stage() {
|
|||||||
next(); // Consume the peek
|
next(); // Consume the peek
|
||||||
return {ast::PipelineStage::kCompute, t.source()};
|
return {ast::PipelineStage::kCompute, t.source()};
|
||||||
}
|
}
|
||||||
return add_error(peek(), "invalid value for stage decoration");
|
return add_error(peek(), "invalid value for stage attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect<ast::Builtin> ParserImpl::expect_builtin() {
|
Expect<ast::Builtin> ParserImpl::expect_builtin() {
|
||||||
@ -1440,7 +1440,7 @@ Expect<ast::Builtin> ParserImpl::expect_builtin() {
|
|||||||
|
|
||||||
ast::Builtin builtin = ident_to_builtin(ident.value);
|
ast::Builtin builtin = ident_to_builtin(ident.value);
|
||||||
if (builtin == ast::Builtin::kNone)
|
if (builtin == ast::Builtin::kNone)
|
||||||
return add_error(ident.source, "invalid value for builtin decoration");
|
return add_error(ident.source, "invalid value for builtin attribute");
|
||||||
|
|
||||||
return {builtin, ident.source};
|
return {builtin, ident.source};
|
||||||
}
|
}
|
||||||
@ -1661,7 +1661,7 @@ Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
|
|||||||
decl->type, // type
|
decl->type, // type
|
||||||
true, // is_const
|
true, // is_const
|
||||||
constructor.value, // constructor
|
constructor.value, // constructor
|
||||||
ast::DecorationList{}); // decorations
|
ast::AttributeList{}); // attributes
|
||||||
|
|
||||||
return create<ast::VariableDeclStatement>(decl->source, var);
|
return create<ast::VariableDeclStatement>(decl->source, var);
|
||||||
}
|
}
|
||||||
@ -1686,12 +1686,12 @@ Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
|
|||||||
auto* var =
|
auto* var =
|
||||||
create<ast::Variable>(decl->source, // source
|
create<ast::Variable>(decl->source, // source
|
||||||
builder_.Symbols().Register(decl->name), // symbol
|
builder_.Symbols().Register(decl->name), // symbol
|
||||||
decl->storage_class, // storage class
|
decl->storage_class, // storage class
|
||||||
decl->access, // access control
|
decl->access, // access control
|
||||||
decl->type, // type
|
decl->type, // type
|
||||||
false, // is_const
|
false, // is_const
|
||||||
constructor, // constructor
|
constructor, // constructor
|
||||||
ast::DecorationList{}); // decorations
|
ast::AttributeList{}); // attributes
|
||||||
|
|
||||||
return create<ast::VariableDeclStatement>(var->source, var);
|
return create<ast::VariableDeclStatement>(var->source, var);
|
||||||
}
|
}
|
||||||
@ -2809,20 +2809,20 @@ Expect<const ast::Expression*> ParserImpl::expect_const_expr() {
|
|||||||
return add_error(peek(), "unable to parse const_expr");
|
return add_error(peek(), "unable to parse const_expr");
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<ast::DecorationList> ParserImpl::decoration_list() {
|
Maybe<ast::AttributeList> ParserImpl::attribute_list() {
|
||||||
bool errored = false;
|
bool errored = false;
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
ast::DecorationList decos;
|
ast::AttributeList attrs;
|
||||||
|
|
||||||
while (continue_parsing()) {
|
while (continue_parsing()) {
|
||||||
if (match(Token::Type::kAttr)) {
|
if (match(Token::Type::kAttr)) {
|
||||||
if (auto deco = expect_decoration(); deco.errored) {
|
if (auto attr = expect_attribute(); attr.errored) {
|
||||||
errored = true;
|
errored = true;
|
||||||
} else {
|
} else {
|
||||||
decos.emplace_back(deco.value);
|
attrs.emplace_back(attr.value);
|
||||||
}
|
}
|
||||||
} else { // [DEPRECATED] - old [[decoration]] style
|
} else { // [DEPRECATED] - old [[attribute]] style
|
||||||
auto list = decoration_bracketed_list(decos);
|
auto list = attribute_bracketed_list(attrs);
|
||||||
if (list.errored) {
|
if (list.errored) {
|
||||||
errored = true;
|
errored = true;
|
||||||
}
|
}
|
||||||
@ -2840,11 +2840,11 @@ Maybe<ast::DecorationList> ParserImpl::decoration_list() {
|
|||||||
if (!matched)
|
if (!matched)
|
||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
|
|
||||||
return decos;
|
return attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<bool> ParserImpl::decoration_bracketed_list(ast::DecorationList& decos) {
|
Maybe<bool> ParserImpl::attribute_bracketed_list(ast::AttributeList& attrs) {
|
||||||
const char* use = "decoration list";
|
const char* use = "attribute list";
|
||||||
|
|
||||||
Source source;
|
Source source;
|
||||||
if (!match(Token::Type::kAttrLeft, &source)) {
|
if (!match(Token::Type::kAttrLeft, &source)) {
|
||||||
@ -2852,28 +2852,28 @@ Maybe<bool> ParserImpl::decoration_bracketed_list(ast::DecorationList& decos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deprecated(source,
|
deprecated(source,
|
||||||
"[[decoration]] style decorations have been replaced with "
|
"[[attribute]] style attributes have been replaced with "
|
||||||
"@decoration style");
|
"@attribute style");
|
||||||
|
|
||||||
if (match(Token::Type::kAttrRight, &source))
|
if (match(Token::Type::kAttrRight, &source))
|
||||||
return add_error(source, "empty decoration list");
|
return add_error(source, "empty attribute list");
|
||||||
|
|
||||||
return sync(Token::Type::kAttrRight, [&]() -> Expect<bool> {
|
return sync(Token::Type::kAttrRight, [&]() -> Expect<bool> {
|
||||||
bool errored = false;
|
bool errored = false;
|
||||||
|
|
||||||
while (continue_parsing()) {
|
while (continue_parsing()) {
|
||||||
auto deco = expect_decoration();
|
auto attr = expect_attribute();
|
||||||
if (deco.errored) {
|
if (attr.errored) {
|
||||||
errored = true;
|
errored = true;
|
||||||
}
|
}
|
||||||
decos.emplace_back(deco.value);
|
attrs.emplace_back(attr.value);
|
||||||
|
|
||||||
if (match(Token::Type::kComma)) {
|
if (match(Token::Type::kComma)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_decoration(peek())) {
|
if (is_attribute(peek())) {
|
||||||
// We have two decorations in a bracket without a separating comma.
|
// We have two attributes in a bracket without a separating comma.
|
||||||
// e.g. @location(1) group(2)
|
// e.g. @location(1) group(2)
|
||||||
// ^^^ expected comma
|
// ^^^ expected comma
|
||||||
expect(use, Token::Type::kComma);
|
expect(use, Token::Type::kComma);
|
||||||
@ -2895,59 +2895,59 @@ Maybe<bool> ParserImpl::decoration_bracketed_list(ast::DecorationList& decos) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect<const ast::Decoration*> ParserImpl::expect_decoration() {
|
Expect<const ast::Attribute*> ParserImpl::expect_attribute() {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
auto deco = decoration();
|
auto attr = attribute();
|
||||||
if (deco.errored)
|
if (attr.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
if (deco.matched)
|
if (attr.matched)
|
||||||
return deco.value;
|
return attr.value;
|
||||||
return add_error(t, "expected decoration");
|
return add_error(t, "expected attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<const ast::Decoration*> ParserImpl::decoration() {
|
Maybe<const ast::Attribute*> ParserImpl::attribute() {
|
||||||
using Result = Maybe<const ast::Decoration*>;
|
using Result = Maybe<const ast::Attribute*>;
|
||||||
auto t = next();
|
auto t = next();
|
||||||
|
|
||||||
if (!t.IsIdentifier()) {
|
if (!t.IsIdentifier()) {
|
||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kLocationDecoration) {
|
if (t == kLocationAttribute) {
|
||||||
const char* use = "location decoration";
|
const char* use = "location attribute";
|
||||||
return expect_paren_block(use, [&]() -> Result {
|
return expect_paren_block(use, [&]() -> Result {
|
||||||
auto val = expect_positive_sint(use);
|
auto val = expect_positive_sint(use);
|
||||||
if (val.errored)
|
if (val.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return create<ast::LocationDecoration>(t.source(), val.value);
|
return create<ast::LocationAttribute>(t.source(), val.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kBindingDecoration) {
|
if (t == kBindingAttribute) {
|
||||||
const char* use = "binding decoration";
|
const char* use = "binding attribute";
|
||||||
return expect_paren_block(use, [&]() -> Result {
|
return expect_paren_block(use, [&]() -> Result {
|
||||||
auto val = expect_positive_sint(use);
|
auto val = expect_positive_sint(use);
|
||||||
if (val.errored)
|
if (val.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return create<ast::BindingDecoration>(t.source(), val.value);
|
return create<ast::BindingAttribute>(t.source(), val.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kGroupDecoration) {
|
if (t == kGroupAttribute) {
|
||||||
const char* use = "group decoration";
|
const char* use = "group attribute";
|
||||||
return expect_paren_block(use, [&]() -> Result {
|
return expect_paren_block(use, [&]() -> Result {
|
||||||
auto val = expect_positive_sint(use);
|
auto val = expect_positive_sint(use);
|
||||||
if (val.errored)
|
if (val.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return create<ast::GroupDecoration>(t.source(), val.value);
|
return create<ast::GroupAttribute>(t.source(), val.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kInterpolateDecoration) {
|
if (t == kInterpolateAttribute) {
|
||||||
return expect_paren_block("interpolate decoration", [&]() -> Result {
|
return expect_paren_block("interpolate attribute", [&]() -> Result {
|
||||||
ast::InterpolationType type;
|
ast::InterpolationType type;
|
||||||
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
|
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
|
||||||
|
|
||||||
@ -2975,26 +2975,26 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return create<ast::InterpolateDecoration>(t.source(), type, sampling);
|
return create<ast::InterpolateAttribute>(t.source(), type, sampling);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kInvariantDecoration) {
|
if (t == kInvariantAttribute) {
|
||||||
return create<ast::InvariantDecoration>(t.source());
|
return create<ast::InvariantAttribute>(t.source());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kBuiltinDecoration) {
|
if (t == kBuiltinAttribute) {
|
||||||
return expect_paren_block("builtin decoration", [&]() -> Result {
|
return expect_paren_block("builtin attribute", [&]() -> Result {
|
||||||
auto builtin = expect_builtin();
|
auto builtin = expect_builtin();
|
||||||
if (builtin.errored)
|
if (builtin.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return create<ast::BuiltinDecoration>(t.source(), builtin.value);
|
return create<ast::BuiltinAttribute>(t.source(), builtin.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kWorkgroupSizeDecoration) {
|
if (t == kWorkgroupSizeAttribute) {
|
||||||
return expect_paren_block("workgroup_size decoration", [&]() -> Result {
|
return expect_paren_block("workgroup_size attribute", [&]() -> Result {
|
||||||
const ast::Expression* x = nullptr;
|
const ast::Expression* x = nullptr;
|
||||||
const ast::Expression* y = nullptr;
|
const ast::Expression* y = nullptr;
|
||||||
const ast::Expression* z = nullptr;
|
const ast::Expression* z = nullptr;
|
||||||
@ -3027,27 +3027,27 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return create<ast::WorkgroupDecoration>(t.source(), x, y, z);
|
return create<ast::WorkgroupAttribute>(t.source(), x, y, z);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kStageDecoration) {
|
if (t == kStageAttribute) {
|
||||||
return expect_paren_block("stage decoration", [&]() -> Result {
|
return expect_paren_block("stage attribute", [&]() -> Result {
|
||||||
auto stage = expect_pipeline_stage();
|
auto stage = expect_pipeline_stage();
|
||||||
if (stage.errored)
|
if (stage.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return create<ast::StageDecoration>(t.source(), stage.value);
|
return create<ast::StageAttribute>(t.source(), stage.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kBlockDecoration) {
|
if (t == kBlockAttribute) {
|
||||||
deprecated(t.source(), "[[block]] attributes have been removed from WGSL");
|
deprecated(t.source(), "[[block]] attributes have been removed from WGSL");
|
||||||
return create<ast::StructBlockDecoration>(t.source());
|
return create<ast::StructBlockAttribute>(t.source());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kStrideDecoration) {
|
if (t == kStrideAttribute) {
|
||||||
const char* use = "stride decoration";
|
const char* use = "stride attribute";
|
||||||
return expect_paren_block(use, [&]() -> Result {
|
return expect_paren_block(use, [&]() -> Result {
|
||||||
auto val = expect_nonzero_positive_sint(use);
|
auto val = expect_nonzero_positive_sint(use);
|
||||||
if (val.errored)
|
if (val.errored)
|
||||||
@ -3055,34 +3055,34 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
|
|||||||
deprecated(t.source(),
|
deprecated(t.source(),
|
||||||
"the @stride attribute is deprecated; use a larger type if "
|
"the @stride attribute is deprecated; use a larger type if "
|
||||||
"necessary");
|
"necessary");
|
||||||
return create<ast::StrideDecoration>(t.source(), val.value);
|
return create<ast::StrideAttribute>(t.source(), val.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kSizeDecoration) {
|
if (t == kSizeAttribute) {
|
||||||
const char* use = "size decoration";
|
const char* use = "size attribute";
|
||||||
return expect_paren_block(use, [&]() -> Result {
|
return expect_paren_block(use, [&]() -> Result {
|
||||||
auto val = expect_positive_sint(use);
|
auto val = expect_positive_sint(use);
|
||||||
if (val.errored)
|
if (val.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return create<ast::StructMemberSizeDecoration>(t.source(), val.value);
|
return create<ast::StructMemberSizeAttribute>(t.source(), val.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kAlignDecoration) {
|
if (t == kAlignAttribute) {
|
||||||
const char* use = "align decoration";
|
const char* use = "align attribute";
|
||||||
return expect_paren_block(use, [&]() -> Result {
|
return expect_paren_block(use, [&]() -> Result {
|
||||||
auto val = expect_positive_sint(use);
|
auto val = expect_positive_sint(use);
|
||||||
if (val.errored)
|
if (val.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return create<ast::StructMemberAlignDecoration>(t.source(), val.value);
|
return create<ast::StructMemberAlignAttribute>(t.source(), val.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == kOverrideDecoration) {
|
if (t == kOverrideAttribute) {
|
||||||
const char* use = "override decoration";
|
const char* use = "override attribute";
|
||||||
|
|
||||||
if (peek_is(Token::Type::kParenLeft)) {
|
if (peek_is(Token::Type::kParenLeft)) {
|
||||||
// @override(x)
|
// @override(x)
|
||||||
@ -3091,22 +3091,22 @@ Maybe<const ast::Decoration*> ParserImpl::decoration() {
|
|||||||
if (val.errored)
|
if (val.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return create<ast::OverrideDecoration>(t.source(), val.value);
|
return create<ast::OverrideAttribute>(t.source(), val.value);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// [[override]]
|
// [[override]]
|
||||||
return create<ast::OverrideDecoration>(t.source());
|
return create<ast::OverrideAttribute>(t.source());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParserImpl::expect_decorations_consumed(ast::DecorationList& in) {
|
bool ParserImpl::expect_attributes_consumed(ast::AttributeList& in) {
|
||||||
if (in.empty()) {
|
if (in.empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
add_error(in[0]->source, "unexpected decorations");
|
add_error(in[0]->source, "unexpected attributes");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,12 +239,12 @@ class ParserImpl {
|
|||||||
/// @param n function name
|
/// @param n function name
|
||||||
/// @param p function parameters
|
/// @param p function parameters
|
||||||
/// @param ret_ty function return type
|
/// @param ret_ty function return type
|
||||||
/// @param ret_decos return type decorations
|
/// @param ret_attrs return type attributes
|
||||||
FunctionHeader(Source src,
|
FunctionHeader(Source src,
|
||||||
std::string n,
|
std::string n,
|
||||||
ast::VariableList p,
|
ast::VariableList p,
|
||||||
const ast::Type* ret_ty,
|
const ast::Type* ret_ty,
|
||||||
ast::DecorationList ret_decos);
|
ast::AttributeList ret_attrs);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~FunctionHeader();
|
~FunctionHeader();
|
||||||
/// Assignment operator
|
/// Assignment operator
|
||||||
@ -260,8 +260,8 @@ class ParserImpl {
|
|||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
/// Function return type
|
/// Function return type
|
||||||
const ast::Type* return_type = nullptr;
|
const ast::Type* return_type = nullptr;
|
||||||
/// Function return type decorations
|
/// Function return type attributes
|
||||||
ast::DecorationList return_type_decorations;
|
ast::AttributeList return_type_attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// VarDeclInfo contains the parsed information for variable declaration.
|
/// VarDeclInfo contains the parsed information for variable declaration.
|
||||||
@ -387,15 +387,15 @@ class ParserImpl {
|
|||||||
/// @return true on parse success, otherwise an error.
|
/// @return true on parse success, otherwise an error.
|
||||||
Expect<bool> expect_global_decl();
|
Expect<bool> expect_global_decl();
|
||||||
/// Parses a `global_variable_decl` grammar element with the initial
|
/// Parses a `global_variable_decl` grammar element with the initial
|
||||||
/// `variable_decoration_list*` provided as `decos`
|
/// `variable_attribute_list*` provided as `attrs`
|
||||||
/// @returns the variable parsed or nullptr
|
/// @returns the variable parsed or nullptr
|
||||||
/// @param decos the list of decorations for the variable declaration.
|
/// @param attrs the list of attributes for the variable declaration.
|
||||||
Maybe<const ast::Variable*> global_variable_decl(ast::DecorationList& decos);
|
Maybe<const ast::Variable*> global_variable_decl(ast::AttributeList& attrs);
|
||||||
/// Parses a `global_constant_decl` grammar element with the initial
|
/// Parses a `global_constant_decl` grammar element with the initial
|
||||||
/// `variable_decoration_list*` provided as `decos`
|
/// `variable_attribute_list*` provided as `attrs`
|
||||||
/// @returns the const object or nullptr
|
/// @returns the const object or nullptr
|
||||||
/// @param decos the list of decorations for the constant declaration.
|
/// @param attrs the list of attributes for the constant declaration.
|
||||||
Maybe<const ast::Variable*> global_constant_decl(ast::DecorationList& decos);
|
Maybe<const ast::Variable*> global_constant_decl(ast::AttributeList& attrs);
|
||||||
/// Parses a `variable_decl` grammar element
|
/// Parses a `variable_decl` grammar element
|
||||||
/// @param allow_inferred if true, do not fail if variable decl does not
|
/// @param allow_inferred if true, do not fail if variable decl does not
|
||||||
/// specify type
|
/// specify type
|
||||||
@ -420,33 +420,33 @@ class ParserImpl {
|
|||||||
/// @returns the parsed Type or nullptr if none matched.
|
/// @returns the parsed Type or nullptr if none matched.
|
||||||
Maybe<const ast::Type*> type_decl();
|
Maybe<const ast::Type*> type_decl();
|
||||||
/// Parses a `type_decl` grammar element with the given pre-parsed
|
/// Parses a `type_decl` grammar element with the given pre-parsed
|
||||||
/// decorations.
|
/// attributes.
|
||||||
/// @param decos the list of decorations for the type.
|
/// @param attrs the list of attributes for the type.
|
||||||
/// @returns the parsed Type or nullptr if none matched.
|
/// @returns the parsed Type or nullptr if none matched.
|
||||||
Maybe<const ast::Type*> type_decl(ast::DecorationList& decos);
|
Maybe<const ast::Type*> type_decl(ast::AttributeList& attrs);
|
||||||
/// Parses a `storage_class` grammar element, erroring on parse failure.
|
/// Parses a `storage_class` grammar element, erroring on parse failure.
|
||||||
/// @param use a description of what was being parsed if an error was raised.
|
/// @param use a description of what was being parsed if an error was raised.
|
||||||
/// @returns the storage class or StorageClass::kNone if none matched
|
/// @returns the storage class or StorageClass::kNone if none matched
|
||||||
Expect<ast::StorageClass> expect_storage_class(std::string_view use);
|
Expect<ast::StorageClass> expect_storage_class(std::string_view use);
|
||||||
/// Parses a `struct_decl` grammar element with the initial
|
/// Parses a `struct_decl` grammar element with the initial
|
||||||
/// `struct_decoration_decl*` provided as `decos`.
|
/// `struct_attribute_decl*` provided as `attrs`.
|
||||||
/// @returns the struct type or nullptr on error
|
/// @returns the struct type or nullptr on error
|
||||||
/// @param decos the list of decorations for the struct declaration.
|
/// @param attrs the list of attributes for the struct declaration.
|
||||||
Maybe<const ast::Struct*> struct_decl(ast::DecorationList& decos);
|
Maybe<const ast::Struct*> struct_decl(ast::AttributeList& attrs);
|
||||||
/// Parses a `struct_body_decl` grammar element, erroring on parse failure.
|
/// Parses a `struct_body_decl` grammar element, erroring on parse failure.
|
||||||
/// @returns the struct members
|
/// @returns the struct members
|
||||||
Expect<ast::StructMemberList> expect_struct_body_decl();
|
Expect<ast::StructMemberList> expect_struct_body_decl();
|
||||||
/// Parses a `struct_member` grammar element with the initial
|
/// Parses a `struct_member` grammar element with the initial
|
||||||
/// `struct_member_decoration_decl+` provided as `decos`, erroring on parse
|
/// `struct_member_attribute_decl+` provided as `attrs`, erroring on parse
|
||||||
/// failure.
|
/// failure.
|
||||||
/// @param decos the list of decorations for the struct member.
|
/// @param attrs the list of attributes for the struct member.
|
||||||
/// @returns the struct member or nullptr
|
/// @returns the struct member or nullptr
|
||||||
Expect<ast::StructMember*> expect_struct_member(ast::DecorationList& decos);
|
Expect<ast::StructMember*> expect_struct_member(ast::AttributeList& attrs);
|
||||||
/// Parses a `function_decl` grammar element with the initial
|
/// Parses a `function_decl` grammar element with the initial
|
||||||
/// `function_decoration_decl*` provided as `decos`.
|
/// `function_attribute_decl*` provided as `attrs`.
|
||||||
/// @param decos the list of decorations for the function declaration.
|
/// @param attrs the list of attributes for the function declaration.
|
||||||
/// @returns the parsed function, nullptr otherwise
|
/// @returns the parsed function, nullptr otherwise
|
||||||
Maybe<const ast::Function*> function_decl(ast::DecorationList& decos);
|
Maybe<const ast::Function*> function_decl(ast::AttributeList& attrs);
|
||||||
/// Parses a `texture_sampler_types` grammar element
|
/// Parses a `texture_sampler_types` grammar element
|
||||||
/// @returns the parsed Type or nullptr if none matched.
|
/// @returns the parsed Type or nullptr if none matched.
|
||||||
Maybe<const ast::Type*> texture_sampler_types();
|
Maybe<const ast::Type*> texture_sampler_types();
|
||||||
@ -670,28 +670,28 @@ class ParserImpl {
|
|||||||
/// Parses a `assignment_stmt` grammar element
|
/// Parses a `assignment_stmt` grammar element
|
||||||
/// @returns the parsed assignment or nullptr
|
/// @returns the parsed assignment or nullptr
|
||||||
Maybe<const ast::AssignmentStatement*> assignment_stmt();
|
Maybe<const ast::AssignmentStatement*> assignment_stmt();
|
||||||
/// Parses one or more decoration lists.
|
/// Parses one or more attribute lists.
|
||||||
/// @return the parsed decoration list, or an empty list on error.
|
/// @return the parsed attribute list, or an empty list on error.
|
||||||
Maybe<ast::DecorationList> decoration_list();
|
Maybe<ast::AttributeList> attribute_list();
|
||||||
/// Parses a list of decorations between `ATTR_LEFT` and `ATTR_RIGHT`
|
/// Parses a list of attributes between `ATTR_LEFT` and `ATTR_RIGHT`
|
||||||
/// brackets.
|
/// brackets.
|
||||||
/// @param decos the list to append newly parsed decorations to.
|
/// @param attrs the list to append newly parsed attributes to.
|
||||||
/// @return true if any decorations were be parsed, otherwise false.
|
/// @return true if any attributes were be parsed, otherwise false.
|
||||||
Maybe<bool> decoration_bracketed_list(ast::DecorationList& decos);
|
Maybe<bool> attribute_bracketed_list(ast::AttributeList& attrs);
|
||||||
/// Parses a single decoration of the following types:
|
/// Parses a single attribute of the following types:
|
||||||
/// * `struct_decoration`
|
/// * `struct_attribute`
|
||||||
/// * `struct_member_decoration`
|
/// * `struct_member_attribute`
|
||||||
/// * `array_decoration`
|
/// * `array_attribute`
|
||||||
/// * `variable_decoration`
|
/// * `variable_attribute`
|
||||||
/// * `global_const_decoration`
|
/// * `global_const_attribute`
|
||||||
/// * `function_decoration`
|
/// * `function_attribute`
|
||||||
/// @return the parsed decoration, or nullptr.
|
/// @return the parsed attribute, or nullptr.
|
||||||
Maybe<const ast::Decoration*> decoration();
|
Maybe<const ast::Attribute*> attribute();
|
||||||
/// Parses a single decoration, reporting an error if the next token does not
|
/// Parses a single attribute, reporting an error if the next token does not
|
||||||
/// represent a decoration.
|
/// represent a attribute.
|
||||||
/// @see #decoration for the full list of decorations this method parses.
|
/// @see #attribute for the full list of attributes this method parses.
|
||||||
/// @return the parsed decoration, or nullptr on error.
|
/// @return the parsed attribute, or nullptr on error.
|
||||||
Expect<const ast::Decoration*> expect_decoration();
|
Expect<const ast::Attribute*> expect_attribute();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// ReturnType resolves to the return type for the function or lambda F.
|
/// ReturnType resolves to the return type for the function or lambda F.
|
||||||
@ -843,15 +843,15 @@ class ParserImpl {
|
|||||||
template <typename F, typename T = ReturnType<F>>
|
template <typename F, typename T = ReturnType<F>>
|
||||||
T without_error(F&& func);
|
T without_error(F&& func);
|
||||||
|
|
||||||
/// Reports an error if the decoration list `list` is not empty.
|
/// Reports an error if the attribute list `list` is not empty.
|
||||||
/// Used to ensure that all decorations are consumed.
|
/// Used to ensure that all attributes are consumed.
|
||||||
bool expect_decorations_consumed(ast::DecorationList& list);
|
bool expect_attributes_consumed(ast::AttributeList& list);
|
||||||
|
|
||||||
Expect<const ast::Type*> expect_type_decl_pointer(Token t);
|
Expect<const ast::Type*> expect_type_decl_pointer(Token t);
|
||||||
Expect<const ast::Type*> expect_type_decl_atomic(Token t);
|
Expect<const ast::Type*> expect_type_decl_atomic(Token t);
|
||||||
Expect<const ast::Type*> expect_type_decl_vector(Token t);
|
Expect<const ast::Type*> expect_type_decl_vector(Token t);
|
||||||
Expect<const ast::Type*> expect_type_decl_array(Token t,
|
Expect<const ast::Type*> expect_type_decl_array(Token t,
|
||||||
ast::DecorationList decos);
|
ast::AttributeList attrs);
|
||||||
Expect<const ast::Type*> expect_type_decl_matrix(Token t);
|
Expect<const ast::Type*> expect_type_decl_matrix(Token t);
|
||||||
|
|
||||||
Expect<const ast::Type*> expect_type(std::string_view use);
|
Expect<const ast::Type*> expect_type(std::string_view use);
|
||||||
|
@ -53,23 +53,23 @@ fn f() { return 1 & >; }
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, AliasDeclInvalidDeco) {
|
TEST_F(ParserImplErrorTest, AliasDeclInvalidAttribute) {
|
||||||
EXPECT("@override type e=u32;",
|
EXPECT("@override type e=u32;",
|
||||||
R"(test.wgsl:1:2 error: unexpected decorations
|
R"(test.wgsl:1:2 error: unexpected attributes
|
||||||
@override type e=u32;
|
@override type e=u32;
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_AliasDeclInvalidDeco) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_AliasDeclInvalidAttribute) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[override]]type e=u32;",
|
"[[override]]type e=u32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[override]]type e=u32;
|
[[override]]type e=u32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:3 error: unexpected decorations
|
test.wgsl:1:3 error: unexpected attributes
|
||||||
[[override]]type e=u32;
|
[[override]]type e=u32;
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
)");
|
)");
|
||||||
@ -322,61 +322,61 @@ fn f() { for (var i : i32 = 0; i < 8; i=i+1) {
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageMissingLParen) {
|
TEST_F(ParserImplErrorTest, FunctionDeclStageMissingLParen) {
|
||||||
EXPECT("@stage vertex) fn f() {}",
|
EXPECT("@stage vertex) fn f() {}",
|
||||||
R"(test.wgsl:1:8 error: expected '(' for stage decoration
|
R"(test.wgsl:1:8 error: expected '(' for stage attribute
|
||||||
@stage vertex) fn f() {}
|
@stage vertex) fn f() {}
|
||||||
^^^^^^
|
^^^^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageMissingRParen) {
|
TEST_F(ParserImplErrorTest, FunctionDeclStageMissingRParen) {
|
||||||
EXPECT("@stage(vertex fn f() {}",
|
EXPECT("@stage(vertex fn f() {}",
|
||||||
R"(test.wgsl:1:15 error: expected ')' for stage decoration
|
R"(test.wgsl:1:15 error: expected ')' for stage attribute
|
||||||
@stage(vertex fn f() {}
|
@stage(vertex fn f() {}
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclDecoStageMissingLParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStageMissingLParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[stage vertex]] fn f() {}",
|
"[[stage vertex]] fn f() {}",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[stage vertex]] fn f() {}
|
[[stage vertex]] fn f() {}
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:9 error: expected '(' for stage decoration
|
test.wgsl:1:9 error: expected '(' for stage attribute
|
||||||
[[stage vertex]] fn f() {}
|
[[stage vertex]] fn f() {}
|
||||||
^^^^^^
|
^^^^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclDecoStageMissingRParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStageMissingRParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[stage(vertex]] fn f() {}",
|
"[[stage(vertex]] fn f() {}",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[stage(vertex]] fn f() {}
|
[[stage(vertex]] fn f() {}
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:15 error: expected ')' for stage decoration
|
test.wgsl:1:15 error: expected ')' for stage attribute
|
||||||
[[stage(vertex]] fn f() {}
|
[[stage(vertex]] fn f() {}
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageInvalid) {
|
TEST_F(ParserImplErrorTest, FunctionDeclStageInvalid) {
|
||||||
EXPECT("@stage(x) fn f() {}",
|
EXPECT("@stage(x) fn f() {}",
|
||||||
R"(test.wgsl:1:8 error: invalid value for stage decoration
|
R"(test.wgsl:1:8 error: invalid value for stage attribute
|
||||||
@stage(x) fn f() {}
|
@stage(x) fn f() {}
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoStageTypeInvalid) {
|
TEST_F(ParserImplErrorTest, FunctionDeclStageTypeInvalid) {
|
||||||
EXPECT("@shader(vertex) fn main() {}",
|
EXPECT("@shader(vertex) fn main() {}",
|
||||||
R"(test.wgsl:1:2 error: expected decoration
|
R"(test.wgsl:1:2 error: expected attribute
|
||||||
@shader(vertex) fn main() {}
|
@shader(vertex) fn main() {}
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
@ -387,36 +387,34 @@ test.wgsl:1:8 error: unexpected token
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest,
|
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclWorkgroupSizeMissingLParen) {
|
||||||
DEPRECATED_FunctionDeclDecoWorkgroupSizeMissingLParen) {
|
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[workgroup_size 1]] fn f() {}",
|
"[[workgroup_size 1]] fn f() {}",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[workgroup_size 1]] fn f() {}
|
[[workgroup_size 1]] fn f() {}
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:18 error: expected '(' for workgroup_size decoration
|
test.wgsl:1:18 error: expected '(' for workgroup_size attribute
|
||||||
[[workgroup_size 1]] fn f() {}
|
[[workgroup_size 1]] fn f() {}
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest,
|
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclWorkgroupSizeMissingRParen) {
|
||||||
DEPRECATED_FunctionDeclDecoWorkgroupSizeMissingRParen) {
|
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[workgroup_size(1]] fn f() {}",
|
"[[workgroup_size(1]] fn f() {}",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[workgroup_size(1]] fn f() {}
|
[[workgroup_size(1]] fn f() {}
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:19 error: expected ')' for workgroup_size decoration
|
test.wgsl:1:19 error: expected ')' for workgroup_size attribute
|
||||||
[[workgroup_size(1]] fn f() {}
|
[[workgroup_size(1]] fn f() {}
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeXInvalid) {
|
TEST_F(ParserImplErrorTest, FunctionDeclWorkgroupSizeXInvalid) {
|
||||||
EXPECT("@workgroup_size() fn f() {}",
|
EXPECT("@workgroup_size() fn f() {}",
|
||||||
R"(test.wgsl:1:17 error: expected workgroup_size x parameter
|
R"(test.wgsl:1:17 error: expected workgroup_size x parameter
|
||||||
@workgroup_size() fn f() {}
|
@workgroup_size() fn f() {}
|
||||||
@ -424,7 +422,7 @@ TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeXInvalid) {
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeYInvalid) {
|
TEST_F(ParserImplErrorTest, FunctionDeclWorkgroupSizeYInvalid) {
|
||||||
EXPECT("@workgroup_size(1, ) fn f() {}",
|
EXPECT("@workgroup_size(1, ) fn f() {}",
|
||||||
R"(test.wgsl:1:20 error: expected workgroup_size y parameter
|
R"(test.wgsl:1:20 error: expected workgroup_size y parameter
|
||||||
@workgroup_size(1, ) fn f() {}
|
@workgroup_size(1, ) fn f() {}
|
||||||
@ -432,7 +430,7 @@ TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeYInvalid) {
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeZInvalid) {
|
TEST_F(ParserImplErrorTest, FunctionDeclWorkgroupSizeZInvalid) {
|
||||||
EXPECT("@workgroup_size(1, 2, ) fn f() {}",
|
EXPECT("@workgroup_size(1, 2, ) fn f() {}",
|
||||||
R"(test.wgsl:1:23 error: expected workgroup_size z parameter
|
R"(test.wgsl:1:23 error: expected workgroup_size z parameter
|
||||||
@workgroup_size(1, 2, ) fn f() {}
|
@workgroup_size(1, 2, ) fn f() {}
|
||||||
@ -517,7 +515,7 @@ fn f() {
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, FunctionScopeUnusedDecl) {
|
TEST_F(ParserImplErrorTest, FunctionScopeUnusedDecl) {
|
||||||
EXPECT("fn f(a:i32)->i32{return a;@size(1)}",
|
EXPECT("fn f(a:i32)->i32{return a;@size(1)}",
|
||||||
R"(test.wgsl:1:28 error: unexpected decorations
|
R"(test.wgsl:1:28 error: unexpected attributes
|
||||||
fn f(a:i32)->i32{return a;@size(1)}
|
fn f(a:i32)->i32{return a;@size(1)}
|
||||||
^^^^
|
^^^^
|
||||||
)");
|
)");
|
||||||
@ -639,9 +637,9 @@ let i : vec2<i32> = vec2<i32>(1, 2;
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclInvalidDeco) {
|
TEST_F(ParserImplErrorTest, GlobalDeclInvalidAttribute) {
|
||||||
EXPECT("@stage(vertex) x;",
|
EXPECT("@stage(vertex) x;",
|
||||||
R"(test.wgsl:1:16 error: expected declaration after decorations
|
R"(test.wgsl:1:16 error: expected declaration after attributes
|
||||||
@stage(vertex) x;
|
@stage(vertex) x;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -728,10 +726,10 @@ var x : texture_storage_2d<1>;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
|
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructDecoMissingStruct) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructAttrMissingStruct) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[block]];",
|
"[[block]];",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[block]];
|
[[block]];
|
||||||
^^
|
^^
|
||||||
|
|
||||||
@ -739,17 +737,17 @@ test.wgsl:1:3 warning: use of deprecated language feature: [[block]] attributes
|
|||||||
[[block]];
|
[[block]];
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
||||||
test.wgsl:1:10 error: expected declaration after decorations
|
test.wgsl:1:10 error: expected declaration after attributes
|
||||||
[[block]];
|
[[block]];
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
|
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructDecoMissingEnd) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructAttrMissingEnd) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[block struct {};",
|
"[[block struct {};",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[block struct {};
|
[[block struct {};
|
||||||
^^
|
^^
|
||||||
|
|
||||||
@ -757,7 +755,7 @@ test.wgsl:1:3 warning: use of deprecated language feature: [[block]] attributes
|
|||||||
[[block struct {};
|
[[block struct {};
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
||||||
test.wgsl:1:9 error: expected ']]' for decoration list
|
test.wgsl:1:9 error: expected ']]' for attribute list
|
||||||
[[block struct {};
|
[[block struct {};
|
||||||
^^^^^^
|
^^^^^^
|
||||||
)");
|
)");
|
||||||
@ -788,28 +786,28 @@ struct S { i : i32;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberDecoEmpty) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberAttrEmpty) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"struct S { [[]] i : i32; };",
|
"struct S { [[]] i : i32; };",
|
||||||
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
struct S { [[]] i : i32; };
|
struct S { [[]] i : i32; };
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:14 error: empty decoration list
|
test.wgsl:1:14 error: empty attribute list
|
||||||
struct S { [[]] i : i32; };
|
struct S { [[]] i : i32; };
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberDecoMissingEnd) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStructMemberAttrMissingEnd) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"struct S { [[ i : i32; };",
|
"struct S { [[ i : i32; };",
|
||||||
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
struct S { [[ i : i32; };
|
struct S { [[ i : i32; };
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:15 error: expected decoration
|
test.wgsl:1:15 error: expected attribute
|
||||||
struct S { [[ i : i32; };
|
struct S { [[ i : i32; };
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -836,11 +834,11 @@ TEST_F(ParserImplErrorTest,
|
|||||||
DEPRECATED_GlobalDeclStructMemberAlignMissingLParen) {
|
DEPRECATED_GlobalDeclStructMemberAlignMissingLParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"struct S { [[align 1)]] i : i32; };",
|
"struct S { [[align 1)]] i : i32; };",
|
||||||
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
struct S { [[align 1)]] i : i32; };
|
struct S { [[align 1)]] i : i32; };
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:20 error: expected '(' for align decoration
|
test.wgsl:1:20 error: expected '(' for align attribute
|
||||||
struct S { [[align 1)]] i : i32; };
|
struct S { [[align 1)]] i : i32; };
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -851,11 +849,11 @@ TEST_F(ParserImplErrorTest,
|
|||||||
DEPRECATED_GlobalDeclStructMemberAlignMissingRParen) {
|
DEPRECATED_GlobalDeclStructMemberAlignMissingRParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"struct S { [[align(1]] i : i32; };",
|
"struct S { [[align(1]] i : i32; };",
|
||||||
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
struct S { [[align(1]] i : i32; };
|
struct S { [[align(1]] i : i32; };
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:21 error: expected ')' for align decoration
|
test.wgsl:1:21 error: expected ')' for align attribute
|
||||||
struct S { [[align(1]] i : i32; };
|
struct S { [[align(1]] i : i32; };
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
@ -864,7 +862,7 @@ struct S { [[align(1]] i : i32; };
|
|||||||
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignInvaldValue) {
|
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignInvaldValue) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"struct S { @align(x) i : i32; };",
|
"struct S { @align(x) i : i32; };",
|
||||||
R"(test.wgsl:1:19 error: expected signed integer literal for align decoration
|
R"(test.wgsl:1:19 error: expected signed integer literal for align attribute
|
||||||
struct S { @align(x) i : i32; };
|
struct S { @align(x) i : i32; };
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -872,7 +870,7 @@ struct S { @align(x) i : i32; };
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignNegativeValue) {
|
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberAlignNegativeValue) {
|
||||||
EXPECT("struct S { @align(-2) i : i32; };",
|
EXPECT("struct S { @align(-2) i : i32; };",
|
||||||
R"(test.wgsl:1:19 error: align decoration must be positive
|
R"(test.wgsl:1:19 error: align attribute must be positive
|
||||||
struct S { @align(-2) i : i32; };
|
struct S { @align(-2) i : i32; };
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
@ -883,11 +881,11 @@ TEST_F(ParserImplErrorTest,
|
|||||||
DEPRECATED_GlobalDeclStructMemberSizeMissingLParen) {
|
DEPRECATED_GlobalDeclStructMemberSizeMissingLParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"struct S { [[size 1)]] i : i32; };",
|
"struct S { [[size 1)]] i : i32; };",
|
||||||
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
struct S { [[size 1)]] i : i32; };
|
struct S { [[size 1)]] i : i32; };
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:19 error: expected '(' for size decoration
|
test.wgsl:1:19 error: expected '(' for size attribute
|
||||||
struct S { [[size 1)]] i : i32; };
|
struct S { [[size 1)]] i : i32; };
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -898,11 +896,11 @@ TEST_F(ParserImplErrorTest,
|
|||||||
DEPRECATED_GlobalDeclStructMemberSizeMissingRParen) {
|
DEPRECATED_GlobalDeclStructMemberSizeMissingRParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"struct S { [[size(1]] i : i32; };",
|
"struct S { [[size(1]] i : i32; };",
|
||||||
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:12 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
struct S { [[size(1]] i : i32; };
|
struct S { [[size(1]] i : i32; };
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:20 error: expected ')' for size decoration
|
test.wgsl:1:20 error: expected ')' for size attribute
|
||||||
struct S { [[size(1]] i : i32; };
|
struct S { [[size(1]] i : i32; };
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
@ -911,7 +909,7 @@ struct S { [[size(1]] i : i32; };
|
|||||||
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeInvaldValue) {
|
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeInvaldValue) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"struct S { @size(x) i : i32; };",
|
"struct S { @size(x) i : i32; };",
|
||||||
R"(test.wgsl:1:18 error: expected signed integer literal for size decoration
|
R"(test.wgsl:1:18 error: expected signed integer literal for size attribute
|
||||||
struct S { @size(x) i : i32; };
|
struct S { @size(x) i : i32; };
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -919,7 +917,7 @@ struct S { @size(x) i : i32; };
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeNegativeValue) {
|
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeNegativeValue) {
|
||||||
EXPECT("struct S { @size(-2) i : i32; };",
|
EXPECT("struct S { @size(-2) i : i32; };",
|
||||||
R"(test.wgsl:1:18 error: size decoration must be positive
|
R"(test.wgsl:1:18 error: size attribute must be positive
|
||||||
struct S { @size(-2) i : i32; };
|
struct S { @size(-2) i : i32; };
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
@ -955,14 +953,14 @@ type meow = f32
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclTypeDecoInvalid) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclTypeAttrInvalid) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"var x : [[]] i32;",
|
"var x : [[]] i32;",
|
||||||
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
var x : [[]] i32;
|
var x : [[]] i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:11 error: empty decoration list
|
test.wgsl:1:11 error: empty attribute list
|
||||||
var x : [[]] i32;
|
var x : [[]] i32;
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
@ -984,70 +982,68 @@ var i : array<u32, 3;
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoNotArray) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayAttrNotArray) {
|
||||||
EXPECT("var i : @location(1) i32;",
|
EXPECT("var i : @location(1) i32;",
|
||||||
R"(test.wgsl:1:10 error: unexpected decorations
|
R"(test.wgsl:1:10 error: unexpected attributes
|
||||||
var i : @location(1) i32;
|
var i : @location(1) i32;
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayDecoMissingEnd) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayAttrMissingEnd) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"var i : [[location(1) array<i32>;",
|
"var i : [[location(1) array<i32>;",
|
||||||
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
var i : [[location(1) array<i32>;
|
var i : [[location(1) array<i32>;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:23 error: expected ']]' for decoration list
|
test.wgsl:1:23 error: expected ']]' for attribute list
|
||||||
var i : [[location(1) array<i32>;
|
var i : [[location(1) array<i32>;
|
||||||
^^^^^
|
^^^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest,
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayStrideMissingLParen) {
|
||||||
DEPRECATED_GlobalDeclVarArrayDecoStrideMissingLParen) {
|
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"var i : [[stride 1)]] array<i32>;",
|
"var i : [[stride 1)]] array<i32>;",
|
||||||
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
var i : [[stride 1)]] array<i32>;
|
var i : [[stride 1)]] array<i32>;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:18 error: expected '(' for stride decoration
|
test.wgsl:1:18 error: expected '(' for stride attribute
|
||||||
var i : [[stride 1)]] array<i32>;
|
var i : [[stride 1)]] array<i32>;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest,
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarArrayStrideMissingRParen) {
|
||||||
DEPRECATED_GlobalDeclVarArrayDecoStrideMissingRParen) {
|
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"var i : [[location(1]] array<i32>;",
|
"var i : [[location(1]] array<i32>;",
|
||||||
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:9 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
var i : [[location(1]] array<i32>;
|
var i : [[location(1]] array<i32>;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:21 error: expected ')' for location decoration
|
test.wgsl:1:21 error: expected ')' for location attribute
|
||||||
var i : [[location(1]] array<i32>;
|
var i : [[location(1]] array<i32>;
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoStrideInvalid) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayStrideInvalid) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"var i : @stride(x) array<i32>;",
|
"var i : @stride(x) array<i32>;",
|
||||||
R"(test.wgsl:1:17 error: expected signed integer literal for stride decoration
|
R"(test.wgsl:1:17 error: expected signed integer literal for stride attribute
|
||||||
var i : @stride(x) array<i32>;
|
var i : @stride(x) array<i32>;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoStrideNegative) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayStrideNegative) {
|
||||||
EXPECT("var i : @stride(-1) array<i32>;",
|
EXPECT("var i : @stride(-1) array<i32>;",
|
||||||
R"(test.wgsl:1:17 error: stride decoration must be greater than 0
|
R"(test.wgsl:1:17 error: stride attribute must be greater than 0
|
||||||
var i : @stride(-1) array<i32>;
|
var i : @stride(-1) array<i32>;
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
@ -1078,36 +1074,36 @@ var i : array<u32, !>;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoListEmpty) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrListEmpty) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[]] var i : i32;",
|
"[[]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[]] var i : i32;
|
[[]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:3 error: empty decoration list
|
test.wgsl:1:3 error: empty attribute list
|
||||||
[[]] var i : i32;
|
[[]] var i : i32;
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoListInvalid) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrListInvalid) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[location(1), meow]] var i : i32;",
|
"[[location(1), meow]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[location(1), meow]] var i : i32;
|
[[location(1), meow]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:16 error: expected decoration
|
test.wgsl:1:16 error: expected attribute
|
||||||
[[location(1), meow]] var i : i32;
|
[[location(1), meow]] var i : i32;
|
||||||
^^^^
|
^^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoListMissingComma) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrListMissingComma) {
|
||||||
EXPECT("@location(1) group(2) var i : i32;",
|
EXPECT("@location(1) group(2) var i : i32;",
|
||||||
R"(test.wgsl:1:14 error: expected declaration after decorations
|
R"(test.wgsl:1:14 error: expected declaration after attributes
|
||||||
@location(1) group(2) var i : i32;
|
@location(1) group(2) var i : i32;
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
||||||
@ -1118,117 +1114,117 @@ test.wgsl:1:19 error: unexpected token
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoListMissingEnd) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrListMissingEnd) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[location(1) meow]] var i : i32;",
|
"[[location(1) meow]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[location(1) meow]] var i : i32;
|
[[location(1) meow]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:15 error: expected ']]' for decoration list
|
test.wgsl:1:15 error: expected ']]' for attribute list
|
||||||
[[location(1) meow]] var i : i32;
|
[[location(1) meow]] var i : i32;
|
||||||
^^^^
|
^^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationMissingLParen) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrLocationMissingLParen) {
|
||||||
EXPECT("@location 1) var i : i32;",
|
EXPECT("@location 1) var i : i32;",
|
||||||
R"(test.wgsl:1:11 error: expected '(' for location decoration
|
R"(test.wgsl:1:11 error: expected '(' for location attribute
|
||||||
@location 1) var i : i32;
|
@location 1) var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationMissingRParen) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrLocationMissingRParen) {
|
||||||
EXPECT("@location (1 var i : i32;",
|
EXPECT("@location (1 var i : i32;",
|
||||||
R"(test.wgsl:1:14 error: expected ')' for location decoration
|
R"(test.wgsl:1:14 error: expected ')' for location attribute
|
||||||
@location (1 var i : i32;
|
@location (1 var i : i32;
|
||||||
^^^
|
^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoLocationMissingLParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrLocationMissingLParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[location 1]] var i : i32;",
|
"[[location 1]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[location 1]] var i : i32;
|
[[location 1]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:12 error: expected '(' for location decoration
|
test.wgsl:1:12 error: expected '(' for location attribute
|
||||||
[[location 1]] var i : i32;
|
[[location 1]] var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoLocationMissingRParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrLocationMissingRParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[location (1]] var i : i32;",
|
"[[location (1]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[location (1]] var i : i32;
|
[[location (1]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:14 error: expected ')' for location decoration
|
test.wgsl:1:14 error: expected ')' for location attribute
|
||||||
[[location (1]] var i : i32;
|
[[location (1]] var i : i32;
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationInvalidValue) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrLocationInvalidValue) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"@location(x) var i : i32;",
|
"@location(x) var i : i32;",
|
||||||
R"(test.wgsl:1:11 error: expected signed integer literal for location decoration
|
R"(test.wgsl:1:11 error: expected signed integer literal for location attribute
|
||||||
@location(x) var i : i32;
|
@location(x) var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinMissingLParen) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinMissingLParen) {
|
||||||
EXPECT("@builtin position) var i : i32;",
|
EXPECT("@builtin position) var i : i32;",
|
||||||
R"(test.wgsl:1:10 error: expected '(' for builtin decoration
|
R"(test.wgsl:1:10 error: expected '(' for builtin attribute
|
||||||
@builtin position) var i : i32;
|
@builtin position) var i : i32;
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinMissingRParen) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinMissingRParen) {
|
||||||
EXPECT("@builtin(position var i : i32;",
|
EXPECT("@builtin(position var i : i32;",
|
||||||
R"(test.wgsl:1:19 error: expected ')' for builtin decoration
|
R"(test.wgsl:1:19 error: expected ')' for builtin attribute
|
||||||
@builtin(position var i : i32;
|
@builtin(position var i : i32;
|
||||||
^^^
|
^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBuiltinMissingLParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBuiltinMissingLParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[builtin position]] var i : i32;",
|
"[[builtin position]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[builtin position]] var i : i32;
|
[[builtin position]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:11 error: expected '(' for builtin decoration
|
test.wgsl:1:11 error: expected '(' for builtin attribute
|
||||||
[[builtin position]] var i : i32;
|
[[builtin position]] var i : i32;
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBuiltinMissingRParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBuiltinMissingRParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[builtin(position]] var i : i32;",
|
"[[builtin(position]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[builtin(position]] var i : i32;
|
[[builtin(position]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:19 error: expected ')' for builtin decoration
|
test.wgsl:1:19 error: expected ')' for builtin attribute
|
||||||
[[builtin(position]] var i : i32;
|
[[builtin(position]] var i : i32;
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinInvalidIdentifer) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinInvalidIdentifer) {
|
||||||
EXPECT("@builtin(1) var i : i32;",
|
EXPECT("@builtin(1) var i : i32;",
|
||||||
R"(test.wgsl:1:10 error: expected identifier for builtin
|
R"(test.wgsl:1:10 error: expected identifier for builtin
|
||||||
@builtin(1) var i : i32;
|
@builtin(1) var i : i32;
|
||||||
@ -1236,115 +1232,115 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinInvalidIdentifer) {
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinInvalidValue) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBuiltinInvalidValue) {
|
||||||
EXPECT("@builtin(x) var i : i32;",
|
EXPECT("@builtin(x) var i : i32;",
|
||||||
R"(test.wgsl:1:10 error: invalid value for builtin decoration
|
R"(test.wgsl:1:10 error: invalid value for builtin attribute
|
||||||
@builtin(x) var i : i32;
|
@builtin(x) var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingMissingLParen) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingMissingLParen) {
|
||||||
EXPECT("@binding 1) var i : i32;",
|
EXPECT("@binding 1) var i : i32;",
|
||||||
R"(test.wgsl:1:10 error: expected '(' for binding decoration
|
R"(test.wgsl:1:10 error: expected '(' for binding attribute
|
||||||
@binding 1) var i : i32;
|
@binding 1) var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingMissingRParen) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingMissingRParen) {
|
||||||
EXPECT("@binding(1 var i : i32;",
|
EXPECT("@binding(1 var i : i32;",
|
||||||
R"(test.wgsl:1:12 error: expected ')' for binding decoration
|
R"(test.wgsl:1:12 error: expected ')' for binding attribute
|
||||||
@binding(1 var i : i32;
|
@binding(1 var i : i32;
|
||||||
^^^
|
^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBindingMissingLParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBindingMissingLParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[binding 1]] var i : i32;",
|
"[[binding 1]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[binding 1]] var i : i32;
|
[[binding 1]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:11 error: expected '(' for binding decoration
|
test.wgsl:1:11 error: expected '(' for binding attribute
|
||||||
[[binding 1]] var i : i32;
|
[[binding 1]] var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoBindingMissingRParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrBindingMissingRParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[binding(1]] var i : i32;",
|
"[[binding(1]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[binding(1]] var i : i32;
|
[[binding(1]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:12 error: expected ')' for binding decoration
|
test.wgsl:1:12 error: expected ')' for binding attribute
|
||||||
[[binding(1]] var i : i32;
|
[[binding(1]] var i : i32;
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingInvalidValue) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingInvalidValue) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"@binding(x) var i : i32;",
|
"@binding(x) var i : i32;",
|
||||||
R"(test.wgsl:1:10 error: expected signed integer literal for binding decoration
|
R"(test.wgsl:1:10 error: expected signed integer literal for binding attribute
|
||||||
@binding(x) var i : i32;
|
@binding(x) var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoGroupMissingLParen) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrGroupMissingLParen) {
|
||||||
EXPECT("@group 1) var i : i32;",
|
EXPECT("@group 1) var i : i32;",
|
||||||
R"(test.wgsl:1:8 error: expected '(' for group decoration
|
R"(test.wgsl:1:8 error: expected '(' for group attribute
|
||||||
@group 1) var i : i32;
|
@group 1) var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoGroupMissingRParen) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrGroupMissingRParen) {
|
||||||
EXPECT("@group(1 var i : i32;",
|
EXPECT("@group(1 var i : i32;",
|
||||||
R"(test.wgsl:1:10 error: expected ')' for group decoration
|
R"(test.wgsl:1:10 error: expected ')' for group attribute
|
||||||
@group(1 var i : i32;
|
@group(1 var i : i32;
|
||||||
^^^
|
^^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoGroupMissingLParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrGroupMissingLParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[group 1]] var i : i32;",
|
"[[group 1]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[group 1]] var i : i32;
|
[[group 1]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:9 error: expected '(' for group decoration
|
test.wgsl:1:9 error: expected '(' for group attribute
|
||||||
[[group 1]] var i : i32;
|
[[group 1]] var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1382): Remove
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarDecoGroupMissingRParen) {
|
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclVarAttrGroupMissingRParen) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"[[group(1]] var i : i32;",
|
"[[group(1]] var i : i32;",
|
||||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
|
R"(test.wgsl:1:1 warning: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
[[group(1]] var i : i32;
|
[[group(1]] var i : i32;
|
||||||
^^
|
^^
|
||||||
|
|
||||||
test.wgsl:1:10 error: expected ')' for group decoration
|
test.wgsl:1:10 error: expected ')' for group attribute
|
||||||
[[group(1]] var i : i32;
|
[[group(1]] var i : i32;
|
||||||
^^
|
^^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingGroupValue) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAttrBindingGroupValue) {
|
||||||
EXPECT(
|
EXPECT(
|
||||||
"@group(x) var i : i32;",
|
"@group(x) var i : i32;",
|
||||||
R"(test.wgsl:1:8 error: expected signed integer literal for group decoration
|
R"(test.wgsl:1:8 error: expected signed integer literal for group attribute
|
||||||
@group(x) var i : i32;
|
@group(x) var i : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
|
@ -55,7 +55,7 @@ test.wgsl:3:6 error: expected ')' for function declaration
|
|||||||
fn x(.) {}
|
fn x(.) {}
|
||||||
^
|
^
|
||||||
|
|
||||||
test.wgsl:4:2 error: expected decoration
|
test.wgsl:4:2 error: expected attribute
|
||||||
@_ fn -> {}
|
@_ fn -> {}
|
||||||
^
|
^
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ test.wgsl:5:10 error: expected ':' for struct member
|
|||||||
blah blah blah;
|
blah blah blah;
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
test.wgsl:7:6 error: expected decoration
|
test.wgsl:7:6 error: expected attribute
|
||||||
@- x : i32;
|
@- x : i32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
|
162
src/reader/wgsl/parser_impl_function_attribute_list_test.cc
Normal file
162
src/reader/wgsl/parser_impl_function_attribute_list_test.cc
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
// Copyright 2020 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "src/ast/workgroup_attribute.h"
|
||||||
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace reader {
|
||||||
|
namespace wgsl {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, AttributeList_Parses) {
|
||||||
|
auto p = parser("@workgroup_size(2) @stage(compute)");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
|
EXPECT_FALSE(attrs.errored);
|
||||||
|
EXPECT_TRUE(attrs.matched);
|
||||||
|
ASSERT_EQ(attrs.value.size(), 2u);
|
||||||
|
|
||||||
|
auto* attr_0 = attrs.value[0]->As<ast::Attribute>();
|
||||||
|
auto* attr_1 = attrs.value[1]->As<ast::Attribute>();
|
||||||
|
ASSERT_NE(attr_0, nullptr);
|
||||||
|
ASSERT_NE(attr_1, nullptr);
|
||||||
|
|
||||||
|
ASSERT_TRUE(attr_0->Is<ast::WorkgroupAttribute>());
|
||||||
|
const ast::Expression* x = attr_0->As<ast::WorkgroupAttribute>()->x;
|
||||||
|
ASSERT_NE(x, nullptr);
|
||||||
|
auto* x_literal = x->As<ast::LiteralExpression>();
|
||||||
|
ASSERT_NE(x_literal, nullptr);
|
||||||
|
ASSERT_TRUE(x_literal->Is<ast::IntLiteralExpression>());
|
||||||
|
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||||
|
|
||||||
|
ASSERT_TRUE(attr_1->Is<ast::StageAttribute>());
|
||||||
|
EXPECT_EQ(attr_1->As<ast::StageAttribute>()->stage,
|
||||||
|
ast::PipelineStage::kCompute);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, AttributeList_Invalid) {
|
||||||
|
auto p = parser("@invalid");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_TRUE(attrs.value.empty());
|
||||||
|
EXPECT_EQ(p->error(), "1:2: expected attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, AttributeList_ExtraComma) {
|
||||||
|
auto p = parser("[[workgroup_size(2), ]]");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_EQ(
|
||||||
|
p->error(),
|
||||||
|
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
|
1:22: expected attribute)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, AttributeList_BadAttribute) {
|
||||||
|
auto p = parser("@stage()");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_EQ(p->error(), "1:8: invalid value for stage attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
|
TEST_F(ParserImplTest, DEPRECATED_AttributeList_Empty) {
|
||||||
|
auto p = parser("[[]]");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_EQ(
|
||||||
|
p->error(),
|
||||||
|
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
|
1:3: empty attribute list)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
|
TEST_F(ParserImplTest, DEPRECATED_AttributeList_Invalid) {
|
||||||
|
auto p = parser("[[invalid]]");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_TRUE(attrs.value.empty());
|
||||||
|
EXPECT_EQ(
|
||||||
|
p->error(),
|
||||||
|
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
|
1:3: expected attribute)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
|
TEST_F(ParserImplTest, DEPRECATED_AttributeList_ExtraComma) {
|
||||||
|
auto p = parser("[[workgroup_size(2), ]]");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_EQ(
|
||||||
|
p->error(),
|
||||||
|
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
|
1:22: expected attribute)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
|
TEST_F(ParserImplTest, DEPRECATED_AttributeList_MissingComma) {
|
||||||
|
auto p = parser("[[workgroup_size(2) workgroup_size(2)]]");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_EQ(
|
||||||
|
p->error(),
|
||||||
|
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
|
1:21: expected ',' for attribute list)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
|
TEST_F(ParserImplTest, DEPRECATED_AttributeList_BadAttribute) {
|
||||||
|
auto p = parser("[[stage()]]");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_EQ(
|
||||||
|
p->error(),
|
||||||
|
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
|
1:9: invalid value for stage attribute)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
|
TEST_F(ParserImplTest, DEPRECATED_AttributeList_MissingRightAttr) {
|
||||||
|
auto p = parser("[[workgroup_size(2), workgroup_size(3, 4, 5)");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_EQ(
|
||||||
|
p->error(),
|
||||||
|
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
|
1:45: expected ']]' for attribute list)");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace wgsl
|
||||||
|
} // namespace reader
|
||||||
|
} // namespace tint
|
260
src/reader/wgsl/parser_impl_function_attribute_test.cc
Normal file
260
src/reader/wgsl/parser_impl_function_attribute_test.cc
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
// Copyright 2020 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "src/ast/stage_attribute.h"
|
||||||
|
#include "src/ast/workgroup_attribute.h"
|
||||||
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace reader {
|
||||||
|
namespace wgsl {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup) {
|
||||||
|
auto p = parser("workgroup_size(4)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_TRUE(attr.matched);
|
||||||
|
EXPECT_FALSE(attr.errored);
|
||||||
|
ASSERT_NE(attr.value, nullptr) << p->error();
|
||||||
|
ASSERT_FALSE(p->has_error());
|
||||||
|
auto* func_attr = attr.value->As<ast::Attribute>();
|
||||||
|
ASSERT_NE(func_attr, nullptr);
|
||||||
|
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
|
||||||
|
|
||||||
|
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
|
||||||
|
|
||||||
|
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||||
|
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||||
|
|
||||||
|
EXPECT_EQ(values[1], nullptr);
|
||||||
|
EXPECT_EQ(values[2], nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_2Param) {
|
||||||
|
auto p = parser("workgroup_size(4, 5)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_TRUE(attr.matched);
|
||||||
|
EXPECT_FALSE(attr.errored);
|
||||||
|
ASSERT_NE(attr.value, nullptr) << p->error();
|
||||||
|
ASSERT_FALSE(p->has_error());
|
||||||
|
auto* func_attr = attr.value->As<ast::Attribute>();
|
||||||
|
ASSERT_NE(func_attr, nullptr) << p->error();
|
||||||
|
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
|
||||||
|
|
||||||
|
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
|
||||||
|
|
||||||
|
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||||
|
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||||
|
|
||||||
|
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||||
|
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
|
||||||
|
|
||||||
|
EXPECT_EQ(values[2], nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_3Param) {
|
||||||
|
auto p = parser("workgroup_size(4, 5, 6)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_TRUE(attr.matched);
|
||||||
|
EXPECT_FALSE(attr.errored);
|
||||||
|
ASSERT_NE(attr.value, nullptr) << p->error();
|
||||||
|
ASSERT_FALSE(p->has_error());
|
||||||
|
auto* func_attr = attr.value->As<ast::Attribute>();
|
||||||
|
ASSERT_NE(func_attr, nullptr);
|
||||||
|
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
|
||||||
|
|
||||||
|
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
|
||||||
|
|
||||||
|
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||||
|
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||||
|
|
||||||
|
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
|
||||||
|
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
|
||||||
|
|
||||||
|
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||||
|
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_WithIdent) {
|
||||||
|
auto p = parser("workgroup_size(4, height)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_TRUE(attr.matched);
|
||||||
|
EXPECT_FALSE(attr.errored);
|
||||||
|
ASSERT_NE(attr.value, nullptr) << p->error();
|
||||||
|
ASSERT_FALSE(p->has_error());
|
||||||
|
auto* func_attr = attr.value->As<ast::Attribute>();
|
||||||
|
ASSERT_NE(func_attr, nullptr);
|
||||||
|
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
|
||||||
|
|
||||||
|
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
|
||||||
|
|
||||||
|
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||||
|
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||||
|
|
||||||
|
ASSERT_NE(values[1], nullptr);
|
||||||
|
auto* y_ident = values[1]->As<ast::IdentifierExpression>();
|
||||||
|
ASSERT_NE(y_ident, nullptr);
|
||||||
|
EXPECT_EQ(p->builder().Symbols().NameFor(y_ident->symbol), "height");
|
||||||
|
|
||||||
|
ASSERT_EQ(values[2], nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_TooManyValues) {
|
||||||
|
auto p = parser("workgroup_size(1, 2, 3, 4)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_MissingLeftParam) {
|
||||||
|
auto p = parser("workgroup_size 4, 5, 6)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:16: expected '(' for workgroup_size attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_MissingRightParam) {
|
||||||
|
auto p = parser("workgroup_size(4, 5, 6");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_MissingValues) {
|
||||||
|
auto p = parser("workgroup_size()");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_X_Value) {
|
||||||
|
auto p = parser("workgroup_size(, 2, 3)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Y_Comma) {
|
||||||
|
auto p = parser("workgroup_size(1 2, 3)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:18: expected ')' for workgroup_size attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Y_Value) {
|
||||||
|
auto p = parser("workgroup_size(1, , 3)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:19: expected workgroup_size y parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Z_Comma) {
|
||||||
|
auto p = parser("workgroup_size(1, 2 3)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:21: expected ')' for workgroup_size attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Z_Value) {
|
||||||
|
auto p = parser("workgroup_size(1, 2, )");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:22: expected workgroup_size z parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Stage) {
|
||||||
|
auto p = parser("stage(compute)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_TRUE(attr.matched);
|
||||||
|
EXPECT_FALSE(attr.errored);
|
||||||
|
ASSERT_NE(attr.value, nullptr) << p->error();
|
||||||
|
ASSERT_FALSE(p->has_error());
|
||||||
|
auto* func_attr = attr.value->As<ast::Attribute>();
|
||||||
|
ASSERT_NE(func_attr, nullptr);
|
||||||
|
ASSERT_TRUE(func_attr->Is<ast::StageAttribute>());
|
||||||
|
EXPECT_EQ(func_attr->As<ast::StageAttribute>()->stage,
|
||||||
|
ast::PipelineStage::kCompute);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Stage_MissingValue) {
|
||||||
|
auto p = parser("stage()");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:7: invalid value for stage attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Stage_MissingInvalid) {
|
||||||
|
auto p = parser("stage(nan)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:7: invalid value for stage attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Stage_MissingLeftParen) {
|
||||||
|
auto p = parser("stage compute)");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:7: expected '(' for stage attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, Attribute_Stage_MissingRightParen) {
|
||||||
|
auto p = parser("stage(compute");
|
||||||
|
auto attr = p->attribute();
|
||||||
|
EXPECT_FALSE(attr.matched);
|
||||||
|
EXPECT_TRUE(attr.errored);
|
||||||
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:14: expected ')' for stage attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace wgsl
|
||||||
|
} // namespace reader
|
||||||
|
} // namespace tint
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_attribute.h"
|
||||||
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
@ -22,11 +22,11 @@ namespace {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionDecl) {
|
TEST_F(ParserImplTest, FunctionDecl) {
|
||||||
auto p = parser("fn main(a : i32, b : f32) { return; }");
|
auto p = parser("fn main(a : i32, b : f32) { return; }");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_FALSE(decos.errored);
|
ASSERT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto f = p->function_decl(decos.value);
|
auto f = p->function_decl(attrs.value);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_FALSE(f.errored);
|
EXPECT_FALSE(f.errored);
|
||||||
EXPECT_TRUE(f.matched);
|
EXPECT_TRUE(f.matched);
|
||||||
@ -48,13 +48,13 @@ TEST_F(ParserImplTest, FunctionDecl) {
|
|||||||
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
|
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionDecl_DecorationList) {
|
TEST_F(ParserImplTest, FunctionDecl_AttributeList) {
|
||||||
auto p = parser("@workgroup_size(2, 3, 4) fn main() { return; }");
|
auto p = parser("@workgroup_size(2, 3, 4) fn main() { return; }");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_FALSE(decos.errored);
|
ASSERT_FALSE(attrs.errored);
|
||||||
ASSERT_TRUE(decos.matched);
|
ASSERT_TRUE(attrs.matched);
|
||||||
auto f = p->function_decl(decos.value);
|
auto f = p->function_decl(attrs.value);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_FALSE(f.errored);
|
EXPECT_FALSE(f.errored);
|
||||||
EXPECT_TRUE(f.matched);
|
EXPECT_TRUE(f.matched);
|
||||||
@ -65,11 +65,11 @@ TEST_F(ParserImplTest, FunctionDecl_DecorationList) {
|
|||||||
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||||
ASSERT_EQ(f->params.size(), 0u);
|
ASSERT_EQ(f->params.size(), 0u);
|
||||||
|
|
||||||
auto& decorations = f->decorations;
|
auto& attributes = f->attributes;
|
||||||
ASSERT_EQ(decorations.size(), 1u);
|
ASSERT_EQ(attributes.size(), 1u);
|
||||||
ASSERT_TRUE(decorations[0]->Is<ast::WorkgroupDecoration>());
|
ASSERT_TRUE(attributes[0]->Is<ast::WorkgroupAttribute>());
|
||||||
|
|
||||||
auto values = decorations[0]->As<ast::WorkgroupDecoration>()->Values();
|
auto values = attributes[0]->As<ast::WorkgroupAttribute>()->Values();
|
||||||
|
|
||||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||||
@ -85,15 +85,15 @@ TEST_F(ParserImplTest, FunctionDecl_DecorationList) {
|
|||||||
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
|
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionDecl_DecorationList_MultipleEntries) {
|
TEST_F(ParserImplTest, FunctionDecl_AttributeList_MultipleEntries) {
|
||||||
auto p = parser(R"(
|
auto p = parser(R"(
|
||||||
@workgroup_size(2, 3, 4) @stage(compute)
|
@workgroup_size(2, 3, 4) @stage(compute)
|
||||||
fn main() { return; })");
|
fn main() { return; })");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_FALSE(decos.errored);
|
ASSERT_FALSE(attrs.errored);
|
||||||
ASSERT_TRUE(decos.matched);
|
ASSERT_TRUE(attrs.matched);
|
||||||
auto f = p->function_decl(decos.value);
|
auto f = p->function_decl(attrs.value);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_FALSE(f.errored);
|
EXPECT_FALSE(f.errored);
|
||||||
EXPECT_TRUE(f.matched);
|
EXPECT_TRUE(f.matched);
|
||||||
@ -104,11 +104,11 @@ fn main() { return; })");
|
|||||||
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||||
ASSERT_EQ(f->params.size(), 0u);
|
ASSERT_EQ(f->params.size(), 0u);
|
||||||
|
|
||||||
auto& decorations = f->decorations;
|
auto& attributes = f->attributes;
|
||||||
ASSERT_EQ(decorations.size(), 2u);
|
ASSERT_EQ(attributes.size(), 2u);
|
||||||
|
|
||||||
ASSERT_TRUE(decorations[0]->Is<ast::WorkgroupDecoration>());
|
ASSERT_TRUE(attributes[0]->Is<ast::WorkgroupAttribute>());
|
||||||
auto values = decorations[0]->As<ast::WorkgroupDecoration>()->Values();
|
auto values = attributes[0]->As<ast::WorkgroupAttribute>()->Values();
|
||||||
|
|
||||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||||
@ -119,8 +119,8 @@ fn main() { return; })");
|
|||||||
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||||
|
|
||||||
ASSERT_TRUE(decorations[1]->Is<ast::StageDecoration>());
|
ASSERT_TRUE(attributes[1]->Is<ast::StageAttribute>());
|
||||||
EXPECT_EQ(decorations[1]->As<ast::StageDecoration>()->stage,
|
EXPECT_EQ(attributes[1]->As<ast::StageAttribute>()->stage,
|
||||||
ast::PipelineStage::kCompute);
|
ast::PipelineStage::kCompute);
|
||||||
|
|
||||||
auto* body = f->body;
|
auto* body = f->body;
|
||||||
@ -128,16 +128,16 @@ fn main() { return; })");
|
|||||||
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
|
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionDecl_DecorationList_MultipleLists) {
|
TEST_F(ParserImplTest, FunctionDecl_AttributeList_MultipleLists) {
|
||||||
auto p = parser(R"(
|
auto p = parser(R"(
|
||||||
@workgroup_size(2, 3, 4)
|
@workgroup_size(2, 3, 4)
|
||||||
@stage(compute)
|
@stage(compute)
|
||||||
fn main() { return; })");
|
fn main() { return; })");
|
||||||
auto decorations = p->decoration_list();
|
auto attributes = p->attribute_list();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_FALSE(decorations.errored);
|
ASSERT_FALSE(attributes.errored);
|
||||||
ASSERT_TRUE(decorations.matched);
|
ASSERT_TRUE(attributes.matched);
|
||||||
auto f = p->function_decl(decorations.value);
|
auto f = p->function_decl(attributes.value);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_FALSE(f.errored);
|
EXPECT_FALSE(f.errored);
|
||||||
EXPECT_TRUE(f.matched);
|
EXPECT_TRUE(f.matched);
|
||||||
@ -148,11 +148,11 @@ fn main() { return; })");
|
|||||||
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||||
ASSERT_EQ(f->params.size(), 0u);
|
ASSERT_EQ(f->params.size(), 0u);
|
||||||
|
|
||||||
auto& decos = f->decorations;
|
auto& attrs = f->attributes;
|
||||||
ASSERT_EQ(decos.size(), 2u);
|
ASSERT_EQ(attrs.size(), 2u);
|
||||||
|
|
||||||
ASSERT_TRUE(decos[0]->Is<ast::WorkgroupDecoration>());
|
ASSERT_TRUE(attrs[0]->Is<ast::WorkgroupAttribute>());
|
||||||
auto values = decos[0]->As<ast::WorkgroupDecoration>()->Values();
|
auto values = attrs[0]->As<ast::WorkgroupAttribute>()->Values();
|
||||||
|
|
||||||
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
|
||||||
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
|
||||||
@ -163,8 +163,8 @@ fn main() { return; })");
|
|||||||
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
|
||||||
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
|
||||||
|
|
||||||
ASSERT_TRUE(decos[1]->Is<ast::StageDecoration>());
|
ASSERT_TRUE(attrs[1]->Is<ast::StageAttribute>());
|
||||||
EXPECT_EQ(decos[1]->As<ast::StageDecoration>()->stage,
|
EXPECT_EQ(attrs[1]->As<ast::StageAttribute>()->stage,
|
||||||
ast::PipelineStage::kCompute);
|
ast::PipelineStage::kCompute);
|
||||||
|
|
||||||
auto* body = f->body;
|
auto* body = f->body;
|
||||||
@ -172,13 +172,13 @@ fn main() { return; })");
|
|||||||
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
|
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionDecl_ReturnTypeDecorationList) {
|
TEST_F(ParserImplTest, FunctionDecl_ReturnTypeAttributeList) {
|
||||||
auto p = parser("fn main() -> @location(1) f32 { return 1.0; }");
|
auto p = parser("fn main() -> @location(1) f32 { return 1.0; }");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_FALSE(decos.errored);
|
ASSERT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto f = p->function_decl(decos.value);
|
auto f = p->function_decl(attrs.value);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_FALSE(f.errored);
|
EXPECT_FALSE(f.errored);
|
||||||
EXPECT_TRUE(f.matched);
|
EXPECT_TRUE(f.matched);
|
||||||
@ -189,12 +189,12 @@ TEST_F(ParserImplTest, FunctionDecl_ReturnTypeDecorationList) {
|
|||||||
EXPECT_TRUE(f->return_type->Is<ast::F32>());
|
EXPECT_TRUE(f->return_type->Is<ast::F32>());
|
||||||
ASSERT_EQ(f->params.size(), 0u);
|
ASSERT_EQ(f->params.size(), 0u);
|
||||||
|
|
||||||
auto& decorations = f->decorations;
|
auto& attributes = f->attributes;
|
||||||
EXPECT_EQ(decorations.size(), 0u);
|
EXPECT_EQ(attributes.size(), 0u);
|
||||||
|
|
||||||
auto& ret_type_decorations = f->return_type_decorations;
|
auto& ret_type_attributes = f->return_type_attributes;
|
||||||
ASSERT_EQ(ret_type_decorations.size(), 1u);
|
ASSERT_EQ(ret_type_attributes.size(), 1u);
|
||||||
auto* loc = ret_type_decorations[0]->As<ast::LocationDecoration>();
|
auto* loc = ret_type_attributes[0]->As<ast::LocationAttribute>();
|
||||||
ASSERT_TRUE(loc != nullptr);
|
ASSERT_TRUE(loc != nullptr);
|
||||||
EXPECT_EQ(loc->value, 1u);
|
EXPECT_EQ(loc->value, 1u);
|
||||||
|
|
||||||
@ -205,11 +205,11 @@ TEST_F(ParserImplTest, FunctionDecl_ReturnTypeDecorationList) {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionDecl_InvalidHeader) {
|
TEST_F(ParserImplTest, FunctionDecl_InvalidHeader) {
|
||||||
auto p = parser("fn main() -> { }");
|
auto p = parser("fn main() -> { }");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_FALSE(decos.errored);
|
ASSERT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto f = p->function_decl(decos.value);
|
auto f = p->function_decl(attrs.value);
|
||||||
EXPECT_TRUE(f.errored);
|
EXPECT_TRUE(f.errored);
|
||||||
EXPECT_FALSE(f.matched);
|
EXPECT_FALSE(f.matched);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
@ -219,11 +219,11 @@ TEST_F(ParserImplTest, FunctionDecl_InvalidHeader) {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionDecl_InvalidBody) {
|
TEST_F(ParserImplTest, FunctionDecl_InvalidBody) {
|
||||||
auto p = parser("fn main() { return }");
|
auto p = parser("fn main() { return }");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_FALSE(decos.errored);
|
ASSERT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto f = p->function_decl(decos.value);
|
auto f = p->function_decl(attrs.value);
|
||||||
EXPECT_TRUE(f.errored);
|
EXPECT_TRUE(f.errored);
|
||||||
EXPECT_FALSE(f.matched);
|
EXPECT_FALSE(f.matched);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
@ -233,11 +233,11 @@ TEST_F(ParserImplTest, FunctionDecl_InvalidBody) {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionDecl_MissingLeftBrace) {
|
TEST_F(ParserImplTest, FunctionDecl_MissingLeftBrace) {
|
||||||
auto p = parser("fn main() return; }");
|
auto p = parser("fn main() return; }");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_FALSE(decos.errored);
|
ASSERT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto f = p->function_decl(decos.value);
|
auto f = p->function_decl(attrs.value);
|
||||||
EXPECT_TRUE(f.errored);
|
EXPECT_TRUE(f.errored);
|
||||||
EXPECT_FALSE(f.matched);
|
EXPECT_FALSE(f.matched);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
|
@ -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>());
|
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType) {
|
TEST_F(ParserImplTest, FunctionHeader_AttributeReturnType) {
|
||||||
auto p = parser("fn main() -> @location(1) f32");
|
auto p = parser("fn main() -> @location(1) f32");
|
||||||
auto f = p->function_header();
|
auto f = p->function_header();
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
@ -55,8 +55,8 @@ TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType) {
|
|||||||
EXPECT_EQ(f->name, "main");
|
EXPECT_EQ(f->name, "main");
|
||||||
EXPECT_EQ(f->params.size(), 0u);
|
EXPECT_EQ(f->params.size(), 0u);
|
||||||
EXPECT_TRUE(f->return_type->Is<ast::F32>());
|
EXPECT_TRUE(f->return_type->Is<ast::F32>());
|
||||||
ASSERT_EQ(f->return_type_decorations.size(), 1u);
|
ASSERT_EQ(f->return_type_attributes.size(), 1u);
|
||||||
auto* loc = f->return_type_decorations[0]->As<ast::LocationDecoration>();
|
auto* loc = f->return_type_attributes[0]->As<ast::LocationAttribute>();
|
||||||
ASSERT_TRUE(loc != nullptr);
|
ASSERT_TRUE(loc != nullptr);
|
||||||
EXPECT_EQ(loc->value, 1u);
|
EXPECT_EQ(loc->value, 1u);
|
||||||
}
|
}
|
||||||
@ -71,11 +71,11 @@ TEST_F(ParserImplTest, FunctionHeader_InvariantReturnType) {
|
|||||||
EXPECT_EQ(f->name, "main");
|
EXPECT_EQ(f->name, "main");
|
||||||
EXPECT_EQ(f->params.size(), 0u);
|
EXPECT_EQ(f->params.size(), 0u);
|
||||||
EXPECT_TRUE(f->return_type->Is<ast::F32>());
|
EXPECT_TRUE(f->return_type->Is<ast::F32>());
|
||||||
ASSERT_EQ(f->return_type_decorations.size(), 1u);
|
ASSERT_EQ(f->return_type_attributes.size(), 1u);
|
||||||
EXPECT_TRUE(f->return_type_decorations[0]->Is<ast::InvariantDecoration>());
|
EXPECT_TRUE(f->return_type_attributes[0]->Is<ast::InvariantAttribute>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType_WithArrayStride) {
|
TEST_F(ParserImplTest, FunctionHeader_AttributeReturnType_WithArrayStride) {
|
||||||
auto p = parser("fn main() -> @location(1) @stride(16) array<f32, 4>");
|
auto p = parser("fn main() -> @location(1) @stride(16) array<f32, 4>");
|
||||||
auto f = p->function_header();
|
auto f = p->function_header();
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
@ -84,14 +84,14 @@ TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType_WithArrayStride) {
|
|||||||
|
|
||||||
EXPECT_EQ(f->name, "main");
|
EXPECT_EQ(f->name, "main");
|
||||||
EXPECT_EQ(f->params.size(), 0u);
|
EXPECT_EQ(f->params.size(), 0u);
|
||||||
ASSERT_EQ(f->return_type_decorations.size(), 1u);
|
ASSERT_EQ(f->return_type_attributes.size(), 1u);
|
||||||
auto* loc = f->return_type_decorations[0]->As<ast::LocationDecoration>();
|
auto* loc = f->return_type_attributes[0]->As<ast::LocationAttribute>();
|
||||||
ASSERT_TRUE(loc != nullptr);
|
ASSERT_TRUE(loc != nullptr);
|
||||||
EXPECT_EQ(loc->value, 1u);
|
EXPECT_EQ(loc->value, 1u);
|
||||||
|
|
||||||
auto* array_type = f->return_type->As<ast::Array>();
|
auto* array_type = f->return_type->As<ast::Array>();
|
||||||
ASSERT_EQ(array_type->decorations.size(), 1u);
|
ASSERT_EQ(array_type->attributes.size(), 1u);
|
||||||
auto* stride = array_type->decorations[0]->As<ast::StrideDecoration>();
|
auto* stride = array_type->attributes[0]->As<ast::StrideAttribute>();
|
||||||
ASSERT_TRUE(stride != nullptr);
|
ASSERT_TRUE(stride != nullptr);
|
||||||
EXPECT_EQ(stride->stride, 16u);
|
EXPECT_EQ(stride->stride, 16u);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_attribute.h"
|
||||||
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
@ -22,10 +22,10 @@ namespace {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalConstantDecl) {
|
TEST_F(ParserImplTest, GlobalConstantDecl) {
|
||||||
auto p = parser("let a : f32 = 1.");
|
auto p = parser("let a : f32 = 1.");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto e = p->global_constant_decl(decos.value);
|
auto e = p->global_constant_decl(attrs.value);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
@ -44,16 +44,15 @@ TEST_F(ParserImplTest, GlobalConstantDecl) {
|
|||||||
ASSERT_NE(e->constructor, nullptr);
|
ASSERT_NE(e->constructor, nullptr);
|
||||||
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
||||||
|
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(ast::HasAttribute<ast::OverrideAttribute>(e.value->attributes));
|
||||||
ast::HasDecoration<ast::OverrideDecoration>(e.value->decorations));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalConstantDecl_Inferred) {
|
TEST_F(ParserImplTest, GlobalConstantDecl_Inferred) {
|
||||||
auto p = parser("let a = 1.");
|
auto p = parser("let a = 1.");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto e = p->global_constant_decl(decos.value);
|
auto e = p->global_constant_decl(attrs.value);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
@ -71,16 +70,15 @@ TEST_F(ParserImplTest, GlobalConstantDecl_Inferred) {
|
|||||||
ASSERT_NE(e->constructor, nullptr);
|
ASSERT_NE(e->constructor, nullptr);
|
||||||
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
||||||
|
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(ast::HasAttribute<ast::OverrideAttribute>(e.value->attributes));
|
||||||
ast::HasDecoration<ast::OverrideDecoration>(e.value->decorations));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
|
TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
|
||||||
auto p = parser("let a : f32 = if (a) {}");
|
auto p = parser("let a : f32 = if (a) {}");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto e = p->global_constant_decl(decos.value);
|
auto e = p->global_constant_decl(attrs.value);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_TRUE(e.errored);
|
EXPECT_TRUE(e.errored);
|
||||||
EXPECT_FALSE(e.matched);
|
EXPECT_FALSE(e.matched);
|
||||||
@ -90,10 +88,10 @@ TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
|
TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
|
||||||
auto p = parser("let a : f32 =");
|
auto p = parser("let a : f32 =");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto e = p->global_constant_decl(decos.value);
|
auto e = p->global_constant_decl(attrs.value);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_TRUE(e.errored);
|
EXPECT_TRUE(e.errored);
|
||||||
EXPECT_FALSE(e.matched);
|
EXPECT_FALSE(e.matched);
|
||||||
@ -103,11 +101,11 @@ TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalConstantDec_Override_WithId) {
|
TEST_F(ParserImplTest, GlobalConstantDec_Override_WithId) {
|
||||||
auto p = parser("@override(7) let a : f32 = 1.");
|
auto p = parser("@override(7) let a : f32 = 1.");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_TRUE(decos.matched);
|
EXPECT_TRUE(attrs.matched);
|
||||||
|
|
||||||
auto e = p->global_constant_decl(decos.value);
|
auto e = p->global_constant_decl(attrs.value);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
@ -126,20 +124,20 @@ TEST_F(ParserImplTest, GlobalConstantDec_Override_WithId) {
|
|||||||
ASSERT_NE(e->constructor, nullptr);
|
ASSERT_NE(e->constructor, nullptr);
|
||||||
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
||||||
|
|
||||||
auto* override_deco =
|
auto* override_attr =
|
||||||
ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations);
|
ast::GetAttribute<ast::OverrideAttribute>(e.value->attributes);
|
||||||
ASSERT_NE(override_deco, nullptr);
|
ASSERT_NE(override_attr, nullptr);
|
||||||
EXPECT_TRUE(override_deco->has_value);
|
EXPECT_TRUE(override_attr->has_value);
|
||||||
EXPECT_EQ(override_deco->value, 7u);
|
EXPECT_EQ(override_attr->value, 7u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) {
|
TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) {
|
||||||
auto p = parser("[[override]] let a : f32 = 1.");
|
auto p = parser("[[override]] let a : f32 = 1.");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_TRUE(decos.matched);
|
EXPECT_TRUE(attrs.matched);
|
||||||
|
|
||||||
auto e = p->global_constant_decl(decos.value);
|
auto e = p->global_constant_decl(attrs.value);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
@ -158,41 +156,41 @@ TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) {
|
|||||||
ASSERT_NE(e->constructor, nullptr);
|
ASSERT_NE(e->constructor, nullptr);
|
||||||
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
|
||||||
|
|
||||||
auto* override_deco =
|
auto* override_attr =
|
||||||
ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations);
|
ast::GetAttribute<ast::OverrideAttribute>(e.value->attributes);
|
||||||
ASSERT_NE(override_deco, nullptr);
|
ASSERT_NE(override_attr, nullptr);
|
||||||
EXPECT_FALSE(override_deco->has_value);
|
EXPECT_FALSE(override_attr->has_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalConstantDec_Override_MissingId) {
|
TEST_F(ParserImplTest, GlobalConstantDec_Override_MissingId) {
|
||||||
auto p = parser("@override() let a : f32 = 1.");
|
auto p = parser("@override() let a : f32 = 1.");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_TRUE(decos.errored);
|
EXPECT_TRUE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
|
||||||
auto e = p->global_constant_decl(decos.value);
|
auto e = p->global_constant_decl(attrs.value);
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
ASSERT_NE(e.value, nullptr);
|
ASSERT_NE(e.value, nullptr);
|
||||||
|
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(),
|
EXPECT_EQ(p->error(),
|
||||||
"1:11: expected signed integer literal for override decoration");
|
"1:11: expected signed integer literal for override attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalConstantDec_Override_InvalidId) {
|
TEST_F(ParserImplTest, GlobalConstantDec_Override_InvalidId) {
|
||||||
auto p = parser("@override(-7) let a : f32 = 1.");
|
auto p = parser("@override(-7) let a : f32 = 1.");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_TRUE(decos.errored);
|
EXPECT_TRUE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
|
||||||
auto e = p->global_constant_decl(decos.value);
|
auto e = p->global_constant_decl(attrs.value);
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
ASSERT_NE(e.value, nullptr);
|
ASSERT_NE(e.value, nullptr);
|
||||||
|
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), "1:11: override decoration must be positive");
|
EXPECT_EQ(p->error(), "1:11: override attribute must be positive");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -131,7 +131,7 @@ TEST_F(ParserImplTest, GlobalDecl_Function) {
|
|||||||
"main");
|
"main");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalDecl_Function_WithDecoration) {
|
TEST_F(ParserImplTest, GlobalDecl_Function_WithAttribute) {
|
||||||
auto p = parser("@workgroup_size(2) fn main() { return; }");
|
auto p = parser("@workgroup_size(2) fn main() { return; }");
|
||||||
p->expect_global_decl();
|
p->expect_global_decl();
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
@ -187,14 +187,14 @@ TEST_F(ParserImplTest, GlobalDecl_Struct_WithStride) {
|
|||||||
ASSERT_TRUE(ty->Is<ast::Array>());
|
ASSERT_TRUE(ty->Is<ast::Array>());
|
||||||
const auto* arr = ty->As<ast::Array>();
|
const auto* arr = ty->As<ast::Array>();
|
||||||
|
|
||||||
ASSERT_EQ(arr->decorations.size(), 1u);
|
ASSERT_EQ(arr->attributes.size(), 1u);
|
||||||
auto* stride = arr->decorations[0];
|
auto* stride = arr->attributes[0];
|
||||||
ASSERT_TRUE(stride->Is<ast::StrideDecoration>());
|
ASSERT_TRUE(stride->Is<ast::StrideAttribute>());
|
||||||
ASSERT_EQ(stride->As<ast::StrideDecoration>()->stride, 4u);
|
ASSERT_EQ(stride->As<ast::StrideAttribute>()->stride, 4u);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when [[block]] is removed.
|
// TODO(crbug.com/tint/1324): DEPRECATED: Remove when @block is removed.
|
||||||
TEST_F(ParserImplTest, GlobalDecl_Struct_WithDecoration) {
|
TEST_F(ParserImplTest, GlobalDecl_Struct_WithAttribute) {
|
||||||
auto p = parser("[[block]] struct A { data: f32; }");
|
auto p = parser("[[block]] struct A { data: f32; }");
|
||||||
p->expect_global_decl();
|
p->expect_global_decl();
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
|
@ -21,10 +21,10 @@ namespace {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
|
||||||
auto p = parser("var<private> a : f32");
|
auto p = parser("var<private> a : f32");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto e = p->global_variable_decl(decos.value);
|
auto e = p->global_variable_decl(attrs.value);
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
@ -44,10 +44,10 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
|
||||||
auto p = parser("var<private> a : f32 = 1.");
|
auto p = parser("var<private> a : f32 = 1.");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto e = p->global_variable_decl(decos.value);
|
auto e = p->global_variable_decl(attrs.value);
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
@ -66,12 +66,12 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
|
|||||||
ASSERT_TRUE(e->constructor->Is<ast::FloatLiteralExpression>());
|
ASSERT_TRUE(e->constructor->Is<ast::FloatLiteralExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_WithAttribute) {
|
||||||
auto p = parser("@binding(2) @group(1) var<uniform> a : f32");
|
auto p = parser("@binding(2) @group(1) var<uniform> a : f32");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_TRUE(decos.matched);
|
EXPECT_TRUE(attrs.matched);
|
||||||
auto e = p->global_variable_decl(decos.value);
|
auto e = p->global_variable_decl(attrs.value);
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
@ -89,19 +89,19 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
|||||||
|
|
||||||
ASSERT_EQ(e->constructor, nullptr);
|
ASSERT_EQ(e->constructor, nullptr);
|
||||||
|
|
||||||
auto& decorations = e->decorations;
|
auto& attributes = e->attributes;
|
||||||
ASSERT_EQ(decorations.size(), 2u);
|
ASSERT_EQ(attributes.size(), 2u);
|
||||||
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
|
ASSERT_TRUE(attributes[0]->Is<ast::BindingAttribute>());
|
||||||
ASSERT_TRUE(decorations[1]->Is<ast::GroupDecoration>());
|
ASSERT_TRUE(attributes[1]->Is<ast::GroupAttribute>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_WithAttribute_MulitpleGroups) {
|
||||||
auto p = parser("@binding(2) @group(1) var<uniform> a : f32");
|
auto p = parser("@binding(2) @group(1) var<uniform> a : f32");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_TRUE(decos.matched);
|
EXPECT_TRUE(attrs.matched);
|
||||||
|
|
||||||
auto e = p->global_variable_decl(decos.value);
|
auto e = p->global_variable_decl(attrs.value);
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
@ -119,34 +119,34 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
|
|||||||
|
|
||||||
ASSERT_EQ(e->constructor, nullptr);
|
ASSERT_EQ(e->constructor, nullptr);
|
||||||
|
|
||||||
auto& decorations = e->decorations;
|
auto& attributes = e->attributes;
|
||||||
ASSERT_EQ(decorations.size(), 2u);
|
ASSERT_EQ(attributes.size(), 2u);
|
||||||
ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
|
ASSERT_TRUE(attributes[0]->Is<ast::BindingAttribute>());
|
||||||
ASSERT_TRUE(decorations[1]->Is<ast::GroupDecoration>());
|
ASSERT_TRUE(attributes[1]->Is<ast::GroupAttribute>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidDecoration) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidAttribute) {
|
||||||
auto p = parser("@binding() var<uniform> a : f32");
|
auto p = parser("@binding() var<uniform> a : f32");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_TRUE(decos.errored);
|
EXPECT_TRUE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
|
||||||
auto e = p->global_variable_decl(decos.value);
|
auto e = p->global_variable_decl(attrs.value);
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
EXPECT_TRUE(e.matched);
|
EXPECT_TRUE(e.matched);
|
||||||
EXPECT_NE(e.value, nullptr);
|
EXPECT_NE(e.value, nullptr);
|
||||||
|
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(),
|
EXPECT_EQ(p->error(),
|
||||||
"1:10: expected signed integer literal for binding decoration");
|
"1:10: expected signed integer literal for binding attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
|
||||||
auto p = parser("var<private> a : f32 = if (a) {}");
|
auto p = parser("var<private> a : f32 = if (a) {}");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto e = p->global_variable_decl(decos.value);
|
auto e = p->global_variable_decl(attrs.value);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_TRUE(e.errored);
|
EXPECT_TRUE(e.errored);
|
||||||
EXPECT_FALSE(e.matched);
|
EXPECT_FALSE(e.matched);
|
||||||
@ -156,10 +156,10 @@ TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
|
|||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
|
||||||
auto p = parser("var<invalid> a : f32;");
|
auto p = parser("var<invalid> a : f32;");
|
||||||
auto decos = p->decoration_list();
|
auto attrs = p->attribute_list();
|
||||||
EXPECT_FALSE(decos.errored);
|
EXPECT_FALSE(attrs.errored);
|
||||||
EXPECT_FALSE(decos.matched);
|
EXPECT_FALSE(attrs.matched);
|
||||||
auto e = p->global_variable_decl(decos.value);
|
auto e = p->global_variable_decl(attrs.value);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_TRUE(e.errored);
|
EXPECT_TRUE(e.errored);
|
||||||
EXPECT_FALSE(e.matched);
|
EXPECT_FALSE(e.matched);
|
||||||
|
@ -91,7 +91,7 @@ TEST_F(ParserImplTest, ParamList_TrailingComma) {
|
|||||||
EXPECT_EQ(e.value.size(), 1u);
|
EXPECT_EQ(e.value.size(), 1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, ParamList_Decorations) {
|
TEST_F(ParserImplTest, ParamList_Attributes) {
|
||||||
auto p =
|
auto p =
|
||||||
parser("@builtin(position) coord : vec4<f32>, @location(1) loc1 : f32");
|
parser("@builtin(position) coord : vec4<f32>, @location(1) loc1 : f32");
|
||||||
|
|
||||||
@ -105,10 +105,10 @@ TEST_F(ParserImplTest, ParamList_Decorations) {
|
|||||||
EXPECT_TRUE(e.value[0]->type->As<ast::Vector>()->type->Is<ast::F32>());
|
EXPECT_TRUE(e.value[0]->type->As<ast::Vector>()->type->Is<ast::F32>());
|
||||||
EXPECT_EQ(e.value[0]->type->As<ast::Vector>()->width, 4u);
|
EXPECT_EQ(e.value[0]->type->As<ast::Vector>()->width, 4u);
|
||||||
EXPECT_TRUE(e.value[0]->is_const);
|
EXPECT_TRUE(e.value[0]->is_const);
|
||||||
auto decos0 = e.value[0]->decorations;
|
auto attrs_0 = e.value[0]->attributes;
|
||||||
ASSERT_EQ(decos0.size(), 1u);
|
ASSERT_EQ(attrs_0.size(), 1u);
|
||||||
EXPECT_TRUE(decos0[0]->Is<ast::BuiltinDecoration>());
|
EXPECT_TRUE(attrs_0[0]->Is<ast::BuiltinAttribute>());
|
||||||
EXPECT_EQ(decos0[0]->As<ast::BuiltinDecoration>()->builtin,
|
EXPECT_EQ(attrs_0[0]->As<ast::BuiltinAttribute>()->builtin,
|
||||||
ast::Builtin::kPosition);
|
ast::Builtin::kPosition);
|
||||||
|
|
||||||
ASSERT_EQ(e.value[0]->source.range.begin.line, 1u);
|
ASSERT_EQ(e.value[0]->source.range.begin.line, 1u);
|
||||||
@ -119,10 +119,10 @@ TEST_F(ParserImplTest, ParamList_Decorations) {
|
|||||||
EXPECT_EQ(e.value[1]->symbol, p->builder().Symbols().Get("loc1"));
|
EXPECT_EQ(e.value[1]->symbol, p->builder().Symbols().Get("loc1"));
|
||||||
EXPECT_TRUE(e.value[1]->type->Is<ast::F32>());
|
EXPECT_TRUE(e.value[1]->type->Is<ast::F32>());
|
||||||
EXPECT_TRUE(e.value[1]->is_const);
|
EXPECT_TRUE(e.value[1]->is_const);
|
||||||
auto decos1 = e.value[1]->decorations;
|
auto attrs_1 = e.value[1]->attributes;
|
||||||
ASSERT_EQ(decos1.size(), 1u);
|
ASSERT_EQ(attrs_1.size(), 1u);
|
||||||
EXPECT_TRUE(decos1[0]->Is<ast::LocationDecoration>());
|
EXPECT_TRUE(attrs_1[0]->Is<ast::LocationAttribute>());
|
||||||
EXPECT_EQ(decos1[0]->As<ast::LocationDecoration>()->value, 1u);
|
EXPECT_EQ(attrs_1[0]->As<ast::LocationAttribute>()->value, 1u);
|
||||||
|
|
||||||
EXPECT_EQ(e.value[1]->source.range.begin.line, 1u);
|
EXPECT_EQ(e.value[1]->source.range.begin.line, 1u);
|
||||||
EXPECT_EQ(e.value[1]->source.range.begin.column, 52u);
|
EXPECT_EQ(e.value[1]->source.range.begin.column, 52u);
|
||||||
|
@ -58,7 +58,7 @@ TEST_F(ParserImplTest, PipelineStage_NoMatch) {
|
|||||||
auto stage = p->expect_pipeline_stage();
|
auto stage = p->expect_pipeline_stage();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_TRUE(stage.errored);
|
ASSERT_TRUE(stage.errored);
|
||||||
ASSERT_EQ(p->error(), "1:1: invalid value for stage decoration");
|
ASSERT_EQ(p->error(), "1:1: invalid value for stage attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
113
src/reader/wgsl/parser_impl_struct_attribute_decl_test.cc
Normal file
113
src/reader/wgsl/parser_impl_struct_attribute_decl_test.cc
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Copyright 2020 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "src/ast/override_attribute.h"
|
||||||
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace reader {
|
||||||
|
namespace wgsl {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, AttributeDecl_Parses) {
|
||||||
|
auto p = parser("@override");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_FALSE(p->has_error());
|
||||||
|
EXPECT_FALSE(attrs.errored);
|
||||||
|
EXPECT_TRUE(attrs.matched);
|
||||||
|
ASSERT_EQ(attrs.value.size(), 1u);
|
||||||
|
auto* override_attr = attrs.value[0]->As<ast::Attribute>();
|
||||||
|
EXPECT_TRUE(override_attr->Is<ast::OverrideAttribute>());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, AttributeDecl_MissingParenLeft) {
|
||||||
|
auto p = parser("@location 1)");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_TRUE(attrs.value.empty());
|
||||||
|
EXPECT_EQ(p->error(), "1:11: expected '(' for location attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, AttributeDecl_MissingValue) {
|
||||||
|
auto p = parser("@location()");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_TRUE(attrs.value.empty());
|
||||||
|
EXPECT_EQ(p->error(),
|
||||||
|
"1:11: expected signed integer literal for location attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, AttributeDecl_MissingParenRight) {
|
||||||
|
auto p = parser("@location(1");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_TRUE(attrs.value.empty());
|
||||||
|
EXPECT_EQ(p->error(), "1:12: expected ')' for location attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, AttributeDecl_Invalidattribute) {
|
||||||
|
auto p = parser("@invalid");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_TRUE(attrs.value.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
|
TEST_F(ParserImplTest, DEPRECATED_attributeDecl_Parses) {
|
||||||
|
auto p = parser("[[override]]");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_FALSE(p->has_error());
|
||||||
|
EXPECT_FALSE(attrs.errored);
|
||||||
|
EXPECT_TRUE(attrs.matched);
|
||||||
|
ASSERT_EQ(attrs.value.size(), 1u);
|
||||||
|
auto* override_attr = attrs.value[0]->As<ast::Attribute>();
|
||||||
|
EXPECT_TRUE(override_attr->Is<ast::OverrideAttribute>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
|
TEST_F(ParserImplTest, DEPRECATED_attributeDecl_MissingAttrRight) {
|
||||||
|
auto p = parser("[[override");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_TRUE(attrs.value.empty());
|
||||||
|
EXPECT_EQ(
|
||||||
|
p->error(),
|
||||||
|
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
|
||||||
|
1:11: expected ']]' for attribute list)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crbug.com/tint/1382): Remove
|
||||||
|
TEST_F(ParserImplTest, DEPRECATED_attributeDecl_Invalidattribute) {
|
||||||
|
auto p = parser("[[invalid]]");
|
||||||
|
auto attrs = p->attribute_list();
|
||||||
|
EXPECT_TRUE(p->has_error());
|
||||||
|
EXPECT_TRUE(attrs.errored);
|
||||||
|
EXPECT_FALSE(attrs.matched);
|
||||||
|
EXPECT_TRUE(attrs.value.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace wgsl
|
||||||
|
} // namespace reader
|
||||||
|
} // namespace tint
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/ast/struct_block_decoration.h"
|
#include "src/ast/struct_block_attribute.h"
|
||||||
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
@ -20,40 +20,40 @@ namespace reader {
|
|||||||
namespace wgsl {
|
namespace wgsl {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct DecorationData {
|
struct AttributeData {
|
||||||
const char* input;
|
const char* input;
|
||||||
bool is_block;
|
bool is_block;
|
||||||
};
|
};
|
||||||
inline std::ostream& operator<<(std::ostream& out, DecorationData data) {
|
inline std::ostream& operator<<(std::ostream& out, AttributeData data) {
|
||||||
out << std::string(data.input);
|
out << std::string(data.input);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DecorationTest : public ParserImplTestWithParam<DecorationData> {};
|
class AttributeTest : public ParserImplTestWithParam<AttributeData> {};
|
||||||
|
|
||||||
TEST_P(DecorationTest, Parses) {
|
TEST_P(AttributeTest, Parses) {
|
||||||
auto params = GetParam();
|
auto params = GetParam();
|
||||||
auto p = parser(params.input);
|
auto p = parser(params.input);
|
||||||
|
|
||||||
auto deco = p->decoration();
|
auto attr = p->attribute();
|
||||||
ASSERT_FALSE(p->has_error());
|
ASSERT_FALSE(p->has_error());
|
||||||
EXPECT_TRUE(deco.matched);
|
EXPECT_TRUE(attr.matched);
|
||||||
EXPECT_FALSE(deco.errored);
|
EXPECT_FALSE(attr.errored);
|
||||||
ASSERT_NE(deco.value, nullptr);
|
ASSERT_NE(attr.value, nullptr);
|
||||||
auto* struct_deco = deco.value->As<ast::Decoration>();
|
auto* struct_attr = attr.value->As<ast::Attribute>();
|
||||||
ASSERT_NE(struct_deco, nullptr);
|
ASSERT_NE(struct_attr, nullptr);
|
||||||
EXPECT_EQ(struct_deco->Is<ast::StructBlockDecoration>(), params.is_block);
|
EXPECT_EQ(struct_attr->Is<ast::StructBlockAttribute>(), params.is_block);
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||||
DecorationTest,
|
AttributeTest,
|
||||||
testing::Values(DecorationData{"block", true}));
|
testing::Values(AttributeData{"block", true}));
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Decoration_NoMatch) {
|
TEST_F(ParserImplTest, Attribute_NoMatch) {
|
||||||
auto p = parser("not-a-stage");
|
auto p = parser("not-a-stage");
|
||||||
auto deco = p->decoration();
|
auto attr = p->attribute();
|
||||||
EXPECT_FALSE(deco.matched);
|
EXPECT_FALSE(attr.matched);
|
||||||
EXPECT_FALSE(deco.errored);
|
EXPECT_FALSE(attr.errored);
|
||||||
ASSERT_EQ(deco.value, nullptr);
|
ASSERT_EQ(attr.value, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
@ -32,7 +32,7 @@ TEST_F(ParserImplTest, StructBodyDecl_Parses) {
|
|||||||
const auto* mem = m.value[0];
|
const auto* mem = m.value[0];
|
||||||
EXPECT_EQ(mem->symbol, builder.Symbols().Get("a"));
|
EXPECT_EQ(mem->symbol, builder.Symbols().Get("a"));
|
||||||
EXPECT_TRUE(mem->type->Is<ast::I32>());
|
EXPECT_TRUE(mem->type->Is<ast::I32>());
|
||||||
EXPECT_EQ(mem->decorations.size(), 0u);
|
EXPECT_EQ(mem->attributes.size(), 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, StructBodyDecl_ParsesEmpty) {
|
TEST_F(ParserImplTest, StructBodyDecl_ParsesEmpty) {
|
||||||
@ -52,7 +52,7 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidAlign) {
|
|||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_TRUE(m.errored);
|
ASSERT_TRUE(m.errored);
|
||||||
EXPECT_EQ(p->error(),
|
EXPECT_EQ(p->error(),
|
||||||
"3:10: expected signed integer literal for align decoration");
|
"3:10: expected signed integer literal for align attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, StructBodyDecl_InvalidSize) {
|
TEST_F(ParserImplTest, StructBodyDecl_InvalidSize) {
|
||||||
@ -64,7 +64,7 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidSize) {
|
|||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_TRUE(m.errored);
|
ASSERT_TRUE(m.errored);
|
||||||
EXPECT_EQ(p->error(),
|
EXPECT_EQ(p->error(),
|
||||||
"3:9: expected signed integer literal for size decoration");
|
"3:9: expected signed integer literal for size attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, StructBodyDecl_MissingClosingBracket) {
|
TEST_F(ParserImplTest, StructBodyDecl_MissingClosingBracket) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user