Update WGSL grammar builtins to match spec.

This CL removes the builtin_decoration from the parser in favour of
using IDENT tokens for builtins. We still convert to an enum in the
parser and validate the value provided.

Bug: tint:41
Change-Id: If5dc3844e3325c75951e7b320c123cf66cb8e106
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/22300
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
dan sinclair 2020-06-01 13:43:11 +00:00 committed by dan sinclair
parent 0647d23607
commit 1d2ad81eb9
11 changed files with 112 additions and 277 deletions

View File

@ -732,7 +732,6 @@ source_set("tint_unittests_wgsl_reader_src") {
"src/reader/wgsl/parser_impl_assignment_stmt_test.cc",
"src/reader/wgsl/parser_impl_body_stmt_test.cc",
"src/reader/wgsl/parser_impl_break_stmt_test.cc",
"src/reader/wgsl/parser_impl_builtin_decoration_test.cc",
"src/reader/wgsl/parser_impl_case_body_test.cc",
"src/reader/wgsl/parser_impl_const_expr_test.cc",
"src/reader/wgsl/parser_impl_const_literal_test.cc",

View File

@ -363,7 +363,6 @@ if(${TINT_BUILD_WGSL_READER})
reader/wgsl/parser_impl_assignment_stmt_test.cc
reader/wgsl/parser_impl_body_stmt_test.cc
reader/wgsl/parser_impl_break_stmt_test.cc
reader/wgsl/parser_impl_builtin_decoration_test.cc
reader/wgsl/parser_impl_case_body_test.cc
reader/wgsl/parser_impl_const_expr_test.cc
reader/wgsl/parser_impl_const_literal_test.cc

View File

@ -524,20 +524,12 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
return {Token::Type::kFine, source, "fine"};
if (str == "fn")
return {Token::Type::kFn, source, "fn"};
if (str == "frag_coord")
return {Token::Type::kFragCoord, source, "frag_coord"};
if (str == "frag_depth")
return {Token::Type::kFragDepth, source, "frag_depth"};
if (str == "fragment")
return {Token::Type::kFragment, source, "fragment"};
if (str == "front_facing")
return {Token::Type::kFrontFacing, source, "front_facing"};
if (str == "function")
return {Token::Type::kFunction, source, "function"};
if (str == "fwidth")
return {Token::Type::kFwidth, source, "fwidth"};
if (str == "global_invocation_id")
return {Token::Type::kGlobalInvocationId, source, "global_invocation_id"};
if (str == "i32")
return {Token::Type::kI32, source, "i32"};
if (str == "if")
@ -548,8 +540,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
return {Token::Type::kImport, source, "import"};
if (str == "in")
return {Token::Type::kIn, source, "in"};
if (str == "instance_idx")
return {Token::Type::kInstanceIdx, source, "instance_idx"};
if (str == "is_nan")
return {Token::Type::kIsNan, source, "is_nan"};
if (str == "is_inf")
@ -560,10 +550,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
return {Token::Type::kIsNormal, source, "is_normal"};
if (str == "kill")
return {Token::Type::kKill, source, "kill"};
if (str == "local_invocation_id")
return {Token::Type::kLocalInvocationId, source, "local_invocation_id"};
if (str == "local_invocation_idx")
return {Token::Type::kLocalInvocationIdx, source, "local_invocation_idx"};
if (str == "location")
return {Token::Type::kLocation, source, "location"};
if (str == "loop")
@ -586,16 +572,12 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
return {Token::Type::kMat4x3, source, "mat4x3"};
if (str == "mat4x4")
return {Token::Type::kMat4x4, source, "mat4x4"};
if (str == "num_workgroups")
return {Token::Type::kNumWorkgroups, source, "num_workgroups"};
if (str == "offset")
return {Token::Type::kOffset, source, "offset"};
if (str == "out")
return {Token::Type::kOut, source, "out"};
if (str == "outer_product")
return {Token::Type::kOuterProduct, source, "outer_product"};
if (str == "position")
return {Token::Type::kPosition, source, "position"};
if (str == "private")
return {Token::Type::kPrivate, source, "private"};
if (str == "ptr")
@ -632,14 +614,10 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
return {Token::Type::kVec4, source, "vec4"};
if (str == "vertex")
return {Token::Type::kVertex, source, "vertex"};
if (str == "vertex_idx")
return {Token::Type::kVertexIdx, source, "vertex_idx"};
if (str == "void")
return {Token::Type::kVoid, source, "void"};
if (str == "workgroup")
return {Token::Type::kWorkgroup, source, "workgroup"};
if (str == "workgroup_size")
return {Token::Type::kWorkgroupSize, source, "workgroup_size"};
return {};
}

View File

@ -437,26 +437,19 @@ INSTANTIATE_TEST_SUITE_P(
TokenData{"false", Token::Type::kFalse},
TokenData{"fine", Token::Type::kFine},
TokenData{"fn", Token::Type::kFn},
TokenData{"frag_coord", Token::Type::kFragCoord},
TokenData{"frag_depth", Token::Type::kFragDepth},
TokenData{"fragment", Token::Type::kFragment},
TokenData{"front_facing", Token::Type::kFrontFacing},
TokenData{"function", Token::Type::kFunction},
TokenData{"fwidth", Token::Type::kFwidth},
TokenData{"global_invocation_id", Token::Type::kGlobalInvocationId},
TokenData{"i32", Token::Type::kI32},
TokenData{"if", Token::Type::kIf},
TokenData{"image", Token::Type::kImage},
TokenData{"import", Token::Type::kImport},
TokenData{"in", Token::Type::kIn},
TokenData{"instance_idx", Token::Type::kInstanceIdx},
TokenData{"is_nan", Token::Type::kIsNan},
TokenData{"is_inf", Token::Type::kIsInf},
TokenData{"is_finite", Token::Type::kIsFinite},
TokenData{"is_normal", Token::Type::kIsNormal},
TokenData{"kill", Token::Type::kKill},
TokenData{"local_invocation_id", Token::Type::kLocalInvocationId},
TokenData{"local_invocation_idx", Token::Type::kLocalInvocationIdx},
TokenData{"location", Token::Type::kLocation},
TokenData{"loop", Token::Type::kLoop},
TokenData{"mat2x2", Token::Type::kMat2x2},
@ -468,11 +461,9 @@ INSTANTIATE_TEST_SUITE_P(
TokenData{"mat4x2", Token::Type::kMat4x2},
TokenData{"mat4x3", Token::Type::kMat4x3},
TokenData{"mat4x4", Token::Type::kMat4x4},
TokenData{"num_workgroups", Token::Type::kNumWorkgroups},
TokenData{"offset", Token::Type::kOffset},
TokenData{"out", Token::Type::kOut},
TokenData{"outer_product", Token::Type::kOuterProduct},
TokenData{"position", Token::Type::kPosition},
TokenData{"private", Token::Type::kPrivate},
TokenData{"ptr", Token::Type::kPtr},
TokenData{"return", Token::Type::kReturn},
@ -491,10 +482,8 @@ INSTANTIATE_TEST_SUITE_P(
TokenData{"vec3", Token::Type::kVec3},
TokenData{"vec4", Token::Type::kVec4},
TokenData{"vertex", Token::Type::kVertex},
TokenData{"vertex_idx", Token::Type::kVertexIdx},
TokenData{"void", Token::Type::kVoid},
TokenData{"workgroup", Token::Type::kWorkgroup},
TokenData{"workgroup_size", Token::Type::kWorkgroupSize}));
TokenData{"workgroup", Token::Type::kWorkgroup}));
using KeywordTest_Reserved = testing::TestWithParam<const char*>;
TEST_P(KeywordTest_Reserved, Parses) {

View File

@ -70,6 +70,46 @@
namespace tint {
namespace reader {
namespace wgsl {
namespace {
ast::Builtin ident_to_builtin(const std::string& str) {
if (str == "position") {
return ast::Builtin::kPosition;
}
if (str == "vertex_idx") {
return ast::Builtin::kVertexIdx;
}
if (str == "instance_idx") {
return ast::Builtin::kInstanceIdx;
}
if (str == "front_facing") {
return ast::Builtin::kFrontFacing;
}
if (str == "frag_coord") {
return ast::Builtin::kFragCoord;
}
if (str == "frag_depth") {
return ast::Builtin::kFragDepth;
}
if (str == "num_workgroups") {
return ast::Builtin::kNumWorkgroups;
}
if (str == "workgroup_size") {
return ast::Builtin::kWorkgroupSize;
}
if (str == "local_invocation_id") {
return ast::Builtin::kLocalInvocationId;
}
if (str == "local_invocation_idx") {
return ast::Builtin::kLocalInvocationIdx;
}
if (str == "global_invocation_id") {
return ast::Builtin::kGlobalInvocationId;
}
return ast::Builtin::kNone;
}
} // namespace
ParserImpl::ParserImpl(Context* ctx, const std::string& input)
: ctx_(*ctx), lexer_(std::make_unique<Lexer>(input)) {}
@ -395,7 +435,7 @@ std::unique_ptr<ast::Variable> ParserImpl::global_constant_decl() {
}
// variable_decoration_list
// : ATTR_LEFT variable_decoration (COMMA variable_decoration)* ATTR_RIGHT
// : ATTR_LEFT (variable_decoration COMMA)* variable_decoration ATTR_RIGHT
ast::VariableDecorationList ParserImpl::variable_decoration_list() {
ast::VariableDecorationList decos;
@ -452,7 +492,7 @@ ast::VariableDecorationList ParserImpl::variable_decoration_list() {
// variable_decoration
// : LOCATION INT_LITERAL
// | BUILTIN builtin_decoration
// | BUILTIN IDENT
// | BINDING INT_LITERAL
// | SET INT_LITERAL
std::unique_ptr<ast::VariableDecoration> ParserImpl::variable_decoration() {
@ -471,11 +511,15 @@ std::unique_ptr<ast::VariableDecoration> ParserImpl::variable_decoration() {
if (t.IsBuiltin()) {
next(); // consume the peek
ast::Builtin builtin = builtin_decoration();
if (has_error())
t = next();
if (!t.IsIdentifier() || t.to_str().empty()) {
set_error(t, "expected identifier for builtin");
return {};
}
ast::Builtin builtin = ident_to_builtin(t.to_str());
if (builtin == ast::Builtin::kNone) {
set_error(peek(), "invalid value for builtin decoration");
set_error(t, "invalid value for builtin decoration");
return {};
}
@ -507,67 +551,6 @@ std::unique_ptr<ast::VariableDecoration> ParserImpl::variable_decoration() {
return nullptr;
}
// builtin_decoration
// : POSITION
// | VERTEX_IDX
// | INSTANCE_IDX
// | FRONT_FACING
// | FRAG_COORD
// | FRAG_DEPTH
// | NUM_WORKGROUPS
// | WORKGROUP_SIZE
// | LOCAL_INVOC_ID
// | LOCAL_INVOC_IDX
// | GLOBAL_INVOC_ID
ast::Builtin ParserImpl::builtin_decoration() {
auto t = peek();
if (t.IsPosition()) {
next(); // consume the peek
return ast::Builtin::kPosition;
}
if (t.IsVertexIdx()) {
next(); // consume the peek
return ast::Builtin::kVertexIdx;
}
if (t.IsInstanceIdx()) {
next(); // consume the peek
return ast::Builtin::kInstanceIdx;
}
if (t.IsFrontFacing()) {
next(); // consume the peek
return ast::Builtin::kFrontFacing;
}
if (t.IsFragCoord()) {
next(); // consume the peek
return ast::Builtin::kFragCoord;
}
if (t.IsFragDepth()) {
next(); // consume the peek
return ast::Builtin::kFragDepth;
}
if (t.IsNumWorkgroups()) {
next(); // consume the peek
return ast::Builtin::kNumWorkgroups;
}
if (t.IsWorkgroupSize()) {
next(); // consume the peek
return ast::Builtin::kWorkgroupSize;
}
if (t.IsLocalInvocationId()) {
next(); // consume the peek
return ast::Builtin::kLocalInvocationId;
}
if (t.IsLocalInvocationIdx()) {
next(); // consume the peek
return ast::Builtin::kLocalInvocationIdx;
}
if (t.IsGlobalInvocationId()) {
next(); // consume the peek
return ast::Builtin::kGlobalInvocationId;
}
return ast::Builtin::kNone;
}
// variable_decl
// : VAR variable_storage_decoration? variable_ident_decl
std::unique_ptr<ast::Variable> ParserImpl::variable_decl() {

View File

@ -117,9 +117,6 @@ class ParserImpl {
/// Parses a `variable_decoration` grammar element
/// @returns the variable decoration or nullptr if an error is encountered
std::unique_ptr<ast::VariableDecoration> variable_decoration();
/// Parses a `builtin_decoration` grammar element
/// @returns the builtin or Builtin::kNone if none matched
ast::Builtin builtin_decoration();
/// Parses a `variable_decl` grammar element
/// @returns the parsed variable or nullptr otherwise
std::unique_ptr<ast::Variable> variable_decl();

View File

@ -1,94 +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 "gtest/gtest.h"
#include "src/ast/builtin.h"
#include "src/reader/wgsl/parser_impl.h"
#include "src/reader/wgsl/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace wgsl {
namespace {
struct BuiltinData {
const char* input;
ast::Builtin result;
};
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
out << std::string(data.input);
return out;
}
class BuiltinTest : public testing::TestWithParam<BuiltinData> {
public:
BuiltinTest() = default;
~BuiltinTest() override = default;
void SetUp() override { ctx_.Reset(); }
void TearDown() override { impl_ = nullptr; }
ParserImpl* parser(const std::string& str) {
impl_ = std::make_unique<ParserImpl>(&ctx_, str);
return impl_.get();
}
private:
std::unique_ptr<ParserImpl> impl_;
Context ctx_;
};
TEST_P(BuiltinTest, Parses) {
auto params = GetParam();
auto* p = parser(params.input);
auto builtin = p->builtin_decoration();
ASSERT_FALSE(p->has_error());
EXPECT_EQ(builtin, params.result);
auto t = p->next();
EXPECT_TRUE(t.IsEof());
}
INSTANTIATE_TEST_SUITE_P(
ParserImplTest,
BuiltinTest,
testing::Values(
BuiltinData{"position", ast::Builtin::kPosition},
BuiltinData{"vertex_idx", ast::Builtin::kVertexIdx},
BuiltinData{"instance_idx", ast::Builtin::kInstanceIdx},
BuiltinData{"front_facing", ast::Builtin::kFrontFacing},
BuiltinData{"frag_coord", ast::Builtin::kFragCoord},
BuiltinData{"frag_depth", ast::Builtin::kFragDepth},
BuiltinData{"num_workgroups", ast::Builtin::kNumWorkgroups},
BuiltinData{"workgroup_size", ast::Builtin::kWorkgroupSize},
BuiltinData{"local_invocation_id", ast::Builtin::kLocalInvocationId},
BuiltinData{"local_invocation_idx", ast::Builtin::kLocalInvocationIdx},
BuiltinData{"global_invocation_id",
ast::Builtin::kGlobalInvocationId}));
TEST_F(ParserImplTest, BuiltinDecoration_NoMatch) {
auto* p = parser("not-a-builtin");
auto builtin = p->builtin_decoration();
ASSERT_EQ(builtin, ast::Builtin::kNone);
auto t = p->next();
EXPECT_TRUE(t.IsIdentifier());
EXPECT_EQ(t.to_str(), "not");
}
} // namespace
} // namespace wgsl
} // namespace reader
} // namespace tint

View File

@ -26,7 +26,7 @@ namespace {
TEST_F(ParserImplTest, VariableDecorationList_Parses) {
auto* p = parser(R"([[location 4, builtin position]])");
auto decos = p->variable_decoration_list();
ASSERT_FALSE(p->has_error());
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_EQ(decos.size(), 2u);
ASSERT_TRUE(decos[0]->IsLocation());
EXPECT_EQ(decos[0]->AsLocation()->value(), 4u);

View File

@ -52,23 +52,77 @@ TEST_F(ParserImplTest, VariableDecoration_Location_MissingInvalid) {
EXPECT_EQ(p->error(), "1:10: invalid value for location decoration");
}
TEST_F(ParserImplTest, VariableDecoration_Builtin) {
auto* p = parser("builtin frag_depth");
struct BuiltinData {
const char* input;
ast::Builtin result;
};
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
out << std::string(data.input);
return out;
}
class BuiltinTest : public testing::TestWithParam<BuiltinData> {
public:
BuiltinTest() = default;
~BuiltinTest() override = default;
void SetUp() override { ctx_.Reset(); }
void TearDown() override { impl_ = nullptr; }
ParserImpl* parser(const std::string& str) {
impl_ = std::make_unique<ParserImpl>(&ctx_, str);
return impl_.get();
}
private:
std::unique_ptr<ParserImpl> impl_;
Context ctx_;
};
TEST_P(BuiltinTest, VariableDecoration_Builtin) {
auto params = GetParam();
auto* p = parser(std::string("builtin ") + params.input);
auto deco = p->variable_decoration();
ASSERT_FALSE(p->has_error());
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(deco, nullptr);
ASSERT_TRUE(deco->IsBuiltin());
auto* builtin = deco->AsBuiltin();
EXPECT_EQ(builtin->value(), ast::Builtin::kFragDepth);
EXPECT_EQ(builtin->value(), params.result);
}
INSTANTIATE_TEST_SUITE_P(
ParserImplTest,
BuiltinTest,
testing::Values(
BuiltinData{"position", ast::Builtin::kPosition},
BuiltinData{"vertex_idx", ast::Builtin::kVertexIdx},
BuiltinData{"instance_idx", ast::Builtin::kInstanceIdx},
BuiltinData{"front_facing", ast::Builtin::kFrontFacing},
BuiltinData{"frag_coord", ast::Builtin::kFragCoord},
BuiltinData{"frag_depth", ast::Builtin::kFragDepth},
BuiltinData{"num_workgroups", ast::Builtin::kNumWorkgroups},
BuiltinData{"workgroup_size", ast::Builtin::kWorkgroupSize},
BuiltinData{"local_invocation_id", ast::Builtin::kLocalInvocationId},
BuiltinData{"local_invocation_idx", ast::Builtin::kLocalInvocationIdx},
BuiltinData{"global_invocation_id",
ast::Builtin::kGlobalInvocationId}));
TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingValue) {
auto* p = parser("builtin");
auto deco = p->variable_decoration();
ASSERT_EQ(deco, nullptr);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:8: invalid value for builtin decoration");
EXPECT_EQ(p->error(), "1:8: expected identifier for builtin");
}
TEST_F(ParserImplTest, VariableDecoration_Builtin_InvalidValue) {
auto* p = parser("builtin other_thingy");
auto deco = p->variable_decoration();
ASSERT_EQ(deco, nullptr);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:9: invalid value for builtin decoration");
}
TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingInvalid) {
@ -76,7 +130,7 @@ TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingInvalid) {
auto deco = p->variable_decoration();
ASSERT_EQ(deco, nullptr);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:9: invalid value for builtin decoration");
EXPECT_EQ(p->error(), "1:9: expected identifier for builtin");
}
TEST_F(ParserImplTest, VariableDecoration_Binding) {

View File

@ -161,20 +161,12 @@ std::string Token::TypeToName(Type type) {
return "fine";
case Token::Type::kFn:
return "fn";
case Token::Type::kFragCoord:
return "frag_coord";
case Token::Type::kFragDepth:
return "frag_depth";
case Token::Type::kFragment:
return "fragment";
case Token::Type::kFrontFacing:
return "front_facing";
case Token::Type::kFunction:
return "function";
case Token::Type::kFwidth:
return "fwidth";
case Token::Type::kGlobalInvocationId:
return "global_invocation_id";
case Token::Type::kI32:
return "i32";
case Token::Type::kIf:
@ -185,8 +177,6 @@ std::string Token::TypeToName(Type type) {
return "import";
case Token::Type::kIn:
return "in";
case Token::Type::kInstanceIdx:
return "instance_idx";
case Token::Type::kIsNan:
return "is_nan";
case Token::Type::kIsInf:
@ -197,10 +187,6 @@ std::string Token::TypeToName(Type type) {
return "is_normal";
case Token::Type::kKill:
return "kill";
case Token::Type::kLocalInvocationId:
return "local_invocation_id";
case Token::Type::kLocalInvocationIdx:
return "local_invocation_idx";
case Token::Type::kLocation:
return "location";
case Token::Type::kLoop:
@ -223,16 +209,12 @@ std::string Token::TypeToName(Type type) {
return "mat4x3";
case Token::Type::kMat4x4:
return "mat4x4";
case Token::Type::kNumWorkgroups:
return "num_workgroups";
case Token::Type::kOffset:
return "offset";
case Token::Type::kOut:
return "out";
case Token::Type::kOuterProduct:
return "outer_product";
case Token::Type::kPosition:
return "position";
case Token::Type::kPremerge:
return "premerge";
case Token::Type::kPrivate:
@ -273,14 +255,10 @@ std::string Token::TypeToName(Type type) {
return "vec4";
case Token::Type::kVertex:
return "vertex";
case Token::Type::kVertexIdx:
return "vertex_idx";
case Token::Type::kVoid:
return "void";
case Token::Type::kWorkgroup:
return "workgroup";
case Token::Type::kWorkgroupSize:
return "workgroup_size";
}
return "<unknown>";

View File

@ -172,20 +172,12 @@ class Token {
kFine,
/// A 'fn'
kFn,
/// A 'frag_coord'
kFragCoord,
// A 'frag_depth'
kFragDepth,
/// A 'fragment'
kFragment,
/// A 'front_facing'
kFrontFacing,
/// A 'function'
kFunction,
/// A 'fwidth'
kFwidth,
/// A 'global_invocation_id'
kGlobalInvocationId,
/// A 'i32'
kI32,
/// A 'if'
@ -196,8 +188,6 @@ class Token {
kImport,
/// A 'in'
kIn,
/// A 'instance_idx'
kInstanceIdx,
/// A 'is_nan'
kIsNan,
/// A 'is_inf'
@ -208,10 +198,6 @@ class Token {
kIsNormal,
/// A 'kill'
kKill,
/// A 'local_invocation_id'
kLocalInvocationId,
/// A 'local_invocation_idx'
kLocalInvocationIdx,
/// A 'location'
kLocation,
/// A 'loop'
@ -234,16 +220,12 @@ class Token {
kMat4x3,
/// A 'mat4x4'
kMat4x4,
/// A 'num_workgroups'
kNumWorkgroups,
/// A 'offset'
kOffset,
/// A 'out'
kOut,
/// A 'outer_product'
kOuterProduct,
/// A 'position'
kPosition,
/// A 'premerge'
kPremerge,
/// A 'private'
@ -284,14 +266,10 @@ class Token {
kVec4,
/// A 'vertex'
kVertex,
/// A 'vertex_idx'
kVertexIdx,
/// A 'void'
kVoid,
/// A 'workgroup'
kWorkgroup,
/// A 'workgroup_size'
kWorkgroupSize
kWorkgroup
};
/// Converts a token type to a name
@ -479,22 +457,12 @@ class Token {
bool IsFine() const { return type_ == Type::kFine; }
/// @returns true if token is a 'fn'
bool IsFn() const { return type_ == Type::kFn; }
/// @returns true if token is a 'frag_coord'
bool IsFragCoord() const { return type_ == Type::kFragCoord; }
/// @returns true if token is a 'frag_depth'
bool IsFragDepth() const { return type_ == Type::kFragDepth; }
/// @returns true if token is a 'fragment'
bool IsFragment() const { return type_ == Type::kFragment; }
/// @returns true if token is a 'front_facing'
bool IsFrontFacing() const { return type_ == Type::kFrontFacing; }
/// @returns true if token is a 'function'
bool IsFunction() const { return type_ == Type::kFunction; }
/// @returns true if token is a 'fwidth'
bool IsFwidth() const { return type_ == Type::kFwidth; }
/// @returns true if token is a 'global_invocation_id'
bool IsGlobalInvocationId() const {
return type_ == Type::kGlobalInvocationId;
}
/// @returns true if token is a 'i32'
bool IsI32() const { return type_ == Type::kI32; }
/// @returns true if token is a 'if'
@ -505,8 +473,6 @@ class Token {
bool IsImport() const { return type_ == Type::kImport; }
/// @returns true if token is a 'in'
bool IsIn() const { return type_ == Type::kIn; }
/// @returns true if token is a 'instance_idx'
bool IsInstanceIdx() const { return type_ == Type::kInstanceIdx; }
/// @returns true if token is a 'is_nan'
bool IsIsNan() const { return type_ == Type::kIsNan; }
/// @returns true if token is a 'is_inf'
@ -517,12 +483,6 @@ class Token {
bool IsIsNormal() const { return type_ == Type::kIsNormal; }
/// @returns true if token is a 'kill'
bool IsKill() const { return type_ == Type::kKill; }
/// @returns true if token is a 'local_invocation_id'
bool IsLocalInvocationId() const { return type_ == Type::kLocalInvocationId; }
/// @returns true if token is a 'local_invocation_idx'
bool IsLocalInvocationIdx() const {
return type_ == Type::kLocalInvocationIdx;
}
/// @returns true if token is a 'location'
bool IsLocation() const { return type_ == Type::kLocation; }
/// @returns true if token is a 'loop'
@ -545,16 +505,12 @@ class Token {
bool IsMat4x3() const { return type_ == Type::kMat4x3; }
/// @returns true if token is a 'mat4x4'
bool IsMat4x4() const { return type_ == Type::kMat4x4; }
/// @returns true if token is a 'num_workgroups'
bool IsNumWorkgroups() const { return type_ == Type::kNumWorkgroups; }
/// @returns true if token is a 'offset'
bool IsOffset() const { return type_ == Type::kOffset; }
/// @returns true if token is a 'out'
bool IsOut() const { return type_ == Type::kOut; }
/// @returns true if token is a 'outer_product'
bool IsOuterProduct() const { return type_ == Type::kOuterProduct; }
/// @returns true if token is a 'position'
bool IsPosition() const { return type_ == Type::kPosition; }
/// @returns true if token is a 'private'
bool IsPrivate() const { return type_ == Type::kPrivate; }
/// @returns true if token is a 'ptr'
@ -591,14 +547,10 @@ class Token {
bool IsVec4() const { return type_ == Type::kVec4; }
/// @returns true if token is a 'vertex'
bool IsVertex() const { return type_ == Type::kVertex; }
/// @returns true if token is a 'vertex_idx'
bool IsVertexIdx() const { return type_ == Type::kVertexIdx; }
/// @returns true if token is a 'void'
bool IsVoid() const { return type_ == Type::kVoid; }
/// @returns true if token is a 'workgroup'
bool IsWorkgroup() const { return type_ == Type::kWorkgroup; }
/// @returns true if token is a 'workgroup_size'
bool IsWorkgroupSize() const { return type_ == Type::kWorkgroupSize; }
/// @returns the source line of the token
size_t line() const { return source_.line; }