[wgsl-reader] Add support for constant_id decoration
Bug: tint:155 Change-Id: I207fd87d0708c66ea0fe7de81b156db98eea8e60 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/39560 Commit-Queue: dan sinclair <dsinclair@chromium.org> Auto-Submit: James Price <jrprice@google.com> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
3d20d49211
commit
a6ced4d0b4
|
@ -27,6 +27,7 @@
|
|||
#include "src/ast/builtin_decoration.h"
|
||||
#include "src/ast/call_expression.h"
|
||||
#include "src/ast/case_statement.h"
|
||||
#include "src/ast/constant_id_decoration.h"
|
||||
#include "src/ast/continue_statement.h"
|
||||
#include "src/ast/discard_statement.h"
|
||||
#include "src/ast/else_statement.h"
|
||||
|
@ -134,6 +135,7 @@ const char kAccessDecoration[] = "access";
|
|||
const char kBindingDecoration[] = "binding";
|
||||
const char kBlockDecoration[] = "block";
|
||||
const char kBuiltinDecoration[] = "builtin";
|
||||
const char kConstantIdDecoration[] = "constant_id";
|
||||
const char kGroupDecoration[] = "group";
|
||||
const char kLocationDecoration[] = "location";
|
||||
const char kOffsetDecoration[] = "offset";
|
||||
|
@ -149,10 +151,10 @@ bool is_decoration(Token t) {
|
|||
auto s = t.to_str();
|
||||
return s == kAccessDecoration || s == kBindingDecoration ||
|
||||
s == kBlockDecoration || s == kBuiltinDecoration ||
|
||||
s == kLocationDecoration || s == kOffsetDecoration ||
|
||||
s == kSetDecoration || s == kGroupDecoration ||
|
||||
s == kStageDecoration || s == kStrideDecoration ||
|
||||
s == kWorkgroupSizeDecoration;
|
||||
s == kConstantIdDecoration || s == kLocationDecoration ||
|
||||
s == kOffsetDecoration || s == kSetDecoration ||
|
||||
s == kGroupDecoration || s == kStageDecoration ||
|
||||
s == kStrideDecoration || s == kWorkgroupSizeDecoration;
|
||||
}
|
||||
|
||||
/// Enter-exit counters for block token types.
|
||||
|
@ -323,7 +325,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto gc = global_constant_decl();
|
||||
auto gc = global_constant_decl(decos.value);
|
||||
if (gc.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
|
@ -441,8 +443,9 @@ Maybe<ast::Variable*> ParserImpl::global_variable_decl(
|
|||
}
|
||||
|
||||
// global_constant_decl
|
||||
// : CONST variable_ident_decl EQUAL const_expr
|
||||
Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
|
||||
// : variable_decoration_list* CONST variable_ident_decl EQUAL const_expr
|
||||
Maybe<ast::Variable*> ParserImpl::global_constant_decl(
|
||||
ast::DecorationList& decos) {
|
||||
if (!match(Token::Type::kConst))
|
||||
return Failure::kNoMatch;
|
||||
|
||||
|
@ -459,6 +462,10 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
|
|||
if (init.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
auto var_decos = cast_decorations<ast::VariableDecoration>(decos);
|
||||
if (var_decos.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::Variable>(
|
||||
decl->source, // source
|
||||
builder_.Symbols().Register(decl->name), // symbol
|
||||
|
@ -466,7 +473,7 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
|
|||
decl->type, // type
|
||||
true, // is_const
|
||||
init.value, // constructor
|
||||
ast::VariableDecorationList{}); // decorations
|
||||
std::move(var_decos.value)); // decorations
|
||||
}
|
||||
|
||||
// variable_decl
|
||||
|
@ -2939,6 +2946,17 @@ Maybe<ast::Decoration*> ParserImpl::decoration() {
|
|||
});
|
||||
}
|
||||
|
||||
if (s == kConstantIdDecoration) {
|
||||
const char* use = "constant_id decoration";
|
||||
return expect_paren_block(use, [&]() -> Result {
|
||||
auto val = expect_positive_sint(use);
|
||||
if (val.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::ConstantIdDecoration>(t.source(), val.value);
|
||||
});
|
||||
}
|
||||
|
||||
return Failure::kNoMatch;
|
||||
}
|
||||
|
||||
|
|
|
@ -365,9 +365,11 @@ class ParserImpl {
|
|||
/// @returns the variable parsed or nullptr
|
||||
/// @param decos the list of decorations for the variable declaration.
|
||||
Maybe<ast::Variable*> global_variable_decl(ast::DecorationList& decos);
|
||||
/// Parses a `global_constant_decl` grammar element
|
||||
/// Parses a `global_constant_decl` grammar element with the initial
|
||||
/// `variable_decoration_list*` provided as `decos`
|
||||
/// @returns the const object or nullptr
|
||||
Maybe<ast::Variable*> global_constant_decl();
|
||||
/// @param decos the list of decorations for the constant declaration.
|
||||
Maybe<ast::Variable*> global_constant_decl(ast::DecorationList& decos);
|
||||
/// Parses a `variable_decl` grammar element
|
||||
/// @returns the parsed variable declaration info
|
||||
Maybe<VarDeclInfo> variable_decl();
|
||||
|
|
|
@ -26,7 +26,10 @@ namespace {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl) {
|
||||
auto p = parser("const a : f32 = 1.");
|
||||
auto e = p->global_constant_decl();
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
|
@ -44,11 +47,16 @@ TEST_F(ParserImplTest, GlobalConstantDecl) {
|
|||
|
||||
ASSERT_NE(e->constructor(), nullptr);
|
||||
EXPECT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
|
||||
|
||||
EXPECT_FALSE(e.value->HasConstantIdDecoration());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl_MissingEqual) {
|
||||
auto p = parser("const a: f32 1.");
|
||||
auto e = p->global_constant_decl();
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
|
@ -58,7 +66,10 @@ TEST_F(ParserImplTest, GlobalConstantDecl_MissingEqual) {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl_InvalidVariable) {
|
||||
auto p = parser("const a: invalid = 1.");
|
||||
auto e = p->global_constant_decl();
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
|
@ -68,7 +79,10 @@ TEST_F(ParserImplTest, GlobalConstantDecl_InvalidVariable) {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
|
||||
auto p = parser("const a: f32 = if (a) {}");
|
||||
auto e = p->global_constant_decl();
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
|
@ -78,7 +92,10 @@ TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
|
|||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
|
||||
auto p = parser("const a: f32 =");
|
||||
auto e = p->global_constant_decl();
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
|
@ -86,6 +103,66 @@ TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
|
|||
EXPECT_EQ(p->error(), "1:15: unable to parse const literal");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalConstantDec_ConstantId) {
|
||||
auto p = parser("[[constant_id(7)]] const a : f32 = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_TRUE(decos.matched);
|
||||
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
|
||||
EXPECT_TRUE(e->is_const());
|
||||
EXPECT_EQ(e->symbol(), p->builder().Symbols().Get("a"));
|
||||
ASSERT_NE(e->type(), nullptr);
|
||||
EXPECT_TRUE(e->type()->Is<type::F32>());
|
||||
|
||||
EXPECT_EQ(e->source().range.begin.line, 1u);
|
||||
EXPECT_EQ(e->source().range.begin.column, 26u);
|
||||
EXPECT_EQ(e->source().range.end.line, 1u);
|
||||
EXPECT_EQ(e->source().range.end.column, 27u);
|
||||
|
||||
ASSERT_NE(e->constructor(), nullptr);
|
||||
EXPECT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
|
||||
|
||||
EXPECT_TRUE(e.value->HasConstantIdDecoration());
|
||||
EXPECT_EQ(e.value->constant_id(), 7u);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalConstantDec_ConstantId_Missing) {
|
||||
auto p = parser("[[constant_id()]] const a : f32 = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_TRUE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(),
|
||||
"1:15: expected signed integer literal for constant_id decoration");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalConstantDec_ConstantId_Invalid) {
|
||||
auto p = parser("[[constant_id(-7)]] const a : f32 = 1.");
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_TRUE(decos.errored);
|
||||
EXPECT_FALSE(decos.matched);
|
||||
|
||||
auto e = p->global_constant_decl(decos.value);
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), "1:15: constant_id decoration must be positive");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace wgsl
|
||||
} // namespace reader
|
||||
|
|
Loading…
Reference in New Issue