mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 22:53:35 +00:00
tint/reader/wgsl: Use ClassifyTemplateArguments()
For parsing. Bug: tint:1810 Change-Id: I189d06136e79615d39c842aaa9ad58595f80283e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/117210 Kokoro: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
ef5434dcd1
commit
355b70d2be
@ -38,6 +38,7 @@
|
|||||||
#include "src/tint/ast/variable_decl_statement.h"
|
#include "src/tint/ast/variable_decl_statement.h"
|
||||||
#include "src/tint/ast/vector.h"
|
#include "src/tint/ast/vector.h"
|
||||||
#include "src/tint/ast/workgroup_attribute.h"
|
#include "src/tint/ast/workgroup_attribute.h"
|
||||||
|
#include "src/tint/reader/wgsl/classify_template_args.h"
|
||||||
#include "src/tint/reader/wgsl/lexer.h"
|
#include "src/tint/reader/wgsl/lexer.h"
|
||||||
#include "src/tint/type/depth_texture.h"
|
#include "src/tint/type/depth_texture.h"
|
||||||
#include "src/tint/type/external_texture.h"
|
#include "src/tint/type/external_texture.h"
|
||||||
@ -319,6 +320,7 @@ Source ParserImpl::last_source() const {
|
|||||||
void ParserImpl::InitializeLex() {
|
void ParserImpl::InitializeLex() {
|
||||||
Lexer l{file_};
|
Lexer l{file_};
|
||||||
tokens_ = l.Lex();
|
tokens_ = l.Lex();
|
||||||
|
ClassifyTemplateArguments(tokens_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParserImpl::Parse() {
|
bool ParserImpl::Parse() {
|
||||||
@ -731,7 +733,7 @@ Maybe<const ast::Type*> ParserImpl::texture_and_sampler_types() {
|
|||||||
if (dim.matched) {
|
if (dim.matched) {
|
||||||
const char* use = "sampled texture type";
|
const char* use = "sampled texture type";
|
||||||
|
|
||||||
auto subtype = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
auto subtype = expect_template_arg_block(use, [&] { return expect_type(use); });
|
||||||
if (subtype.errored) {
|
if (subtype.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
@ -743,7 +745,7 @@ Maybe<const ast::Type*> ParserImpl::texture_and_sampler_types() {
|
|||||||
if (ms_dim.matched) {
|
if (ms_dim.matched) {
|
||||||
const char* use = "multisampled texture type";
|
const char* use = "multisampled texture type";
|
||||||
|
|
||||||
auto subtype = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
auto subtype = expect_template_arg_block(use, [&] { return expect_type(use); });
|
||||||
if (subtype.errored) {
|
if (subtype.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
@ -755,7 +757,7 @@ Maybe<const ast::Type*> ParserImpl::texture_and_sampler_types() {
|
|||||||
if (storage.matched) {
|
if (storage.matched) {
|
||||||
const char* use = "storage texture type";
|
const char* use = "storage texture type";
|
||||||
using StorageTextureInfo = std::pair<tint::type::TexelFormat, tint::type::Access>;
|
using StorageTextureInfo = std::pair<tint::type::TexelFormat, tint::type::Access>;
|
||||||
auto params = expect_lt_gt_block(use, [&]() -> Expect<StorageTextureInfo> {
|
auto params = expect_template_arg_block(use, [&]() -> Expect<StorageTextureInfo> {
|
||||||
auto format = expect_texel_format(use);
|
auto format = expect_texel_format(use);
|
||||||
if (format.errored) {
|
if (format.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -1129,7 +1131,8 @@ Maybe<const ast::Type*> ParserImpl::type_specifier_without_ident() {
|
|||||||
return builder_.ty.u32(t.source());
|
return builder_.ty.u32(t.source());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.Is(Token::Type::kArray) && peek_is(Token::Type::kLessThan, 1)) {
|
if (t.Is(Token::Type::kArray) &&
|
||||||
|
(peek_is(Token::Type::kTemplateArgsLeft, 1) || peek_is(Token::Type::kLessThan, 1))) {
|
||||||
if (match(Token::Type::kArray)) {
|
if (match(Token::Type::kArray)) {
|
||||||
return expect_type_specifier_array(t.source());
|
return expect_type_specifier_array(t.source());
|
||||||
}
|
}
|
||||||
@ -1143,14 +1146,16 @@ Maybe<const ast::Type*> ParserImpl::type_specifier_without_ident() {
|
|||||||
return expect_type_specifier_pointer(t.source());
|
return expect_type_specifier_pointer(t.source());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.IsMatrix() && peek_is(Token::Type::kLessThan, 1)) {
|
if (t.IsMatrix() &&
|
||||||
|
(peek_is(Token::Type::kTemplateArgsLeft, 1) || peek_is(Token::Type::kLessThan, 1))) {
|
||||||
auto mat = mat_prefix();
|
auto mat = mat_prefix();
|
||||||
if (mat.matched) {
|
if (mat.matched) {
|
||||||
return expect_type_specifier_matrix(t.source(), mat.value);
|
return expect_type_specifier_matrix(t.source(), mat.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.IsVector() && peek_is(Token::Type::kLessThan, 1)) {
|
if (t.IsVector() &&
|
||||||
|
(peek_is(Token::Type::kTemplateArgsLeft, 1) || peek_is(Token::Type::kLessThan, 1))) {
|
||||||
auto vec = vec_prefix();
|
auto vec = vec_prefix();
|
||||||
if (vec.matched) {
|
if (vec.matched) {
|
||||||
return expect_type_specifier_vector(t.source(), vec.value);
|
return expect_type_specifier_vector(t.source(), vec.value);
|
||||||
@ -1259,7 +1264,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_pointer(const Source&
|
|||||||
auto address_space = type::AddressSpace::kNone;
|
auto address_space = type::AddressSpace::kNone;
|
||||||
auto access = type::Access::kUndefined;
|
auto access = type::Access::kUndefined;
|
||||||
|
|
||||||
auto subtype = expect_lt_gt_block(use, [&]() -> Expect<const ast::Type*> {
|
auto subtype = expect_template_arg_block(use, [&]() -> Expect<const ast::Type*> {
|
||||||
auto sc = expect_address_space(use);
|
auto sc = expect_address_space(use);
|
||||||
if (sc.errored) {
|
if (sc.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -1297,7 +1302,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_pointer(const Source&
|
|||||||
Expect<const ast::Type*> ParserImpl::expect_type_specifier_atomic(const Source& s) {
|
Expect<const ast::Type*> ParserImpl::expect_type_specifier_atomic(const Source& s) {
|
||||||
const char* use = "atomic declaration";
|
const char* use = "atomic declaration";
|
||||||
|
|
||||||
auto subtype = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
auto subtype = expect_template_arg_block(use, [&] { return expect_type(use); });
|
||||||
if (subtype.errored) {
|
if (subtype.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
@ -1308,7 +1313,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_atomic(const Source&
|
|||||||
// LESS_THAN type_specifier GREATER_THAN
|
// LESS_THAN type_specifier GREATER_THAN
|
||||||
Expect<const ast::Type*> ParserImpl::expect_type_specifier_vector(const Source& s, uint32_t count) {
|
Expect<const ast::Type*> ParserImpl::expect_type_specifier_vector(const Source& s, uint32_t count) {
|
||||||
const char* use = "vector";
|
const char* use = "vector";
|
||||||
auto ty = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
auto ty = expect_template_arg_block(use, [&] { return expect_type(use); });
|
||||||
if (ty.errored) {
|
if (ty.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
@ -1325,11 +1330,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_array(const Source& s
|
|||||||
const ast::Expression* size = nullptr;
|
const ast::Expression* size = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!peek_is(Token::Type::kLessThan)) {
|
auto type_size = expect_template_arg_block(use, [&]() -> Expect<TypeAndSize> {
|
||||||
return add_error(peek(), "expected < for array");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto type_size = expect_lt_gt_block(use, [&]() -> Expect<TypeAndSize> {
|
|
||||||
auto type = expect_type(use);
|
auto type = expect_type(use);
|
||||||
if (type.errored) {
|
if (type.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -1361,7 +1362,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_array(const Source& s
|
|||||||
Expect<const ast::Type*> ParserImpl::expect_type_specifier_matrix(const Source& s,
|
Expect<const ast::Type*> ParserImpl::expect_type_specifier_matrix(const Source& s,
|
||||||
const MatrixDimensions& dims) {
|
const MatrixDimensions& dims) {
|
||||||
const char* use = "matrix";
|
const char* use = "matrix";
|
||||||
auto ty = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
auto ty = expect_template_arg_block(use, [&] { return expect_type(use); });
|
||||||
if (ty.errored) {
|
if (ty.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
@ -2555,7 +2556,7 @@ Maybe<const ast::Expression*> ParserImpl::primary_expression() {
|
|||||||
if (match(Token::Type::kBitcast)) {
|
if (match(Token::Type::kBitcast)) {
|
||||||
const char* use = "bitcast expression";
|
const char* use = "bitcast expression";
|
||||||
|
|
||||||
auto type = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
auto type = expect_template_arg_block(use, [&] { return expect_type(use); });
|
||||||
if (type.errored) {
|
if (type.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
@ -2592,6 +2593,14 @@ Maybe<const ast::Expression*> ParserImpl::primary_expression() {
|
|||||||
if (t.IsIdentifier()) {
|
if (t.IsIdentifier()) {
|
||||||
next();
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
auto* ident =
|
auto* ident =
|
||||||
create<ast::IdentifierExpression>(t.source(), builder_.Symbols().Register(t.to_str()));
|
create<ast::IdentifierExpression>(t.source(), builder_.Symbols().Register(t.to_str()));
|
||||||
|
|
||||||
@ -3733,7 +3742,11 @@ bool ParserImpl::expect(std::string_view use, Token::Type tok) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream err;
|
std::stringstream err;
|
||||||
err << "expected '" << Token::TypeToName(tok) << "'";
|
if (tok == Token::Type::kTemplateArgsLeft && t.type() == Token::Type::kLessThan) {
|
||||||
|
err << "missing closing '>'";
|
||||||
|
} else {
|
||||||
|
err << "expected '" << Token::TypeToName(tok) << "'";
|
||||||
|
}
|
||||||
if (!use.empty()) {
|
if (!use.empty()) {
|
||||||
err << " for " << use;
|
err << " for " << use;
|
||||||
}
|
}
|
||||||
@ -3842,6 +3855,12 @@ T ParserImpl::expect_lt_gt_block(std::string_view use, F&& body) {
|
|||||||
std::forward<F>(body));
|
std::forward<F>(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename F, typename T>
|
||||||
|
T ParserImpl::expect_template_arg_block(std::string_view use, F&& body) {
|
||||||
|
return expect_block(Token::Type::kTemplateArgsLeft, Token::Type::kTemplateArgsRight, use,
|
||||||
|
std::forward<F>(body));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename F, typename T>
|
template <typename F, typename T>
|
||||||
T ParserImpl::sync(Token::Type tok, F&& body) {
|
T ParserImpl::sync(Token::Type tok, F&& body) {
|
||||||
if (parse_depth_ >= kMaxParseDepth) {
|
if (parse_depth_ >= kMaxParseDepth) {
|
||||||
|
@ -799,6 +799,16 @@ class ParserImpl {
|
|||||||
/// an Expect with error state.
|
/// an Expect with error state.
|
||||||
template <typename F, typename T = ReturnType<F>>
|
template <typename F, typename T = ReturnType<F>>
|
||||||
T expect_lt_gt_block(std::string_view use, F&& body);
|
T expect_lt_gt_block(std::string_view use, F&& body);
|
||||||
|
/// A convenience function that calls `expect_block` passing
|
||||||
|
/// `Token::Type::kTemplateArgsLeft` and `Token::Type::kTemplateArgsRight` for the `start` and
|
||||||
|
/// `end` arguments, respectively.
|
||||||
|
/// @param use a description of what was being parsed if an error was raised
|
||||||
|
/// @param body a function or lambda that is called to parse the lexical block body, with the
|
||||||
|
/// signature: `Expect<Result>()` or `Maybe<Result>()`.
|
||||||
|
/// @return the value returned by `body` if no errors are raised, otherwise an Expect with error
|
||||||
|
/// state.
|
||||||
|
template <typename F, typename T = ReturnType<F>>
|
||||||
|
T expect_template_arg_block(std::string_view use, F&& body);
|
||||||
|
|
||||||
/// sync() calls the function `func`, and attempts to resynchronize the
|
/// sync() calls the function `func`, and attempts to resynchronize the
|
||||||
/// parser to the next found resynchronization token if `func` fails. If the
|
/// parser to the next found resynchronization token if `func` fails. If the
|
||||||
|
@ -120,8 +120,9 @@ fn f() { a = >; }
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, BitcastExprMissingLessThan) {
|
TEST_F(ParserImplErrorTest, BitcastExprMissingLessThan) {
|
||||||
EXPECT("fn f() { x = bitcast(y); }",
|
EXPECT(
|
||||||
R"(test.wgsl:1:21 error: expected '<' for bitcast expression
|
"fn f() { x = bitcast(y); }",
|
||||||
|
R"(test.wgsl:1:21 error: expected '< (opening template argument list)' for bitcast expression
|
||||||
fn f() { x = bitcast(y); }
|
fn f() { x = bitcast(y); }
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -129,9 +130,9 @@ fn f() { x = bitcast(y); }
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, BitcastExprMissingGreaterThan) {
|
TEST_F(ParserImplErrorTest, BitcastExprMissingGreaterThan) {
|
||||||
EXPECT("fn f() { x = bitcast<u32(y); }",
|
EXPECT("fn f() { x = bitcast<u32(y); }",
|
||||||
R"(test.wgsl:1:25 error: expected '>' for bitcast expression
|
R"(test.wgsl:1:21 error: missing closing '>' for bitcast expression
|
||||||
fn f() { x = bitcast<u32(y); }
|
fn f() { x = bitcast<u32(y); }
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,8 +660,9 @@ TEST_F(ParserImplErrorTest, GlobalDeclInvalidAttribute) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclSampledTextureMissingLessThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclSampledTextureMissingLessThan) {
|
||||||
EXPECT("var x : texture_1d;",
|
EXPECT(
|
||||||
R"(test.wgsl:1:19 error: expected '<' for sampled texture type
|
"var x : texture_1d;",
|
||||||
|
R"(test.wgsl:1:19 error: expected '< (opening template argument list)' for sampled texture type
|
||||||
var x : texture_1d;
|
var x : texture_1d;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -668,9 +670,9 @@ var x : texture_1d;
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclSampledTextureMissingGreaterThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclSampledTextureMissingGreaterThan) {
|
||||||
EXPECT("var x : texture_1d<f32;",
|
EXPECT("var x : texture_1d<f32;",
|
||||||
R"(test.wgsl:1:23 error: expected '>' for sampled texture type
|
R"(test.wgsl:1:19 error: missing closing '>' for sampled texture type
|
||||||
var x : texture_1d<f32;
|
var x : texture_1d<f32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,8 +685,9 @@ var x : texture_1d<1>;
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclMultisampledTextureMissingLessThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclMultisampledTextureMissingLessThan) {
|
||||||
EXPECT("var x : texture_multisampled_2d;",
|
EXPECT(
|
||||||
R"(test.wgsl:1:32 error: expected '<' for multisampled texture type
|
"var x : texture_multisampled_2d;",
|
||||||
|
R"(test.wgsl:1:32 error: expected '< (opening template argument list)' for multisampled texture type
|
||||||
var x : texture_multisampled_2d;
|
var x : texture_multisampled_2d;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -692,9 +695,9 @@ var x : texture_multisampled_2d;
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclMultisampledTextureMissingGreaterThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclMultisampledTextureMissingGreaterThan) {
|
||||||
EXPECT("var x : texture_multisampled_2d<f32;",
|
EXPECT("var x : texture_multisampled_2d<f32;",
|
||||||
R"(test.wgsl:1:36 error: expected '>' for multisampled texture type
|
R"(test.wgsl:1:32 error: missing closing '>' for multisampled texture type
|
||||||
var x : texture_multisampled_2d<f32;
|
var x : texture_multisampled_2d<f32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,8 +833,9 @@ static_assert true static_assert true;
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingLessThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingLessThan) {
|
||||||
EXPECT("var x : texture_storage_2d;",
|
EXPECT(
|
||||||
R"(test.wgsl:1:27 error: expected '<' for storage texture type
|
"var x : texture_storage_2d;",
|
||||||
|
R"(test.wgsl:1:27 error: expected '< (opening template argument list)' for storage texture type
|
||||||
var x : texture_storage_2d;
|
var x : texture_storage_2d;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -839,9 +843,9 @@ var x : texture_storage_2d;
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingGreaterThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingGreaterThan) {
|
||||||
EXPECT("var x : texture_storage_2d<r32uint, read;",
|
EXPECT("var x : texture_storage_2d<r32uint, read;",
|
||||||
R"(test.wgsl:1:41 error: expected '>' for storage texture type
|
R"(test.wgsl:1:27 error: missing closing '>' for storage texture type
|
||||||
var x : texture_storage_2d<r32uint, read;
|
var x : texture_storage_2d<r32uint, read;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,9 +997,9 @@ type meow = f32
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayMissingGreaterThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayMissingGreaterThan) {
|
||||||
EXPECT("var i : array<u32, 3;",
|
EXPECT("var i : array<u32, 3;",
|
||||||
R"(test.wgsl:1:21 error: expected '>' for array declaration
|
R"(test.wgsl:1:14 error: missing closing '>' for array declaration
|
||||||
var i : array<u32, 3;
|
var i : array<u32, 3;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1174,9 +1178,9 @@ var ^ : mat4x4;
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarMatrixMissingGreaterThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarMatrixMissingGreaterThan) {
|
||||||
EXPECT("var i : mat4x4<u32;", R"(test.wgsl:1:19 error: expected '>' for matrix
|
EXPECT("var i : mat4x4<u32;", R"(test.wgsl:1:15 error: missing closing '>' for matrix
|
||||||
var i : mat4x4<u32;
|
var i : mat4x4<u32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1196,8 +1200,9 @@ var i : i32
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingLessThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingLessThan) {
|
||||||
EXPECT("var i : ptr;",
|
EXPECT(
|
||||||
R"(test.wgsl:1:12 error: expected '<' for ptr declaration
|
"var i : ptr;",
|
||||||
|
R"(test.wgsl:1:12 error: expected '< (opening template argument list)' for ptr declaration
|
||||||
var i : ptr;
|
var i : ptr;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -1205,9 +1210,9 @@ var i : ptr;
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingGreaterThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingGreaterThan) {
|
||||||
EXPECT("var i : ptr<private, u32;",
|
EXPECT("var i : ptr<private, u32;",
|
||||||
R"(test.wgsl:1:25 error: expected '>' for ptr declaration
|
R"(test.wgsl:1:12 error: missing closing '>' for ptr declaration
|
||||||
var i : ptr<private, u32;
|
var i : ptr<private, u32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1237,8 +1242,9 @@ var i : ptr<private, 1>;
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAtomicMissingLessThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAtomicMissingLessThan) {
|
||||||
EXPECT("var i : atomic;",
|
EXPECT(
|
||||||
R"(test.wgsl:1:15 error: expected '<' for atomic declaration
|
"var i : atomic;",
|
||||||
|
R"(test.wgsl:1:15 error: expected '< (opening template argument list)' for atomic declaration
|
||||||
var i : atomic;
|
var i : atomic;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
@ -1246,9 +1252,9 @@ var i : atomic;
|
|||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAtomicMissingGreaterThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarAtomicMissingGreaterThan) {
|
||||||
EXPECT("var i : atomic<u32 x;",
|
EXPECT("var i : atomic<u32 x;",
|
||||||
R"(test.wgsl:1:20 error: expected '>' for atomic declaration
|
R"(test.wgsl:1:15 error: missing closing '>' for atomic declaration
|
||||||
var i : atomic<u32 x;
|
var i : atomic<u32 x;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1270,9 +1276,9 @@ var<private i : i32
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, GlobalDeclVarVectorMissingGreaterThan) {
|
TEST_F(ParserImplErrorTest, GlobalDeclVarVectorMissingGreaterThan) {
|
||||||
EXPECT("var i : vec3<u32;", R"(test.wgsl:1:17 error: expected '>' for vector
|
EXPECT("var i : vec3<u32;", R"(test.wgsl:1:13 error: missing closing '>' for vector
|
||||||
var i : vec3<u32;
|
var i : vec3<u32;
|
||||||
^
|
^
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,6 +463,9 @@ struct Case {
|
|||||||
bool should_parse;
|
bool should_parse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool ParsedAsTemplateArgumentList(BinaryOperatorInfo lhs_op, BinaryOperatorInfo rhs_op) {
|
||||||
|
return lhs_op.bit == kOpLt && rhs_op.bit & (kOpGt | kOpGe | kOpShr);
|
||||||
|
}
|
||||||
static std::ostream& operator<<(std::ostream& o, const Case& c) {
|
static std::ostream& operator<<(std::ostream& o, const Case& c) {
|
||||||
return o << "a " << c.lhs_op.symbol << " b " << c.rhs_op.symbol << " c ";
|
return o << "a " << c.lhs_op.symbol << " b " << c.rhs_op.symbol << " c ";
|
||||||
}
|
}
|
||||||
@ -471,7 +474,8 @@ static std::vector<Case> Cases() {
|
|||||||
std::vector<Case> out;
|
std::vector<Case> out;
|
||||||
for (auto& lhs_op : kBinaryOperators) {
|
for (auto& lhs_op : kBinaryOperators) {
|
||||||
for (auto& rhs_op : kBinaryOperators) {
|
for (auto& rhs_op : kBinaryOperators) {
|
||||||
bool should_parse = lhs_op.can_follow_without_paren & rhs_op.bit;
|
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});
|
out.push_back({lhs_op, rhs_op, should_parse});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,8 +498,14 @@ TEST_P(ParserImplMixedBinaryOpTest, Test) {
|
|||||||
EXPECT_EQ(e.value, nullptr);
|
EXPECT_EQ(e.value, nullptr);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
std::stringstream expected;
|
std::stringstream expected;
|
||||||
expected << "1:3: mixing '" << GetParam().lhs_op.symbol << "' and '"
|
if (ParsedAsTemplateArgumentList(GetParam().lhs_op, GetParam().rhs_op)) {
|
||||||
<< GetParam().rhs_op.symbol << "' requires parenthesis";
|
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";
|
||||||
|
}
|
||||||
EXPECT_EQ(p->error(), expected.str());
|
EXPECT_EQ(p->error(), expected.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingGreaterThan) {
|
|||||||
EXPECT_TRUE(e.errored);
|
EXPECT_TRUE(e.errored);
|
||||||
EXPECT_EQ(e.value, nullptr);
|
EXPECT_EQ(e.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), "1:12: expected '>' for bitcast expression");
|
EXPECT_EQ(p->error(), "1:8: missing closing '>' for bitcast expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingType) {
|
TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingType) {
|
||||||
@ -319,5 +319,18 @@ TEST_F(ParserImplTest, PrimaryExpression_bitcast_InvalidExpression) {
|
|||||||
EXPECT_EQ(p->error(), "1:14: unable to parse expression");
|
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
|
||||||
} // namespace tint::reader::wgsl
|
} // namespace tint::reader::wgsl
|
||||||
|
@ -154,7 +154,7 @@ TEST_F(ParserImplTest, Peek_PastPlaceholder) {
|
|||||||
auto& n = p->next();
|
auto& n = p->next();
|
||||||
ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
|
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::kVec2)) << "expected: vec2 got: " << p->peek().to_name();
|
||||||
EXPECT_TRUE(p->peek_is(Token::Type::kLessThan, 1))
|
EXPECT_TRUE(p->peek_is(Token::Type::kTemplateArgsLeft, 1))
|
||||||
<< "expected: < got: " << p->peek(1).to_name();
|
<< "expected: < got: " << p->peek(1).to_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,10 +163,10 @@ TEST_F(ParserImplTest, Peek_MultiplePlaceholder) {
|
|||||||
auto& n = p->next();
|
auto& n = p->next();
|
||||||
ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
|
ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
|
||||||
EXPECT_TRUE(p->peek_is(Token::Type::kGreaterThanEqual))
|
EXPECT_TRUE(p->peek_is(Token::Type::kGreaterThanEqual))
|
||||||
<< "expected: <= got: " << p->peek().to_name();
|
<< "expected: >= got: " << p->peek().to_name();
|
||||||
EXPECT_TRUE(p->peek_is(Token::Type::kVec2, 1))
|
EXPECT_TRUE(p->peek_is(Token::Type::kVec2, 1))
|
||||||
<< "expected: vec2 got: " << p->peek(1).to_name();
|
<< "expected: vec2 got: " << p->peek(1).to_name();
|
||||||
EXPECT_TRUE(p->peek_is(Token::Type::kLessThan, 2))
|
EXPECT_TRUE(p->peek_is(Token::Type::kTemplateArgsLeft, 2))
|
||||||
<< "expected: < got: " << p->peek(2).to_name();
|
<< "expected: < got: " << p->peek(2).to_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingLessThan) {
|
|||||||
EXPECT_EQ(t.value, nullptr);
|
EXPECT_EQ(t.value, nullptr);
|
||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
EXPECT_TRUE(t.errored);
|
EXPECT_TRUE(t.errored);
|
||||||
EXPECT_EQ(p->error(), "1:11: expected '<' for sampled texture type");
|
EXPECT_EQ(p->error(),
|
||||||
|
"1:11: expected '< (opening template argument list)' for sampled texture type");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingGreaterThan) {
|
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingGreaterThan) {
|
||||||
@ -136,7 +137,7 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingGreaterThan) {
|
|||||||
EXPECT_EQ(t.value, nullptr);
|
EXPECT_EQ(t.value, nullptr);
|
||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
EXPECT_TRUE(t.errored);
|
EXPECT_TRUE(t.errored);
|
||||||
EXPECT_EQ(p->error(), "1:15: expected '>' for sampled texture type");
|
EXPECT_EQ(p->error(), "1:11: missing closing '>' for sampled texture type");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_I32) {
|
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_I32) {
|
||||||
@ -169,7 +170,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingLessThan)
|
|||||||
EXPECT_EQ(t.value, nullptr);
|
EXPECT_EQ(t.value, nullptr);
|
||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
EXPECT_TRUE(t.errored);
|
EXPECT_TRUE(t.errored);
|
||||||
EXPECT_EQ(p->error(), "1:24: expected '<' for multisampled texture type");
|
EXPECT_EQ(p->error(),
|
||||||
|
"1:24: expected '< (opening template argument list)' for multisampled texture type");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingGreaterThan) {
|
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingGreaterThan) {
|
||||||
@ -178,7 +180,7 @@ TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingGreaterTha
|
|||||||
EXPECT_EQ(t.value, nullptr);
|
EXPECT_EQ(t.value, nullptr);
|
||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
EXPECT_TRUE(t.errored);
|
EXPECT_TRUE(t.errored);
|
||||||
EXPECT_EQ(p->error(), "1:28: expected '>' for multisampled texture type");
|
EXPECT_EQ(p->error(), "1:24: missing closing '>' for multisampled texture type");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Readonly1dRg32Float) {
|
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Readonly1dRg32Float) {
|
||||||
@ -261,7 +263,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingLessThan) {
|
|||||||
EXPECT_EQ(t.value, nullptr);
|
EXPECT_EQ(t.value, nullptr);
|
||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
EXPECT_TRUE(t.errored);
|
EXPECT_TRUE(t.errored);
|
||||||
EXPECT_EQ(p->error(), "1:19: expected '<' for storage texture type");
|
EXPECT_EQ(p->error(),
|
||||||
|
"1:19: expected '< (opening template argument list)' for storage texture type");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingGreaterThan) {
|
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingGreaterThan) {
|
||||||
@ -270,7 +273,7 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingGreaterThan) {
|
|||||||
EXPECT_EQ(t.value, nullptr);
|
EXPECT_EQ(t.value, nullptr);
|
||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
EXPECT_TRUE(t.errored);
|
EXPECT_TRUE(t.errored);
|
||||||
EXPECT_EQ(p->error(), "1:33: expected '>' for storage texture type");
|
EXPECT_EQ(p->error(), "1:19: missing closing '>' for storage texture type");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -139,7 +139,7 @@ TEST_P(VecMissingGreaterThanTest, Handles_Missing_GreaterThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:9: expected '>' for vector");
|
ASSERT_EQ(p->error(), "1:5: missing closing '>' for vector");
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||||
VecMissingGreaterThanTest,
|
VecMissingGreaterThanTest,
|
||||||
@ -222,7 +222,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingLessThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:5: expected '<' for ptr declaration");
|
ASSERT_EQ(p->error(), "1:5: expected '< (opening template argument list)' for ptr declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingGreaterThanAfterType) {
|
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingGreaterThanAfterType) {
|
||||||
@ -232,7 +232,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingGreaterThanAfterType) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:18: expected '>' for ptr declaration");
|
ASSERT_EQ(p->error(), "1:4: missing closing '>' for ptr declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingGreaterThanAfterAccess) {
|
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingGreaterThanAfterAccess) {
|
||||||
@ -242,7 +242,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingGreaterThanAfterAccess) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:24: expected '>' for ptr declaration");
|
ASSERT_EQ(p->error(), "1:4: missing closing '>' for ptr declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAddressSpace) {
|
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAddressSpace) {
|
||||||
@ -262,7 +262,8 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAccess) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:19: expected '>' for ptr declaration");
|
ASSERT_EQ(p->error(),
|
||||||
|
"1:19: expected '> (closing template argument list)' for ptr declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingAddressSpace) {
|
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingAddressSpace) {
|
||||||
@ -370,7 +371,8 @@ TEST_F(ParserImplTest, TypeDecl_Atomic_MissingLessThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:8: expected '<' for atomic declaration");
|
ASSERT_EQ(p->error(),
|
||||||
|
"1:8: expected '< (opening template argument list)' for atomic declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDecl_Atomic_MissingGreaterThan) {
|
TEST_F(ParserImplTest, TypeDecl_Atomic_MissingGreaterThan) {
|
||||||
@ -380,7 +382,7 @@ TEST_F(ParserImplTest, TypeDecl_Atomic_MissingGreaterThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:11: expected '>' for atomic declaration");
|
ASSERT_EQ(p->error(), "1:7: missing closing '>' for atomic declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDecl_Atomic_MissingType) {
|
TEST_F(ParserImplTest, TypeDecl_Atomic_MissingType) {
|
||||||
@ -561,7 +563,7 @@ TEST_F(ParserImplTest, TypeDecl_Array_MissingGreaterThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:10: expected '>' for array declaration");
|
ASSERT_EQ(p->error(), "1:6: missing closing '>' for array declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDecl_Array_MissingComma) {
|
TEST_F(ParserImplTest, TypeDecl_Array_MissingComma) {
|
||||||
@ -571,7 +573,8 @@ TEST_F(ParserImplTest, TypeDecl_Array_MissingComma) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:11: expected '>' for array declaration");
|
ASSERT_EQ(p->error(),
|
||||||
|
"1:11: expected '> (closing template argument list)' for array declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MatrixData {
|
struct MatrixData {
|
||||||
@ -623,7 +626,7 @@ TEST_P(MatrixMissingGreaterThanTest, Handles_Missing_GreaterThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:11: expected '>' for matrix");
|
ASSERT_EQ(p->error(), "1:7: missing closing '>' for matrix");
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||||
MatrixMissingGreaterThanTest,
|
MatrixMissingGreaterThanTest,
|
||||||
|
@ -130,7 +130,7 @@ TEST_P(TypeDeclWithoutIdent_VecMissingGreaterThanTest, Handles_Missing_GreaterTh
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:9: expected '>' for vector");
|
ASSERT_EQ(p->error(), "1:5: missing closing '>' for vector");
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||||
TypeDeclWithoutIdent_VecMissingGreaterThanTest,
|
TypeDeclWithoutIdent_VecMissingGreaterThanTest,
|
||||||
@ -213,7 +213,7 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingLessThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:5: expected '<' for ptr declaration");
|
ASSERT_EQ(p->error(), "1:5: expected '< (opening template argument list)' for ptr declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingGreaterThanAfterType) {
|
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingGreaterThanAfterType) {
|
||||||
@ -223,7 +223,7 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingGreaterThanAfterType) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:18: expected '>' for ptr declaration");
|
ASSERT_EQ(p->error(), "1:4: missing closing '>' for ptr declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingGreaterThanAfterAccess) {
|
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingGreaterThanAfterAccess) {
|
||||||
@ -233,7 +233,7 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingGreaterThanAfterAccess) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:24: expected '>' for ptr declaration");
|
ASSERT_EQ(p->error(), "1:4: missing closing '>' for ptr declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingCommaAfterAddressSpace) {
|
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingCommaAfterAddressSpace) {
|
||||||
@ -253,7 +253,8 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingCommaAfterAccess) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:19: expected '>' for ptr declaration");
|
ASSERT_EQ(p->error(),
|
||||||
|
"1:19: expected '> (closing template argument list)' for ptr declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingAddressSpace) {
|
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingAddressSpace) {
|
||||||
@ -361,7 +362,8 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_MissingLessThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:8: expected '<' for atomic declaration");
|
ASSERT_EQ(p->error(),
|
||||||
|
"1:8: expected '< (opening template argument list)' for atomic declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_MissingGreaterThan) {
|
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_MissingGreaterThan) {
|
||||||
@ -371,7 +373,7 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_MissingGreaterThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:11: expected '>' for atomic declaration");
|
ASSERT_EQ(p->error(), "1:7: missing closing '>' for atomic declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_MissingType) {
|
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic_MissingType) {
|
||||||
@ -552,7 +554,7 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_MissingGreaterThan) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:10: expected '>' for array declaration");
|
ASSERT_EQ(p->error(), "1:6: missing closing '>' for array declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_MissingComma) {
|
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_MissingComma) {
|
||||||
@ -562,7 +564,8 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Array_MissingComma) {
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:11: expected '>' for array declaration");
|
ASSERT_EQ(p->error(),
|
||||||
|
"1:11: expected '> (closing template argument list)' for array declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MatrixData {
|
struct MatrixData {
|
||||||
@ -615,7 +618,7 @@ TEST_P(TypeDeclWithoutIdent_MatrixMissingGreaterThanTest, Handles_Missing_Greate
|
|||||||
EXPECT_FALSE(t.matched);
|
EXPECT_FALSE(t.matched);
|
||||||
ASSERT_EQ(t.value, nullptr);
|
ASSERT_EQ(t.value, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:11: expected '>' for matrix");
|
ASSERT_EQ(p->error(), "1:7: missing closing '>' for matrix");
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||||
TypeDeclWithoutIdent_MatrixMissingGreaterThanTest,
|
TypeDeclWithoutIdent_MatrixMissingGreaterThanTest,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user