tint/reader/wgsl: Remove type keywords

Fixes: tint:1810
Change-Id: Iff296a3923947801b9559fd0f5354b72f4b171d2
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/120081
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2023-02-18 08:36:01 +00:00 committed by Dawn LUCI CQ
parent a1bda83c42
commit 643f2aad43
94 changed files with 335 additions and 3091 deletions

View File

@ -1653,14 +1653,12 @@ if (tint_build_unittests) {
"reader/wgsl/parser_impl_break_stmt_test.cc",
"reader/wgsl/parser_impl_bug_cases_test.cc",
"reader/wgsl/parser_impl_call_stmt_test.cc",
"reader/wgsl/parser_impl_callable_test.cc",
"reader/wgsl/parser_impl_case_body_test.cc",
"reader/wgsl/parser_impl_compound_stmt_test.cc",
"reader/wgsl/parser_impl_const_literal_test.cc",
"reader/wgsl/parser_impl_continue_stmt_test.cc",
"reader/wgsl/parser_impl_continuing_stmt_test.cc",
"reader/wgsl/parser_impl_core_lhs_expression_test.cc",
"reader/wgsl/parser_impl_depth_texture_test.cc",
"reader/wgsl/parser_impl_diagnostic_attribute_test.cc",
"reader/wgsl/parser_impl_diagnostic_control_test.cc",
"reader/wgsl/parser_impl_diagnostic_directive_test.cc",
@ -1669,7 +1667,6 @@ if (tint_build_unittests) {
"reader/wgsl/parser_impl_error_msg_test.cc",
"reader/wgsl/parser_impl_error_resync_test.cc",
"reader/wgsl/parser_impl_expression_test.cc",
"reader/wgsl/parser_impl_external_texture_test.cc",
"reader/wgsl/parser_impl_for_stmt_test.cc",
"reader/wgsl/parser_impl_function_attribute_list_test.cc",
"reader/wgsl/parser_impl_function_attribute_test.cc",
@ -1689,13 +1686,10 @@ if (tint_build_unittests) {
"reader/wgsl/parser_impl_primary_expression_test.cc",
"reader/wgsl/parser_impl_relational_expression_test.cc",
"reader/wgsl/parser_impl_reserved_keyword_test.cc",
"reader/wgsl/parser_impl_sampled_texture_test.cc",
"reader/wgsl/parser_impl_sampler_test.cc",
"reader/wgsl/parser_impl_shift_expression_test.cc",
"reader/wgsl/parser_impl_singular_expression_test.cc",
"reader/wgsl/parser_impl_statement_test.cc",
"reader/wgsl/parser_impl_statements_test.cc",
"reader/wgsl/parser_impl_storage_texture_test.cc",
"reader/wgsl/parser_impl_struct_attribute_decl_test.cc",
"reader/wgsl/parser_impl_struct_body_decl_test.cc",
"reader/wgsl/parser_impl_struct_decl_test.cc",
@ -1707,11 +1701,8 @@ if (tint_build_unittests) {
"reader/wgsl/parser_impl_test.cc",
"reader/wgsl/parser_impl_test_helper.cc",
"reader/wgsl/parser_impl_test_helper.h",
"reader/wgsl/parser_impl_texel_format_test.cc",
"reader/wgsl/parser_impl_texture_sampler_test.cc",
"reader/wgsl/parser_impl_type_alias_test.cc",
"reader/wgsl/parser_impl_type_decl_test.cc",
"reader/wgsl/parser_impl_type_decl_without_ident_test.cc",
"reader/wgsl/parser_impl_unary_expression_test.cc",
"reader/wgsl/parser_impl_variable_attribute_list_test.cc",
"reader/wgsl/parser_impl_variable_attribute_test.cc",
@ -1719,7 +1710,6 @@ if (tint_build_unittests) {
"reader/wgsl/parser_impl_variable_ident_decl_test.cc",
"reader/wgsl/parser_impl_variable_qualifier_test.cc",
"reader/wgsl/parser_impl_variable_stmt_test.cc",
"reader/wgsl/parser_impl_vec_mat_prefix_test.cc",
"reader/wgsl/parser_impl_while_stmt_test.cc",
"reader/wgsl/parser_test.cc",
"reader/wgsl/token_test.cc",

View File

@ -1055,14 +1055,12 @@ if(TINT_BUILD_TESTS)
reader/wgsl/parser_impl_break_stmt_test.cc
reader/wgsl/parser_impl_bug_cases_test.cc
reader/wgsl/parser_impl_call_stmt_test.cc
reader/wgsl/parser_impl_callable_test.cc
reader/wgsl/parser_impl_case_body_test.cc
reader/wgsl/parser_impl_compound_stmt_test.cc
reader/wgsl/parser_impl_const_literal_test.cc
reader/wgsl/parser_impl_continue_stmt_test.cc
reader/wgsl/parser_impl_continuing_stmt_test.cc
reader/wgsl/parser_impl_core_lhs_expression_test.cc
reader/wgsl/parser_impl_depth_texture_test.cc
reader/wgsl/parser_impl_diagnostic_attribute_test.cc
reader/wgsl/parser_impl_diagnostic_control_test.cc
reader/wgsl/parser_impl_diagnostic_directive_test.cc
@ -1071,7 +1069,6 @@ if(TINT_BUILD_TESTS)
reader/wgsl/parser_impl_error_msg_test.cc
reader/wgsl/parser_impl_error_resync_test.cc
reader/wgsl/parser_impl_expression_test.cc
reader/wgsl/parser_impl_external_texture_test.cc
reader/wgsl/parser_impl_for_stmt_test.cc
reader/wgsl/parser_impl_function_decl_test.cc
reader/wgsl/parser_impl_function_attribute_list_test.cc
@ -1091,14 +1088,11 @@ if(TINT_BUILD_TESTS)
reader/wgsl/parser_impl_primary_expression_test.cc
reader/wgsl/parser_impl_relational_expression_test.cc
reader/wgsl/parser_impl_reserved_keyword_test.cc
reader/wgsl/parser_impl_sampled_texture_test.cc
reader/wgsl/parser_impl_sampler_test.cc
reader/wgsl/parser_impl_shift_expression_test.cc
reader/wgsl/parser_impl_singular_expression_test.cc
reader/wgsl/parser_impl_statement_test.cc
reader/wgsl/parser_impl_statements_test.cc
reader/wgsl/parser_impl_address_space_test.cc
reader/wgsl/parser_impl_storage_texture_test.cc
reader/wgsl/parser_impl_struct_body_decl_test.cc
reader/wgsl/parser_impl_struct_decl_test.cc
reader/wgsl/parser_impl_struct_attribute_decl_test.cc
@ -1110,11 +1104,8 @@ if(TINT_BUILD_TESTS)
reader/wgsl/parser_impl_test.cc
reader/wgsl/parser_impl_test_helper.cc
reader/wgsl/parser_impl_test_helper.h
reader/wgsl/parser_impl_texel_format_test.cc
reader/wgsl/parser_impl_texture_sampler_test.cc
reader/wgsl/parser_impl_type_alias_test.cc
reader/wgsl/parser_impl_type_decl_test.cc
reader/wgsl/parser_impl_type_decl_without_ident_test.cc
reader/wgsl/parser_impl_unary_expression_test.cc
reader/wgsl/parser_impl_variable_decl_test.cc
reader/wgsl/parser_impl_variable_attribute_list_test.cc
@ -1122,7 +1113,6 @@ if(TINT_BUILD_TESTS)
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
reader/wgsl/parser_impl_vec_mat_prefix_test.cc
reader/wgsl/parser_impl_while_stmt_test.cc
reader/wgsl/token_test.cc
)

View File

@ -72,33 +72,7 @@ void ClassifyTemplateArguments(std::vector<Token>& tokens) {
switch (tokens[i].type()) {
// <identifier> + all type / builtin keywords that will become identifiers.
case Token::Type::kIdentifier:
case Token::Type::kArray:
case Token::Type::kAtomic:
case Token::Type::kBitcast:
case Token::Type::kMat2x2:
case Token::Type::kMat2x3:
case Token::Type::kMat2x4:
case Token::Type::kMat3x2:
case Token::Type::kMat3x3:
case Token::Type::kMat3x4:
case Token::Type::kMat4x2:
case Token::Type::kMat4x3:
case Token::Type::kMat4x4:
case Token::Type::kPtr:
case Token::Type::kTextureMultisampled2d:
case Token::Type::kTextureSampled1d:
case Token::Type::kTextureSampled2d:
case Token::Type::kTextureSampled2dArray:
case Token::Type::kTextureSampled3d:
case Token::Type::kTextureSampledCube:
case Token::Type::kTextureSampledCubeArray:
case Token::Type::kTextureStorage1d:
case Token::Type::kTextureStorage2d:
case Token::Type::kTextureStorage2dArray:
case Token::Type::kVec2:
case Token::Type::kVec3:
case Token::Type::kVec4:
case Token::Type::kTextureStorage3d: {
case Token::Type::kBitcast: {
auto& next = tokens[i + 1];
if (next.type() == Token::Type::kLessThan) {
// ident '<'

View File

@ -232,9 +232,9 @@ INSTANTIATE_TEST_SUITE_P(Template,
{
"vec3<i32>",
{
T::kVec3, // vec3
T::kIdentifier, // vec3
T::kTemplateArgsLeft, // <
T::kI32, // i32
T::kIdentifier, // i32
T::kTemplateArgsRight, // >
T::kEOF,
},
@ -242,9 +242,9 @@ INSTANTIATE_TEST_SUITE_P(Template,
{
"vec3<i32>()",
{
T::kVec3, // vec3
T::kIdentifier, // vec3
T::kTemplateArgsLeft, // <
T::kI32, // i32
T::kIdentifier, // i32
T::kTemplateArgsRight, // >
T::kParenLeft, // (
T::kParenRight, // )
@ -254,11 +254,11 @@ INSTANTIATE_TEST_SUITE_P(Template,
{
"array<vec3<i32>,5>",
{
T::kArray, // array
T::kIdentifier, // array
T::kTemplateArgsLeft, // <
T::kVec3, // vec3
T::kIdentifier, // vec3
T::kTemplateArgsLeft, // <
T::kI32, // i32
T::kIdentifier, // i32
T::kTemplateArgsRight, // >
T::kComma, // ,
T::kIntLiteral, // 5

View File

@ -1118,18 +1118,9 @@ Token Lexer::check_keyword(const Source& source, std::string_view str) {
if (str == "alias") {
return {Token::Type::kAlias, source, "alias"};
}
if (str == "array") {
return {Token::Type::kArray, source, "array"};
}
if (str == "atomic") {
return {Token::Type::kAtomic, source, "atomic"};
}
if (str == "bitcast") {
return {Token::Type::kBitcast, source, "bitcast"};
}
if (str == "bool") {
return {Token::Type::kBool, source, "bool"};
}
if (str == "break") {
return {Token::Type::kBreak, source, "break"};
}
@ -1163,12 +1154,6 @@ Token Lexer::check_keyword(const Source& source, std::string_view str) {
if (str == "enable") {
return {Token::Type::kEnable, source, "enable"};
}
if (str == "f16") {
return {Token::Type::kF16, source, "f16"};
}
if (str == "f32") {
return {Token::Type::kF32, source, "f32"};
}
if (str == "fallthrough") {
return {Token::Type::kFallthrough, source, "fallthrough"};
}
@ -1181,9 +1166,6 @@ Token Lexer::check_keyword(const Source& source, std::string_view str) {
if (str == "for") {
return {Token::Type::kFor, source, "for"};
}
if (str == "i32") {
return {Token::Type::kI32, source, "i32"};
}
if (str == "if") {
return {Token::Type::kIf, source, "if"};
}
@ -1193,48 +1175,12 @@ Token Lexer::check_keyword(const Source& source, std::string_view str) {
if (str == "loop") {
return {Token::Type::kLoop, source, "loop"};
}
if (str == "mat2x2") {
return {Token::Type::kMat2x2, source, "mat2x2"};
}
if (str == "mat2x3") {
return {Token::Type::kMat2x3, source, "mat2x3"};
}
if (str == "mat2x4") {
return {Token::Type::kMat2x4, source, "mat2x4"};
}
if (str == "mat3x2") {
return {Token::Type::kMat3x2, source, "mat3x2"};
}
if (str == "mat3x3") {
return {Token::Type::kMat3x3, source, "mat3x3"};
}
if (str == "mat3x4") {
return {Token::Type::kMat3x4, source, "mat3x4"};
}
if (str == "mat4x2") {
return {Token::Type::kMat4x2, source, "mat4x2"};
}
if (str == "mat4x3") {
return {Token::Type::kMat4x3, source, "mat4x3"};
}
if (str == "mat4x4") {
return {Token::Type::kMat4x4, source, "mat4x4"};
}
if (str == "override") {
return {Token::Type::kOverride, source, "override"};
}
if (str == "ptr") {
return {Token::Type::kPtr, source, "ptr"};
}
if (str == "return") {
return {Token::Type::kReturn, source, "return"};
}
if (str == "sampler") {
return {Token::Type::kSampler, source, "sampler"};
}
if (str == "sampler_comparison") {
return {Token::Type::kComparisonSampler, source, "sampler_comparison"};
}
if (str == "static_assert") {
return {Token::Type::kStaticAssert, source, "static_assert"};
}
@ -1244,78 +1190,15 @@ Token Lexer::check_keyword(const Source& source, std::string_view str) {
if (str == "switch") {
return {Token::Type::kSwitch, source, "switch"};
}
if (str == "texture_1d") {
return {Token::Type::kTextureSampled1d, source, "texture_1d"};
}
if (str == "texture_2d") {
return {Token::Type::kTextureSampled2d, source, "texture_2d"};
}
if (str == "texture_2d_array") {
return {Token::Type::kTextureSampled2dArray, source, "texture_2d_array"};
}
if (str == "texture_3d") {
return {Token::Type::kTextureSampled3d, source, "texture_3d"};
}
if (str == "texture_cube") {
return {Token::Type::kTextureSampledCube, source, "texture_cube"};
}
if (str == "texture_cube_array") {
return {Token::Type::kTextureSampledCubeArray, source, "texture_cube_array"};
}
if (str == "texture_depth_2d") {
return {Token::Type::kTextureDepth2d, source, "texture_depth_2d"};
}
if (str == "texture_depth_2d_array") {
return {Token::Type::kTextureDepth2dArray, source, "texture_depth_2d_array"};
}
if (str == "texture_depth_cube") {
return {Token::Type::kTextureDepthCube, source, "texture_depth_cube"};
}
if (str == "texture_depth_cube_array") {
return {Token::Type::kTextureDepthCubeArray, source, "texture_depth_cube_array"};
}
if (str == "texture_depth_multisampled_2d") {
return {Token::Type::kTextureDepthMultisampled2d, source, "texture_depth_multisampled_2d"};
}
if (str == "texture_external") {
return {Token::Type::kTextureExternal, source, "texture_external"};
}
if (str == "texture_multisampled_2d") {
return {Token::Type::kTextureMultisampled2d, source, "texture_multisampled_2d"};
}
if (str == "texture_storage_1d") {
return {Token::Type::kTextureStorage1d, source, "texture_storage_1d"};
}
if (str == "texture_storage_2d") {
return {Token::Type::kTextureStorage2d, source, "texture_storage_2d"};
}
if (str == "texture_storage_2d_array") {
return {Token::Type::kTextureStorage2dArray, source, "texture_storage_2d_array"};
}
if (str == "texture_storage_3d") {
return {Token::Type::kTextureStorage3d, source, "texture_storage_3d"};
}
if (str == "true") {
return {Token::Type::kTrue, source, "true"};
}
if (str == "type") {
return {Token::Type::kType, source, "type"};
}
if (str == "u32") {
return {Token::Type::kU32, source, "u32"};
}
if (str == "var") {
return {Token::Type::kVar, source, "var"};
}
if (str == "vec2") {
return {Token::Type::kVec2, source, "vec2"};
}
if (str == "vec3") {
return {Token::Type::kVec3, source, "vec3"};
}
if (str == "vec4") {
return {Token::Type::kVec4, source, "vec4"};
}
if (str == "while") {
return {Token::Type::kWhile, source, "while"};
}

View File

@ -1054,75 +1054,37 @@ TEST_P(KeywordTest, Parses) {
EXPECT_EQ(list[1].source().range.begin.column, 1 + std::string(params.input).size());
}
INSTANTIATE_TEST_SUITE_P(
LexerTest,
KeywordTest,
testing::Values(TokenData{"alias", Token::Type::kAlias},
TokenData{"array", Token::Type::kArray},
TokenData{"bitcast", Token::Type::kBitcast},
TokenData{"bool", Token::Type::kBool},
TokenData{"break", Token::Type::kBreak},
TokenData{"case", Token::Type::kCase},
TokenData{"const", Token::Type::kConst},
TokenData{"const_assert", Token::Type::kConstAssert},
TokenData{"continue", Token::Type::kContinue},
TokenData{"continuing", Token::Type::kContinuing},
TokenData{"default", Token::Type::kDefault},
TokenData{"diagnostic", Token::Type::kDiagnostic},
TokenData{"discard", Token::Type::kDiscard},
TokenData{"else", Token::Type::kElse},
TokenData{"enable", Token::Type::kEnable},
TokenData{"f32", Token::Type::kF32},
TokenData{"fallthrough", Token::Type::kFallthrough},
TokenData{"false", Token::Type::kFalse},
TokenData{"fn", Token::Type::kFn},
TokenData{"for", Token::Type::kFor},
TokenData{"i32", Token::Type::kI32},
TokenData{"if", Token::Type::kIf},
TokenData{"let", Token::Type::kLet},
TokenData{"loop", Token::Type::kLoop},
TokenData{"mat2x2", Token::Type::kMat2x2},
TokenData{"mat2x3", Token::Type::kMat2x3},
TokenData{"mat2x4", Token::Type::kMat2x4},
TokenData{"mat3x2", Token::Type::kMat3x2},
TokenData{"mat3x3", Token::Type::kMat3x3},
TokenData{"mat3x4", Token::Type::kMat3x4},
TokenData{"mat4x2", Token::Type::kMat4x2},
TokenData{"mat4x3", Token::Type::kMat4x3},
TokenData{"mat4x4", Token::Type::kMat4x4},
TokenData{"override", Token::Type::kOverride},
TokenData{"ptr", Token::Type::kPtr},
TokenData{"return", Token::Type::kReturn},
TokenData{"sampler", Token::Type::kSampler},
TokenData{"sampler_comparison", Token::Type::kComparisonSampler},
TokenData{"static_assert", Token::Type::kStaticAssert},
TokenData{"struct", Token::Type::kStruct},
TokenData{"switch", Token::Type::kSwitch},
TokenData{"texture_1d", Token::Type::kTextureSampled1d},
TokenData{"texture_2d", Token::Type::kTextureSampled2d},
TokenData{"texture_2d_array", Token::Type::kTextureSampled2dArray},
TokenData{"texture_3d", Token::Type::kTextureSampled3d},
TokenData{"texture_cube", Token::Type::kTextureSampledCube},
TokenData{"texture_cube_array", Token::Type::kTextureSampledCubeArray},
TokenData{"texture_depth_2d", Token::Type::kTextureDepth2d},
TokenData{"texture_depth_2d_array", Token::Type::kTextureDepth2dArray},
TokenData{"texture_depth_cube", Token::Type::kTextureDepthCube},
TokenData{"texture_depth_cube_array", Token::Type::kTextureDepthCubeArray},
TokenData{"texture_depth_multisampled_2d",
Token::Type::kTextureDepthMultisampled2d},
TokenData{"texture_multisampled_2d", Token::Type::kTextureMultisampled2d},
TokenData{"texture_storage_1d", Token::Type::kTextureStorage1d},
TokenData{"texture_storage_2d", Token::Type::kTextureStorage2d},
TokenData{"texture_storage_2d_array", Token::Type::kTextureStorage2dArray},
TokenData{"texture_storage_3d", Token::Type::kTextureStorage3d},
TokenData{"true", Token::Type::kTrue},
TokenData{"type", Token::Type::kType},
TokenData{"u32", Token::Type::kU32},
TokenData{"var", Token::Type::kVar},
TokenData{"vec2", Token::Type::kVec2},
TokenData{"vec3", Token::Type::kVec3},
TokenData{"vec4", Token::Type::kVec4},
TokenData{"while", Token::Type::kWhile}));
INSTANTIATE_TEST_SUITE_P(LexerTest,
KeywordTest,
testing::Values(TokenData{"alias", Token::Type::kAlias},
TokenData{"bitcast", Token::Type::kBitcast},
TokenData{"break", Token::Type::kBreak},
TokenData{"case", Token::Type::kCase},
TokenData{"const", Token::Type::kConst},
TokenData{"const_assert", Token::Type::kConstAssert},
TokenData{"continue", Token::Type::kContinue},
TokenData{"continuing", Token::Type::kContinuing},
TokenData{"default", Token::Type::kDefault},
TokenData{"diagnostic", Token::Type::kDiagnostic},
TokenData{"discard", Token::Type::kDiscard},
TokenData{"else", Token::Type::kElse},
TokenData{"enable", Token::Type::kEnable},
TokenData{"fallthrough", Token::Type::kFallthrough},
TokenData{"false", Token::Type::kFalse},
TokenData{"fn", Token::Type::kFn},
TokenData{"for", Token::Type::kFor},
TokenData{"if", Token::Type::kIf},
TokenData{"let", Token::Type::kLet},
TokenData{"loop", Token::Type::kLoop},
TokenData{"override", Token::Type::kOverride},
TokenData{"return", Token::Type::kReturn},
TokenData{"static_assert", Token::Type::kStaticAssert},
TokenData{"struct", Token::Type::kStruct},
TokenData{"switch", Token::Type::kSwitch},
TokenData{"true", Token::Type::kTrue},
TokenData{"type", Token::Type::kType},
TokenData{"var", Token::Type::kVar},
TokenData{"while", Token::Type::kWhile}));
} // namespace
} // namespace tint::reader::wgsl

View File

@ -422,25 +422,15 @@ Maybe<Void> ParserImpl::enable_directive() {
return add_error(t.source(), "enable directives don't take parenthesis");
}
auto extension = builtin::Extension::kUndefined;
if (t.Is(Token::Type::kF16)) {
// `f16` is a valid extension name and also a keyword
synchronized_ = true;
next();
extension = builtin::Extension::kF16;
} else {
auto ext =
expect_enum("extension", builtin::ParseExtension, builtin::kExtensionStrings);
if (ext.errored) {
return Failure::kErrored;
}
extension = ext.value;
auto ext = expect_enum("extension", builtin::ParseExtension, builtin::kExtensionStrings);
if (ext.errored) {
return Failure::kErrored;
}
if (!expect("enable directive", Token::Type::kSemicolon)) {
return Failure::kErrored;
}
builder_.AST().AddEnable(create<ast::Enable>(t.source(), extension));
builder_.AST().AddEnable(create<ast::Enable>(t.source(), ext.value));
return kSuccess;
});
@ -724,229 +714,6 @@ Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl() {
return VarDeclInfo{decl->source, decl->name, vq.address_space, vq.access, decl->type};
}
// texture_and_sampler_types
// : sampler_type
// | depth_texture_type
// | sampled_texture_type LESS_THAN type_specifier GREATER_THAN
// | multisampled_texture_type LESS_THAN type_specifier GREATER_THAN
// | storage_texture_type LESS_THAN texel_format
// COMMA access_mode GREATER_THAN
Maybe<ast::Type> ParserImpl::texture_and_sampler_types() {
auto type = sampler_type();
if (type.matched) {
return type;
}
type = depth_texture_type();
if (type.matched) {
return type;
}
type = external_texture();
if (type.matched) {
return type.value;
}
auto source_range = make_source_range();
auto dim = sampled_texture_type();
if (dim.matched) {
const char* use = "sampled texture type";
auto subtype = expect_template_arg_block(use, [&] { return expect_type(use); });
if (subtype.errored) {
return Failure::kErrored;
}
return builder_.ty.sampled_texture(source_range, dim.value, subtype.value);
}
auto ms_dim = multisampled_texture_type();
if (ms_dim.matched) {
const char* use = "multisampled texture type";
auto subtype = expect_template_arg_block(use, [&] { return expect_type(use); });
if (subtype.errored) {
return Failure::kErrored;
}
return builder_.ty.multisampled_texture(source_range, ms_dim.value, subtype.value);
}
auto storage = storage_texture_type();
if (storage.matched) {
const char* use = "storage texture type";
using StorageTextureInfo = std::pair<tint::type::TexelFormat, tint::type::Access>;
auto params = expect_template_arg_block(use, [&]() -> Expect<StorageTextureInfo> {
auto format = expect_texel_format(use);
if (format.errored) {
return Failure::kErrored;
}
if (!expect("access control", Token::Type::kComma)) {
return Failure::kErrored;
}
auto access = expect_access_mode(use);
if (access.errored) {
return Failure::kErrored;
}
return std::make_pair(format.value, access.value);
});
if (params.errored) {
return Failure::kErrored;
}
return builder_.ty.storage_texture(source_range, storage.value, params->first,
params->second);
}
return Failure::kNoMatch;
}
// sampler_type
// : SAMPLER
// | SAMPLER_COMPARISON
Maybe<ast::Type> ParserImpl::sampler_type() {
Source source;
if (match(Token::Type::kSampler, &source)) {
return builder_.ty.sampler(source, type::SamplerKind::kSampler);
}
if (match(Token::Type::kComparisonSampler, &source)) {
return builder_.ty.sampler(source, type::SamplerKind::kComparisonSampler);
}
return Failure::kNoMatch;
}
// sampled_texture_type
// : TEXTURE_SAMPLED_1D
// | TEXTURE_SAMPLED_2D
// | TEXTURE_SAMPLED_2D_ARRAY
// | TEXTURE_SAMPLED_3D
// | TEXTURE_SAMPLED_CUBE
// | TEXTURE_SAMPLED_CUBE_ARRAY
Maybe<const type::TextureDimension> ParserImpl::sampled_texture_type() {
if (match(Token::Type::kTextureSampled1d)) {
return type::TextureDimension::k1d;
}
if (match(Token::Type::kTextureSampled2d)) {
return type::TextureDimension::k2d;
}
if (match(Token::Type::kTextureSampled2dArray)) {
return type::TextureDimension::k2dArray;
}
if (match(Token::Type::kTextureSampled3d)) {
return type::TextureDimension::k3d;
}
if (match(Token::Type::kTextureSampledCube)) {
return type::TextureDimension::kCube;
}
if (match(Token::Type::kTextureSampledCubeArray)) {
return type::TextureDimension::kCubeArray;
}
return Failure::kNoMatch;
}
// external_texture
// : TEXTURE_EXTERNAL
Maybe<ast::Type> ParserImpl::external_texture() {
Source source;
if (match(Token::Type::kTextureExternal, &source)) {
return builder_.ty.external_texture(source);
}
return Failure::kNoMatch;
}
// multisampled_texture_type
// : TEXTURE_MULTISAMPLED_2D
Maybe<const type::TextureDimension> ParserImpl::multisampled_texture_type() {
if (match(Token::Type::kTextureMultisampled2d)) {
return type::TextureDimension::k2d;
}
return Failure::kNoMatch;
}
// storage_texture_type
// : TEXTURE_STORAGE_1D
// | TEXTURE_STORAGE_2D
// | TEXTURE_STORAGE_2D_ARRAY
// | TEXTURE_STORAGE_3D
Maybe<const type::TextureDimension> ParserImpl::storage_texture_type() {
if (match(Token::Type::kTextureStorage1d)) {
return type::TextureDimension::k1d;
}
if (match(Token::Type::kTextureStorage2d)) {
return type::TextureDimension::k2d;
}
if (match(Token::Type::kTextureStorage2dArray)) {
return type::TextureDimension::k2dArray;
}
if (match(Token::Type::kTextureStorage3d)) {
return type::TextureDimension::k3d;
}
return Failure::kNoMatch;
}
// depth_texture_type
// : TEXTURE_DEPTH_2D
// | TEXTURE_DEPTH_2D_ARRAY
// | TEXTURE_DEPTH_CUBE
// | TEXTURE_DEPTH_CUBE_ARRAY
// | TEXTURE_DEPTH_MULTISAMPLED_2D
Maybe<ast::Type> ParserImpl::depth_texture_type() {
Source source;
if (match(Token::Type::kTextureDepth2d, &source)) {
return builder_.ty.depth_texture(source, type::TextureDimension::k2d);
}
if (match(Token::Type::kTextureDepth2dArray, &source)) {
return builder_.ty.depth_texture(source, type::TextureDimension::k2dArray);
}
if (match(Token::Type::kTextureDepthCube, &source)) {
return builder_.ty.depth_texture(source, type::TextureDimension::kCube);
}
if (match(Token::Type::kTextureDepthCubeArray, &source)) {
return builder_.ty.depth_texture(source, type::TextureDimension::kCubeArray);
}
if (match(Token::Type::kTextureDepthMultisampled2d, &source)) {
return builder_.ty.depth_multisampled_texture(source, type::TextureDimension::k2d);
}
return Failure::kNoMatch;
}
// texel_format
// : 'rgba8unorm'
// | 'rgba8snorm'
// | 'rgba8uint'
// | 'rgba8sint'
// | 'rgba16uint'
// | 'rgba16sint'
// | 'rgba16float'
// | 'r32uint'
// | 'r32sint'
// | 'r32float'
// | 'rg32uint'
// | 'rg32sint'
// | 'rg32float'
// | 'rgba32uint'
// | 'rgba32sint'
// | 'rgba32float'
Expect<type::TexelFormat> ParserImpl::expect_texel_format(std::string_view use) {
return expect_enum("texel format", type::ParseTexelFormat, type::kTexelFormatStrings, use);
}
Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_ident_with_optional_type_specifier(
std::string_view use,
bool allow_inferred) {
@ -1064,146 +831,27 @@ Maybe<const ast::Alias*> ParserImpl::type_alias_decl() {
return builder_.ty.alias(make_source_range_from(source), name.value, type.value);
}
// vec_prefix
// : 'vec2'
// | 'vec3'
// | 'vec4'
Maybe<uint32_t> ParserImpl::vec_prefix() {
auto& t = peek();
if (!t.IsVector()) {
// type_specifier
// : IDENTIFIER template_arguments?
Maybe<ast::Type> ParserImpl::type_specifier() {
MultiTokenSource source(this);
auto& ident = peek();
if (!match(Token::Type::kIdentifier)) {
return Failure::kNoMatch;
}
next();
if (t.Is(Token::Type::kVec3)) {
return 3u;
}
if (t.Is(Token::Type::kVec4)) {
return 4u;
}
return 2u;
}
// mat_prefix
// : 'mat2x2'
// | 'mat2x3'
// | 'mat2x4'
// | 'mat3x2'
// | 'mat3x3'
// | 'mat3x4'
// | 'mat4x2'
// | 'mat4x3'
// | 'mat4x4'
Maybe<ParserImpl::MatrixDimensions> ParserImpl::mat_prefix() {
auto& t = peek();
if (!t.IsMatrix()) {
return Failure::kNoMatch;
}
next();
uint32_t columns = 2;
if (t.IsMat3xN()) {
columns = 3;
} else if (t.IsMat4xN()) {
columns = 4;
}
if (t.IsMatNx3()) {
return MatrixDimensions{columns, 3};
}
if (t.IsMatNx4()) {
return MatrixDimensions{columns, 4};
}
return MatrixDimensions{columns, 2};
}
// type_specifier_without_ident:
// : BOOL
// | F16
// | F32
// | I32
// | U32
// | ARRAY LESS_THAN type_specifier ( COMMA element_count_expression )? GREATER_THAN
// | ATOMIC LESS_THAN type_specifier GREATER_THAN
// | PTR LESS_THAN address_space COMMA type_specifier ( COMMA access_mode )? GREATER_THAN
// | mat_prefix LESS_THAN type_specifier GREATER_THAN
// | vec_prefix LESS_THAN type_specifier GREATER_THAN
// | texture_and_sampler_types
Maybe<ast::Type> ParserImpl::type_specifier_without_ident() {
auto& t = peek();
if (match(Token::Type::kBool)) {
return builder_.ty.bool_(t.source());
if (!peek_is(Token::Type::kTemplateArgsLeft)) {
return builder_.ty(builder_.Ident(source.Source(), ident.to_str()));
}
if (match(Token::Type::kF16)) {
return builder_.ty.f16(t.source());
}
if (match(Token::Type::kF32)) {
return builder_.ty.f32(t.source());
}
if (match(Token::Type::kI32)) {
return builder_.ty.i32(t.source());
}
if (match(Token::Type::kU32)) {
return builder_.ty.u32(t.source());
}
if (t.Is(Token::Type::kArray) &&
(peek_is(Token::Type::kTemplateArgsLeft, 1) || peek_is(Token::Type::kLessThan, 1))) {
if (match(Token::Type::kArray)) {
return expect_type_specifier_array(t.source());
}
}
if (match(Token::Type::kAtomic)) {
return expect_type_specifier_atomic(t.source());
}
if (match(Token::Type::kPtr)) {
return expect_type_specifier_pointer(t.source());
}
if (t.IsMatrix() &&
(peek_is(Token::Type::kTemplateArgsLeft, 1) || peek_is(Token::Type::kLessThan, 1))) {
auto mat = mat_prefix();
if (mat.matched) {
return expect_type_specifier_matrix(t.source(), mat.value);
}
}
if (t.IsVector() &&
(peek_is(Token::Type::kTemplateArgsLeft, 1) || peek_is(Token::Type::kLessThan, 1))) {
auto vec = vec_prefix();
if (vec.matched) {
return expect_type_specifier_vector(t.source(), vec.value);
}
}
auto texture_or_sampler = texture_and_sampler_types();
if (texture_or_sampler.errored) {
auto args = expect_template_arg_block("type template arguments", [&]() {
return expect_expression_list("type template argument list",
Token::Type::kTemplateArgsRight);
});
if (args.errored) {
return Failure::kErrored;
}
if (texture_or_sampler.matched) {
return texture_or_sampler;
}
return Failure::kNoMatch;
}
// type_specifier
// : IDENTIFIER
// | type_specifier_without_ident
Maybe<ast::Type> ParserImpl::type_specifier() {
auto& t = peek();
Source source;
if (match(Token::Type::kIdentifier, &source)) {
return builder_.ty(source, t.to_str());
}
return type_specifier_without_ident();
return builder_.ty(builder_.Ident(source.Source(), ident.to_str(), std::move(args.value)));
}
template <typename ENUM, size_t N>
@ -1252,123 +900,6 @@ Expect<ast::Type> ParserImpl::expect_type(std::string_view use) {
return type.value;
}
// LESS_THAN address_space COMMA type_specifier ( COMMA access_mode )? GREATER_THAN
Expect<ast::Type> ParserImpl::expect_type_specifier_pointer(const Source& s) {
const char* use = "ptr declaration";
auto address_space = type::AddressSpace::kNone;
auto access = type::Access::kUndefined;
auto subtype = expect_template_arg_block(use, [&]() -> Expect<ast::Type> {
auto sc = expect_address_space(use);
if (sc.errored) {
return Failure::kErrored;
}
address_space = sc.value;
if (!expect(use, Token::Type::kComma)) {
return Failure::kErrored;
}
auto type = expect_type(use);
if (type.errored) {
return Failure::kErrored;
}
if (match(Token::Type::kComma)) {
auto ac = expect_access_mode(use);
if (ac.errored) {
return Failure::kErrored;
}
access = ac.value;
}
return type.value;
});
if (subtype.errored) {
return Failure::kErrored;
}
return builder_.ty.pointer(make_source_range_from(s), subtype.value, address_space, access);
}
// LESS_THAN type_specifier GREATER_THAN
Expect<ast::Type> ParserImpl::expect_type_specifier_atomic(const Source& s) {
const char* use = "atomic declaration";
auto subtype = expect_template_arg_block(use, [&] { return expect_type(use); });
if (subtype.errored) {
return Failure::kErrored;
}
return builder_.ty.atomic(make_source_range_from(s), subtype.value);
}
// LESS_THAN type_specifier GREATER_THAN
Expect<ast::Type> ParserImpl::expect_type_specifier_vector(const Source& s, uint32_t count) {
const char* use = "vector";
auto ty = expect_template_arg_block(use, [&] { return expect_type(use); });
if (ty.errored) {
return Failure::kErrored;
}
return builder_.ty.vec(make_source_range_from(s), ty.value, count);
}
// LESS_THAN type_specifier ( COMMA element_count_expression )? GREATER_THAN
Expect<ast::Type> ParserImpl::expect_type_specifier_array(const Source& s) {
const char* use = "array declaration";
struct TypeAndSize {
ast::Type type;
const ast::Expression* size = nullptr;
};
auto type_size = expect_template_arg_block(use, [&]() -> Expect<TypeAndSize> {
auto type = expect_type(use);
if (type.errored) {
return Failure::kErrored;
}
if (!match(Token::Type::kComma)) {
return TypeAndSize{type.value, nullptr};
}
auto size = element_count_expression();
if (size.errored) {
return Failure::kErrored;
}
if (!size.matched) {
return add_error(peek(), "expected array size expression");
}
return TypeAndSize{type.value, size.value};
});
if (type_size.errored) {
return Failure::kErrored;
}
if (type_size->size) {
return builder_.ty.array(make_source_range_from(s), type_size->type, type_size->size);
} else {
return builder_.ty.array(make_source_range_from(s), type_size->type);
}
}
// LESS_THAN type_specifier GREATER_THAN
Expect<ast::Type> ParserImpl::expect_type_specifier_matrix(const Source& s,
const MatrixDimensions& dims) {
const char* use = "matrix";
auto ty = expect_template_arg_block(use, [&] { return expect_type(use); });
if (ty.errored) {
return Failure::kErrored;
}
return builder_.ty.mat(make_source_range_from(s), ty.value, dims.columns, dims.rows);
}
// address_space
// : 'function'
// | 'private'
@ -2520,59 +2051,14 @@ Maybe<const ast::BlockStatement*> ParserImpl::continuing_statement() {
return continuing_compound_statement();
}
// callable
// : type_specifier_without_ident
// | ARRAY
// | mat_prefix
// | vec_prefix
//
// Note, `ident` is pulled out to `primary_expression` as it's the only one that
// doesn't create a `type`. Then we can just return a `type` from here on match and
// deal with `ident` in `primary_expression.
Maybe<const ast::IdentifierExpression*> ParserImpl::callable() {
auto& t = peek();
// This _must_ match `type_specifier_without_ident` before any of the other types as they're
// all prefixes of the types and we want to match the longer `vec3<f32>` then the shorter
// prefix match of `vec3`.
auto ty = type_specifier_without_ident();
if (ty.errored) {
return Failure::kErrored;
}
if (ty.matched) {
return ty->expr;
}
if (match(Token::Type::kArray)) {
return builder_.ty.array<Infer>(make_source_range_from(t.source()));
}
auto vec = vec_prefix();
if (vec.matched) {
return builder_.ty.vec<Infer>(make_source_range_from(t.source()), vec.value);
}
auto mat = mat_prefix();
if (mat.matched) {
return builder_.ty.mat<Infer>(make_source_range_from(t.source()), mat.value.columns,
mat.value.rows);
}
return Failure::kNoMatch;
}
// primary_expression
// : BITCAST LESS_THAN type_specifier GREATER_THAN paren_expression
// | callable argument_expression_list
// | const_literal
// | IDENT argument_expression_list?
// | paren_expression
//
// Note, PAREN_LEFT ( expression ( COMMA expression ) * COMMA? )? PAREN_RIGHT is replaced
// with `argument_expression_list`.
//
// Note, this is matching the `callable` ident here instead of having to come from
// callable so we can return a `type` from callable.
Maybe<const ast::Expression*> ParserImpl::primary_expression() {
auto& t = peek();
@ -2592,19 +2078,6 @@ Maybe<const ast::Expression*> ParserImpl::primary_expression() {
return builder_.Bitcast(t.source(), type.value, params.value);
}
auto call = callable();
if (call.errored) {
return Failure::kErrored;
}
if (call.matched) {
auto params = expect_argument_expression_list("type initializer");
if (params.errored) {
return Failure::kErrored;
}
return builder_.Call(t.source(), call.value, std::move(params.value));
}
auto lit = const_literal();
if (lit.errored) {
return Failure::kErrored;
@ -2614,14 +2087,19 @@ Maybe<const ast::Expression*> ParserImpl::primary_expression() {
}
if (t.IsIdentifier()) {
MultiTokenSource source(this);
next();
if (Source source; match(Token::Type::kTemplateArgsLeft, &source)) {
return add_error(
source,
"'<' treated as the start of a template argument list, which is not supported for "
"user-declared types or functions. If you intended less-than, wrap the expression "
"in parentheses");
const ast::Identifier* ident = nullptr;
if (peek_is(Token::Type::kTemplateArgsLeft)) {
auto tmpl_args = expect_template_arg_block("template arguments", [&]() {
return expect_expression_list("template argument list",
Token::Type::kTemplateArgsRight);
});
ident = builder_.Ident(source.Source(), t.to_str(), std::move(tmpl_args.value));
} else {
ident = builder_.Ident(source.Source(), t.to_str());
}
if (peek_is(Token::Type::kParenLeft)) {
@ -2630,10 +2108,10 @@ Maybe<const ast::Expression*> ParserImpl::primary_expression() {
return Failure::kErrored;
}
return builder_.Call(t.source(), t.to_str(), std::move(params.value));
return builder_.Call(source.Source(), ident, std::move(params.value));
}
return builder_.Expr(t.source(), t.to_str());
return builder_.Expr(ident);
}
if (t.Is(Token::Type::kParenLeft)) {
@ -3042,6 +2520,41 @@ Expect<const ast::Expression*> ParserImpl::expect_relational_expression_post_una
return create<ast::BinaryExpression>(tok_op.source(), op, lhs, rhs.value);
}
Expect<const ast::Expression*> ParserImpl::expect_expression() {
auto& t = peek();
auto expr = expression();
if (expr.errored) {
return Failure::kErrored;
}
if (expr.matched) {
return expr.value;
}
return add_error(t, "expected expression");
}
Expect<utils::Vector<const ast::Expression*, 3>> ParserImpl::expect_expression_list(
std::string_view use,
Token::Type terminator) {
utils::Vector<const ast::Expression*, 3> exprs;
while (continue_parsing()) {
auto expr = expect_expression();
if (expr.errored) {
return Failure::kErrored;
}
exprs.Push(expr.value);
if (peek_is(terminator)) {
break;
}
if (!expect(use, Token::Type::kComma)) {
return Failure::kErrored;
}
if (peek_is(terminator)) {
break;
}
}
return exprs;
}
// expression
// : unary_expression bitwise_expression.post.unary_expression
// | unary_expression relational_expression.post.unary_expression

View File

@ -25,9 +25,6 @@
#include "src/tint/program_builder.h"
#include "src/tint/reader/wgsl/parser_impl_detail.h"
#include "src/tint/reader/wgsl/token.h"
#include "src/tint/type/access.h"
#include "src/tint/type/storage_texture.h"
#include "src/tint/type/texture_dimension.h"
namespace tint::ast {
class BreakStatement;
@ -447,18 +444,6 @@ class ParserImpl {
/// Parses a `type_alias_decl` grammar element
/// @returns the type alias or nullptr on error
Maybe<const ast::Alias*> type_alias_decl();
/// Parses a `callable` grammar element
/// @returns the type or nullptr
Maybe<const ast::IdentifierExpression*> callable();
/// Parses a `vec_prefix` grammar element
/// @returns the vector size or nullptr
Maybe<uint32_t> vec_prefix();
/// Parses a `mat_prefix` grammar element
/// @returns the matrix dimensions or nullptr
Maybe<MatrixDimensions> mat_prefix();
/// Parses a `type_specifier_without_ident` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<ast::Type> type_specifier_without_ident();
/// Parses a `type_specifier` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<ast::Type> type_specifier();
@ -481,33 +466,6 @@ class ParserImpl {
/// by the declaration, then this vector is cleared before returning.
/// @returns the parsed function, nullptr otherwise
Maybe<const ast::Function*> function_decl(AttributeList& attrs);
/// Parses a `texture_and_sampler_types` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<ast::Type> texture_and_sampler_types();
/// Parses a `sampler_type` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<ast::Type> sampler_type();
/// Parses a `multisampled_texture_type` grammar element
/// @returns returns the multisample texture dimension or kNone if none
/// matched.
Maybe<const type::TextureDimension> multisampled_texture_type();
/// Parses a `sampled_texture_type` grammar element
/// @returns returns the sample texture dimension or kNone if none matched.
Maybe<const type::TextureDimension> sampled_texture_type();
/// Parses a `storage_texture_type` grammar element
/// @returns returns the storage texture dimension.
/// Returns kNone if none matched.
Maybe<const type::TextureDimension> storage_texture_type();
/// Parses a `depth_texture_type` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<ast::Type> depth_texture_type();
/// Parses a 'texture_external_type' grammar element
/// @returns the parsed Type or nullptr if none matched
Maybe<ast::Type> external_texture();
/// Parses a `texel_format` grammar element
/// @param use a description of what was being parsed if an error was raised
/// @returns returns the texel format or kNone if none matched.
Expect<type::TexelFormat> expect_texel_format(std::string_view use);
/// Parses a `const_assert_statement` grammar element
/// @returns returns the const assert, if it matched.
Maybe<const ast::ConstAssert*> const_assert_statement();
@ -638,6 +596,15 @@ class ParserImpl {
/// Parses the `expression` grammar rule
/// @returns the parsed expression or nullptr
Maybe<const ast::Expression*> expression();
/// Parses the `expression` grammar rule
/// @returns the parsed expression or error
Expect<const ast::Expression*> expect_expression();
/// Parses a comma separated expression list
/// @param use the use of the expression list
/// @param terminator the terminating token for the list
/// @returns the parsed expression list or error
Expect<utils::Vector<const ast::Expression*, 3>> expect_expression_list(std::string_view use,
Token::Type terminator);
/// Parses the `bitwise_expression.post.unary_expression` grammar element
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
@ -891,12 +858,6 @@ class ParserImpl {
/// Used to ensure that all attributes are consumed.
bool expect_attributes_consumed(utils::VectorRef<const ast::Attribute*> list);
Expect<ast::Type> expect_type_specifier_pointer(const Source& s);
Expect<ast::Type> expect_type_specifier_atomic(const Source& s);
Expect<ast::Type> expect_type_specifier_vector(const Source& s, uint32_t count);
Expect<ast::Type> expect_type_specifier_array(const Source& s);
Expect<ast::Type> expect_type_specifier_matrix(const Source& s, const MatrixDimensions& dims);
/// Parses the given enum, providing sensible error messages if the next token does not match
/// any of the enum values.
/// @param name the name of the enumerator

View File

@ -1,117 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
namespace {
using namespace tint::number_suffixes; // NOLINT
TEST_F(ParserImplTest, Callable_Array) {
auto p = parser("array");
auto t = p->callable();
ASSERT_TRUE(p->peek_is(Token::Type::kEOF));
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "array");
}
TEST_F(ParserImplTest, Callable_VecPrefix) {
auto p = parser("vec3");
auto t = p->callable();
ASSERT_TRUE(p->peek_is(Token::Type::kEOF));
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "vec3");
}
TEST_F(ParserImplTest, Callable_MatPrefix) {
auto p = parser("mat3x2");
auto t = p->callable();
ASSERT_TRUE(p->peek_is(Token::Type::kEOF));
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "mat3x2");
}
TEST_F(ParserImplTest, Callable_TypeDecl_Array) {
auto p = parser("array<f32, 2>");
auto t = p->callable();
ASSERT_TRUE(p->peek_is(Token::Type::kEOF));
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("array", "f32", 2_a));
}
TEST_F(ParserImplTest, Callable_TypeDecl_Array_Runtime) {
auto p = parser("array<f32>");
auto t = p->callable();
ASSERT_TRUE(p->peek_is(Token::Type::kEOF));
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("array", "f32"));
}
TEST_F(ParserImplTest, Callable_TypeDecl_VecPrefix) {
auto p = parser("vec3<f32>");
auto t = p->callable();
ASSERT_TRUE(p->peek_is(Token::Type::kEOF));
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("vec3", "f32"));
}
TEST_F(ParserImplTest, Callable_TypeDecl_MatPrefix) {
auto p = parser("mat3x2<f32>");
auto t = p->callable();
ASSERT_TRUE(p->peek_is(Token::Type::kEOF));
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("mat3x2", "f32"));
}
TEST_F(ParserImplTest, Callable_NoMatch) {
auto p = parser("ident");
auto t = p->callable();
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(nullptr, t.value);
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -1,87 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/type/depth_texture.h"
#include "src/tint/type/texture_dimension.h"
namespace tint::reader::wgsl {
namespace {
TEST_F(ParserImplTest, DepthTextureType_Invalid) {
auto p = parser("1234");
auto t = p->depth_texture_type();
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, DepthTextureType_2d) {
auto p = parser("texture_depth_2d");
auto t = p->depth_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_2d");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
TEST_F(ParserImplTest, DepthTextureType_2dArray) {
auto p = parser("texture_depth_2d_array");
auto t = p->depth_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_2d_array");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 23u}}));
}
TEST_F(ParserImplTest, DepthTextureType_Cube) {
auto p = parser("texture_depth_cube");
auto t = p->depth_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_cube");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
}
TEST_F(ParserImplTest, DepthTextureType_CubeArray) {
auto p = parser("texture_depth_cube_array");
auto t = p->depth_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_cube_array");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}}));
}
TEST_F(ParserImplTest, DepthTextureType_Multisampled2d) {
auto p = parser("texture_depth_multisampled_2d");
auto t = p->depth_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_multisampled_2d");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 30u}}));
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -146,6 +146,7 @@ Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
Did you mean 'f16'?
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();

View File

@ -193,7 +193,7 @@ fn f() { f() }
TEST_F(ParserImplErrorTest, InitializerExprMissingLParen) {
EXPECT("fn f() { x = vec2<u32>1,2); }",
R"(test.wgsl:1:23 error: expected '(' for type initializer
R"(test.wgsl:1:23 error: expected ';' for assignment statement
fn f() { x = vec2<u32>1,2); }
^
)");
@ -201,7 +201,7 @@ fn f() { x = vec2<u32>1,2); }
TEST_F(ParserImplErrorTest, InitializerExprMissingRParen) {
EXPECT("fn f() { x = vec2<u32>(1,2; }",
R"(test.wgsl:1:27 error: expected ')' for type initializer
R"(test.wgsl:1:27 error: expected ')' for function call
fn f() { x = vec2<u32>(1,2; }
^
)");
@ -575,17 +575,9 @@ const i : i32 = 1
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstMissingLParen) {
EXPECT("const i : vec2<i32> = vec2<i32>;",
R"(test.wgsl:1:32 error: expected '(' for type initializer
const i : vec2<i32> = vec2<i32>;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstMissingRParen) {
EXPECT("const i : vec2<i32> = vec2<i32>(1., 2.;",
R"(test.wgsl:1:39 error: expected ')' for type initializer
R"(test.wgsl:1:39 error: expected ')' for function call
const i : vec2<i32> = vec2<i32>(1., 2.;
^
)");
@ -628,7 +620,7 @@ TEST_F(ParserImplErrorTest, GlobalDeclConstExprMaxDepth) {
TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingLParen) {
EXPECT("const i : vec2<i32> = vec2<i32> 1, 2);",
R"(test.wgsl:1:33 error: expected '(' for type initializer
R"(test.wgsl:1:33 error: expected ';' for 'const' declaration
const i : vec2<i32> = vec2<i32> 1, 2);
^
)");
@ -636,7 +628,7 @@ const i : vec2<i32> = vec2<i32> 1, 2);
TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingRParen) {
EXPECT("const i : vec2<i32> = vec2<i32>(1, 2;",
R"(test.wgsl:1:37 error: expected ')' for type initializer
R"(test.wgsl:1:37 error: expected ')' for function call
const i : vec2<i32> = vec2<i32>(1, 2;
^
)");
@ -658,54 +650,22 @@ TEST_F(ParserImplErrorTest, GlobalDeclInvalidAttribute) {
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclSampledTextureMissingLessThan) {
EXPECT("var x : texture_1d;",
R"(test.wgsl:1:19 error: expected '<' for sampled texture type
var x : texture_1d;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclSampledTextureMissingGreaterThan) {
EXPECT("var x : texture_1d<f32;",
R"(test.wgsl:1:19 error: missing closing '>' for sampled texture type
R"(test.wgsl:1:19 error: expected ';' for variable declaration
var x : texture_1d<f32;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclSampledTextureInvalidSubtype) {
EXPECT("var x : texture_1d<1>;",
R"(test.wgsl:1:20 error: invalid type for sampled texture type
var x : texture_1d<1>;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclMultisampledTextureMissingLessThan) {
EXPECT("var x : texture_multisampled_2d;",
R"(test.wgsl:1:32 error: expected '<' for multisampled texture type
var x : texture_multisampled_2d;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclMultisampledTextureMissingGreaterThan) {
EXPECT("var x : texture_multisampled_2d<f32;",
R"(test.wgsl:1:32 error: missing closing '>' for multisampled texture type
R"(test.wgsl:1:32 error: expected ';' for variable declaration
var x : texture_multisampled_2d<f32;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclMultisampledTextureInvalidSubtype) {
EXPECT("var x : texture_multisampled_2d<1>;",
R"(test.wgsl:1:33 error: invalid type for multisampled texture type
var x : texture_multisampled_2d<1>;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstAssertMissingCondThenEOF) {
EXPECT("const_assert", R"(test.wgsl:1:13 error: unable to parse condition expression
const_assert
@ -829,17 +789,9 @@ static_assert true static_assert true;
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingLessThan) {
EXPECT("var x : texture_storage_2d;",
R"(test.wgsl:1:27 error: expected '<' for storage texture type
var x : texture_storage_2d;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingGreaterThan) {
EXPECT("var x : texture_storage_2d<r32uint, read;",
R"(test.wgsl:1:27 error: missing closing '>' for storage texture type
R"(test.wgsl:1:27 error: expected ';' for variable declaration
var x : texture_storage_2d<r32uint, read;
^
)");
@ -847,22 +799,12 @@ var x : texture_storage_2d<r32uint, read;
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingSubtype) {
EXPECT("var x : texture_storage_2d<>;",
R"(test.wgsl:1:28 error: expected texel format for storage texture type
Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm'
R"(test.wgsl:1:28 error: expected expression
var x : texture_storage_2d<>;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingInvalidSubtype) {
EXPECT("var x : texture_storage_2d<1>;",
R"(test.wgsl:1:28 error: expected texel format for storage texture type
Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm'
var x : texture_storage_2d<1>;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclStructDeclMissingIdentifier) {
EXPECT("struct {};",
R"(test.wgsl:1:8 error: expected identifier for struct declaration
@ -993,28 +935,12 @@ type meow = f32
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayMissingGreaterThan) {
EXPECT("var i : array<u32, 3;",
R"(test.wgsl:1:14 error: missing closing '>' for array declaration
R"(test.wgsl:1:14 error: expected ';' for variable declaration
var i : array<u32, 3;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayMissingType) {
EXPECT("var i : array<1, 3>;",
R"(test.wgsl:1:15 error: invalid type for array declaration
var i : array<1, 3>;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayMissingSize) {
EXPECT("var i : array<u32, >;",
R"(test.wgsl:1:20 error: expected array size expression
var i : array<u32, >;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayInvalidSize) {
EXPECT("var i : array<u32, !>;",
R"(test.wgsl:1:21 error: unable to parse right side of ! expression
@ -1175,19 +1101,12 @@ var ^ : mat4x4;
}
TEST_F(ParserImplErrorTest, GlobalDeclVarMatrixMissingGreaterThan) {
EXPECT("var i : mat4x4<u32;", R"(test.wgsl:1:15 error: missing closing '>' for matrix
EXPECT("var i : mat4x4<u32;", R"(test.wgsl:1:15 error: expected ';' for variable declaration
var i : mat4x4<u32;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarMatrixMissingType) {
EXPECT("var i : mat4x4<1>;", R"(test.wgsl:1:16 error: invalid type for matrix
var i : mat4x4<1>;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarMissingSemicolon) {
EXPECT("var i : i32",
R"(test.wgsl:1:12 error: expected ';' for variable declaration
@ -1196,63 +1115,14 @@ var i : i32
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingLessThan) {
EXPECT("var i : ptr;",
R"(test.wgsl:1:12 error: expected '<' for ptr declaration
var i : ptr;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingGreaterThan) {
EXPECT("var i : ptr<private, u32;",
R"(test.wgsl:1:12 error: missing closing '>' for ptr declaration
R"(test.wgsl:1:12 error: expected ';' for variable declaration
var i : ptr<private, u32;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingComma) {
EXPECT("var i : ptr<private u32>;",
R"(test.wgsl:1:21 error: expected ',' for ptr declaration
var i : ptr<private u32>;
^^^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingAddressSpace) {
EXPECT("var i : ptr<meow, u32>;",
R"(test.wgsl:1:13 error: expected address space for ptr declaration
Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup'
var i : ptr<meow, u32>;
^^^^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingType) {
EXPECT("var i : ptr<private, 1>;",
R"(test.wgsl:1:22 error: invalid type for ptr declaration
var i : ptr<private, 1>;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarAtomicMissingLessThan) {
EXPECT("var i : atomic;",
R"(test.wgsl:1:15 error: expected '<' for atomic declaration
var i : atomic;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarAtomicMissingGreaterThan) {
EXPECT("var i : atomic<u32 x;",
R"(test.wgsl:1:15 error: missing closing '>' for atomic declaration
var i : atomic<u32 x;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclInvalidClass) {
EXPECT("var<fish> i : i32",
R"(test.wgsl:1:5 error: expected address space for variable declaration
@ -1271,19 +1141,12 @@ var<private i : i32
}
TEST_F(ParserImplErrorTest, GlobalDeclVarVectorMissingGreaterThan) {
EXPECT("var i : vec3<u32;", R"(test.wgsl:1:13 error: missing closing '>' for vector
EXPECT("var i : vec3<u32;", R"(test.wgsl:1:13 error: expected ';' for variable declaration
var i : vec3<u32;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclVarVectorMissingType) {
EXPECT("var i : vec3<1>;", R"(test.wgsl:1:14 error: invalid type for vector
var i : vec3<1>;
^
)");
}
TEST_F(ParserImplErrorTest, IfStmtMissingRParen) {
EXPECT("fn f() { if (true {} }", R"(test.wgsl:1:19 error: expected ')'
fn f() { if (true {} }

View File

@ -474,9 +474,10 @@ static std::vector<Case> Cases() {
std::vector<Case> out;
for (auto& lhs_op : kBinaryOperators) {
for (auto& rhs_op : kBinaryOperators) {
bool should_parse = (lhs_op.can_follow_without_paren & rhs_op.bit) &&
!ParsedAsTemplateArgumentList(lhs_op, rhs_op);
out.push_back({lhs_op, rhs_op, should_parse});
if (!ParsedAsTemplateArgumentList(lhs_op, rhs_op)) {
bool should_parse = lhs_op.can_follow_without_paren & rhs_op.bit;
out.push_back({lhs_op, rhs_op, should_parse});
}
}
}
return out;
@ -498,14 +499,8 @@ TEST_P(ParserImplMixedBinaryOpTest, Test) {
EXPECT_EQ(e.value, nullptr);
EXPECT_TRUE(p->has_error());
std::stringstream expected;
if (ParsedAsTemplateArgumentList(GetParam().lhs_op, GetParam().rhs_op)) {
expected << "1:3: '<' treated as the start of a template argument list, which is not "
"supported for user-declared types or functions. If you intended "
"less-than, wrap the expression in parentheses";
} else {
expected << "1:3: mixing '" << GetParam().lhs_op.symbol << "' and '"
<< GetParam().rhs_op.symbol << "' requires parenthesis";
}
expected << "1:3: mixing '" << GetParam().lhs_op.symbol << "' and '"
<< GetParam().rhs_op.symbol << "' requires parenthesis";
EXPECT_EQ(p->error(), expected.str());
}
}

View File

@ -1,37 +0,0 @@
// 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
namespace {
TEST_F(ParserImplTest, ExternalTextureType_Invalid) {
auto p = parser("1234");
auto t = p->external_texture();
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, ExternalTextureType) {
auto p = parser("texture_external");
auto t = p->external_texture();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -77,26 +77,6 @@ TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_ZeroInitializer) {
ASSERT_EQ(call->args.Length(), 0u);
}
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_InvalidTypeDecl) {
auto p = parser("vec4<if>(2., 3., 4., 5.)");
auto e = p->primary_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:6: invalid type for vector");
}
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_MissingLeftParen) {
auto p = parser("vec4<f32> 2., 3., 4., 5.)");
auto e = p->primary_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:11: expected '(' for type initializer");
}
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_MissingRightParen) {
auto p = parser("vec4<f32>(2., 3., 4., 5.");
auto e = p->primary_expression();
@ -104,7 +84,7 @@ TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_MissingRightParen) {
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:25: expected ')' for type initializer");
EXPECT_EQ(p->error(), "1:25: expected ')' for function call");
}
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_InvalidValue) {
@ -114,7 +94,7 @@ TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_InvalidValue) {
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:5: expected ')' for type initializer");
EXPECT_EQ(p->error(), "1:5: expected ')' for function call");
}
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_StructInitializer_Empty) {
@ -318,18 +298,5 @@ TEST_F(ParserImplTest, PrimaryExpression_bitcast_InvalidExpression) {
EXPECT_EQ(p->error(), "1:14: unable to parse expression");
}
TEST_F(ParserImplTest, PrimaryExpression_Template) {
auto p = parser("a<b>()");
auto e = p->primary_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(),
"1:2: '<' treated as the start of a template argument list, which is not supported "
"for user-declared types or functions. If you intended less-than, wrap the "
"expression in parentheses");
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -1,84 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/type/texture_dimension.h"
namespace tint::reader::wgsl {
namespace {
TEST_F(ParserImplTest, SampledTextureType_Invalid) {
auto p = parser("1234");
auto t = p->sampled_texture_type();
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, SampledTextureType_1d) {
auto p = parser("texture_1d");
auto t = p->sampled_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::k1d);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, SampledTextureType_2d) {
auto p = parser("texture_2d");
auto t = p->sampled_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::k2d);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, SampledTextureType_2dArray) {
auto p = parser("texture_2d_array");
auto t = p->sampled_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::k2dArray);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, SampledTextureType_3d) {
auto p = parser("texture_3d");
auto t = p->sampled_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::k3d);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, SampledTextureType_Cube) {
auto p = parser("texture_cube");
auto t = p->sampled_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::kCube);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, SampledTextureType_kCubeArray) {
auto p = parser("texture_cube_array");
auto t = p->sampled_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::kCubeArray);
EXPECT_FALSE(p->has_error());
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -1,53 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
namespace {
TEST_F(ParserImplTest, SamplerType_Invalid) {
auto p = parser("1234");
auto t = p->sampler_type();
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, SamplerType_Sampler) {
auto p = parser("sampler");
auto t = p->sampler_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "sampler");
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 8u}}));
}
TEST_F(ParserImplTest, SamplerType_ComparisonSampler) {
auto p = parser("sampler_comparison");
auto t = p->sampler_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "sampler_comparison");
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -1,66 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/type/texture_dimension.h"
namespace tint::reader::wgsl {
namespace {
TEST_F(ParserImplTest, StorageTextureType_Invalid) {
auto p = parser("abc");
auto t = p->storage_texture_type();
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, StorageTextureType_1d) {
auto p = parser("texture_storage_1d");
auto t = p->storage_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::k1d);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, StorageTextureType_2d) {
auto p = parser("texture_storage_2d");
auto t = p->storage_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::k2d);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, StorageTextureType_2dArray) {
auto p = parser("texture_storage_2d_array");
auto t = p->storage_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::k2dArray);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, StorageTextureType_3d) {
auto p = parser("texture_storage_3d");
auto t = p->storage_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TextureDimension::k3d);
EXPECT_FALSE(p->has_error());
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -153,7 +153,8 @@ TEST_F(ParserImplTest, Peek_PastPlaceholder) {
auto p = parser(">= vec2<u32>");
auto& n = p->next();
ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
EXPECT_TRUE(p->peek_is(Token::Type::kVec2)) << "expected: vec2 got: " << p->peek().to_name();
EXPECT_TRUE(p->peek_is(Token::Type::kIdentifier))
<< "expected: vec2 got: " << p->peek().to_name();
EXPECT_TRUE(p->peek_is(Token::Type::kTemplateArgsLeft, 1))
<< "expected: < got: " << p->peek(1).to_name();
}
@ -164,7 +165,7 @@ TEST_F(ParserImplTest, Peek_MultiplePlaceholder) {
ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
EXPECT_TRUE(p->peek_is(Token::Type::kGreaterThanEqual))
<< "expected: >= got: " << p->peek().to_name();
EXPECT_TRUE(p->peek_is(Token::Type::kVec2, 1))
EXPECT_TRUE(p->peek_is(Token::Type::kIdentifier, 1))
<< "expected: vec2 got: " << p->peek(1).to_name();
EXPECT_TRUE(p->peek_is(Token::Type::kTemplateArgsLeft, 2))
<< "expected: < got: " << p->peek(2).to_name();
@ -190,7 +191,8 @@ TEST_F(ParserImplTest, Peek_AfterSplit) {
auto p = parser(">= vec2<u32>");
auto& n = p->next();
ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
EXPECT_TRUE(p->peek_is(Token::Type::kVec2)) << "expected: vec2 got: " << p->peek().to_name();
EXPECT_TRUE(p->peek_is(Token::Type::kIdentifier))
<< "expected: vec2 got: " << p->peek().to_name();
p->split_token(Token::Type::kGreaterThan, Token::Type::kEqual);
ASSERT_TRUE(n.Is(Token::Type::kGreaterThan));

View File

@ -1,158 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
namespace {
TEST_F(ParserImplTest, TexelFormat_Invalid) {
auto p = parser("1234");
auto t = p->expect_texel_format("test");
EXPECT_TRUE(t.errored);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:1: expected texel format for test
Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
}
TEST_F(ParserImplTest, TexelFormat_R32Uint) {
auto p = parser("r32uint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kR32Uint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_R32Sint) {
auto p = parser("r32sint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kR32Sint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_R32Float) {
auto p = parser("r32float");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kR32Float);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba8Unorm) {
auto p = parser("rgba8unorm");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba8Unorm);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba8Snorm) {
auto p = parser("rgba8snorm");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba8Snorm);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba8Uint) {
auto p = parser("rgba8uint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba8Uint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba8Sint) {
auto p = parser("rgba8sint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba8Sint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rg32Uint) {
auto p = parser("rg32uint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRg32Uint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rg32Sint) {
auto p = parser("rg32sint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRg32Sint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rg32Float) {
auto p = parser("rg32float");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRg32Float);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba16Uint) {
auto p = parser("rgba16uint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba16Uint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba16Sint) {
auto p = parser("rgba16sint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba16Sint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba16Float) {
auto p = parser("rgba16float");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba16Float);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba32Uint) {
auto p = parser("rgba32uint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba32Uint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba32Sint) {
auto p = parser("rgba32sint");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba32Sint);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TexelFormat_Rgba32Float) {
auto p = parser("rgba32float");
auto t = p->expect_texel_format("test");
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value, type::TexelFormat::kRgba32Float);
EXPECT_FALSE(p->has_error());
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -1,185 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/type/depth_texture.h"
#include "src/tint/type/multisampled_texture.h"
#include "src/tint/type/sampled_texture.h"
#include "src/tint/type/texture_dimension.h"
namespace tint::reader::wgsl {
namespace {
TEST_F(ParserImplTest, TextureSamplerTypes_Invalid) {
auto p = parser("1234");
auto t = p->texture_and_sampler_types();
EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_FALSE(p->has_error());
}
TEST_F(ParserImplTest, TextureSamplerTypes_Sampler) {
auto p = parser("sampler");
auto t = p->texture_and_sampler_types();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "sampler");
EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 8u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_SamplerComparison) {
auto p = parser("sampler_comparison");
auto t = p->texture_and_sampler_types();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "sampler_comparison");
EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_DepthTexture) {
auto p = parser("texture_depth_2d");
auto t = p->texture_and_sampler_types();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, "texture_depth_2d");
EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_F32) {
auto p = parser("texture_1d<f32>");
auto t = p->texture_and_sampler_types();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("texture_1d", "f32"));
EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 16u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_I32) {
auto p = parser("texture_2d<i32>");
auto t = p->texture_and_sampler_types();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("texture_2d", "i32"));
EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 16u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_U32) {
auto p = parser("texture_3d<u32>");
auto t = p->texture_and_sampler_types();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("texture_3d", "u32"));
EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 16u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_I32) {
auto p = parser("texture_multisampled_2d<i32>");
auto t = p->texture_and_sampler_types();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value,
ast::Template("texture_multisampled_2d", "i32"));
EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 29u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingType) {
auto p = parser("texture_multisampled_2d<>");
auto t = p->texture_and_sampler_types();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored);
EXPECT_EQ(p->error(), "1:25: invalid type for multisampled texture type");
}
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingLessThan) {
auto p = parser("texture_multisampled_2d");
auto t = p->texture_and_sampler_types();
EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored);
EXPECT_EQ(p->error(), "1:24: expected '<' for multisampled texture type");
}
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingGreaterThan) {
auto p = parser("texture_multisampled_2d<u32");
auto t = p->texture_and_sampler_types();
EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored);
EXPECT_EQ(p->error(), "1:24: missing closing '>' for multisampled texture type");
}
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Readonly1dRg32Float) {
auto p = parser("texture_storage_1d<rg32float, read>");
auto t = p->texture_and_sampler_types();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value,
ast::Template("texture_storage_1d", "rg32float", "read"));
EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 36u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Writeonly2dR32Uint) {
auto p = parser("texture_storage_2d<r32uint, write>");
auto t = p->texture_and_sampler_types();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value,
ast::Template("texture_storage_2d", "r32uint", "write"));
EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 35u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingType) {
auto p = parser("texture_storage_1d<>");
auto t = p->texture_and_sampler_types();
EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored);
EXPECT_EQ(p->error(), R"(1:20: expected texel format for storage texture type
Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
}
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingGreaterThan) {
auto p = parser("texture_storage_1d<r32uint, read");
auto t = p->texture_and_sampler_types();
EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored);
EXPECT_EQ(p->error(), "1:19: missing closing '>' for storage texture type");
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -127,24 +127,6 @@ INSTANTIATE_TEST_SUITE_P(ParserImplTest,
VecData{"vec3<f32>", 3, {{1u, 1u}, {1u, 10u}}},
VecData{"vec4<f32>", 4, {{1u, 1u}, {1u, 10u}}}));
class VecMissingGreaterThanTest : public ParserImplTestWithParam<VecData> {};
TEST_P(VecMissingGreaterThanTest, Handles_Missing_GreaterThan) {
auto params = GetParam();
auto p = parser(params.input);
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:5: missing closing '>' for vector");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
VecMissingGreaterThanTest,
testing::Values(VecData{"vec2<f32", 2, {}},
VecData{"vec3<f32", 3, {}},
VecData{"vec4<f32", 4, {}}));
class VecMissingType : public ParserImplTestWithParam<VecData> {};
TEST_P(VecMissingType, Handles_Missing_Type) {
@ -155,7 +137,7 @@ TEST_P(VecMissingType, Handles_Missing_Type) {
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:6: invalid type for vector");
ASSERT_EQ(p->error(), "1:6: expected expression");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
VecMissingType,
@ -202,36 +184,6 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_ToVec) {
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25}}));
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingLessThan) {
auto p = parser("ptr private, f32>");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:5: expected '<' for ptr declaration");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingGreaterThanAfterType) {
auto p = parser("ptr<function, f32");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:4: missing closing '>' for ptr declaration");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingGreaterThanAfterAccess) {
auto p = parser("ptr<function, f32, read");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:4: missing closing '>' for ptr declaration");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAddressSpace) {
auto p = parser("ptr<function f32>");
auto t = p->type_specifier();
@ -239,7 +191,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAddressSpace) {
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:14: expected ',' for ptr declaration");
ASSERT_EQ(p->error(), "1:14: expected ',' for type template argument list");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAccess) {
@ -249,7 +201,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAccess) {
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:19: expected '>' for ptr declaration");
ASSERT_EQ(p->error(), "1:19: expected ',' for type template argument list");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingAddressSpace) {
@ -259,29 +211,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingAddressSpace) {
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), R"(1:5: expected address space for ptr declaration
Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingType) {
auto p = parser("ptr<function,>");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:14: invalid type for ptr declaration");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingAccess) {
auto p = parser("ptr<function, i32, >");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), R"(1:20: expected access control for ptr declaration
Possible values: 'read', 'read_write', 'write')");
ASSERT_EQ(p->error(), R"(1:5: expected expression)");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) {
@ -291,32 +221,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) {
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), R"(1:5: expected address space for ptr declaration
Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_BadAddressSpace) {
auto p = parser("ptr<unknown, f32>");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(),
R"(1:5: expected address space for ptr declaration
Did you mean 'uniform'?
Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
}
TEST_F(ParserImplTest, TypeDecl_Ptr_BadAccess) {
auto p = parser("ptr<function, i32, unknown>");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), R"(1:20: expected access control for ptr declaration
Possible values: 'read', 'read_write', 'write')");
ASSERT_EQ(p->error(), R"(1:5: expected expression)");
}
TEST_F(ParserImplTest, TypeDecl_Atomic) {
@ -344,26 +249,6 @@ TEST_F(ParserImplTest, TypeDecl_Atomic_ToVec) {
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 18u}}));
}
TEST_F(ParserImplTest, TypeDecl_Atomic_MissingLessThan) {
auto p = parser("atomic f32>");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:8: expected '<' for atomic declaration");
}
TEST_F(ParserImplTest, TypeDecl_Atomic_MissingGreaterThan) {
auto p = parser("atomic<f32");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:7: missing closing '>' for atomic declaration");
}
TEST_F(ParserImplTest, TypeDecl_Atomic_MissingType) {
auto p = parser("atomic<>");
auto t = p->type_specifier();
@ -371,7 +256,7 @@ TEST_F(ParserImplTest, TypeDecl_Atomic_MissingType) {
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:8: invalid type for atomic declaration");
ASSERT_EQ(p->error(), "1:8: expected expression");
}
TEST_F(ParserImplTest, TypeDecl_Array_AbstractIntLiteralSize) {
@ -486,26 +371,6 @@ TEST_F(ParserImplTest, TypeDecl_Array_BadSize) {
ASSERT_EQ(p->error(), "1:13: unable to parse right side of ! expression");
}
TEST_F(ParserImplTest, TypeDecl_Array_MissingSize) {
auto p = parser("array<f32,>");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:11: expected array size expression");
}
TEST_F(ParserImplTest, TypeDecl_Array_MissingGreaterThan) {
auto p = parser("array<f32");
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:6: missing closing '>' for array declaration");
}
TEST_F(ParserImplTest, TypeDecl_Array_MissingComma) {
auto p = parser("array<f32 3>");
auto t = p->type_specifier();
@ -513,7 +378,7 @@ TEST_F(ParserImplTest, TypeDecl_Array_MissingComma) {
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:11: expected '>' for array declaration");
ASSERT_EQ(p->error(), "1:11: expected ',' for type template argument list");
}
struct MatrixData {
@ -556,30 +421,6 @@ INSTANTIATE_TEST_SUITE_P(ParserImplTest,
MatrixData{"mat4x3<f32>", 4, 3, {{1u, 1u}, {1u, 12u}}},
MatrixData{"mat4x4<f32>", 4, 4, {{1u, 1u}, {1u, 12u}}}));
class MatrixMissingGreaterThanTest : public ParserImplTestWithParam<MatrixData> {};
TEST_P(MatrixMissingGreaterThanTest, Handles_Missing_GreaterThan) {
auto params = GetParam();
auto p = parser(params.input);
auto t = p->type_specifier();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:7: missing closing '>' for matrix");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
MatrixMissingGreaterThanTest,
testing::Values(MatrixData{"mat2x2<f32", 2, 2, {}},
MatrixData{"mat2x3<f32", 2, 3, {}},
MatrixData{"mat2x4<f32", 2, 4, {}},
MatrixData{"mat3x2<f32", 3, 2, {}},
MatrixData{"mat3x3<f32", 3, 3, {}},
MatrixData{"mat3x4<f32", 3, 4, {}},
MatrixData{"mat4x2<f32", 4, 2, {}},
MatrixData{"mat4x3<f32", 4, 3, {}},
MatrixData{"mat4x4<f32", 4, 4, {}}));
class MatrixMissingType : public ParserImplTestWithParam<MatrixData> {};
TEST_P(MatrixMissingType, Handles_Missing_Type) {
@ -590,7 +431,7 @@ TEST_P(MatrixMissingType, Handles_Missing_Type) {
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:8: invalid type for matrix");
ASSERT_EQ(p->error(), "1:8: expected expression");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
MatrixMissingType,

View File

@ -1,625 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/ast/alias.h"
#include "src/tint/ast/test_helper.h"
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
#include "src/tint/type/sampled_texture.h"
namespace tint::reader::wgsl {
namespace {
using namespace tint::number_suffixes; // NOLINT
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Invalid) {
auto p = parser("1234");
auto t = p->type_specifier_without_ident();
EXPECT_EQ(t.errored, false);
EXPECT_EQ(t.matched, false);
EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(p->has_error()) << p->error();
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Identifier) {
auto p = parser("A");
auto t = p->type_specifier_without_ident();
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_EQ(t.value, nullptr);
EXPECT_FALSE(p->has_error()) << p->error();
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Bool) {
auto p = parser("bool");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ast::CheckIdentifier(p->builder().Symbols(), t.value, "bool");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_F16) {
auto p = parser("f16");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ast::CheckIdentifier(p->builder().Symbols(), t.value, "f16");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_F32) {
auto p = parser("f32");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ast::CheckIdentifier(p->builder().Symbols(), t.value, "f32");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_I32) {
auto p = parser("i32");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ast::CheckIdentifier(p->builder().Symbols(), t.value, "i32");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_U32) {
auto p = parser("u32");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ast::CheckIdentifier(p->builder().Symbols(), t.value, "u32");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
}
struct VecData {
const char* input;
size_t count;
Source::Range range;
};
inline std::ostream& operator<<(std::ostream& out, VecData data) {
out << std::string(data.input);
return out;
}
class TypeDeclWithoutIdent_VecTest : public ParserImplTestWithParam<VecData> {};
TEST_P(TypeDeclWithoutIdent_VecTest, Parse) {
auto params = GetParam();
auto p = parser(params.input);
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value,
ast::Template("vec" + std::to_string(params.count), "f32"));
EXPECT_EQ(t.value->source.range, params.range);
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
TypeDeclWithoutIdent_VecTest,
testing::Values(VecData{"vec2<f32>", 2, {{1u, 1u}, {1u, 10u}}},
VecData{"vec3<f32>", 3, {{1u, 1u}, {1u, 10u}}},
VecData{"vec4<f32>", 4, {{1u, 1u}, {1u, 10u}}}));
class TypeDeclWithoutIdent_VecMissingGreaterThanTest : public ParserImplTestWithParam<VecData> {};
TEST_P(TypeDeclWithoutIdent_VecMissingGreaterThanTest, Handles_Missing_GreaterThan) {
auto params = GetParam();
auto p = parser(params.input);
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:5: missing closing '>' for vector");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
TypeDeclWithoutIdent_VecMissingGreaterThanTest,
testing::Values(VecData{"vec2<f32", 2, {}},
VecData{"vec3<f32", 3, {}},
VecData{"vec4<f32", 4, {}}));
class TypeDeclWithoutIdent_VecMissingType : public ParserImplTestWithParam<VecData> {};
TEST_P(TypeDeclWithoutIdent_VecMissingType, Handles_Missing_Type) {
auto params = GetParam();
auto p = parser(params.input);
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:6: invalid type for vector");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
TypeDeclWithoutIdent_VecMissingType,
testing::Values(VecData{"vec2<>", 2, {}},
VecData{"vec3<>", 3, {}},
VecData{"vec4<>", 4, {}}));
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr) {
auto p = parser("ptr<function, f32>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("ptr", "function", "f32"));
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_WithAccess) {
auto p = parser("ptr<function, f32, read>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value,
ast::Template("ptr", "function", "f32", "read"));
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_ToVec) {
auto p = parser("ptr<function, vec2<f32>>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value,
ast::Template("ptr", "function", ast::Template("vec2", "f32")));
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingLessThan) {
auto p = parser("ptr private, f32>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:5: expected '<' for ptr declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingGreaterThanAfterType) {
auto p = parser("ptr<function, f32");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:4: missing closing '>' for ptr declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingGreaterThanAfterAccess) {
auto p = parser("ptr<function, f32, read");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:4: missing closing '>' for ptr declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingCommaAfterAddressSpace) {
auto p = parser("ptr<function f32>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:14: expected ',' for ptr declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingCommaAfterAccess) {
auto p = parser("ptr<function, f32 read>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:19: expected '>' for ptr declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingAddressSpace) {
auto p = parser("ptr<, f32>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), R"(1:5: expected address space for ptr declaration
Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingType) {
auto p = parser("ptr<function,>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:14: invalid type for ptr declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingAccess) {
auto p = parser("ptr<function, i32, >");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), R"(1:20: expected access control for ptr declaration
Possible values: 'read', 'read_write', 'write')");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingParams) {
auto p = parser("ptr<>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), R"(1:5: expected address space for ptr declaration
Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_BadAddressSpace) {
auto p = parser("ptr<unknown, f32>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(),
R"(1:5: expected address space for ptr declaration
Did you mean 'uniform'?
Possible values: 'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_BadAccess) {
auto p = parser("ptr<function, i32, unknown>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), R"(1:20: expected access control for ptr declaration
Possible values: 'read', 'read_write', 'write')");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic) {
auto p = parser("atomic<f32>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("atomic", "f32"));
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 12u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_ToVec) {
auto p = parser("atomic<vec2<f32>>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value,
ast::Template("atomic", ast::Template("vec2", "f32")));
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 18u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_MissingLessThan) {
auto p = parser("atomic f32>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:8: expected '<' for atomic declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_MissingGreaterThan) {
auto p = parser("atomic<f32");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:7: missing closing '>' for atomic declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_MissingType) {
auto p = parser("atomic<>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:8: invalid type for atomic declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_AbstractIntLiteralSize) {
auto p = parser("array<f32, 5>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("array", "f32", 5_a));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_SintLiteralSize) {
auto p = parser("array<f32, 5i>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("array", "f32", 5_i));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_UintLiteralSize) {
auto p = parser("array<f32, 5u>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("array", "f32", 5_u));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_ConstantSize) {
auto p = parser("array<f32, size>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("array", "f32", "size"));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_ExpressionSize) {
auto p = parser("array<f32, size + 2>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto name_for = [&](const Symbol& sym) { return p->builder().Symbols().NameFor(sym); };
auto* arr = t->expr->identifier->As<ast::TemplatedIdentifier>();
EXPECT_EQ(name_for(arr->symbol), "array");
EXPECT_TRUE(arr->attributes.IsEmpty());
ASSERT_EQ(arr->arguments.Length(), 2u);
auto* ty = As<ast::IdentifierExpression>(arr->arguments[0]);
ASSERT_NE(ty, nullptr);
EXPECT_EQ(name_for(ty->identifier->symbol), "f32");
auto* count = As<ast::BinaryExpression>(arr->arguments[1]);
ASSERT_NE(count, nullptr);
EXPECT_EQ(ast::BinaryOp::kAdd, count->op);
auto* count_lhs = As<ast::IdentifierExpression>(count->lhs);
ASSERT_NE(count_lhs, nullptr);
EXPECT_EQ(name_for(count_lhs->identifier->symbol), "size");
auto* count_rhs = As<ast::IntLiteralExpression>(count->rhs);
ASSERT_NE(count_rhs, nullptr);
EXPECT_EQ(count_rhs->value, static_cast<int64_t>(2));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_Runtime) {
auto p = parser("array<u32>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("array", "u32"));
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 11u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_Runtime_Vec) {
auto p = parser("array<vec4<u32>>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ast::CheckIdentifier(p->builder().Symbols(), t.value,
ast::Template("array", ast::Template("vec4", "u32")));
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_BadSize) {
auto p = parser("array<f32, !>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:13: unable to parse right side of ! expression");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_MissingSize) {
auto p = parser("array<f32,>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:11: expected array size expression");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_MissingGreaterThan) {
auto p = parser("array<f32");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:6: missing closing '>' for array declaration");
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_MissingComma) {
auto p = parser("array<f32 3>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:11: expected '>' for array declaration");
}
struct MatrixData {
const char* input;
size_t columns;
size_t rows;
Source::Range range;
};
inline std::ostream& operator<<(std::ostream& out, MatrixData data) {
out << std::string(data.input);
return out;
}
class TypeDeclWithoutIdent_MatrixTest : public ParserImplTestWithParam<MatrixData> {};
TEST_P(TypeDeclWithoutIdent_MatrixTest, Parse) {
auto params = GetParam();
auto p = parser(params.input);
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
std::string expected_name =
"mat" + std::to_string(GetParam().columns) + "x" + std::to_string(GetParam().rows);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template(expected_name, "f32"));
EXPECT_EQ(t.value->source.range, params.range);
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
TypeDeclWithoutIdent_MatrixTest,
testing::Values(MatrixData{"mat2x2<f32>", 2, 2, {{1u, 1u}, {1u, 12u}}},
MatrixData{"mat2x3<f32>", 2, 3, {{1u, 1u}, {1u, 12u}}},
MatrixData{"mat2x4<f32>", 2, 4, {{1u, 1u}, {1u, 12u}}},
MatrixData{"mat3x2<f32>", 3, 2, {{1u, 1u}, {1u, 12u}}},
MatrixData{"mat3x3<f32>", 3, 3, {{1u, 1u}, {1u, 12u}}},
MatrixData{"mat3x4<f32>", 3, 4, {{1u, 1u}, {1u, 12u}}},
MatrixData{"mat4x2<f32>", 4, 2, {{1u, 1u}, {1u, 12u}}},
MatrixData{"mat4x3<f32>", 4, 3, {{1u, 1u}, {1u, 12u}}},
MatrixData{"mat4x4<f32>", 4, 4, {{1u, 1u}, {1u, 12u}}}));
class TypeDeclWithoutIdent_MatrixMissingGreaterThanTest
: public ParserImplTestWithParam<MatrixData> {};
TEST_P(TypeDeclWithoutIdent_MatrixMissingGreaterThanTest, Handles_Missing_GreaterThan) {
auto params = GetParam();
auto p = parser(params.input);
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:7: missing closing '>' for matrix");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
TypeDeclWithoutIdent_MatrixMissingGreaterThanTest,
testing::Values(MatrixData{"mat2x2<f32", 2, 2, {}},
MatrixData{"mat2x3<f32", 2, 3, {}},
MatrixData{"mat2x4<f32", 2, 4, {}},
MatrixData{"mat3x2<f32", 3, 2, {}},
MatrixData{"mat3x3<f32", 3, 3, {}},
MatrixData{"mat3x4<f32", 3, 4, {}},
MatrixData{"mat4x2<f32", 4, 2, {}},
MatrixData{"mat4x3<f32", 4, 3, {}},
MatrixData{"mat4x4<f32", 4, 4, {}}));
class TypeDeclWithoutIdent_MatrixMissingType : public ParserImplTestWithParam<MatrixData> {};
TEST_P(TypeDeclWithoutIdent_MatrixMissingType, Handles_Missing_Type) {
auto params = GetParam();
auto p = parser(params.input);
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:8: invalid type for matrix");
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
TypeDeclWithoutIdent_MatrixMissingType,
testing::Values(MatrixData{"mat2x2<>", 2, 2, {}},
MatrixData{"mat2x3<>", 2, 3, {}},
MatrixData{"mat2x4<>", 2, 4, {}},
MatrixData{"mat3x2<>", 3, 2, {}},
MatrixData{"mat3x3<>", 3, 3, {}},
MatrixData{"mat3x4<>", 3, 4, {}},
MatrixData{"mat4x2<>", 4, 2, {}},
MatrixData{"mat4x3<>", 4, 3, {}},
MatrixData{"mat4x4<>", 4, 4, {}}));
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Sampler) {
auto p = parser("sampler");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr) << p->error();
ast::CheckIdentifier(p->builder().Symbols(), t.value, "sampler");
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 8u}}));
}
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Texture) {
auto p = parser("texture_cube<f32>");
auto t = p->type_specifier_without_ident();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ast::CheckIdentifier(p->builder().Symbols(), t.value, ast::Template("texture_cube", "f32"));
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 18u}}));
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -1,103 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
namespace tint::reader::wgsl {
namespace {
TEST_F(ParserImplTest, VecPrefix_Vec2) {
auto p = parser("vec2");
auto t = p->vec_prefix();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(2u, t.value);
}
TEST_F(ParserImplTest, VecPrefix_Vec3) {
auto p = parser("vec3");
auto t = p->vec_prefix();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(3u, t.value);
}
TEST_F(ParserImplTest, VecPrefix_Vec4) {
auto p = parser("vec4");
auto t = p->vec_prefix();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(4u, t.value);
}
TEST_F(ParserImplTest, VecPrefix_NoMatch) {
auto p = parser("mat2x2");
auto t = p->vec_prefix();
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(0u, t.value);
}
struct MatData {
std::string name;
uint32_t columns;
uint32_t rows;
};
class MatPrefixTest : public ParserImplTestWithParam<MatData> {};
TEST_P(MatPrefixTest, Parse) {
auto params = GetParam();
auto p = parser(params.name);
auto t = p->mat_prefix();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
auto dims = t.value;
EXPECT_EQ(params.columns, dims.columns);
EXPECT_EQ(params.rows, dims.rows);
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
MatPrefixTest,
testing::Values(MatData{"mat2x2", 2, 2},
MatData{"mat2x3", 2, 3},
MatData{"mat2x4", 2, 4},
MatData{"mat3x2", 3, 2},
MatData{"mat3x3", 3, 3},
MatData{"mat3x4", 3, 4},
MatData{"mat4x2", 4, 2},
MatData{"mat4x3", 4, 3},
MatData{"mat4x4", 4, 4}));
TEST_F(ParserImplTest, MatPrefix_NoMatch) {
auto p = parser("vec2");
auto t = p->mat_prefix();
EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(0u, t.value.columns);
EXPECT_EQ(0u, t.value.rows);
}
} // namespace
} // namespace tint::reader::wgsl

View File

@ -94,7 +94,7 @@ class WhileStmtErrorTest : public ParserImplTest {
// Test a while loop with missing left parenthesis is invalid.
TEST_F(WhileStmtErrorTest, MissingLeftParen) {
std::string while_str = "while bool) { }";
std::string error_str = "1:11: expected '(' for type initializer";
std::string error_str = "1:11: expected '{' for while loop";
TestWhileWithError(while_str, error_str);
}

View File

@ -139,14 +139,8 @@ std::string_view Token::TypeToName(Type type) {
case Token::Type::kAlias:
return "alias";
case Token::Type::kArray:
return "array";
case Token::Type::kAtomic:
return "atomic";
case Token::Type::kBitcast:
return "bitcast";
case Token::Type::kBool:
return "bool";
case Token::Type::kBreak:
return "break";
case Token::Type::kCase:
@ -169,10 +163,6 @@ std::string_view Token::TypeToName(Type type) {
return "else";
case Token::Type::kEnable:
return "enable";
case Token::Type::kF16:
return "f16";
case Token::Type::kF32:
return "f32";
case Token::Type::kFallthrough:
return "fallthrough";
case Token::Type::kFalse:
@ -181,96 +171,28 @@ std::string_view Token::TypeToName(Type type) {
return "fn";
case Token::Type::kFor:
return "for";
case Token::Type::kI32:
return "i32";
case Token::Type::kIf:
return "if";
case Token::Type::kLet:
return "let";
case Token::Type::kLoop:
return "loop";
case Token::Type::kMat2x2:
return "mat2x2";
case Token::Type::kMat2x3:
return "mat2x3";
case Token::Type::kMat2x4:
return "mat2x4";
case Token::Type::kMat3x2:
return "mat3x2";
case Token::Type::kMat3x3:
return "mat3x3";
case Token::Type::kMat3x4:
return "mat3x4";
case Token::Type::kMat4x2:
return "mat4x2";
case Token::Type::kMat4x3:
return "mat4x3";
case Token::Type::kMat4x4:
return "mat4x4";
case Token::Type::kOverride:
return "override";
case Token::Type::kPtr:
return "ptr";
case Token::Type::kReturn:
return "return";
case Token::Type::kSampler:
return "sampler";
case Token::Type::kComparisonSampler:
return "sampler_comparison";
case Token::Type::kStaticAssert:
return "static_assert";
case Token::Type::kStruct:
return "struct";
case Token::Type::kSwitch:
return "switch";
case Token::Type::kTextureDepth2d:
return "texture_depth_2d";
case Token::Type::kTextureDepth2dArray:
return "texture_depth_2d_array";
case Token::Type::kTextureDepthCube:
return "texture_depth_cube";
case Token::Type::kTextureDepthCubeArray:
return "texture_depth_cube_array";
case Token::Type::kTextureDepthMultisampled2d:
return "texture_depth_multisampled_2d";
case Token::Type::kTextureExternal:
return "texture_external";
case Token::Type::kTextureMultisampled2d:
return "texture_multisampled_2d";
case Token::Type::kTextureSampled1d:
return "texture_1d";
case Token::Type::kTextureSampled2d:
return "texture_2d";
case Token::Type::kTextureSampled2dArray:
return "texture_2d_array";
case Token::Type::kTextureSampled3d:
return "texture_3d";
case Token::Type::kTextureSampledCube:
return "texture_cube";
case Token::Type::kTextureSampledCubeArray:
return "texture_cube_array";
case Token::Type::kTextureStorage1d:
return "texture_storage_1d";
case Token::Type::kTextureStorage2d:
return "texture_storage_2d";
case Token::Type::kTextureStorage2dArray:
return "texture_storage_2d_array";
case Token::Type::kTextureStorage3d:
return "texture_storage_3d";
case Token::Type::kTrue:
return "true";
case Token::Type::kType:
return "type";
case Token::Type::kU32:
return "u32";
case Token::Type::kVar:
return "var";
case Token::Type::kVec2:
return "vec2";
case Token::Type::kVec3:
return "vec3";
case Token::Type::kVec4:
return "vec4";
case Token::Type::kWhile:
return "while";
}

View File

@ -151,14 +151,8 @@ class Token {
/// A 'alias'
kAlias,
/// A 'array'
kArray,
/// A 'atomic'
kAtomic,
/// A 'bitcast'
kBitcast,
/// A 'bool'
kBool,
/// A 'break'
kBreak,
/// A 'case'
@ -181,10 +175,6 @@ class Token {
kElse,
/// A 'enable'
kEnable,
/// A 'f16'
kF16,
/// A 'f32'
kF32,
/// A 'fallthrough'
kFallthrough,
/// A 'false'
@ -193,96 +183,28 @@ class Token {
kFn,
// A 'for'
kFor,
/// A 'i32'
kI32,
/// A 'if'
kIf,
/// A 'let'
kLet,
/// A 'loop'
kLoop,
/// A 'mat2x2'
kMat2x2,
/// A 'mat2x3'
kMat2x3,
/// A 'mat2x4'
kMat2x4,
/// A 'mat3x2'
kMat3x2,
/// A 'mat3x3'
kMat3x3,
/// A 'mat3x4'
kMat3x4,
/// A 'mat4x2'
kMat4x2,
/// A 'mat4x3'
kMat4x3,
/// A 'mat4x4'
kMat4x4,
/// A 'override'
kOverride,
/// A 'ptr'
kPtr,
/// A 'return'
kReturn,
/// A 'sampler'
kSampler,
/// A 'sampler_comparison'
kComparisonSampler,
/// A 'static_assert'
kStaticAssert,
/// A 'struct'
kStruct,
/// A 'switch'
kSwitch,
/// A 'texture_depth_2d'
kTextureDepth2d,
/// A 'texture_depth_2d_array'
kTextureDepth2dArray,
/// A 'texture_depth_cube'
kTextureDepthCube,
/// A 'texture_depth_cube_array'
kTextureDepthCubeArray,
/// A 'texture_depth_multisampled_2d'
kTextureDepthMultisampled2d,
/// A 'texture_external'
kTextureExternal,
/// A 'texture_multisampled_2d'
kTextureMultisampled2d,
/// A 'texture_1d'
kTextureSampled1d,
/// A 'texture_2d'
kTextureSampled2d,
/// A 'texture_2d_array'
kTextureSampled2dArray,
/// A 'texture_3d'
kTextureSampled3d,
/// A 'texture_cube'
kTextureSampledCube,
/// A 'texture_cube_array'
kTextureSampledCubeArray,
/// A 'texture_storage_1d'
kTextureStorage1d,
/// A 'texture_storage_2d'
kTextureStorage2d,
/// A 'texture_storage_2d_array'
kTextureStorage2dArray,
/// A 'texture_storage_3d'
kTextureStorage3d,
/// A 'true'
kTrue,
/// A 'type'
kType,
/// A 'u32'
kU32,
/// A 'var'
kVar,
/// A 'vec2'
kVec2,
/// A 'vec3'
kVec3,
/// A 'vec4'
kVec4,
/// A 'while'
kWhile,
};
@ -359,33 +281,6 @@ class Token {
type_ == Type::kFloatLiteral || type_ == Type::kFloatLiteral_F ||
type_ == Type::kFloatLiteral_H;
}
/// @returns true if token is a 'matNxM'
bool IsMatrix() const {
return type_ == Type::kMat2x2 || type_ == Type::kMat2x3 || type_ == Type::kMat2x4 ||
type_ == Type::kMat3x2 || type_ == Type::kMat3x3 || type_ == Type::kMat3x4 ||
type_ == Type::kMat4x2 || type_ == Type::kMat4x3 || type_ == Type::kMat4x4;
}
/// @returns true if token is a 'mat3xM'
bool IsMat3xN() const {
return type_ == Type::kMat3x2 || type_ == Type::kMat3x3 || type_ == Type::kMat3x4;
}
/// @returns true if token is a 'mat4xM'
bool IsMat4xN() const {
return type_ == Type::kMat4x2 || type_ == Type::kMat4x3 || type_ == Type::kMat4x4;
}
/// @returns true if token is a 'matNx3'
bool IsMatNx3() const {
return type_ == Type::kMat2x3 || type_ == Type::kMat3x3 || type_ == Type::kMat4x3;
}
/// @returns true if token is a 'matNx4'
bool IsMatNx4() const {
return type_ == Type::kMat2x4 || type_ == Type::kMat3x4 || type_ == Type::kMat4x4;
}
/// @returns true if token is a 'vecN'
bool IsVector() const {
return type_ == Type::kVec2 || type_ == Type::kVec3 || type_ == Type::kVec4;
}
/// @returns the number of placeholder tokens required to follow the token, in order to provide
/// space for token splitting.

View File

@ -7390,7 +7390,7 @@ fn main() {
EXPECT_EQ(error_,
R"(test:5:41 error: 'dpdx' must only be called from uniform control flow
let b = (non_uniform_global == 0) && (dpdx(1.0) == 0.0);
^^^^
^^^^^^^^^
test:5:37 note: control flow depends on possibly non-uniform value
let b = (non_uniform_global == 0) && (dpdx(1.0) == 0.0);
@ -7784,7 +7784,7 @@ test:5:3 note: control flow depends on possibly non-uniform value
test:5:7 note: return value of 'atomicAdd' may be non-uniform
if (atomicAdd(&a, 1) == 1) {
^^^^^^^^^
^^^^^^^^^^^^^^^^
)");
}
@ -7811,7 +7811,7 @@ test:5:3 note: control flow depends on possibly non-uniform value
test:5:7 note: return value of 'atomicAdd' may be non-uniform
if (atomicAdd(&a, 1) == 1) {
^^^^^^^^^
^^^^^^^^^^^^^^^^
)");
}
@ -8154,7 +8154,7 @@ fn foo() {
EXPECT_EQ(error_,
R"(test:10:9 error: 'dpdy' must only be called from uniform control flow
_ = dpdy(1.0); // Should trigger an error
^^^^
^^^^^^^^^
test:9:3 note: control flow depends on possibly non-uniform value
if (x < 0.5) {
@ -8162,7 +8162,7 @@ test:9:3 note: control flow depends on possibly non-uniform value
test:6:9 note: return value of 'dpdx' may be non-uniform
x = dpdx(1.0);
^^^^
^^^^^^^^^
)");
}
@ -8194,7 +8194,7 @@ fn bar() {
EXPECT_EQ(error_,
R"(test:16:9 error: 'dpdy' must only be called from uniform control flow
_ = dpdy(1.0); // Should trigger an error
^^^^
^^^^^^^^^
test:15:3 note: control flow depends on possibly non-uniform value
if (ret) {
@ -8423,7 +8423,7 @@ test:17:3 note: control flow depends on possibly non-uniform value
test:17:7 note: return value of 'foo' may be non-uniform
if (foo() == 42) {
^^^
^^^^^
)");
}

View File

@ -1571,60 +1571,99 @@ INSTANTIATE_TEST_SUITE_P(
kUnicodeIdentifier));
std::string ExpandBuiltinType(std::string_view name) {
if (name == "array") {
return "array<i32, 4>";
}
if (name == "atomic") {
return "atomic<i32>";
}
if (name == "mat2x2") {
return "mat2x2<f32>";
}
if (name == "mat2x2f") {
return "mat2x2<f32>";
}
if (name == "mat2x2h") {
return "mat2x2<f16>";
}
if (name == "mat2x3") {
return "mat2x3<f32>";
}
if (name == "mat2x3f") {
return "mat2x3<f32>";
}
if (name == "mat2x3h") {
return "mat2x3<f16>";
}
if (name == "mat2x4") {
return "mat2x4<f32>";
}
if (name == "mat2x4f") {
return "mat2x4<f32>";
}
if (name == "mat2x4h") {
return "mat2x4<f16>";
}
if (name == "mat3x2") {
return "mat3x2<f32>";
}
if (name == "mat3x2f") {
return "mat3x2<f32>";
}
if (name == "mat3x2h") {
return "mat3x2<f16>";
}
if (name == "mat3x3") {
return "mat3x3<f32>";
}
if (name == "mat3x3f") {
return "mat3x3<f32>";
}
if (name == "mat3x3h") {
return "mat3x3<f16>";
}
if (name == "mat3x4") {
return "mat3x4<f32>";
}
if (name == "mat3x4f") {
return "mat3x4<f32>";
}
if (name == "mat3x4h") {
return "mat3x4<f16>";
}
if (name == "mat4x2") {
return "mat4x2<f32>";
}
if (name == "mat4x2f") {
return "mat4x2<f32>";
}
if (name == "mat4x2h") {
return "mat4x2<f16>";
}
if (name == "mat4x3") {
return "mat4x3<f32>";
}
if (name == "mat4x3f") {
return "mat4x3<f32>";
}
if (name == "mat4x3h") {
return "mat4x3<f16>";
}
if (name == "mat4x4") {
return "mat4x4<f32>";
}
if (name == "mat4x4f") {
return "mat4x4<f32>";
}
if (name == "mat4x4h") {
return "mat4x4<f16>";
}
if (name == "ptr") {
return "ptr<function, i32>";
}
if (name == "vec2") {
return "vec2<f32>";
}
if (name == "vec2f") {
return "vec2<f32>";
}
@ -1637,6 +1676,9 @@ std::string ExpandBuiltinType(std::string_view name) {
if (name == "vec2u") {
return "vec2<u32>";
}
if (name == "vec3") {
return "vec3<f32>";
}
if (name == "vec3f") {
return "vec3<f32>";
}
@ -1649,6 +1691,9 @@ std::string ExpandBuiltinType(std::string_view name) {
if (name == "vec3u") {
return "vec3<u32>";
}
if (name == "vec4") {
return "vec4<f32>";
}
if (name == "vec4f") {
return "vec4<f32>";
}
@ -1664,58 +1709,13 @@ std::string ExpandBuiltinType(std::string_view name) {
return std::string(name);
}
/// @return all the identifiers parsed as keywords
std::unordered_set<std::string> Keywords() {
return {
"array",
"atomic",
"bool",
"f16",
"f32",
"i32",
"mat2x2",
"mat2x3",
"mat2x4",
"mat3x2",
"mat3x3",
"mat3x4",
"mat4x2",
"mat4x3",
"mat4x4",
"ptr",
"sampler_comparison",
"sampler",
"texture_1d",
"texture_2d_array",
"texture_2d",
"texture_3d",
"texture_cube_array",
"texture_cube",
"texture_depth_2d_array",
"texture_depth_2d",
"texture_depth_cube_array",
"texture_depth_cube",
"texture_depth_multisampled_2d",
"texture_external",
"texture_multisampled_2d",
"texture_storage_1d",
"texture_storage_2d_array",
"texture_storage_2d",
"texture_storage_3d",
"u32",
"vec2",
"vec3",
"vec4",
};
}
/// @return WGSL builtin types that aren't keywords
std::vector<const char*> NonKeywordBuiltinTypes() {
auto keywords = Keywords();
std::vector<const char*> ConstructableTypes() {
std::vector<const char*> out;
for (auto* ident : type::kBuiltinStrings) {
if (!keywords.count(ident)) {
out.push_back(ident);
for (auto* ty : type::kBuiltinStrings) {
std::string_view type(ty);
if (type != "ptr" && type != "atomic" && !utils::HasPrefix(type, "sampler") &&
!utils::HasPrefix(type, "texture")) {
out.push_back(ty);
}
}
return out;
@ -1725,38 +1725,36 @@ using RenamerBuiltinTypeTest = TransformTestWithParam<const char*>;
TEST_P(RenamerBuiltinTypeTest, PreserveTypeUsage) {
auto expand = [&](const char* source) {
auto out = utils::ReplaceAll(source, "$name", GetParam());
out = utils::ReplaceAll(out, "$type", ExpandBuiltinType(GetParam()));
return out;
return utils::ReplaceAll(source, "$type", ExpandBuiltinType(GetParam()));
};
auto src = expand(R"(
enable f16;
fn x(v : $name) -> $name {
const a : $name = $name();
let b : $name = a;
var c : $name = b;
fn x(v : $type) -> $type {
const a : $type = $type();
let b : $type = a;
var c : $type = b;
return c;
}
struct y {
a : $name,
a : $type,
}
)");
auto expect = expand(R"(
enable f16;
fn tint_symbol(tint_symbol_1 : $name) -> $name {
const tint_symbol_2 : $name = $name();
let tint_symbol_3 : $name = tint_symbol_2;
var tint_symbol_4 : $name = tint_symbol_3;
fn tint_symbol(tint_symbol_1 : $type) -> $type {
const tint_symbol_2 : $type = $type();
let tint_symbol_3 : $type = tint_symbol_2;
var tint_symbol_4 : $type = tint_symbol_3;
return tint_symbol_4;
}
struct tint_symbol_5 {
tint_symbol_2 : $name,
tint_symbol_2 : $type,
}
)");
@ -1766,9 +1764,7 @@ struct tint_symbol_5 {
}
TEST_P(RenamerBuiltinTypeTest, PreserveTypeInitializer) {
auto expand = [&](const char* source) {
auto out = utils::ReplaceAll(source, "$name", GetParam());
out = utils::ReplaceAll(out, "$type", ExpandBuiltinType(GetParam()));
return out;
return utils::ReplaceAll(source, "$type", ExpandBuiltinType(GetParam()));
};
auto src = expand(R"(
@ -1776,7 +1772,7 @@ enable f16;
@fragment
fn f() {
var v : $type = $name();
var v : $type = $type();
}
)");
@ -1785,7 +1781,7 @@ enable f16;
@fragment
fn tint_symbol() {
var tint_symbol_1 : $type = $name();
var tint_symbol_1 : $type = $type();
}
)");
@ -1795,10 +1791,12 @@ fn tint_symbol() {
}
TEST_P(RenamerBuiltinTypeTest, PreserveTypeConversion) {
if (std::string_view(GetParam()) == "array") {
return; // Cannot type convert arrays.
}
auto expand = [&](const char* source) {
auto out = utils::ReplaceAll(source, "$name", GetParam());
out = utils::ReplaceAll(out, "$type", ExpandBuiltinType(GetParam()));
return out;
return utils::ReplaceAll(source, "$type", ExpandBuiltinType(GetParam()));
};
auto src = expand(R"(
@ -1806,7 +1804,7 @@ enable f16;
@fragment
fn f() {
var v : $type = $name($type());
var v : $type = $type($type());
}
)");
@ -1815,7 +1813,7 @@ enable f16;
@fragment
fn tint_symbol() {
var tint_symbol_1 : $type = $name($type());
var tint_symbol_1 : $type = $type($type());
}
)");
@ -1850,26 +1848,28 @@ fn tint_symbol() {
TEST_P(RenamerBuiltinTypeTest, RenameShadowedByAlias) {
auto expand = [&](const char* source) {
auto out = utils::ReplaceAll(source, "$name", GetParam());
out = utils::ReplaceAll(out, "$type", ExpandBuiltinType(GetParam()));
std::string_view ty = GetParam();
auto out = utils::ReplaceAll(source, "$name", ty);
out = utils::ReplaceAll(out, "$type", ExpandBuiltinType(ty));
out = utils::ReplaceAll(out, "$other_type", ty == "i32" ? "u32" : "i32");
return out;
};
auto src = expand(R"(
type $name = i32;
type $name = $other_type;
@fragment
fn f() {
var v : i32 = $name();
var v : $other_type = $name();
}
)");
auto expect = expand(R"(
alias tint_symbol = i32;
alias tint_symbol = $other_type;
@fragment
fn tint_symbol_1() {
var tint_symbol_2 : i32 = tint_symbol();
var tint_symbol_2 : $other_type = tint_symbol();
}
)");
@ -1880,14 +1880,16 @@ fn tint_symbol_1() {
TEST_P(RenamerBuiltinTypeTest, RenameShadowedByStruct) {
auto expand = [&](const char* source) {
auto out = utils::ReplaceAll(source, "$name", GetParam());
out = utils::ReplaceAll(out, "$type", ExpandBuiltinType(GetParam()));
std::string_view ty = GetParam();
auto out = utils::ReplaceAll(source, "$name", ty);
out = utils::ReplaceAll(out, "$type", ExpandBuiltinType(ty));
out = utils::ReplaceAll(out, "$other_type", ty == "i32" ? "u32" : "i32");
return out;
};
auto src = expand(R"(
struct $name {
i : i32,
i : $other_type,
}
@fragment
@ -1899,7 +1901,7 @@ fn f() {
auto expect = expand(R"(
struct tint_symbol {
tint_symbol_1 : i32,
tint_symbol_1 : $other_type,
}
@fragment
@ -1916,31 +1918,22 @@ fn tint_symbol_2() {
INSTANTIATE_TEST_SUITE_P(RenamerBuiltinTypeTest,
RenamerBuiltinTypeTest,
testing::ValuesIn(NonKeywordBuiltinTypes()));
testing::ValuesIn(ConstructableTypes()));
/// @return WGSL builtin identifiers keywords
std::vector<const char*> NonKeywordIdentifiers() {
auto keywords = Keywords();
/// @return WGSL builtin identifier keywords
std::vector<const char*> Identifiers() {
std::vector<const char*> out;
for (auto* ident : type::kBuiltinStrings) {
if (!keywords.count(ident)) {
out.push_back(ident);
}
out.push_back(ident);
}
for (auto* ident : type::kAddressSpaceStrings) {
if (!keywords.count(ident)) {
out.push_back(ident);
}
out.push_back(ident);
}
for (auto* ident : type::kTexelFormatStrings) {
if (!keywords.count(ident)) {
out.push_back(ident);
}
out.push_back(ident);
}
for (auto* ident : type::kAccessStrings) {
if (!keywords.count(ident)) {
out.push_back(ident);
}
out.push_back(ident);
}
return out;
}
@ -2025,12 +2018,14 @@ fn tint_symbol_1() {
TEST_P(RenamerBuiltinIdentifierTest, StructName) {
auto expand = [&](const char* source) {
return utils::ReplaceAll(source, "$name", GetParam());
std::string_view name = GetParam();
auto out = utils::ReplaceAll(source, "$name", name);
return utils::ReplaceAll(out, "$other_type", name == "i32" ? "u32" : "i32");
};
auto src = expand(R"(
struct $name {
i : i32,
i : $other_type,
}
fn f() {
@ -2040,7 +2035,7 @@ fn f() {
auto expect = expand(R"(
struct tint_symbol {
tint_symbol_1 : i32,
tint_symbol_1 : $other_type,
}
fn tint_symbol_2() {
@ -2055,7 +2050,7 @@ fn tint_symbol_2() {
INSTANTIATE_TEST_SUITE_P(RenamerBuiltinIdentifierTest,
RenamerBuiltinIdentifierTest,
testing::ValuesIn(NonKeywordIdentifiers()));
testing::ValuesIn(Identifiers()));
} // namespace
} // namespace tint::transform

View File

@ -1,6 +1,6 @@
diagnostic_filtering/case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/compound_statement_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/compound_statement_attribute.wgsl:7:5 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/compound_statement_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/compound_statement_attribute.wgsl:7:5 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/compound_statement_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/compound_statement_attribute.wgsl:7:5 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/compound_statement_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/compound_statement_attribute.wgsl:7:5 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/compound_statement_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/compound_statement_attribute.wgsl:7:5 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/compound_statement_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/compound_statement_attribute.wgsl:7:5 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/default_case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/default_case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/default_case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/default_case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/default_case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/default_case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/default_case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/default_case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/default_case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/default_case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/default_case_body_attribute.wgsl:8:11 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/default_case_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
switch (i32(x)) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/directive.wgsl:9:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/directive.wgsl:8:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/directive.wgsl:9:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/directive.wgsl:8:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/directive.wgsl:9:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/directive.wgsl:8:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/directive.wgsl:9:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/directive.wgsl:8:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/directive.wgsl:9:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/directive.wgsl:8:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/directive.wgsl:9:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/directive.wgsl:8:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_if_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_if_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_if_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_if_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_if_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/else_if_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/else_if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
for (; x > v.x; ) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Texture2D<float4> t : register(t1, space0);
SamplerState s : register(s2, space0);

View File

@ -1,6 +1,6 @@
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
for (; x > v.x; ) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#version 310 es
precision mediump float;

View File

@ -1,6 +1,6 @@
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
for (; x > v.x; ) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#include <metal_stdlib>

View File

@ -1,6 +1,6 @@
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
for (; x > v.x; ) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
; SPIR-V
; Version: 1.3

View File

@ -1,6 +1,6 @@
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
for (; x > v.x; ) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/for_loop_body_attribute.wgsl:7:3 note: control flow depends
diagnostic_filtering/for_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@group(0) @binding(1) var t : texture_2d<f32>;

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/function_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/function_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/if_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) @diagnostic(warning, derivative_uniformity) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/if_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) @diagnostic(warning, derivative_uniformity) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/if_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) @diagnostic(warning, derivative_uniformity) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/if_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) @diagnostic(warning, derivative_uniformity) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/if_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) @diagnostic(warning, derivative_uniformity) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/if_body_attribute.wgsl:7:9 warning: 'textureSample' must only be called from uniform control flow
_ = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/if_body_attribute.wgsl:6:3 note: control flow depends on possibly non-uniform value
if (x > 0) @diagnostic(warning, derivative_uniformity) {

View File

@ -1,6 +1,6 @@
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
while (x > v.x) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depen
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Texture2D<float4> t : register(t1, space0);
SamplerState s : register(s2, space0);

View File

@ -1,6 +1,6 @@
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
while (x > v.x) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depen
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#version 310 es
precision mediump float;

View File

@ -1,6 +1,6 @@
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
while (x > v.x) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depen
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#include <metal_stdlib>

View File

@ -1,6 +1,6 @@
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
while (x > v.x) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depen
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
; SPIR-V
; Version: 1.3

View File

@ -1,6 +1,6 @@
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 warning: 'textureSample' must only be called from uniform control flow
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depends on possibly non-uniform value
while (x > v.x) @diagnostic(warning, derivative_uniformity) {
@ -8,7 +8,7 @@ diagnostic_filtering/while_loop_body_attribute.wgsl:7:3 note: control flow depen
diagnostic_filtering/while_loop_body_attribute.wgsl:8:9 note: return value of 'textureSample' may be non-uniform
v = textureSample(t, s, vec2(0, 0));
^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@group(0) @binding(1) var t : texture_2d<f32>;

View File

@ -284,6 +284,11 @@ crbug.com/dawn/1500 [ intel-gen-9 monterey ] webgpu:api,operation,command_buffer
################################################################################
crbug.com/dawn/1599 [ webgpu-adapter-swiftshader ] webgpu:web_platform,copyToTexture,canvas:color_space_conversion:* [ Failure ]
################################################################################
# Temporary disabling of types-as-keywords tests
################################################################################
crbug.com/tint/1810 webgpu:shader,validation,parse,identifiers:* [ Failure ]
################################################################################
# untriaged failures
################################################################################