reader/wgsl: Parse atomic<T> types
Bug: tint:892 Change-Id: Ib6338ee78fccfca339f53c9074671f89bae1537f Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54645 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
8c7f0da8c8
commit
989c3a1811
|
@ -474,6 +474,8 @@ Token Lexer::try_punctuation() {
|
||||||
Token Lexer::check_keyword(const Source& source, const std::string& str) {
|
Token Lexer::check_keyword(const Source& source, const std::string& str) {
|
||||||
if (str == "array")
|
if (str == "array")
|
||||||
return {Token::Type::kArray, source, "array"};
|
return {Token::Type::kArray, source, "array"};
|
||||||
|
if (str == "atomic")
|
||||||
|
return {Token::Type::kAtomic, source, "atomic"};
|
||||||
if (str == "bitcast")
|
if (str == "bitcast")
|
||||||
return {Token::Type::kBitcast, source, "bitcast"};
|
return {Token::Type::kBitcast, source, "bitcast"};
|
||||||
if (str == "bool")
|
if (str == "bool")
|
||||||
|
|
|
@ -1063,8 +1063,13 @@ Maybe<ast::Type*> ParserImpl::type_decl(ast::DecorationList& decos) {
|
||||||
return expect_type_decl_vector(t);
|
return expect_type_decl_vector(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match(Token::Type::kPtr))
|
if (match(Token::Type::kPtr)) {
|
||||||
return expect_type_decl_pointer(t);
|
return expect_type_decl_pointer(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match(Token::Type::kAtomic)) {
|
||||||
|
return expect_type_decl_atomic(t);
|
||||||
|
}
|
||||||
|
|
||||||
if (match(Token::Type::kArray, &source)) {
|
if (match(Token::Type::kArray, &source)) {
|
||||||
return expect_type_decl_array(t, std::move(decos));
|
return expect_type_decl_array(t, std::move(decos));
|
||||||
|
@ -1136,6 +1141,17 @@ Expect<ast::Type*> ParserImpl::expect_type_decl_pointer(Token t) {
|
||||||
storage_class, access);
|
storage_class, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expect<ast::Type*> ParserImpl::expect_type_decl_atomic(Token t) {
|
||||||
|
const char* use = "atomic declaration";
|
||||||
|
|
||||||
|
auto subtype = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
||||||
|
if (subtype.errored) {
|
||||||
|
return Failure::kErrored;
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder_.ty.atomic(make_source_range_from(t.source()), subtype.value);
|
||||||
|
}
|
||||||
|
|
||||||
Expect<ast::Type*> ParserImpl::expect_type_decl_vector(Token t) {
|
Expect<ast::Type*> ParserImpl::expect_type_decl_vector(Token t) {
|
||||||
uint32_t count = 2;
|
uint32_t count = 2;
|
||||||
if (t.IsVec3())
|
if (t.IsVec3())
|
||||||
|
|
|
@ -843,6 +843,7 @@ class ParserImpl {
|
||||||
bool expect_decorations_consumed(const ast::DecorationList& list);
|
bool expect_decorations_consumed(const ast::DecorationList& list);
|
||||||
|
|
||||||
Expect<ast::Type*> expect_type_decl_pointer(Token t);
|
Expect<ast::Type*> expect_type_decl_pointer(Token t);
|
||||||
|
Expect<ast::Type*> expect_type_decl_atomic(Token t);
|
||||||
Expect<ast::Type*> expect_type_decl_vector(Token t);
|
Expect<ast::Type*> expect_type_decl_vector(Token t);
|
||||||
Expect<ast::Type*> expect_type_decl_array(Token t, ast::DecorationList decos);
|
Expect<ast::Type*> expect_type_decl_array(Token t, ast::DecorationList decos);
|
||||||
Expect<ast::Type*> expect_type_decl_matrix(Token t);
|
Expect<ast::Type*> expect_type_decl_matrix(Token t);
|
||||||
|
|
|
@ -1023,6 +1023,20 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingType) {
|
||||||
" ^\n");
|
" ^\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAtomicMissingLessThan) {
|
||||||
|
EXPECT("var i : atomic;",
|
||||||
|
"test.wgsl:1:15 error: expected '<' for atomic declaration\n"
|
||||||
|
"var i : atomic;\n"
|
||||||
|
" ^\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAtomicMissingGreaterThan) {
|
||||||
|
EXPECT("var i : atomic<u32 x;",
|
||||||
|
"test.wgsl:1:20 error: expected '>' for atomic declaration\n"
|
||||||
|
"var i : atomic<u32 x;\n"
|
||||||
|
" ^\n");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclInvalidClass) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclInvalidClass) {
|
||||||
EXPECT("var<fish> i : i32",
|
EXPECT("var<fish> i : i32",
|
||||||
"test.wgsl:1:5 error: invalid storage class for variable declaration\n"
|
"test.wgsl:1:5 error: invalid storage class for variable declaration\n"
|
||||||
|
|
|
@ -378,6 +378,68 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_BadAccess) {
|
||||||
ASSERT_EQ(p->error(), "1:20: invalid value for access control");
|
ASSERT_EQ(p->error(), "1:20: invalid value for access control");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, TypeDecl_Atomic) {
|
||||||
|
auto p = parser("atomic<f32>");
|
||||||
|
auto t = p->type_decl();
|
||||||
|
EXPECT_TRUE(t.matched);
|
||||||
|
EXPECT_FALSE(t.errored);
|
||||||
|
ASSERT_NE(t.value, nullptr) << p->error();
|
||||||
|
ASSERT_FALSE(p->has_error());
|
||||||
|
ASSERT_TRUE(t.value->Is<ast::Atomic>());
|
||||||
|
|
||||||
|
auto* atomic = t.value->As<ast::Atomic>();
|
||||||
|
ASSERT_TRUE(atomic->type()->Is<ast::F32>());
|
||||||
|
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 12u}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, TypeDecl_Atomic_ToVec) {
|
||||||
|
auto p = parser("atomic<vec2<f32>>");
|
||||||
|
auto t = p->type_decl();
|
||||||
|
EXPECT_TRUE(t.matched);
|
||||||
|
EXPECT_FALSE(t.errored);
|
||||||
|
ASSERT_NE(t.value, nullptr) << p->error();
|
||||||
|
ASSERT_FALSE(p->has_error());
|
||||||
|
ASSERT_TRUE(t.value->Is<ast::Atomic>());
|
||||||
|
|
||||||
|
auto* atomic = t.value->As<ast::Atomic>();
|
||||||
|
ASSERT_TRUE(atomic->type()->Is<ast::Vector>());
|
||||||
|
|
||||||
|
auto* vec = atomic->type()->As<ast::Vector>();
|
||||||
|
ASSERT_EQ(vec->size(), 2u);
|
||||||
|
ASSERT_TRUE(vec->type()->Is<ast::F32>());
|
||||||
|
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_decl();
|
||||||
|
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_decl();
|
||||||
|
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 atomic declaration");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, TypeDecl_Atomic_MissingType) {
|
||||||
|
auto p = parser("atomic<>");
|
||||||
|
auto t = p->type_decl();
|
||||||
|
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, TypeDecl_Array) {
|
TEST_F(ParserImplTest, TypeDecl_Array) {
|
||||||
auto p = parser("array<f32, 5>");
|
auto p = parser("array<f32, 5>");
|
||||||
auto t = p->type_decl();
|
auto t = p->type_decl();
|
||||||
|
|
|
@ -109,6 +109,8 @@ std::string Token::TypeToName(Type type) {
|
||||||
|
|
||||||
case Token::Type::kArray:
|
case Token::Type::kArray:
|
||||||
return "array";
|
return "array";
|
||||||
|
case Token::Type::kAtomic:
|
||||||
|
return "atomic";
|
||||||
case Token::Type::kBitcast:
|
case Token::Type::kBitcast:
|
||||||
return "bitcast";
|
return "bitcast";
|
||||||
case Token::Type::kBool:
|
case Token::Type::kBool:
|
||||||
|
|
|
@ -117,6 +117,8 @@ class Token {
|
||||||
|
|
||||||
/// A 'array'
|
/// A 'array'
|
||||||
kArray,
|
kArray,
|
||||||
|
/// A 'atomic'
|
||||||
|
kAtomic,
|
||||||
/// A 'bitcast'
|
/// A 'bitcast'
|
||||||
kBitcast,
|
kBitcast,
|
||||||
/// A 'bool'
|
/// A 'bool'
|
||||||
|
|
|
@ -943,7 +943,7 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestMsl,
|
||||||
// "array", // Also used in WGSL
|
// "array", // Also used in WGSL
|
||||||
"array_ref",
|
"array_ref",
|
||||||
"as_type",
|
"as_type",
|
||||||
"atomic",
|
// "atomic", // Also used in WGSL
|
||||||
"atomic_bool",
|
"atomic_bool",
|
||||||
"atomic_int",
|
"atomic_int",
|
||||||
"atomic_uint",
|
"atomic_uint",
|
||||||
|
|
Loading…
Reference in New Issue