Rename 'decoration' to 'attribute'

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,162 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/workgroup_attribute.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, AttributeList_Parses) {
auto p = parser("@workgroup_size(2) @stage(compute)");
auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
ASSERT_EQ(attrs.value.size(), 2u);
auto* attr_0 = attrs.value[0]->As<ast::Attribute>();
auto* attr_1 = attrs.value[1]->As<ast::Attribute>();
ASSERT_NE(attr_0, nullptr);
ASSERT_NE(attr_1, nullptr);
ASSERT_TRUE(attr_0->Is<ast::WorkgroupAttribute>());
const ast::Expression* x = attr_0->As<ast::WorkgroupAttribute>()->x;
ASSERT_NE(x, nullptr);
auto* x_literal = x->As<ast::LiteralExpression>();
ASSERT_NE(x_literal, nullptr);
ASSERT_TRUE(x_literal->Is<ast::IntLiteralExpression>());
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
ASSERT_TRUE(attr_1->Is<ast::StageAttribute>());
EXPECT_EQ(attr_1->As<ast::StageAttribute>()->stage,
ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, AttributeList_Invalid) {
auto p = parser("@invalid");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(p->error(), "1:2: expected attribute");
}
TEST_F(ParserImplTest, AttributeList_ExtraComma) {
auto p = parser("[[workgroup_size(2), ]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:22: expected attribute)");
}
TEST_F(ParserImplTest, AttributeList_BadAttribute) {
auto p = parser("@stage()");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(p->error(), "1:8: invalid value for stage attribute");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_Empty) {
auto p = parser("[[]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:3: empty attribute list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_Invalid) {
auto p = parser("[[invalid]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:3: expected attribute)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_ExtraComma) {
auto p = parser("[[workgroup_size(2), ]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:22: expected attribute)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_MissingComma) {
auto p = parser("[[workgroup_size(2) workgroup_size(2)]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:21: expected ',' for attribute list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_BadAttribute) {
auto p = parser("[[stage()]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:9: invalid value for stage attribute)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_AttributeList_MissingRightAttr) {
auto p = parser("[[workgroup_size(2), workgroup_size(3, 4, 5)");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:45: expected ']]' for attribute list)");
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

@ -0,0 +1,260 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/stage_attribute.h"
#include "src/ast/workgroup_attribute.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, Attribute_Workgroup) {
auto p = parser("workgroup_size(4)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
EXPECT_EQ(values[1], nullptr);
EXPECT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Attribute_Workgroup_2Param) {
auto p = parser("workgroup_size(4, 5)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr) << p->error();
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
EXPECT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Attribute_Workgroup_3Param) {
auto p = parser("workgroup_size(4, 5, 6)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
}
TEST_F(ParserImplTest, Attribute_Workgroup_WithIdent) {
auto p = parser("workgroup_size(4, height)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::WorkgroupAttribute>());
auto values = func_attr->As<ast::WorkgroupAttribute>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_NE(values[1], nullptr);
auto* y_ident = values[1]->As<ast::IdentifierExpression>();
ASSERT_NE(y_ident, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(y_ident->symbol), "height");
ASSERT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Attribute_Workgroup_TooManyValues) {
auto p = parser("workgroup_size(1, 2, 3, 4)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_MissingLeftParam) {
auto p = parser("workgroup_size 4, 5, 6)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected '(' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_MissingRightParam) {
auto p = parser("workgroup_size(4, 5, 6");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_MissingValues) {
auto p = parser("workgroup_size()");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_X_Value) {
auto p = parser("workgroup_size(, 2, 3)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Y_Comma) {
auto p = parser("workgroup_size(1 2, 3)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:18: expected ')' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Y_Value) {
auto p = parser("workgroup_size(1, , 3)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:19: expected workgroup_size y parameter");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Z_Comma) {
auto p = parser("workgroup_size(1, 2 3)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:21: expected ')' for workgroup_size attribute");
}
TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Z_Value) {
auto p = parser("workgroup_size(1, 2, )");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:22: expected workgroup_size z parameter");
}
TEST_F(ParserImplTest, Attribute_Stage) {
auto p = parser("stage(compute)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::StageAttribute>());
EXPECT_EQ(func_attr->As<ast::StageAttribute>()->stage,
ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, Attribute_Stage_MissingValue) {
auto p = parser("stage()");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: invalid value for stage attribute");
}
TEST_F(ParserImplTest, Attribute_Stage_MissingInvalid) {
auto p = parser("stage(nan)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: invalid value for stage attribute");
}
TEST_F(ParserImplTest, Attribute_Stage_MissingLeftParen) {
auto p = parser("stage compute)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: expected '(' for stage attribute");
}
TEST_F(ParserImplTest, Attribute_Stage_MissingRightParen) {
auto p = parser("stage(compute");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:14: expected ')' for stage attribute");
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

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

View File

@ -1,162 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/workgroup_decoration.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, DecorationList_Parses) {
auto p = parser("@workgroup_size(2) @stage(compute)");
auto decos = p->decoration_list();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(decos.errored);
EXPECT_TRUE(decos.matched);
ASSERT_EQ(decos.value.size(), 2u);
auto* deco_0 = decos.value[0]->As<ast::Decoration>();
auto* deco_1 = decos.value[1]->As<ast::Decoration>();
ASSERT_NE(deco_0, nullptr);
ASSERT_NE(deco_1, nullptr);
ASSERT_TRUE(deco_0->Is<ast::WorkgroupDecoration>());
const ast::Expression* x = deco_0->As<ast::WorkgroupDecoration>()->x;
ASSERT_NE(x, nullptr);
auto* x_literal = x->As<ast::LiteralExpression>();
ASSERT_NE(x_literal, nullptr);
ASSERT_TRUE(x_literal->Is<ast::IntLiteralExpression>());
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
ASSERT_TRUE(deco_1->Is<ast::StageDecoration>());
EXPECT_EQ(deco_1->As<ast::StageDecoration>()->stage,
ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, DecorationList_Invalid) {
auto p = parser("@invalid");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_TRUE(decos.value.empty());
EXPECT_EQ(p->error(), "1:2: expected decoration");
}
TEST_F(ParserImplTest, DecorationList_ExtraComma) {
auto p = parser("[[workgroup_size(2), ]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:22: expected decoration)");
}
TEST_F(ParserImplTest, DecorationList_BadDecoration) {
auto p = parser("@stage()");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(p->error(), "1:8: invalid value for stage decoration");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_Empty) {
auto p = parser("[[]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:3: empty decoration list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_Invalid) {
auto p = parser("[[invalid]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_TRUE(decos.value.empty());
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:3: expected decoration)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_ExtraComma) {
auto p = parser("[[workgroup_size(2), ]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:22: expected decoration)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_MissingComma) {
auto p = parser("[[workgroup_size(2) workgroup_size(2)]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:21: expected ',' for decoration list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_BadDecoration) {
auto p = parser("[[stage()]]");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:9: invalid value for stage decoration)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_DecorationList_MissingRightAttr) {
auto p = parser("[[workgroup_size(2), workgroup_size(3, 4, 5)");
auto decos = p->decoration_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched);
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[decoration]] style decorations have been replaced with @decoration style
1:45: expected ']]' for decoration list)");
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

@ -1,260 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/stage_decoration.h"
#include "src/ast/workgroup_decoration.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, Decoration_Workgroup) {
auto p = parser("workgroup_size(4)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
EXPECT_EQ(values[1], nullptr);
EXPECT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Decoration_Workgroup_2Param) {
auto p = parser("workgroup_size(4, 5)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr) << p->error();
ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
EXPECT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Decoration_Workgroup_3Param) {
auto p = parser("workgroup_size(4, 5, 6)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
}
TEST_F(ParserImplTest, Decoration_Workgroup_WithIdent) {
auto p = parser("workgroup_size(4, height)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
ASSERT_NE(values[1], nullptr);
auto* y_ident = values[1]->As<ast::IdentifierExpression>();
ASSERT_NE(y_ident, nullptr);
EXPECT_EQ(p->builder().Symbols().NameFor(y_ident->symbol), "height");
ASSERT_EQ(values[2], nullptr);
}
TEST_F(ParserImplTest, Decoration_Workgroup_TooManyValues) {
auto p = parser("workgroup_size(1, 2, 3, 4)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_MissingLeftParam) {
auto p = parser("workgroup_size 4, 5, 6)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected '(' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_MissingRightParam) {
auto p = parser("workgroup_size(4, 5, 6");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_MissingValues) {
auto p = parser("workgroup_size()");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_X_Value) {
auto p = parser("workgroup_size(, 2, 3)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Y_Comma) {
auto p = parser("workgroup_size(1 2, 3)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:18: expected ')' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Y_Value) {
auto p = parser("workgroup_size(1, , 3)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:19: expected workgroup_size y parameter");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Z_Comma) {
auto p = parser("workgroup_size(1, 2 3)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:21: expected ')' for workgroup_size decoration");
}
TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Z_Value) {
auto p = parser("workgroup_size(1, 2, )");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:22: expected workgroup_size z parameter");
}
TEST_F(ParserImplTest, Decoration_Stage) {
auto p = parser("stage(compute)");
auto deco = p->decoration();
EXPECT_TRUE(deco.matched);
EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_deco = deco.value->As<ast::Decoration>();
ASSERT_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->Is<ast::StageDecoration>());
EXPECT_EQ(func_deco->As<ast::StageDecoration>()->stage,
ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, Decoration_Stage_MissingValue) {
auto p = parser("stage()");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: invalid value for stage decoration");
}
TEST_F(ParserImplTest, Decoration_Stage_MissingInvalid) {
auto p = parser("stage(nan)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: invalid value for stage decoration");
}
TEST_F(ParserImplTest, Decoration_Stage_MissingLeftParen) {
auto p = parser("stage compute)");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: expected '(' for stage decoration");
}
TEST_F(ParserImplTest, Decoration_Stage_MissingRightParen) {
auto p = parser("stage(compute");
auto deco = p->decoration();
EXPECT_FALSE(deco.matched);
EXPECT_TRUE(deco.errored);
EXPECT_EQ(deco.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:14: expected ')' for stage decoration");
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,113 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/override_attribute.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, AttributeDecl_Parses) {
auto p = parser("@override");
auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
ASSERT_EQ(attrs.value.size(), 1u);
auto* override_attr = attrs.value[0]->As<ast::Attribute>();
EXPECT_TRUE(override_attr->Is<ast::OverrideAttribute>());
}
TEST_F(ParserImplTest, AttributeDecl_MissingParenLeft) {
auto p = parser("@location 1)");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(p->error(), "1:11: expected '(' for location attribute");
}
TEST_F(ParserImplTest, AttributeDecl_MissingValue) {
auto p = parser("@location()");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(p->error(),
"1:11: expected signed integer literal for location attribute");
}
TEST_F(ParserImplTest, AttributeDecl_MissingParenRight) {
auto p = parser("@location(1");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(p->error(), "1:12: expected ')' for location attribute");
}
TEST_F(ParserImplTest, AttributeDecl_Invalidattribute) {
auto p = parser("@invalid");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_attributeDecl_Parses) {
auto p = parser("[[override]]");
auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
ASSERT_EQ(attrs.value.size(), 1u);
auto* override_attr = attrs.value[0]->As<ast::Attribute>();
EXPECT_TRUE(override_attr->Is<ast::OverrideAttribute>());
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_attributeDecl_MissingAttrRight) {
auto p = parser("[[override");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
EXPECT_EQ(
p->error(),
R"(1:1: use of deprecated language feature: [[attribute]] style attributes have been replaced with @attribute style
1:11: expected ']]' for attribute list)");
}
// TODO(crbug.com/tint/1382): Remove
TEST_F(ParserImplTest, DEPRECATED_attributeDecl_Invalidattribute) {
auto p = parser("[[invalid]]");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_TRUE(attrs.value.empty());
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

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

View File

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

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