Remove type alias struct variant.
This CL removes the `type IDENT = struct` format in favour of the `struct IDENT` variant. Bug: tint:175 Change-Id: I4fde8012fd07f811cd0bd80445198f6bbc92b720 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/30661 Commit-Queue: dan sinclair <dsinclair@chromium.org> Commit-Queue: Ryan Harrison <rharrison@chromium.org> Reviewed-by: Ryan Harrison <rharrison@chromium.org>
This commit is contained in:
parent
4f79c84050
commit
0ce0704741
|
@ -261,7 +261,7 @@ void ParserImpl::global_decl() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto str = struct_decl("");
|
auto str = struct_decl();
|
||||||
if (has_error()) {
|
if (has_error()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1080,7 +1080,6 @@ ast::StorageClass ParserImpl::variable_storage_decoration() {
|
||||||
|
|
||||||
// type_alias
|
// type_alias
|
||||||
// : TYPE IDENT EQUAL type_decl
|
// : TYPE IDENT EQUAL type_decl
|
||||||
// | TYPE IDENT EQUAL struct_decl
|
|
||||||
ast::type::Type* ParserImpl::type_alias() {
|
ast::type::Type* ParserImpl::type_alias() {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (!t.IsType())
|
if (!t.IsType())
|
||||||
|
@ -1105,17 +1104,8 @@ ast::type::Type* ParserImpl::type_alias() {
|
||||||
if (has_error())
|
if (has_error())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (type == nullptr) {
|
if (type == nullptr) {
|
||||||
auto str = struct_decl(name);
|
set_error(peek(), "invalid type alias");
|
||||||
if (has_error())
|
return nullptr;
|
||||||
return nullptr;
|
|
||||||
if (str == nullptr) {
|
|
||||||
set_error(peek(), "invalid type alias");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = ctx_.type_mgr().Get(std::move(str));
|
|
||||||
register_constructed(name, type);
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
if (type == nullptr) {
|
if (type == nullptr) {
|
||||||
set_error(peek(), "invalid type for alias");
|
set_error(peek(), "invalid type for alias");
|
||||||
|
@ -1501,9 +1491,8 @@ ast::StorageClass ParserImpl::storage_class() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct_decl
|
// struct_decl
|
||||||
// : struct_decoration_decl* STRUCT struct_body_decl
|
// : struct_decoration_decl* STRUCT IDENT struct_body_decl
|
||||||
std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl(
|
std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl() {
|
||||||
const std::string& name) {
|
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
auto source = t.source();
|
auto source = t.source();
|
||||||
|
|
||||||
|
@ -1527,17 +1516,12 @@ std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl(
|
||||||
}
|
}
|
||||||
next(); // Consume the peek
|
next(); // Consume the peek
|
||||||
|
|
||||||
// If there is no name this is a global struct call. This check will go
|
t = next();
|
||||||
// away when the type_alias struct entry is removed.
|
if (!t.IsIdentifier()) {
|
||||||
std::string str_name = name;
|
set_error(t, "missing identifier for struct declaration");
|
||||||
if (name.empty()) {
|
return nullptr;
|
||||||
t = next();
|
|
||||||
if (!t.IsIdentifier()) {
|
|
||||||
set_error(t, "missing identifier for struct declaration");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
str_name = t.to_str();
|
|
||||||
}
|
}
|
||||||
|
auto name = t.to_str();
|
||||||
|
|
||||||
auto body = struct_body_decl();
|
auto body = struct_body_decl();
|
||||||
if (has_error()) {
|
if (has_error()) {
|
||||||
|
@ -1545,7 +1529,7 @@ std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl(
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_unique<ast::type::StructType>(
|
return std::make_unique<ast::type::StructType>(
|
||||||
str_name,
|
name,
|
||||||
std::make_unique<ast::Struct>(source, std::move(decos), std::move(body)));
|
std::make_unique<ast::Struct>(source, std::move(decos), std::move(body)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,9 +156,8 @@ class ParserImpl {
|
||||||
/// @returns the storage class or StorageClass::kNone if none matched
|
/// @returns the storage class or StorageClass::kNone if none matched
|
||||||
ast::StorageClass storage_class();
|
ast::StorageClass storage_class();
|
||||||
/// Parses a `struct_decl` grammar element
|
/// Parses a `struct_decl` grammar element
|
||||||
/// @param name the name of the struct
|
|
||||||
/// @returns the struct type or nullptr on error
|
/// @returns the struct type or nullptr on error
|
||||||
std::unique_ptr<ast::type::StructType> struct_decl(const std::string& name);
|
std::unique_ptr<ast::type::StructType> struct_decl();
|
||||||
/// Parses a `struct_decoration_decl` grammar element, appending newly
|
/// Parses a `struct_decoration_decl` grammar element, appending newly
|
||||||
/// parsed decorations to the end of |decos|.
|
/// parsed decorations to the end of |decos|.
|
||||||
/// @param decos list to store the parsed decorations
|
/// @param decos list to store the parsed decorations
|
||||||
|
|
|
@ -92,17 +92,6 @@ TEST_F(ParserImplTest, GlobalDecl_TypeAlias) {
|
||||||
EXPECT_EQ(m.constructed_types()[0]->AsAlias()->name(), "A");
|
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) {
|
TEST_F(ParserImplTest, GlobalDecl_TypeAlias_StructIdent) {
|
||||||
auto* p = parser(R"(struct A {
|
auto* p = parser(R"(struct A {
|
||||||
a : f32;
|
a : f32;
|
||||||
|
@ -239,21 +228,6 @@ TEST_F(ParserImplTest, GlobalDecl_StructMissing_Semi) {
|
||||||
EXPECT_EQ(p->error(), "1:22: missing ';' for struct declaration");
|
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
|
||||||
} // namespace wgsl
|
} // namespace wgsl
|
||||||
} // namespace reader
|
} // namespace reader
|
||||||
|
|
|
@ -28,22 +28,7 @@ struct S {
|
||||||
a : i32;
|
a : i32;
|
||||||
[[offset(4)]] b : f32;
|
[[offset(4)]] b : f32;
|
||||||
})");
|
})");
|
||||||
auto s = p->struct_decl("");
|
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;
|
|
||||||
})");
|
|
||||||
auto s = p->struct_decl("S");
|
|
||||||
ASSERT_FALSE(p->has_error());
|
ASSERT_FALSE(p->has_error());
|
||||||
ASSERT_NE(s, nullptr);
|
ASSERT_NE(s, nullptr);
|
||||||
ASSERT_EQ(s->name(), "S");
|
ASSERT_EQ(s->name(), "S");
|
||||||
|
@ -58,7 +43,7 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithDecoration) {
|
||||||
a : f32;
|
a : f32;
|
||||||
b : f32;
|
b : f32;
|
||||||
})");
|
})");
|
||||||
auto s = p->struct_decl("");
|
auto s = p->struct_decl();
|
||||||
ASSERT_FALSE(p->has_error());
|
ASSERT_FALSE(p->has_error());
|
||||||
ASSERT_NE(s, nullptr);
|
ASSERT_NE(s, nullptr);
|
||||||
ASSERT_EQ(s->name(), "B");
|
ASSERT_EQ(s->name(), "B");
|
||||||
|
@ -76,7 +61,7 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
|
||||||
a : f32;
|
a : f32;
|
||||||
b : f32;
|
b : f32;
|
||||||
})");
|
})");
|
||||||
auto s = p->struct_decl("");
|
auto s = p->struct_decl();
|
||||||
ASSERT_FALSE(p->has_error());
|
ASSERT_FALSE(p->has_error());
|
||||||
ASSERT_NE(s, nullptr);
|
ASSERT_NE(s, nullptr);
|
||||||
ASSERT_EQ(s->name(), "S");
|
ASSERT_EQ(s->name(), "S");
|
||||||
|
@ -90,7 +75,7 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, StructDecl_EmptyMembers) {
|
TEST_F(ParserImplTest, StructDecl_EmptyMembers) {
|
||||||
auto* p = parser("struct S {}");
|
auto* p = parser("struct S {}");
|
||||||
auto s = p->struct_decl("");
|
auto s = p->struct_decl();
|
||||||
ASSERT_FALSE(p->has_error());
|
ASSERT_FALSE(p->has_error());
|
||||||
ASSERT_NE(s, nullptr);
|
ASSERT_NE(s, nullptr);
|
||||||
ASSERT_EQ(s->impl()->members().size(), 0u);
|
ASSERT_EQ(s->impl()->members().size(), 0u);
|
||||||
|
@ -98,7 +83,7 @@ TEST_F(ParserImplTest, StructDecl_EmptyMembers) {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, StructDecl_MissingIdent) {
|
TEST_F(ParserImplTest, StructDecl_MissingIdent) {
|
||||||
auto* p = parser("struct {}");
|
auto* p = parser("struct {}");
|
||||||
auto s = p->struct_decl("");
|
auto s = p->struct_decl();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(s, nullptr);
|
ASSERT_EQ(s, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:8: missing identifier for struct declaration");
|
EXPECT_EQ(p->error(), "1:8: missing identifier for struct declaration");
|
||||||
|
@ -106,7 +91,7 @@ TEST_F(ParserImplTest, StructDecl_MissingIdent) {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, StructDecl_MissingBracketLeft) {
|
TEST_F(ParserImplTest, StructDecl_MissingBracketLeft) {
|
||||||
auto* p = parser("struct S }");
|
auto* p = parser("struct S }");
|
||||||
auto s = p->struct_decl("");
|
auto s = p->struct_decl();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(s, nullptr);
|
ASSERT_EQ(s, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:10: missing { for struct declaration");
|
EXPECT_EQ(p->error(), "1:10: missing { for struct declaration");
|
||||||
|
@ -114,7 +99,7 @@ TEST_F(ParserImplTest, StructDecl_MissingBracketLeft) {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, StructDecl_InvalidStructBody) {
|
TEST_F(ParserImplTest, StructDecl_InvalidStructBody) {
|
||||||
auto* p = parser("struct S { a : B; }");
|
auto* p = parser("struct S { a : B; }");
|
||||||
auto s = p->struct_decl("");
|
auto s = p->struct_decl();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(s, nullptr);
|
ASSERT_EQ(s, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:16: unknown constructed type 'B'");
|
EXPECT_EQ(p->error(), "1:16: unknown constructed type 'B'");
|
||||||
|
@ -122,7 +107,7 @@ TEST_F(ParserImplTest, StructDecl_InvalidStructBody) {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, StructDecl_InvalidStructDecorationDecl) {
|
TEST_F(ParserImplTest, StructDecl_InvalidStructDecorationDecl) {
|
||||||
auto* p = parser("[[block struct S { a : i32; }");
|
auto* p = parser("[[block struct S { a : i32; }");
|
||||||
auto s = p->struct_decl("");
|
auto s = p->struct_decl();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(s, nullptr);
|
ASSERT_EQ(s, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:9: missing ]] for struct decoration");
|
EXPECT_EQ(p->error(), "1:9: missing ]] for struct decoration");
|
||||||
|
@ -130,7 +115,7 @@ TEST_F(ParserImplTest, StructDecl_InvalidStructDecorationDecl) {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, StructDecl_MissingStruct) {
|
TEST_F(ParserImplTest, StructDecl_MissingStruct) {
|
||||||
auto* p = parser("[[block]] S {}");
|
auto* p = parser("[[block]] S {}");
|
||||||
auto s = p->struct_decl("");
|
auto s = p->struct_decl();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(s, nullptr);
|
ASSERT_EQ(s, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:11: missing struct declaration");
|
EXPECT_EQ(p->error(), "1:11: missing struct declaration");
|
||||||
|
|
|
@ -89,59 +89,6 @@ TEST_F(ParserImplTest, TypeDecl_InvalidType) {
|
||||||
EXPECT_EQ(p->error(), "1:10: unknown constructed type '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) {
|
|
||||||
auto* p = parser("type a = [[block]] {}");
|
|
||||||
auto* t = p->type_alias();
|
|
||||||
ASSERT_TRUE(p->has_error());
|
|
||||||
ASSERT_EQ(t, nullptr);
|
|
||||||
EXPECT_EQ(p->error(), "1:20: missing struct declaration");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, TypeDecl_Struct_WithStride) {
|
|
||||||
auto* p = parser(
|
|
||||||
"type a = [[block]] struct { [[offset(0)]] data: [[stride(4)]] "
|
|
||||||
"array<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(), 1u);
|
|
||||||
|
|
||||||
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, 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
|
||||||
} // namespace wgsl
|
} // namespace wgsl
|
||||||
} // namespace reader
|
} // namespace reader
|
||||||
|
|
|
@ -202,22 +202,22 @@ bool GeneratorImpl::EmitConstructedType(std::ostream& out,
|
||||||
|
|
||||||
if (ty->IsAlias()) {
|
if (ty->IsAlias()) {
|
||||||
auto* alias = ty->AsAlias();
|
auto* alias = ty->AsAlias();
|
||||||
// This will go away once type_alias doesn't accept anonymous
|
// HLSL typedef is for intrinsic types only. For an alias'd struct,
|
||||||
// structs anymore
|
// generate a secondary struct with the new name.
|
||||||
if (alias->type()->IsStruct() &&
|
if (alias->type()->IsStruct()) {
|
||||||
alias->type()->AsStruct()->name() == alias->name()) {
|
if (!EmitStructType(out, alias->type()->AsStruct(), alias->name())) {
|
||||||
if (!EmitStructType(out, alias->type()->AsStruct())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
return true;
|
||||||
out << "typedef ";
|
|
||||||
if (!EmitType(out, alias->type(), "")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
out << " " << namer_.NameFor(alias->name()) << ";" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
out << "typedef ";
|
||||||
|
if (!EmitType(out, alias->type(), "")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out << " " << namer_.NameFor(alias->name()) << ";" << std::endl;
|
||||||
} else if (ty->IsStruct()) {
|
} else if (ty->IsStruct()) {
|
||||||
if (!EmitStructType(out, ty->AsStruct())) {
|
auto* str = ty->AsStruct();
|
||||||
|
if (!EmitStructType(out, str, str->name())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1975,11 +1975,12 @@ bool GeneratorImpl::EmitType(std::ostream& out,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitStructType(std::ostream& out,
|
bool GeneratorImpl::EmitStructType(std::ostream& out,
|
||||||
const ast::type::StructType* str) {
|
const ast::type::StructType* str,
|
||||||
|
const std::string& name) {
|
||||||
// TODO(dsinclair): Block decoration?
|
// TODO(dsinclair): Block decoration?
|
||||||
// if (str->impl()->decoration() != ast::StructDecoration::kNone) {
|
// if (str->impl()->decoration() != ast::StructDecoration::kNone) {
|
||||||
// }
|
// }
|
||||||
out << "struct " << str->name() << " {" << std::endl;
|
out << "struct " << name << " {" << std::endl;
|
||||||
|
|
||||||
increment_indent();
|
increment_indent();
|
||||||
for (const auto& mem : str->impl()->members()) {
|
for (const auto& mem : str->impl()->members()) {
|
||||||
|
|
|
@ -264,8 +264,11 @@ class GeneratorImpl {
|
||||||
/// Handles generating a structure declaration
|
/// Handles generating a structure declaration
|
||||||
/// @param out the output stream
|
/// @param out the output stream
|
||||||
/// @param ty the struct to generate
|
/// @param ty the struct to generate
|
||||||
|
/// @param name the struct name
|
||||||
/// @returns true if the struct is emitted
|
/// @returns true if the struct is emitted
|
||||||
bool EmitStructType(std::ostream& out, const ast::type::StructType* ty);
|
bool EmitStructType(std::ostream& out,
|
||||||
|
const ast::type::StructType* ty,
|
||||||
|
const std::string& name);
|
||||||
/// Handles a unary op expression
|
/// Handles a unary op expression
|
||||||
/// @param pre the preamble for the expression stream
|
/// @param pre the preamble for the expression stream
|
||||||
/// @param out the output of the expression stream
|
/// @param out the output of the expression stream
|
||||||
|
|
|
@ -63,13 +63,13 @@ TEST_F(HlslGeneratorImplTest_AliasType, EmitAliasType_Struct) {
|
||||||
auto str = std::make_unique<ast::Struct>();
|
auto str = std::make_unique<ast::Struct>();
|
||||||
str->set_members(std::move(members));
|
str->set_members(std::move(members));
|
||||||
|
|
||||||
ast::type::StructType s("a", std::move(str));
|
ast::type::StructType s("A", std::move(str));
|
||||||
ast::type::AliasType alias("a", &s);
|
ast::type::AliasType alias("B", &s);
|
||||||
|
|
||||||
ast::Module m;
|
ast::Module m;
|
||||||
GeneratorImpl g(&m);
|
GeneratorImpl g(&m);
|
||||||
ASSERT_TRUE(gen().EmitConstructedType(out(), &alias)) << gen().error();
|
ASSERT_TRUE(gen().EmitConstructedType(out(), &alias)) << gen().error();
|
||||||
EXPECT_EQ(result(), R"(struct a {
|
EXPECT_EQ(result(), R"(struct B {
|
||||||
float a;
|
float a;
|
||||||
int b;
|
int b;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
#include "src/ast/struct_member_offset_decoration.h"
|
#include "src/ast/struct_member_offset_decoration.h"
|
||||||
#include "src/ast/type/alias_type.h"
|
|
||||||
#include "src/ast/type/array_type.h"
|
#include "src/ast/type/array_type.h"
|
||||||
#include "src/ast/type/f32_type.h"
|
#include "src/ast/type/f32_type.h"
|
||||||
#include "src/ast/type/i32_type.h"
|
#include "src/ast/type/i32_type.h"
|
||||||
|
@ -310,13 +309,12 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
str->set_members(std::move(members));
|
str->set_members(std::move(members));
|
||||||
|
|
||||||
ast::type::StructType s("Uniforms", std::move(str));
|
ast::type::StructType s("Uniforms", std::move(str));
|
||||||
auto alias = std::make_unique<ast::type::AliasType>("Uniforms", &s);
|
|
||||||
|
|
||||||
auto coord_var =
|
auto coord_var =
|
||||||
std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
|
std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
|
||||||
"uniforms", ast::StorageClass::kUniform, alias.get()));
|
"uniforms", ast::StorageClass::kUniform, &s));
|
||||||
|
|
||||||
mod()->AddConstructedType(alias.get());
|
mod()->AddConstructedType(&s);
|
||||||
|
|
||||||
ast::VariableDecorationList decos;
|
ast::VariableDecorationList decos;
|
||||||
decos.push_back(std::make_unique<ast::BindingDecoration>(0));
|
decos.push_back(std::make_unique<ast::BindingDecoration>(0));
|
||||||
|
|
|
@ -181,7 +181,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) {
|
||||||
|
|
||||||
ast::type::StructType s("S", std::move(str));
|
ast::type::StructType s("S", std::move(str));
|
||||||
|
|
||||||
ASSERT_TRUE(gen().EmitStructType(out(), &s)) << gen().error();
|
ASSERT_TRUE(gen().EmitStructType(out(), &s, "S")) << gen().error();
|
||||||
EXPECT_EQ(result(), R"(struct S {
|
EXPECT_EQ(result(), R"(struct S {
|
||||||
int a;
|
int a;
|
||||||
float b;
|
float b;
|
||||||
|
@ -263,7 +263,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) {
|
||||||
|
|
||||||
ast::type::StructType s("S", std::move(str));
|
ast::type::StructType s("S", std::move(str));
|
||||||
|
|
||||||
ASSERT_TRUE(gen().EmitStructType(out(), &s)) << gen().error();
|
ASSERT_TRUE(gen().EmitStructType(out(), &s, "S")) << gen().error();
|
||||||
EXPECT_EQ(result(), R"(struct S {
|
EXPECT_EQ(result(), R"(struct S {
|
||||||
int double_tint_0;
|
int double_tint_0;
|
||||||
float float_tint_0;
|
float float_tint_0;
|
||||||
|
@ -293,8 +293,8 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_WithDecoration) {
|
||||||
|
|
||||||
ast::type::StructType s("S", std::move(str));
|
ast::type::StructType s("S", std::move(str));
|
||||||
|
|
||||||
ASSERT_TRUE(gen().EmitStructType(out(), &s)) << gen().error();
|
ASSERT_TRUE(gen().EmitStructType(out(), &s, "B")) << gen().error();
|
||||||
EXPECT_EQ(result(), R"(struct S {
|
EXPECT_EQ(result(), R"(struct B {
|
||||||
int a;
|
int a;
|
||||||
float b;
|
float b;
|
||||||
})");
|
})");
|
||||||
|
|
|
@ -245,19 +245,11 @@ bool GeneratorImpl::EmitConstructedType(const ast::type::Type* ty) {
|
||||||
if (ty->IsAlias()) {
|
if (ty->IsAlias()) {
|
||||||
auto* alias = ty->AsAlias();
|
auto* alias = ty->AsAlias();
|
||||||
|
|
||||||
// This will go away once type_alias does not accept anonymous structs
|
out_ << "typedef ";
|
||||||
if (alias->type()->IsStruct() &&
|
if (!EmitType(alias->type(), "")) {
|
||||||
alias->type()->AsStruct()->name() == alias->name()) {
|
return false;
|
||||||
if (!EmitStructType(alias->type()->AsStruct())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out_ << "typedef ";
|
|
||||||
if (!EmitType(alias->type(), "")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
out_ << " " << namer_.NameFor(alias->name()) << ";" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
out_ << " " << namer_.NameFor(alias->name()) << ";" << std::endl;
|
||||||
} else if (ty->IsStruct()) {
|
} else if (ty->IsStruct()) {
|
||||||
if (!EmitStructType(ty->AsStruct())) {
|
if (!EmitStructType(ty->AsStruct())) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -80,35 +80,6 @@ TEST_F(MslGeneratorImplTest, EmitConstructedType_Struct) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, EmitConstructedType_AliasMatchStruct) {
|
|
||||||
ast::type::I32Type i32;
|
|
||||||
ast::type::F32Type f32;
|
|
||||||
|
|
||||||
ast::StructMemberList members;
|
|
||||||
members.push_back(std::make_unique<ast::StructMember>(
|
|
||||||
"a", &f32, ast::StructMemberDecorationList{}));
|
|
||||||
|
|
||||||
ast::StructMemberDecorationList b_deco;
|
|
||||||
b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
|
|
||||||
members.push_back(
|
|
||||||
std::make_unique<ast::StructMember>("b", &i32, std::move(b_deco)));
|
|
||||||
|
|
||||||
auto str = std::make_unique<ast::Struct>();
|
|
||||||
str->set_members(std::move(members));
|
|
||||||
|
|
||||||
ast::type::StructType s("a", std::move(str));
|
|
||||||
ast::type::AliasType alias("a", &s);
|
|
||||||
|
|
||||||
ast::Module m;
|
|
||||||
GeneratorImpl g(&m);
|
|
||||||
ASSERT_TRUE(g.EmitConstructedType(&alias)) << g.error();
|
|
||||||
EXPECT_EQ(g.result(), R"(struct a {
|
|
||||||
float a;
|
|
||||||
int b;
|
|
||||||
};
|
|
||||||
)");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, EmitConstructedType_AliasStructIdent) {
|
TEST_F(MslGeneratorImplTest, EmitConstructedType_AliasStructIdent) {
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::F32Type f32;
|
ast::type::F32Type f32;
|
||||||
|
|
|
@ -168,21 +168,11 @@ bool GeneratorImpl::EmitConstructedType(const ast::type::Type* ty) {
|
||||||
make_indent();
|
make_indent();
|
||||||
if (ty->IsAlias()) {
|
if (ty->IsAlias()) {
|
||||||
auto* alias = ty->AsAlias();
|
auto* alias = ty->AsAlias();
|
||||||
// Emitting an alias to a struct where the names are the same means we can
|
out_ << "type " << alias->name() << " = ";
|
||||||
// skip emitting the alias and just emit the struct. This will go away once
|
if (!EmitType(alias->type())) {
|
||||||
// the anonymous structs are removed from the type alias
|
return false;
|
||||||
if (alias->type()->IsStruct() &&
|
|
||||||
alias->type()->AsStruct()->name() == alias->name()) {
|
|
||||||
if (!EmitStructType(alias->type()->AsStruct())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out_ << "type " << alias->name() << " = ";
|
|
||||||
if (!EmitType(alias->type())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
out_ << ";" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
out_ << ";" << std::endl;
|
||||||
} else if (ty->IsStruct()) {
|
} else if (ty->IsStruct()) {
|
||||||
if (!EmitStructType(ty->AsStruct())) {
|
if (!EmitStructType(ty->AsStruct())) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -39,7 +39,7 @@ TEST_F(WgslGeneratorImplTest, EmitAliasType_F32) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, EmitAliasType_Struct_Ident) {
|
TEST_F(WgslGeneratorImplTest, EmitConstructedType_Struct) {
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::F32Type f32;
|
ast::type::F32Type f32;
|
||||||
|
|
||||||
|
@ -70,8 +70,7 @@ type B = A;
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should go away once type_alias'd anonymous structs are removed.
|
TEST_F(WgslGeneratorImplTest, EmitAliasType_ToStruct) {
|
||||||
TEST_F(WgslGeneratorImplTest, EmitAliasType_Struct) {
|
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::F32Type f32;
|
ast::type::F32Type f32;
|
||||||
|
|
||||||
|
@ -88,15 +87,11 @@ TEST_F(WgslGeneratorImplTest, EmitAliasType_Struct) {
|
||||||
str->set_members(std::move(members));
|
str->set_members(std::move(members));
|
||||||
|
|
||||||
ast::type::StructType s("A", std::move(str));
|
ast::type::StructType s("A", std::move(str));
|
||||||
ast::type::AliasType alias("A", &s);
|
ast::type::AliasType alias("B", &s);
|
||||||
|
|
||||||
GeneratorImpl g;
|
GeneratorImpl g;
|
||||||
ASSERT_TRUE(g.EmitConstructedType(&alias)) << g.error();
|
ASSERT_TRUE(g.EmitConstructedType(&alias)) << g.error();
|
||||||
EXPECT_EQ(g.result(), R"(struct A {
|
EXPECT_EQ(g.result(), R"(type B = A;
|
||||||
a : f32;
|
|
||||||
[[offset(4)]]
|
|
||||||
b : i32;
|
|
||||||
};
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue