mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 10:49:14 +00:00
[wgsl-reader] Add parsing of named structs.
This CL adds the parsing of structs with names. The parsing of type aliased structs remains to allow for migration to the new system. The named struct format is always emitted. Bug: tint:175 Change-Id: Ic0579dedbd2dd0edc7dfd30bc2ec02972091e718 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/30341 Commit-Queue: dan sinclair <dsinclair@chromium.org> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
committed by
Commit Bot service account
parent
c9a3e47396
commit
7156d3e314
@@ -218,10 +218,10 @@ TEST_F(SpvParserTest_Composite_Construct, Struct) {
|
||||
Variable{
|
||||
x_1
|
||||
none
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
{
|
||||
TypeConstructor{
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
TypeConstructor{
|
||||
__vec_2__f32
|
||||
ScalarConstructor{50.000000}
|
||||
|
||||
@@ -800,8 +800,7 @@ TEST_F(SpvParserTest, RemapStorageBuffer_TypesAndVarDeclarations) {
|
||||
const auto module_str = p->module().to_str();
|
||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||
RTArr -> __array__u32_stride_4
|
||||
S -> __struct_S
|
||||
Struct{
|
||||
S Struct{
|
||||
[[block]]
|
||||
StructMember{[[ offset 0 ]] field0: __u32}
|
||||
StructMember{[[ offset 4 ]] field1: __alias_RTArr__array__u32_stride_4}
|
||||
@@ -809,7 +808,7 @@ TEST_F(SpvParserTest, RemapStorageBuffer_TypesAndVarDeclarations) {
|
||||
Variable{
|
||||
myvar
|
||||
storage_buffer
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
})"));
|
||||
}
|
||||
|
||||
|
||||
@@ -264,10 +264,10 @@ TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Struct) {
|
||||
Variable{
|
||||
x_11
|
||||
none
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
{
|
||||
TypeConstructor{
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
ScalarConstructor{false}
|
||||
ScalarConstructor{0}
|
||||
ScalarConstructor{0}
|
||||
|
||||
@@ -563,10 +563,10 @@ TEST_F(SpvParserTest, EmitFunctionVariables_StructInitializer) {
|
||||
Variable{
|
||||
x_200
|
||||
function
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
{
|
||||
TypeConstructor{
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
ScalarConstructor{1}
|
||||
ScalarConstructor{1.500000}
|
||||
TypeConstructor{
|
||||
@@ -602,10 +602,10 @@ TEST_F(SpvParserTest, EmitFunctionVariables_StructInitializer_Null) {
|
||||
Variable{
|
||||
x_200
|
||||
function
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
{
|
||||
TypeConstructor{
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
ScalarConstructor{0}
|
||||
ScalarConstructor{0.000000}
|
||||
TypeConstructor{
|
||||
|
||||
@@ -870,6 +870,8 @@ ast::type::Type* ParserImpl::ConvertType(
|
||||
namer_.GetName(type_id), std::move(ast_struct));
|
||||
|
||||
auto* result = ctx_.type_mgr().Get(std::move(ast_struct_type));
|
||||
id_to_type_[type_id] = result;
|
||||
ast_module_.AddConstructedType(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -934,11 +936,8 @@ void ParserImpl::MaybeGenerateAlias(uint32_t type_id,
|
||||
return;
|
||||
}
|
||||
|
||||
// We only care about struct, arrays, and runtime arrays.
|
||||
// We only care about arrays, and runtime arrays.
|
||||
switch (type->kind()) {
|
||||
case spvtools::opt::analysis::Type::kStruct:
|
||||
// The struct already got a name when the type was first registered.
|
||||
break;
|
||||
case spvtools::opt::analysis::Type::kRuntimeArray:
|
||||
// Runtime arrays are always decorated with ArrayStride so always get a
|
||||
// type alias.
|
||||
@@ -967,7 +966,7 @@ void ParserImpl::MaybeGenerateAlias(uint32_t type_id,
|
||||
->AsAlias();
|
||||
// Record this new alias as the AST type for this SPIR-V ID.
|
||||
id_to_type_[type_id] = ast_alias_type;
|
||||
ast_module_.AddAliasType(ast_alias_type);
|
||||
ast_module_.AddConstructedType(ast_alias_type);
|
||||
}
|
||||
|
||||
bool ParserImpl::EmitModuleScopeVariables() {
|
||||
|
||||
@@ -1058,10 +1058,10 @@ TEST_F(SpvParserTest, ModuleScopeVar_StructInitializer) {
|
||||
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||
x_200
|
||||
private
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
{
|
||||
TypeConstructor{
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
ScalarConstructor{1}
|
||||
ScalarConstructor{1.500000}
|
||||
TypeConstructor{
|
||||
@@ -1087,10 +1087,10 @@ TEST_F(SpvParserTest, ModuleScopeVar_StructNullInitializer) {
|
||||
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||
x_200
|
||||
private
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
{
|
||||
TypeConstructor{
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
ScalarConstructor{0}
|
||||
ScalarConstructor{0.000000}
|
||||
TypeConstructor{
|
||||
@@ -1116,10 +1116,10 @@ TEST_F(SpvParserTest, ModuleScopeVar_StructUndefInitializer) {
|
||||
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||
x_200
|
||||
private
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
{
|
||||
TypeConstructor{
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
ScalarConstructor{0}
|
||||
ScalarConstructor{0.000000}
|
||||
TypeConstructor{
|
||||
@@ -1203,7 +1203,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_DescriptorSetDecoration_Valid) {
|
||||
}
|
||||
myvar
|
||||
storage_buffer
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
})"))
|
||||
<< module_str;
|
||||
}
|
||||
@@ -1257,7 +1257,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_BindingDecoration_Valid) {
|
||||
}
|
||||
myvar
|
||||
storage_buffer
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
})"))
|
||||
<< module_str;
|
||||
}
|
||||
@@ -1305,8 +1305,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_NonReadableDecoration_DroppedForNow) {
|
||||
EXPECT_TRUE(p->error().empty());
|
||||
const auto module_str = p->module().to_str();
|
||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||
S -> __struct_S
|
||||
Struct{
|
||||
S Struct{
|
||||
[[block]]
|
||||
StructMember{field0: __u32}
|
||||
StructMember{field1: __f32}
|
||||
@@ -1315,7 +1314,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_NonReadableDecoration_DroppedForNow) {
|
||||
Variable{
|
||||
myvar
|
||||
storage_buffer
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
}
|
||||
})")) << module_str;
|
||||
}
|
||||
@@ -1333,8 +1332,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_NonWritableDecoration_DroppedForNow) {
|
||||
EXPECT_TRUE(p->error().empty());
|
||||
const auto module_str = p->module().to_str();
|
||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||
S -> __struct_S
|
||||
Struct{
|
||||
S Struct{
|
||||
[[block]]
|
||||
StructMember{field0: __u32}
|
||||
StructMember{field1: __f32}
|
||||
@@ -1343,7 +1341,7 @@ TEST_F(SpvParserTest, ModuleScopeVar_NonWritableDecoration_DroppedForNow) {
|
||||
Variable{
|
||||
myvar
|
||||
storage_buffer
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
}
|
||||
})")) << module_str;
|
||||
}
|
||||
@@ -1365,15 +1363,14 @@ TEST_F(SpvParserTest, ModuleScopeVar_ColMajorDecoration_Dropped) {
|
||||
EXPECT_TRUE(p->error().empty());
|
||||
const auto module_str = p->module().to_str();
|
||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||
S -> __struct_S
|
||||
Struct{
|
||||
S Struct{
|
||||
[[block]]
|
||||
StructMember{field0: __mat_2_3__f32}
|
||||
}
|
||||
Variable{
|
||||
myvar
|
||||
storage_buffer
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
}
|
||||
})")) << module_str;
|
||||
}
|
||||
@@ -1395,15 +1392,14 @@ TEST_F(SpvParserTest, ModuleScopeVar_MatrixStrideDecoration_Dropped) {
|
||||
EXPECT_TRUE(p->error().empty());
|
||||
const auto module_str = p->module().to_str();
|
||||
EXPECT_THAT(module_str, HasSubstr(R"(
|
||||
S -> __struct_S
|
||||
Struct{
|
||||
S Struct{
|
||||
[[block]]
|
||||
StructMember{field0: __mat_2_3__f32}
|
||||
}
|
||||
Variable{
|
||||
myvar
|
||||
storage_buffer
|
||||
__alias_S__struct_S
|
||||
__struct_S
|
||||
}
|
||||
})")) << module_str;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ TEST_F(SpvParserTest, NamedTypes_AnonStruct) {
|
||||
%s = OpTypeStruct %uint %uint
|
||||
)"));
|
||||
EXPECT_TRUE(p->BuildAndParseInternalModule());
|
||||
EXPECT_THAT(p->module().to_str(), HasSubstr("S -> __struct_"));
|
||||
EXPECT_THAT(p->module().to_str(), HasSubstr("S Struct"));
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, NamedTypes_NamedStruct) {
|
||||
@@ -50,7 +50,7 @@ TEST_F(SpvParserTest, NamedTypes_NamedStruct) {
|
||||
%s = OpTypeStruct %uint %uint
|
||||
)"));
|
||||
EXPECT_TRUE(p->BuildAndParseInternalModule());
|
||||
EXPECT_THAT(p->module().to_str(), HasSubstr("mystruct -> __struct_"));
|
||||
EXPECT_THAT(p->module().to_str(), HasSubstr("mystruct Struct"));
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, NamedTypes_Dup_EmitBoth) {
|
||||
@@ -60,13 +60,11 @@ TEST_F(SpvParserTest, NamedTypes_Dup_EmitBoth) {
|
||||
%s2 = OpTypeStruct %uint %uint
|
||||
)"));
|
||||
EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
|
||||
EXPECT_THAT(p->module().to_str(), HasSubstr(R"(S -> __struct_S
|
||||
Struct{
|
||||
EXPECT_THAT(p->module().to_str(), HasSubstr(R"(S Struct{
|
||||
StructMember{field0: __u32}
|
||||
StructMember{field1: __u32}
|
||||
}
|
||||
S_1 -> __struct_S_1
|
||||
Struct{
|
||||
S_1 Struct{
|
||||
StructMember{field0: __u32}
|
||||
StructMember{field1: __u32}
|
||||
})"));
|
||||
|
||||
@@ -168,17 +168,17 @@ Token ParserImpl::peek() {
|
||||
return peek(0);
|
||||
}
|
||||
|
||||
void ParserImpl::register_alias(const std::string& name,
|
||||
ast::type::Type* type) {
|
||||
void ParserImpl::register_constructed(const std::string& name,
|
||||
ast::type::Type* type) {
|
||||
assert(type);
|
||||
registered_aliases_[name] = type;
|
||||
registered_constructs_[name] = type;
|
||||
}
|
||||
|
||||
ast::type::Type* ParserImpl::get_alias(const std::string& name) {
|
||||
if (registered_aliases_.find(name) == registered_aliases_.end()) {
|
||||
ast::type::Type* ParserImpl::get_constructed(const std::string& name) {
|
||||
if (registered_constructs_.find(name) == registered_constructs_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return registered_aliases_[name];
|
||||
return registered_constructs_[name];
|
||||
}
|
||||
|
||||
bool ParserImpl::Parse() {
|
||||
@@ -206,11 +206,13 @@ void ParserImpl::translation_unit() {
|
||||
// | global_variable_decl SEMICLON
|
||||
// | global_constant_decl SEMICOLON
|
||||
// | type_alias SEMICOLON
|
||||
// | struct_decl SEMICOLON
|
||||
// | function_decl
|
||||
void ParserImpl::global_decl() {
|
||||
auto t = peek();
|
||||
if (t.IsEof())
|
||||
if (t.IsEof()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.IsSemicolon()) {
|
||||
next(); // consume the peek
|
||||
@@ -218,8 +220,9 @@ void ParserImpl::global_decl() {
|
||||
}
|
||||
|
||||
auto gv = global_variable_decl();
|
||||
if (has_error())
|
||||
if (has_error()) {
|
||||
return;
|
||||
}
|
||||
if (gv != nullptr) {
|
||||
t = next();
|
||||
if (!t.IsSemicolon()) {
|
||||
@@ -231,8 +234,9 @@ void ParserImpl::global_decl() {
|
||||
}
|
||||
|
||||
auto gc = global_constant_decl();
|
||||
if (has_error())
|
||||
if (has_error()) {
|
||||
return;
|
||||
}
|
||||
if (gc != nullptr) {
|
||||
t = next();
|
||||
if (!t.IsSemicolon()) {
|
||||
@@ -244,21 +248,39 @@ void ParserImpl::global_decl() {
|
||||
}
|
||||
|
||||
auto* ta = type_alias();
|
||||
if (has_error())
|
||||
if (has_error()) {
|
||||
return;
|
||||
}
|
||||
if (ta != nullptr) {
|
||||
t = next();
|
||||
if (!t.IsSemicolon()) {
|
||||
set_error(t, "missing ';' for type alias");
|
||||
return;
|
||||
}
|
||||
module_.AddAliasType(ta);
|
||||
module_.AddConstructedType(ta);
|
||||
return;
|
||||
}
|
||||
|
||||
auto str = struct_decl("");
|
||||
if (has_error()) {
|
||||
return;
|
||||
}
|
||||
if (str != nullptr) {
|
||||
t = next();
|
||||
if (!t.IsSemicolon()) {
|
||||
set_error(t, "missing ';' for struct declaration");
|
||||
return;
|
||||
}
|
||||
auto* type = ctx_.type_mgr().Get(std::move(str));
|
||||
register_constructed(type->AsStruct()->name(), type);
|
||||
module_.AddConstructedType(type);
|
||||
return;
|
||||
}
|
||||
|
||||
auto func = function_decl();
|
||||
if (has_error())
|
||||
if (has_error()) {
|
||||
return;
|
||||
}
|
||||
if (func != nullptr) {
|
||||
module_.AddFunction(std::move(func));
|
||||
return;
|
||||
@@ -1059,7 +1081,7 @@ ast::StorageClass ParserImpl::variable_storage_decoration() {
|
||||
// type_alias
|
||||
// : TYPE IDENT EQUAL type_decl
|
||||
// | TYPE IDENT EQUAL struct_decl
|
||||
ast::type::AliasType* ParserImpl::type_alias() {
|
||||
ast::type::Type* ParserImpl::type_alias() {
|
||||
auto t = peek();
|
||||
if (!t.IsType())
|
||||
return nullptr;
|
||||
@@ -1092,6 +1114,8 @@ ast::type::AliasType* ParserImpl::type_alias() {
|
||||
}
|
||||
|
||||
type = ctx_.type_mgr().Get(std::move(str));
|
||||
register_constructed(name, type);
|
||||
return type;
|
||||
}
|
||||
if (type == nullptr) {
|
||||
set_error(peek(), "invalid type for alias");
|
||||
@@ -1100,7 +1124,7 @@ ast::type::AliasType* ParserImpl::type_alias() {
|
||||
|
||||
auto* alias =
|
||||
ctx_.type_mgr().Get(std::make_unique<ast::type::AliasType>(name, type));
|
||||
register_alias(name, alias);
|
||||
register_constructed(name, alias);
|
||||
|
||||
return alias->AsAlias();
|
||||
}
|
||||
@@ -1133,12 +1157,12 @@ ast::type::Type* ParserImpl::type_decl() {
|
||||
auto t = peek();
|
||||
if (t.IsIdentifier()) {
|
||||
next(); // Consume the peek
|
||||
auto* alias = get_alias(t.to_str());
|
||||
if (alias == nullptr) {
|
||||
set_error(t, "unknown type alias '" + t.to_str() + "'");
|
||||
auto* ty = get_constructed(t.to_str());
|
||||
if (ty == nullptr) {
|
||||
set_error(t, "unknown constructed type '" + t.to_str() + "'");
|
||||
return nullptr;
|
||||
}
|
||||
return alias;
|
||||
return ty;
|
||||
}
|
||||
if (t.IsBool()) {
|
||||
next(); // Consume the peek
|
||||
@@ -1494,10 +1518,25 @@ std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl(
|
||||
}
|
||||
}
|
||||
|
||||
t = next();
|
||||
if (!t.IsStruct()) {
|
||||
t = peek();
|
||||
if (!decos.empty() && !t.IsStruct()) {
|
||||
set_error(t, "missing struct declaration");
|
||||
return nullptr;
|
||||
} else if (!t.IsStruct()) {
|
||||
return nullptr;
|
||||
}
|
||||
next(); // Consume the peek
|
||||
|
||||
// If there is no name this is a global struct call. This check will go
|
||||
// away when the type_alias struct entry is removed.
|
||||
std::string str_name = name;
|
||||
if (name.empty()) {
|
||||
t = next();
|
||||
if (!t.IsIdentifier()) {
|
||||
set_error(t, "missing identifier for struct declaration");
|
||||
return nullptr;
|
||||
}
|
||||
str_name = t.to_str();
|
||||
}
|
||||
|
||||
auto body = struct_body_decl();
|
||||
@@ -1506,7 +1545,7 @@ std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl(
|
||||
}
|
||||
|
||||
return std::make_unique<ast::type::StructType>(
|
||||
name,
|
||||
str_name,
|
||||
std::make_unique<ast::Struct>(source, std::move(decos), std::move(body)));
|
||||
}
|
||||
|
||||
|
||||
@@ -110,14 +110,14 @@ class ParserImpl {
|
||||
/// @param msg the error message
|
||||
void set_error(const Token& t, const std::string& msg);
|
||||
|
||||
/// Registers a type alias into the parser
|
||||
/// @param name the alias name
|
||||
/// @param type the alias'd type
|
||||
void register_alias(const std::string& name, ast::type::Type* type);
|
||||
/// Retrieves an aliased type
|
||||
/// @param name The alias name to lookup
|
||||
/// @returns the alias type for |name| or nullptr if not found
|
||||
ast::type::Type* get_alias(const std::string& name);
|
||||
/// Registers a constructed type into the parser
|
||||
/// @param name the constructed name
|
||||
/// @param type the constructed type
|
||||
void register_constructed(const std::string& name, ast::type::Type* type);
|
||||
/// Retrieves a constructed type
|
||||
/// @param name The name to lookup
|
||||
/// @returns the constructed type for |name| or nullptr if not found
|
||||
ast::type::Type* get_constructed(const std::string& name);
|
||||
|
||||
/// Parses the `translation_unit` grammar element
|
||||
void translation_unit();
|
||||
@@ -148,7 +148,7 @@ class ParserImpl {
|
||||
ast::StorageClass variable_storage_decoration();
|
||||
/// Parses a `type_alias` grammar element
|
||||
/// @returns the type alias or nullptr on error
|
||||
ast::type::AliasType* type_alias();
|
||||
ast::type::Type* type_alias();
|
||||
/// Parses a `type_decl` grammar element
|
||||
/// @returns the parsed Type or nullptr if none matched.
|
||||
ast::type::Type* type_decl();
|
||||
@@ -410,7 +410,7 @@ class ParserImpl {
|
||||
std::string error_;
|
||||
std::unique_ptr<Lexer> lexer_;
|
||||
std::deque<Token> token_queue_;
|
||||
std::unordered_map<std::string, ast::type::Type*> registered_aliases_;
|
||||
std::unordered_map<std::string, ast::type::Type*> registered_constructs_;
|
||||
ast::Module module_;
|
||||
};
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ TEST_F(ParserImplTest, ConstExpr_ConstLiteral_Invalid) {
|
||||
auto e = p->const_expr();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(e, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:1: unknown type alias 'invalid'");
|
||||
EXPECT_EQ(p->error(), "1:1: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, ConstExpr_Recursion) {
|
||||
|
||||
@@ -89,7 +89,7 @@ TEST_F(ParserImplTest, FunctionHeader_InvalidReturnType) {
|
||||
auto f = p->function_header();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(f, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:14: unknown type alias 'invalid'");
|
||||
EXPECT_EQ(p->error(), "1:14: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, FunctionHeader_MissingReturnType) {
|
||||
|
||||
@@ -51,7 +51,7 @@ TEST_F(ParserImplTest, FunctionTypeDecl_InvalidType) {
|
||||
auto* e = p->function_type_decl();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(e, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:6: unknown type alias 'invalid'");
|
||||
EXPECT_EQ(p->error(), "1:6: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -51,7 +51,7 @@ TEST_F(ParserImplTest, GlobalConstantDecl_InvalidVariable) {
|
||||
auto e = p->global_constant_decl();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(e, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:10: unknown type alias 'invalid'");
|
||||
EXPECT_EQ(p->error(), "1:10: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/ast/type/array_type.h"
|
||||
#include "src/ast/type/struct_type.h"
|
||||
#include "src/reader/wgsl/parser_impl.h"
|
||||
#include "src/reader/wgsl/parser_impl_test_helper.h"
|
||||
|
||||
@@ -43,7 +45,7 @@ TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_Invalid) {
|
||||
auto* p = parser("var<out> a : vec2<invalid>;");
|
||||
p->global_decl();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), "1:19: unknown type alias 'invalid'");
|
||||
EXPECT_EQ(p->error(), "1:19: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_MissingSemicolon) {
|
||||
@@ -85,15 +87,48 @@ TEST_F(ParserImplTest, GlobalDecl_TypeAlias) {
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
||||
auto m = p->module();
|
||||
ASSERT_EQ(m.alias_types().size(), 1u);
|
||||
EXPECT_EQ(m.alias_types()[0]->name(), "A");
|
||||
ASSERT_EQ(m.constructed_types().size(), 1u);
|
||||
ASSERT_TRUE(m.constructed_types()[0]->IsAlias());
|
||||
EXPECT_EQ(m.constructed_types()[0]->AsAlias()->name(), "A");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_TypeAlias_Struct) {
|
||||
auto* p = parser("type A = struct { a : f32; };");
|
||||
p->global_decl();
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
||||
auto m = p->module();
|
||||
ASSERT_EQ(m.constructed_types().size(), 1u);
|
||||
ASSERT_TRUE(m.constructed_types()[0]->IsStruct());
|
||||
EXPECT_EQ(m.constructed_types()[0]->AsStruct()->name(), "A");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_TypeAlias_StructIdent) {
|
||||
auto* p = parser(R"(struct A {
|
||||
a : f32;
|
||||
};
|
||||
type B = A;)");
|
||||
p->global_decl();
|
||||
p->global_decl();
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
||||
auto m = p->module();
|
||||
ASSERT_EQ(m.constructed_types().size(), 2u);
|
||||
ASSERT_TRUE(m.constructed_types()[0]->IsStruct());
|
||||
auto* str = m.constructed_types()[0]->AsStruct();
|
||||
EXPECT_EQ(str->name(), "A");
|
||||
|
||||
ASSERT_TRUE(m.constructed_types()[1]->IsAlias());
|
||||
auto* alias = m.constructed_types()[1]->AsAlias();
|
||||
EXPECT_EQ(alias->name(), "B");
|
||||
EXPECT_EQ(alias->type(), str);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_TypeAlias_Invalid) {
|
||||
auto* p = parser("type A = invalid;");
|
||||
p->global_decl();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), "1:10: unknown type alias 'invalid'");
|
||||
EXPECT_EQ(p->error(), "1:10: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_TypeAlias_MissingSemicolon) {
|
||||
@@ -130,6 +165,95 @@ TEST_F(ParserImplTest, GlobalDecl_Function_Invalid) {
|
||||
EXPECT_EQ(p->error(), "1:14: unable to determine function return type");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_ParsesStruct) {
|
||||
auto* p = parser("struct A { b: i32; c: f32;};");
|
||||
p->global_decl();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
|
||||
auto m = p->module();
|
||||
ASSERT_EQ(m.constructed_types().size(), 1u);
|
||||
|
||||
auto* t = m.constructed_types()[0];
|
||||
ASSERT_NE(t, nullptr);
|
||||
ASSERT_TRUE(t->IsStruct());
|
||||
|
||||
auto* str = t->AsStruct();
|
||||
EXPECT_EQ(str->name(), "A");
|
||||
EXPECT_EQ(str->impl()->members().size(), 2u);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_Struct_WithStride) {
|
||||
auto* p =
|
||||
parser("struct A { [[offset(0)]] data: [[stride(4)]] array<f32>; };");
|
||||
p->global_decl();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
|
||||
auto m = p->module();
|
||||
ASSERT_EQ(m.constructed_types().size(), 1u);
|
||||
|
||||
auto* t = m.constructed_types()[0];
|
||||
ASSERT_NE(t, nullptr);
|
||||
ASSERT_TRUE(t->IsStruct());
|
||||
|
||||
auto* str = t->AsStruct();
|
||||
EXPECT_EQ(str->name(), "A");
|
||||
EXPECT_EQ(str->impl()->members().size(), 1u);
|
||||
EXPECT_FALSE(str->IsBlockDecorated());
|
||||
|
||||
const auto* ty = str->impl()->members()[0]->type();
|
||||
ASSERT_TRUE(ty->IsArray());
|
||||
const auto* arr = ty->AsArray();
|
||||
EXPECT_TRUE(arr->has_array_stride());
|
||||
EXPECT_EQ(arr->array_stride(), 4u);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_Struct_WithDecoration) {
|
||||
auto* p = parser("[[block]] struct A { [[offset(0)]] data: f32; };");
|
||||
p->global_decl();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
|
||||
auto m = p->module();
|
||||
ASSERT_EQ(m.constructed_types().size(), 1u);
|
||||
|
||||
auto* t = m.constructed_types()[0];
|
||||
ASSERT_NE(t, nullptr);
|
||||
ASSERT_TRUE(t->IsStruct());
|
||||
|
||||
auto* str = t->AsStruct();
|
||||
EXPECT_EQ(str->name(), "A");
|
||||
EXPECT_EQ(str->impl()->members().size(), 1u);
|
||||
EXPECT_TRUE(str->IsBlockDecorated());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_Struct_Invalid) {
|
||||
auto* p = parser("[[block]] A {};");
|
||||
p->global_decl();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), "1:11: missing struct declaration");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalDecl_StructMissing_Semi) {
|
||||
auto* p = parser("[[block]] struct A {}");
|
||||
p->global_decl();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), "1:22: missing ';' for struct declaration");
|
||||
}
|
||||
|
||||
// This was failing due to not finding the missing ;. https://crbug.com/tint/218
|
||||
TEST_F(ParserImplTest, TypeDecl_Struct_Empty) {
|
||||
auto* p = parser("type str = struct {};");
|
||||
p->global_decl();
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
||||
auto module = p->module();
|
||||
ASSERT_EQ(module.constructed_types().size(), 1u);
|
||||
|
||||
ASSERT_TRUE(module.constructed_types()[0]->IsStruct());
|
||||
auto* str = module.constructed_types()[0]->AsStruct();
|
||||
EXPECT_EQ(str->name(), "str");
|
||||
EXPECT_EQ(str->impl()->members().size(), 0u);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace wgsl
|
||||
} // namespace reader
|
||||
|
||||
@@ -221,7 +221,7 @@ TEST_F(ParserImplTest, PrimaryExpression_Bitcast_InvalidType) {
|
||||
auto e = p->primary_expression();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(e, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:9: unknown type alias 'invalid'");
|
||||
EXPECT_EQ(p->error(), "1:9: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingLeftParen) {
|
||||
|
||||
@@ -24,6 +24,21 @@ namespace {
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_Parses) {
|
||||
auto* p = parser(R"(
|
||||
struct S {
|
||||
a : i32;
|
||||
[[offset(4)]] b : f32;
|
||||
})");
|
||||
auto s = p->struct_decl("");
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(s, nullptr);
|
||||
ASSERT_EQ(s->name(), "S");
|
||||
ASSERT_EQ(s->impl()->members().size(), 2u);
|
||||
EXPECT_EQ(s->impl()->members()[0]->name(), "a");
|
||||
EXPECT_EQ(s->impl()->members()[1]->name(), "b");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_Parses_WithoutName) {
|
||||
auto* p = parser(R"(
|
||||
struct {
|
||||
a : i32;
|
||||
[[offset(4)]] b : f32;
|
||||
@@ -39,11 +54,11 @@ struct {
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_ParsesWithDecoration) {
|
||||
auto* p = parser(R"(
|
||||
[[block]] struct {
|
||||
[[block]] struct B {
|
||||
a : f32;
|
||||
b : f32;
|
||||
})");
|
||||
auto s = p->struct_decl("B");
|
||||
auto s = p->struct_decl("");
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(s, nullptr);
|
||||
ASSERT_EQ(s->name(), "B");
|
||||
@@ -57,11 +72,11 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithDecoration) {
|
||||
TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
|
||||
auto* p = parser(R"(
|
||||
[[block]]
|
||||
[[block]] struct {
|
||||
[[block]] struct S {
|
||||
a : f32;
|
||||
b : f32;
|
||||
})");
|
||||
auto s = p->struct_decl("S");
|
||||
auto s = p->struct_decl("");
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(s, nullptr);
|
||||
ASSERT_EQ(s->name(), "S");
|
||||
@@ -74,40 +89,48 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_EmptyMembers) {
|
||||
auto* p = parser("struct {}");
|
||||
auto s = p->struct_decl("S");
|
||||
auto* p = parser("struct S {}");
|
||||
auto s = p->struct_decl("");
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(s, nullptr);
|
||||
ASSERT_EQ(s->impl()->members().size(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_MissingBracketLeft) {
|
||||
auto* p = parser("struct }");
|
||||
auto s = p->struct_decl("S");
|
||||
TEST_F(ParserImplTest, StructDecl_MissingIdent) {
|
||||
auto* p = parser("struct {}");
|
||||
auto s = p->struct_decl("");
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(s, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:8: missing { for struct declaration");
|
||||
EXPECT_EQ(p->error(), "1:8: missing identifier for struct declaration");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_MissingBracketLeft) {
|
||||
auto* p = parser("struct S }");
|
||||
auto s = p->struct_decl("");
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(s, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:10: missing { for struct declaration");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_InvalidStructBody) {
|
||||
auto* p = parser("struct { a : B; }");
|
||||
auto s = p->struct_decl("S");
|
||||
auto* p = parser("struct S { a : B; }");
|
||||
auto s = p->struct_decl("");
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(s, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:14: unknown type alias 'B'");
|
||||
EXPECT_EQ(p->error(), "1:16: unknown constructed type 'B'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_InvalidStructDecorationDecl) {
|
||||
auto* p = parser("[[block struct { a : i32; }");
|
||||
auto s = p->struct_decl("S");
|
||||
auto* p = parser("[[block struct S { a : i32; }");
|
||||
auto s = p->struct_decl("");
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(s, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:9: missing ]] for struct decoration");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_MissingStruct) {
|
||||
auto* p = parser("[[block]] {}");
|
||||
auto s = p->struct_decl("S");
|
||||
auto* p = parser("[[block]] S {}");
|
||||
auto s = p->struct_decl("");
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(s, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:11: missing struct declaration");
|
||||
|
||||
@@ -83,7 +83,7 @@ TEST_F(ParserImplTest, StructMember_InvalidVariable) {
|
||||
auto m = p->struct_member();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(m, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:19: unknown type alias 'B'");
|
||||
EXPECT_EQ(p->error(), "1:19: unknown constructed type 'B'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructMember_MissingSemicolon) {
|
||||
|
||||
@@ -58,16 +58,16 @@ fn main() -> { # missing return type
|
||||
TEST_F(ParserImplTest, GetRegisteredType) {
|
||||
auto* p = parser("");
|
||||
ast::type::I32Type i32;
|
||||
p->register_alias("my_alias", &i32);
|
||||
p->register_constructed("my_alias", &i32);
|
||||
|
||||
auto* alias = p->get_alias("my_alias");
|
||||
auto* alias = p->get_constructed("my_alias");
|
||||
ASSERT_NE(alias, nullptr);
|
||||
ASSERT_EQ(alias, &i32);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GetUnregisteredType) {
|
||||
auto* p = parser("");
|
||||
auto* alias = p->get_alias("my_alias");
|
||||
auto* alias = p->get_constructed("my_alias");
|
||||
ASSERT_EQ(alias, nullptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_Invalid) {
|
||||
auto* t = p->texture_sampler_types();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
EXPECT_EQ(t, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:20: unknown type alias 'abc'");
|
||||
EXPECT_EQ(p->error(), "1:20: unknown constructed type 'abc'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingType) {
|
||||
@@ -140,7 +140,7 @@ TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_Invalid) {
|
||||
auto* t = p->texture_sampler_types();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
EXPECT_EQ(t, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:25: unknown type alias 'abc'");
|
||||
EXPECT_EQ(p->error(), "1:25: unknown constructed type 'abc'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingType) {
|
||||
|
||||
@@ -33,20 +33,28 @@ TEST_F(ParserImplTest, TypeDecl_ParsesType) {
|
||||
auto* t = p->type_alias();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(t, nullptr);
|
||||
ASSERT_TRUE(t->type()->IsI32());
|
||||
ASSERT_EQ(t->type(), i32);
|
||||
ASSERT_TRUE(t->IsAlias());
|
||||
auto* alias = t->AsAlias();
|
||||
ASSERT_TRUE(alias->type()->IsI32());
|
||||
ASSERT_EQ(alias->type(), i32);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_ParsesStruct) {
|
||||
auto* p = parser("type a = struct { b: i32; c: f32;}");
|
||||
TEST_F(ParserImplTest, TypeDecl_ParsesStruct_Ident) {
|
||||
ast::type::StructType str("B", {});
|
||||
|
||||
auto* p = parser("type a = B");
|
||||
p->register_constructed("B", &str);
|
||||
|
||||
auto* t = p->type_alias();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(t, nullptr);
|
||||
EXPECT_EQ(t->name(), "a");
|
||||
ASSERT_TRUE(t->type()->IsStruct());
|
||||
ASSERT_TRUE(t->IsAlias());
|
||||
auto* alias = t->AsAlias();
|
||||
EXPECT_EQ(alias->name(), "a");
|
||||
ASSERT_TRUE(alias->type()->IsStruct());
|
||||
|
||||
auto* s = t->type()->AsStruct();
|
||||
EXPECT_EQ(s->impl()->members().size(), 2u);
|
||||
auto* s = alias->type()->AsStruct();
|
||||
EXPECT_EQ(s->name(), "B");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_MissingIdent) {
|
||||
@@ -78,7 +86,18 @@ TEST_F(ParserImplTest, TypeDecl_InvalidType) {
|
||||
auto* t = p->type_alias();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(t, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:10: unknown type alias 'B'");
|
||||
EXPECT_EQ(p->error(), "1:10: unknown constructed type 'B'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_ParsesStruct) {
|
||||
auto* p = parser("type a = struct { b: i32; c: f32;}");
|
||||
auto* t = p->type_alias();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(t, nullptr);
|
||||
ASSERT_TRUE(t->IsStruct());
|
||||
auto* str = t->AsStruct();
|
||||
EXPECT_EQ(str->name(), "a");
|
||||
EXPECT_EQ(str->impl()->members().size(), 2u);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_InvalidStruct) {
|
||||
@@ -97,35 +116,30 @@ TEST_F(ParserImplTest, TypeDecl_Struct_WithStride) {
|
||||
auto* t = p->type_alias();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(t, nullptr);
|
||||
EXPECT_EQ(t->name(), "a");
|
||||
ASSERT_TRUE(t->type()->IsStruct());
|
||||
ASSERT_TRUE(t->IsStruct());
|
||||
auto* str = t->AsStruct();
|
||||
EXPECT_EQ(str->name(), "a");
|
||||
EXPECT_EQ(str->impl()->members().size(), 1u);
|
||||
|
||||
auto* s = t->type()->AsStruct();
|
||||
EXPECT_EQ(s->impl()->members().size(), 1u);
|
||||
|
||||
const auto* ty = s->impl()->members()[0]->type();
|
||||
const auto* ty = str->impl()->members()[0]->type();
|
||||
ASSERT_TRUE(ty->IsArray());
|
||||
const auto* arr = ty->AsArray();
|
||||
EXPECT_TRUE(arr->has_array_stride());
|
||||
EXPECT_EQ(arr->array_stride(), 4u);
|
||||
}
|
||||
|
||||
// This was failing due to not finding the missing ;. https://crbug.com/tint/218
|
||||
TEST_F(ParserImplTest, TypeDecl_Struct_Empty) {
|
||||
auto* p = parser("type str = struct {};");
|
||||
p->global_decl();
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
||||
auto module = p->module();
|
||||
ASSERT_EQ(module.alias_types().size(), 1u);
|
||||
ASSERT_EQ(module.constructed_types().size(), 1u);
|
||||
|
||||
auto* t = module.alias_types()[0];
|
||||
ASSERT_NE(t, nullptr);
|
||||
EXPECT_EQ(t->name(), "str");
|
||||
|
||||
ASSERT_TRUE(t->type()->IsStruct());
|
||||
auto* s = t->type()->AsStruct();
|
||||
EXPECT_EQ(s->impl()->members().size(), 0u);
|
||||
ASSERT_TRUE(module.constructed_types()[0]->IsStruct());
|
||||
auto* str = module.constructed_types()[0]->AsStruct();
|
||||
EXPECT_EQ(str->name(), "str");
|
||||
EXPECT_EQ(str->impl()->members().size(), 0u);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -50,7 +50,7 @@ TEST_F(ParserImplTest, TypeDecl_Identifier) {
|
||||
auto* alias_type =
|
||||
tm()->Get(std::make_unique<ast::type::AliasType>("A", int_type));
|
||||
|
||||
p->register_alias("A", alias_type);
|
||||
p->register_constructed("A", alias_type);
|
||||
|
||||
auto* t = p->type_decl();
|
||||
ASSERT_NE(t, nullptr);
|
||||
@@ -68,7 +68,7 @@ TEST_F(ParserImplTest, TypeDecl_Identifier_NotFound) {
|
||||
auto* t = p->type_decl();
|
||||
ASSERT_EQ(t, nullptr);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), "1:1: unknown type alias 'B'");
|
||||
EXPECT_EQ(p->error(), "1:1: unknown constructed type 'B'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Bool) {
|
||||
@@ -248,7 +248,7 @@ TEST_P(VecBadType, Handles_Unknown_Type) {
|
||||
auto* t = p->type_decl();
|
||||
ASSERT_EQ(t, nullptr);
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(p->error(), "1:6: unknown type alias 'unknown'");
|
||||
ASSERT_EQ(p->error(), "1:6: unknown constructed type 'unknown'");
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||
VecBadType,
|
||||
@@ -378,7 +378,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_BadType) {
|
||||
auto* t = p->type_decl();
|
||||
ASSERT_EQ(t, nullptr);
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(p->error(), "1:15: unknown type alias 'unknown'");
|
||||
ASSERT_EQ(p->error(), "1:15: unknown constructed type 'unknown'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array) {
|
||||
@@ -544,7 +544,7 @@ TEST_F(ParserImplTest, TypeDecl_Array_BadType) {
|
||||
auto* t = p->type_decl();
|
||||
ASSERT_EQ(t, nullptr);
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(p->error(), "1:7: unknown type alias 'unknown'");
|
||||
ASSERT_EQ(p->error(), "1:7: unknown constructed type 'unknown'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_ZeroSize) {
|
||||
@@ -746,7 +746,7 @@ TEST_P(MatrixBadType, Handles_Unknown_Type) {
|
||||
auto* t = p->type_decl();
|
||||
ASSERT_EQ(t, nullptr);
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(p->error(), "1:8: unknown type alias 'unknown'");
|
||||
ASSERT_EQ(p->error(), "1:8: unknown constructed type 'unknown'");
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||
MatrixBadType,
|
||||
|
||||
@@ -76,7 +76,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_InvalidType) {
|
||||
auto* p = parser("my_var : invalid");
|
||||
auto r = p->variable_ident_decl();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(p->error(), "1:10: unknown type alias 'invalid'");
|
||||
ASSERT_EQ(p->error(), "1:10: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -53,7 +53,7 @@ TEST_F(ParserImplTest, VariableStmt_VariableDecl_Invalid) {
|
||||
auto e = p->variable_stmt();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(e, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:9: unknown type alias 'invalid'");
|
||||
EXPECT_EQ(p->error(), "1:9: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, VariableStmt_VariableDecl_ConstructorInvalid) {
|
||||
@@ -77,7 +77,7 @@ TEST_F(ParserImplTest, VariableStmt_Const_InvalidVarIdent) {
|
||||
auto e = p->variable_stmt();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(e, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:11: unknown type alias 'invalid'");
|
||||
EXPECT_EQ(p->error(), "1:11: unknown constructed type 'invalid'");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, VariableStmt_Const_MissingEqual) {
|
||||
|
||||
Reference in New Issue
Block a user