From ba6ab5e6bd056e7bbd186d7ed33edfd6142409ef Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Fri, 7 May 2021 14:49:34 +0000 Subject: [PATCH] sem: Fold together sem::Struct and sem::StructType There's now no need to have both. Removes a whole bunch of Sem().Get() smell, and simplifies the resolver. Bug: tint:724 Fixed: tint:761 Change-Id: I756a32680ac52441fd6eebf6fc53dd507ef5e538 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49961 Kokoro: Kokoro Reviewed-by: Antonio Maiorano Commit-Queue: Ben Clayton --- src/BUILD.gn | 2 - src/CMakeLists.txt | 6 +- src/inspector/inspector.cc | 32 +-- src/program_builder.cc | 2 +- src/program_builder.h | 34 +-- src/reader/spirv/parser_impl.h | 8 +- .../wgsl/parser_impl_type_alias_test.cc | 2 +- .../parser_impl_variable_ident_decl_test.cc | 10 +- src/resolver/decoration_validation_test.cc | 4 +- src/resolver/entry_point_validation_test.cc | 42 +-- .../host_shareable_validation_test.cc | 48 ++-- src/resolver/intrinsic_test.cc | 4 +- src/resolver/is_host_shareable_test.cc | 41 +-- src/resolver/is_storeable_test.cc | 62 +++-- src/resolver/resolver.cc | 240 +++++++----------- src/resolver/resolver.h | 53 ++-- src/resolver/resolver_test.cc | 24 +- src/resolver/storage_class_validation_test.cc | 26 +- src/resolver/struct_layout_test.cc | 210 +++++++-------- .../struct_pipeline_stage_use_test.cc | 44 ++-- src/resolver/struct_storage_class_use_test.cc | 54 ++-- src/sem/access_control_type_test.cc | 2 +- src/sem/alias_type_test.cc | 2 +- src/sem/array_type_test.cc | 2 +- src/sem/bool_type_test.cc | 2 +- src/sem/depth_texture_type_test.cc | 2 +- src/sem/external_texture_type_test.cc | 2 +- src/sem/f32_type_test.cc | 2 +- src/sem/i32_type_test.cc | 2 +- src/sem/matrix_type_test.cc | 2 +- src/sem/multisampled_texture_type_test.cc | 2 +- src/sem/pointer_type_test.cc | 2 +- src/sem/sampled_texture_type_test.cc | 2 +- src/sem/sampler_type_test.cc | 2 +- ...struct_type_test.cc => sem_struct_test.cc} | 30 ++- src/sem/storage_texture_type_test.cc | 2 +- src/sem/struct.cc | 21 +- src/sem/struct.h | 51 +++- src/sem/struct_type.cc | 41 --- src/sem/struct_type.h | 59 ----- src/sem/type_mappings.h | 2 - src/sem/u32_type_test.cc | 2 +- src/sem/vector_type_test.cc | 2 +- src/transform/calculate_array_length.cc | 20 +- src/transform/canonicalize_entry_point_io.cc | 12 +- src/transform/decompose_storage_access.cc | 23 +- src/transform/first_index_offset.cc | 2 +- src/transform/hlsl.cc | 2 +- src/transform/spirv.cc | 12 +- src/transform/transform.cc | 5 +- src/transform/transform_test.cc | 10 +- src/transform/vertex_pulling.cc | 10 +- src/typepair.h | 5 +- src/writer/hlsl/generator_impl.cc | 39 ++- src/writer/hlsl/generator_impl.h | 4 +- .../hlsl/generator_impl_alias_type_test.cc | 59 ----- .../hlsl/generator_impl_constructor_test.cc | 20 +- .../hlsl/generator_impl_function_test.cc | 72 +++--- .../generator_impl_member_accessor_test.cc | 52 ++-- .../hlsl/generator_impl_sanitizer_test.cc | 26 +- src/writer/hlsl/generator_impl_type_test.cc | 65 ++--- src/writer/msl/generator_impl.cc | 48 ++-- src/writer/msl/generator_impl.h | 4 +- .../msl/generator_impl_alias_type_test.cc | 68 ----- .../msl/generator_impl_constructor_test.cc | 2 +- .../msl/generator_impl_function_test.cc | 60 ++--- src/writer/msl/generator_impl_type_test.cc | 99 ++++---- ...rator_impl_variable_decl_statement_test.cc | 8 +- src/writer/spirv/builder.cc | 41 ++- src/writer/spirv/builder.h | 2 +- .../spirv/builder_accessor_expression_test.cc | 72 +++--- src/writer/spirv/builder_assign_test.cc | 8 +- .../builder_constructor_expression_test.cc | 26 +- src/writer/spirv/builder_entry_point_test.cc | 2 +- src/writer/spirv/builder_function_test.cc | 4 +- .../spirv/builder_global_variable_test.cc | 24 +- src/writer/spirv/builder_intrinsic_test.cc | 16 +- src/writer/spirv/builder_type_test.cc | 73 +++--- src/writer/wgsl/generator_impl.cc | 8 +- src/writer/wgsl/generator_impl.h | 2 +- .../wgsl/generator_impl_alias_type_test.cc | 16 +- .../wgsl/generator_impl_function_test.cc | 4 +- .../wgsl/generator_impl_global_decl_test.cc | 4 +- .../generator_impl_member_accessor_test.cc | 2 +- src/writer/wgsl/generator_impl_type_test.cc | 56 ++-- test/BUILD.gn | 4 +- 86 files changed, 962 insertions(+), 1313 deletions(-) rename src/sem/{struct_type_test.cc => sem_struct_test.cc} (66%) delete mode 100644 src/sem/struct_type.cc delete mode 100644 src/sem/struct_type.h delete mode 100644 src/writer/hlsl/generator_impl_alias_type_test.cc delete mode 100644 src/writer/msl/generator_impl_alias_type_test.cc diff --git a/src/BUILD.gn b/src/BUILD.gn index 80a0c3a1b6..699c066510 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -480,8 +480,6 @@ libtint_source_set("libtint_core_all_src") { "sem/sampler_type.h", "sem/storage_texture_type.cc", "sem/storage_texture_type.h", - "sem/struct_type.cc", - "sem/struct_type.h", "sem/texture_type.cc", "sem/texture_type.h", "sem/type.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 514a04c8c2..b2a3369cd8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -313,8 +313,6 @@ set(TINT_LIB_SRCS sem/sampler_type.h sem/storage_texture_type.cc sem/storage_texture_type.h - sem/struct_type.cc - sem/struct_type.h sem/texture_type.cc sem/texture_type.h sem/type.cc @@ -581,8 +579,8 @@ if(${TINT_BUILD_TESTS}) sem/pointer_type_test.cc sem/sampled_texture_type_test.cc sem/sampler_type_test.cc + sem/sem_struct_test.cc sem/storage_texture_type_test.cc - sem/struct_type_test.cc sem/texture_type_test.cc sem/type_manager_test.cc sem/u32_type_test.cc @@ -809,7 +807,6 @@ if(${TINT_BUILD_TESTS}) if(${TINT_BUILD_MSL_WRITER}) list(APPEND TINT_TEST_SRCS - writer/msl/generator_impl_alias_type_test.cc writer/msl/generator_impl_array_accessor_test.cc writer/msl/generator_impl_assign_test.cc writer/msl/generator_impl_binary_test.cc @@ -846,7 +843,6 @@ if(${TINT_BUILD_TESTS}) if (${TINT_BUILD_HLSL_WRITER}) list(APPEND TINT_TEST_SRCS transform/hlsl_test.cc - writer/hlsl/generator_impl_alias_type_test.cc writer/hlsl/generator_impl_array_accessor_test.cc writer/hlsl/generator_impl_assign_test.cc writer/hlsl/generator_impl_binary_test.cc diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc index 68442e90c3..c91edc1a56 100644 --- a/src/inspector/inspector.cc +++ b/src/inspector/inspector.cc @@ -33,7 +33,6 @@ #include "src/sem/sampled_texture_type.h" #include "src/sem/storage_texture_type.h" #include "src/sem/struct.h" -#include "src/sem/struct_type.h" #include "src/sem/u32_type.h" #include "src/sem/variable.h" #include "src/sem/vector_type.h" @@ -389,7 +388,7 @@ std::vector Inspector::GetUniformBufferResourceBindings( auto binding_info = ruv.second; auto* unwrapped_type = var->Type()->UnwrapIfNeeded(); - auto* str = unwrapped_type->As(); + auto* str = unwrapped_type->As(); if (str == nullptr) { continue; } @@ -398,19 +397,12 @@ std::vector Inspector::GetUniformBufferResourceBindings( continue; } - auto* sem = program_->Sem().Get(str); - if (!sem) { - error_ = "Missing semantic information for structure " + - program_->Symbols().NameFor(str->impl()->name()); - continue; - } - ResourceBinding entry; entry.resource_type = ResourceBinding::ResourceType::kUniformBuffer; entry.bind_group = binding_info.group->value(); entry.binding = binding_info.binding->value(); - entry.size = sem->Size(); - entry.size_no_padding = sem->SizeNoPadding(); + entry.size = str->Size(); + entry.size_no_padding = str->SizeNoPadding(); result.push_back(entry); } @@ -554,10 +546,9 @@ void Inspector::AddEntryPointInOutVariables( auto* unwrapped_type = type->UnwrapAll(); - if (auto* struct_ty = unwrapped_type->As()) { + if (auto* struct_ty = unwrapped_type->As()) { // Recurse into members. - auto* sem = program_->Sem().Get(struct_ty); - for (auto* member : sem->Members()) { + for (auto* member : struct_ty->Members()) { AddEntryPointInOutVariables( name + "." + program_->Symbols().NameFor(member->Declaration()->symbol()), @@ -611,26 +602,19 @@ std::vector Inspector::GetStorageBufferResourceBindingsImpl( continue; } - auto* str = var->Type()->UnwrapIfNeeded()->As(); + auto* str = var->Type()->UnwrapIfNeeded()->As(); if (!str) { continue; } - auto* sem = program_->Sem().Get(str); - if (!sem) { - error_ = "Missing semantic information for structure " + - program_->Symbols().NameFor(str->impl()->name()); - continue; - } - ResourceBinding entry; entry.resource_type = read_only ? ResourceBinding::ResourceType::kReadOnlyStorageBuffer : ResourceBinding::ResourceType::kStorageBuffer; entry.bind_group = binding_info.group->value(); entry.binding = binding_info.binding->value(); - entry.size = sem->Size(); - entry.size_no_padding = sem->SizeNoPadding(); + entry.size = str->Size(); + entry.size_no_padding = str->SizeNoPadding(); result.push_back(entry); } diff --git a/src/program_builder.cc b/src/program_builder.cc index d270cc76db..a59b03a0b9 100644 --- a/src/program_builder.cc +++ b/src/program_builder.cc @@ -80,7 +80,7 @@ void ProgramBuilder::MarkAsMoved() { void ProgramBuilder::AssertNotMoved() const { if (moved_) { - TINT_ICE(const_cast(this)->Diagnostics()) + TINT_ICE(const_cast(this)->diagnostics_) << "Attempting to use ProgramBuilder after it has been moved"; } } diff --git a/src/program_builder.h b/src/program_builder.h index 2ab6624465..7b0fdcec17 100644 --- a/src/program_builder.h +++ b/src/program_builder.h @@ -72,7 +72,7 @@ #include "src/sem/pointer_type.h" #include "src/sem/sampled_texture_type.h" #include "src/sem/storage_texture_type.h" -#include "src/sem/struct_type.h" +#include "src/sem/struct.h" #include "src/sem/u32_type.h" #include "src/sem/vector_type.h" #include "src/sem/void_type.h" @@ -772,12 +772,6 @@ class ProgramBuilder { return pointer(Of(), storage_class); } - /// @param impl the struct implementation - /// @returns a struct pointer - typ::Struct struct_(ast::Struct* impl) const { - return {impl, builder->create(impl)}; - } - /// @param kind the kind of sampler /// @returns the sampler typ::Sampler sampler(ast::SamplerKind kind) const { @@ -1544,40 +1538,36 @@ class ProgramBuilder { return create(Expr(std::forward(val))); } - /// Creates a ast::Struct and sem::StructType, registering the - /// sem::StructType with the AST().ConstructedTypes(). + /// Creates a ast::Struct registering it with the AST().ConstructedTypes(). /// @param source the source information /// @param name the struct name /// @param members the struct members /// @param decorations the optional struct decorations /// @returns the struct type template - typ::Struct Structure(const Source& source, - NAME&& name, - ast::StructMemberList members, - ast::DecorationList decorations = {}) { + ast::Struct* Structure(const Source& source, + NAME&& name, + ast::StructMemberList members, + ast::DecorationList decorations = {}) { auto sym = Sym(std::forward(name)); - auto* impl = create(source, sym, std::move(members), + auto* type = create(source, sym, std::move(members), std::move(decorations)); - auto type = ty.struct_(impl); AST().AddConstructedType(type); return type; } - /// Creates a ast::Struct and sem::StructType, registering the - /// sem::StructType with the AST().ConstructedTypes(). + /// Creates a ast::Struct registering it with the AST().ConstructedTypes(). /// @param name the struct name /// @param members the struct members /// @param decorations the optional struct decorations /// @returns the struct type template - typ::Struct Structure(NAME&& name, - ast::StructMemberList members, - ast::DecorationList decorations = {}) { + ast::Struct* Structure(NAME&& name, + ast::StructMemberList members, + ast::DecorationList decorations = {}) { auto sym = Sym(std::forward(name)); - auto* impl = + auto* type = create(sym, std::move(members), std::move(decorations)); - auto type = ty.struct_(impl); AST().AddConstructedType(type); return type; } diff --git a/src/reader/spirv/parser_impl.h b/src/reader/spirv/parser_impl.h index 492d7be531..900165b9ab 100644 --- a/src/reader/spirv/parser_impl.h +++ b/src/reader/spirv/parser_impl.h @@ -414,14 +414,14 @@ class ParserImpl : Reader { const spvtools::opt::Instruction& inst, ast::Type* first_operand_type); - /// Returns the given expression, but ensuring it's an unsigned type of the - /// same shape as the operand. Wraps the expresison with a bitcast if needed. + /// @returns the given expression, but ensuring it's an unsigned type of the + /// same shape as the operand. Wraps the expresion with a bitcast if needed. /// Assumes the given expresion is a integer scalar or vector. /// @param expr an integer scalar or integer vector expression. TypedExpression AsUnsigned(TypedExpression expr); - /// Returns the given expression, but ensuring it's a signed type of the - /// same shape as the operand. Wraps the expresison with a bitcast if needed. + /// @returns the given expression, but ensuring it's a signed type of the + /// same shape as the operand. Wraps the expresion with a bitcast if needed. /// Assumes the given expresion is a integer scalar or vector. /// @param expr an integer scalar or integer vector expression. TypedExpression AsSigned(TypedExpression expr); diff --git a/src/reader/wgsl/parser_impl_type_alias_test.cc b/src/reader/wgsl/parser_impl_type_alias_test.cc index fba0e5cbe7..fb2f2d31f6 100644 --- a/src/reader/wgsl/parser_impl_type_alias_test.cc +++ b/src/reader/wgsl/parser_impl_type_alias_test.cc @@ -37,7 +37,7 @@ TEST_F(ParserImplTest, TypeDecl_ParsesType) { TEST_F(ParserImplTest, TypeDecl_ParsesStruct_Ident) { auto p = parser("type a = B"); - auto str = p->builder().Structure(p->builder().Symbols().Register("B"), {}); + auto* str = p->builder().Structure(p->builder().Symbols().Register("B"), {}); p->register_constructed("B", str); auto t = p->type_alias(); diff --git a/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc b/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc index 55605b9cf2..32cf335d1a 100644 --- a/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc +++ b/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc @@ -113,7 +113,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_Read) { ast::DecorationList decos; decos.push_back(block_deco); - auto s = Structure(Sym("S"), members, decos); + auto* s = Structure(Sym("S"), members, decos); p->register_constructed("S", s); @@ -137,7 +137,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_ReadWrite) { ast::DecorationList decos; decos.push_back(block_deco); - auto s = Structure(Sym("S"), members, decos); + auto* s = Structure(Sym("S"), members, decos); p->register_constructed("S", s); @@ -161,7 +161,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDecoFail) { ast::DecorationList decos; decos.push_back(block_deco); - auto s = Structure(Sym("S"), members, decos); + auto* s = Structure(Sym("S"), members, decos); p->register_constructed("S", s); @@ -182,7 +182,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDeco_MultiBlock_Fail) { ast::DecorationList decos; decos.push_back(block_deco); - auto s = Structure(Sym("S"), members, decos); + auto* s = Structure(Sym("S"), members, decos); p->register_constructed("S", s); @@ -219,7 +219,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_NonAccessDecoFail) { ast::DecorationList decos; decos.push_back(block_deco); - auto s = Structure(Sym("S"), members, decos); + auto* s = Structure(Sym("S"), members, decos); p->register_constructed("S", s); diff --git a/src/resolver/decoration_validation_test.cc b/src/resolver/decoration_validation_test.cc index be3926e85a..75ba8a3bc6 100644 --- a/src/resolver/decoration_validation_test.cc +++ b/src/resolver/decoration_validation_test.cc @@ -466,8 +466,8 @@ namespace { using StructBlockTest = ResolverTest; TEST_F(StructBlockTest, StructUsedAsArrayElement) { - auto s = Structure("S", {Member("x", ty.i32())}, - {create()}); + auto* s = Structure("S", {Member("x", ty.i32())}, + {create()}); auto a = ty.array(s, 4); Global("G", a, ast::StorageClass::kPrivate); diff --git a/src/resolver/entry_point_validation_test.cc b/src/resolver/entry_point_validation_test.cc index 5516b77217..f872844f3f 100644 --- a/src/resolver/entry_point_validation_test.cc +++ b/src/resolver/entry_point_validation_test.cc @@ -85,7 +85,7 @@ TEST_F(ResolverEntryPointValidationTest, ReturnTypeAttribute_Struct) { // fn main() -> [[location(0)]] Output { // return Output(); // } - auto output = Structure("Output", {}); + auto* output = Structure("Output", {}); Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, {Stage(ast::PipelineStage::kVertex)}, {Location(Source{{13, 43}}, 0)}); @@ -105,7 +105,7 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_Valid) { // fn main() -> Output { // return Output(); // } - auto output = Structure( + auto* output = Structure( "Output", {Member("a", ty.f32(), {Location(0)}), Member("b", ty.f32(), {Builtin(ast::Builtin::kFragDepth)})}); Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, @@ -123,7 +123,7 @@ TEST_F(ResolverEntryPointValidationTest, // fn main() -> Output { // return Output(); // } - auto output = Structure( + auto* output = Structure( "Output", {Member("a", ty.f32(), {Location(Source{{13, 43}}, 0), @@ -147,7 +147,7 @@ TEST_F(ResolverEntryPointValidationTest, // fn main() -> Output { // return Output(); // } - auto output = Structure( + auto* output = Structure( "Output", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}), Member(Source{{14, 52}}, "b", ty.f32(), {})}); Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, @@ -170,9 +170,9 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_NestedStruct) { // fn main() -> Output { // return Output(); // } - auto inner = Structure( + auto* inner = Structure( "Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})}); - auto output = Structure( + auto* output = Structure( "Output", {Member(Source{{14, 52}}, "a", inner, {Location(0)})}); Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, {Stage(ast::PipelineStage::kFragment)}); @@ -193,7 +193,7 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_RuntimeArray) { // fn main() -> Output { // return Output(); // } - auto output = Structure( + auto* output = Structure( "Output", {Member(Source{{13, 43}}, "a", ty.array(), {Location(0)})}, {create()}); @@ -216,7 +216,7 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_DuplicateBuiltins) { // fn main() -> Output { // return Output(); // } - auto output = Structure( + auto* output = Structure( "Output", {Member("a", ty.f32(), {Builtin(ast::Builtin::kFragDepth)}), Member("b", ty.f32(), {Builtin(ast::Builtin::kFragDepth)})}); Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, @@ -238,8 +238,8 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_DuplicateLocation) { // fn main() -> Output { // return Output(); // } - auto output = Structure("Output", {Member("a", ty.f32(), {Location(1)}), - Member("b", ty.f32(), {Location(1)})}); + auto* output = Structure("Output", {Member("a", ty.f32(), {Location(1)}), + Member("b", ty.f32(), {Location(1)})}); Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, {Stage(ast::PipelineStage::kFragment)}); @@ -302,7 +302,7 @@ TEST_F(ResolverEntryPointValidationTest, ParameterAttribute_Struct) { // }; // [[stage(fragment)]] // fn main([[location(0)]] param : Input) {} - auto input = Structure("Input", {}); + auto* input = Structure("Input", {}); auto* param = Param("param", input, {Location(Source{{13, 43}}, 0)}); Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)}); @@ -321,7 +321,7 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_Valid) { // }; // [[stage(fragment)]] // fn main(param : Input) {} - auto input = Structure( + auto* input = Structure( "Input", {Member("a", ty.f32(), {Location(0)}), Member("b", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)})}); auto* param = Param("param", input); @@ -338,7 +338,7 @@ TEST_F(ResolverEntryPointValidationTest, // }; // [[stage(fragment)]] // fn main(param : Input) {} - auto input = Structure( + auto* input = Structure( "Input", {Member("a", ty.f32(), {Location(Source{{13, 43}}, 0), @@ -361,7 +361,7 @@ TEST_F(ResolverEntryPointValidationTest, // }; // [[stage(fragment)]] // fn main(param : Input) {} - auto input = Structure( + auto* input = Structure( "Input", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}), Member(Source{{14, 52}}, "b", ty.f32(), {})}); auto* param = Param("param", input); @@ -382,9 +382,9 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_NestedStruct) { // }; // [[stage(fragment)]] // fn main(param : Input) {} - auto inner = Structure( + auto* inner = Structure( "Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})}); - auto input = + auto* input = Structure("Input", {Member(Source{{14, 52}}, "a", inner, {Location(0)})}); auto* param = Param("param", input); Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, @@ -404,7 +404,7 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_RuntimeArray) { // }; // [[stage(fragment)]] // fn main(param : Input) {} - auto input = Structure( + auto* input = Structure( "Input", {Member(Source{{13, 43}}, "a", ty.array(), {Location(0)})}, {create()}); @@ -446,9 +446,9 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_DuplicateBuiltins) { // }; // [[stage(fragment)]] // fn main(param_a : InputA, param_b : InputB) {} - auto input_a = Structure( + auto* input_a = Structure( "InputA", {Member("a", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)})}); - auto input_b = Structure( + auto* input_b = Structure( "InputB", {Member("a", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)})}); auto* param_a = Param("param_a", input_a); auto* param_b = Param("param_b", input_b); @@ -486,8 +486,8 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_DuplicateLocation) { // }; // [[stage(fragment)]] // fn main(param_a : InputA, param_b : InputB) {} - auto input_a = Structure("InputA", {Member("a", ty.f32(), {Location(1)})}); - auto input_b = Structure("InputB", {Member("a", ty.f32(), {Location(1)})}); + auto* input_a = Structure("InputA", {Member("a", ty.f32(), {Location(1)})}); + auto* input_b = Structure("InputB", {Member("a", ty.f32(), {Location(1)})}); auto* param_a = Param("param_a", input_a); auto* param_b = Param("param_b", input_b); Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {}, diff --git a/src/resolver/host_shareable_validation_test.cc b/src/resolver/host_shareable_validation_test.cc index ec04c2e5ea..5bbde0e77e 100644 --- a/src/resolver/host_shareable_validation_test.cc +++ b/src/resolver/host_shareable_validation_test.cc @@ -27,8 +27,8 @@ namespace { using ResolverHostShareableValidationTest = ResolverTest; TEST_F(ResolverHostShareableValidationTest, BoolMember) { - auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.bool_())}, - {create()}); + auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.bool_())}, + {create()}); auto a = ty.access(ast::AccessControl::kReadOnly, s); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); @@ -42,8 +42,8 @@ TEST_F(ResolverHostShareableValidationTest, BoolMember) { } TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) { - auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.vec3())}, - {create()}); + auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.vec3())}, + {create()}); auto a = ty.access(ast::AccessControl::kReadOnly, s); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); @@ -59,8 +59,8 @@ TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) { TEST_F(ResolverHostShareableValidationTest, Aliases) { auto a1 = ty.alias("a1", ty.bool_()); AST().AddConstructedType(a1); - auto s = Structure("S", {Member(Source{{12, 34}}, "x", a1)}, - {create()}); + auto* s = Structure("S", {Member(Source{{12, 34}}, "x", a1)}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, s); auto a2 = ty.alias("a2", ac); AST().AddConstructedType(a2); @@ -76,12 +76,12 @@ TEST_F(ResolverHostShareableValidationTest, Aliases) { } TEST_F(ResolverHostShareableValidationTest, NestedStructures) { - auto i1 = Structure("I1", {Member(Source{{1, 2}}, "x", ty.bool_())}); - auto i2 = Structure("I2", {Member(Source{{3, 4}}, "y", i1)}); - auto i3 = Structure("I3", {Member(Source{{5, 6}}, "z", i2)}); + auto* i1 = Structure("I1", {Member(Source{{1, 2}}, "x", ty.bool_())}); + auto* i2 = Structure("I2", {Member(Source{{3, 4}}, "y", i1)}); + auto* i3 = Structure("I3", {Member(Source{{5, 6}}, "z", i2)}); - auto s = Structure("S", {Member(Source{{7, 8}}, "m", i3)}, - {create()}); + auto* s = Structure("S", {Member(Source{{7, 8}}, "m", i3)}, + {create()}); auto a = ty.access(ast::AccessControl::kReadOnly, s); Global(Source{{9, 10}}, "g", a, ast::StorageClass::kStorage); @@ -98,7 +98,7 @@ TEST_F(ResolverHostShareableValidationTest, NestedStructures) { } TEST_F(ResolverHostShareableValidationTest, NoError) { - auto i1 = + auto* i1 = Structure("I1", { Member(Source{{1, 1}}, "x1", ty.f32()), Member(Source{{2, 1}}, "y1", ty.vec3()), @@ -106,21 +106,21 @@ TEST_F(ResolverHostShareableValidationTest, NoError) { }); auto a1 = ty.alias("a1", i1); AST().AddConstructedType(a1); - auto i2 = Structure("I2", { - Member(Source{{4, 1}}, "x2", ty.mat2x2()), - Member(Source{{5, 1}}, "y2", i1), - Member(Source{{6, 1}}, "z2", ty.mat3x2()), - }); + auto* i2 = Structure("I2", { + Member(Source{{4, 1}}, "x2", ty.mat2x2()), + Member(Source{{5, 1}}, "y2", i1), + Member(Source{{6, 1}}, "z2", ty.mat3x2()), + }); auto a2 = ty.alias("a2", i2); AST().AddConstructedType(a2); - auto i3 = Structure("I3", { - Member(Source{{4, 1}}, "x3", a1), - Member(Source{{5, 1}}, "y3", i2), - Member(Source{{6, 1}}, "z3", a2), - }); + auto* i3 = Structure("I3", { + Member(Source{{4, 1}}, "x3", a1), + Member(Source{{5, 1}}, "y3", i2), + Member(Source{{6, 1}}, "z3", a2), + }); - auto s = Structure("S", {Member(Source{{7, 8}}, "m", i3)}, - {create()}); + auto* s = Structure("S", {Member(Source{{7, 8}}, "m", i3)}, + {create()}); auto a = ty.access(ast::AccessControl::kReadOnly, s); Global(Source{{9, 10}}, "g", a, ast::StorageClass::kStorage); diff --git a/src/resolver/intrinsic_test.cc b/src/resolver/intrinsic_test.cc index 7233f18843..f73b19acfb 100644 --- a/src/resolver/intrinsic_test.cc +++ b/src/resolver/intrinsic_test.cc @@ -757,8 +757,8 @@ using ResolverIntrinsicDataTest = ResolverTest; TEST_F(ResolverIntrinsicDataTest, ArrayLength_Vector) { auto ary = ty.array(); - auto str = Structure("S", {Member("x", ary)}, - {create()}); + auto* str = Structure("S", {Member("x", ary)}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, str); Global("a", ac, ast::StorageClass::kStorage); diff --git a/src/resolver/is_host_shareable_test.cc b/src/resolver/is_host_shareable_test.cc index d2eca751e2..346a1321d0 100644 --- a/src/resolver/is_host_shareable_test.cc +++ b/src/resolver/is_host_shareable_test.cc @@ -105,46 +105,7 @@ TEST_F(ResolverIsHostShareable, ArrayUnsizedOfHostShareable) { EXPECT_TRUE(r()->IsHostShareable(ty.array())); } -TEST_F(ResolverIsHostShareable, Struct_AllMembersHostShareable) { - EXPECT_TRUE(r()->IsHostShareable(Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - }))); -} - -TEST_F(ResolverIsHostShareable, Struct_SomeMembersNonHostShareable) { - auto ptr_ty = ty.pointer(ast::StorageClass::kPrivate); - EXPECT_FALSE(r()->IsHostShareable(Structure("S", { - Member("a", ty.i32()), - Member("b", ptr_ty), - }))); -} - -TEST_F(ResolverIsHostShareable, Struct_NestedHostShareable) { - auto host_shareable = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - }); - EXPECT_TRUE( - r()->IsHostShareable(Structure("S", { - Member("a", ty.i32()), - Member("b", host_shareable), - }))); -} - -TEST_F(ResolverIsHostShareable, Struct_NestedNonHostShareable) { - auto ptr_ty = ty.pointer(ast::StorageClass::kPrivate); - auto non_host_shareable = - Structure("non_host_shareable", { - Member("a", ty.i32()), - Member("b", ptr_ty), - }); - EXPECT_FALSE( - r()->IsHostShareable(Structure("S", { - Member("a", ty.i32()), - Member("b", non_host_shareable), - }))); -} +// Note: Structure tests covered in host_shareable_validation_test.cc } // namespace } // namespace resolver diff --git a/src/resolver/is_storeable_test.cc b/src/resolver/is_storeable_test.cc index eb7b391847..72f9cc6042 100644 --- a/src/resolver/is_storeable_test.cc +++ b/src/resolver/is_storeable_test.cc @@ -90,41 +90,55 @@ TEST_F(ResolverIsStorableTest, ArrayUnsizedOfStorable) { } TEST_F(ResolverIsStorableTest, Struct_AllMembersStorable) { - EXPECT_TRUE(r()->IsStorable(Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - }))); + Structure("S", { + Member("a", ty.i32()), + Member("b", ty.f32()), + }); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); } TEST_F(ResolverIsStorableTest, Struct_SomeMembersNonStorable) { auto ptr_ty = ty.pointer(ast::StorageClass::kPrivate); - EXPECT_FALSE(r()->IsStorable(Structure("S", { - Member("a", ty.i32()), - Member("b", ptr_ty), - }))); + Structure("S", { + Member("a", ty.i32()), + Member("b", ptr_ty), + }); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ( + r()->error(), + R"(error: ptr cannot be used as the type of a structure member)"); } TEST_F(ResolverIsStorableTest, Struct_NestedStorable) { - auto storable = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - }); - EXPECT_TRUE(r()->IsStorable(Structure("S", { - Member("a", ty.i32()), - Member("b", storable), - }))); + auto* storable = Structure("Storable", { + Member("a", ty.i32()), + Member("b", ty.f32()), + }); + Structure("S", { + Member("a", ty.i32()), + Member("b", storable), + }); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); } TEST_F(ResolverIsStorableTest, Struct_NestedNonStorable) { auto ptr_ty = ty.pointer(ast::StorageClass::kPrivate); - auto non_storable = Structure("nonstorable", { - Member("a", ty.i32()), - Member("b", ptr_ty), - }); - EXPECT_FALSE(r()->IsStorable(Structure("S", { - Member("a", ty.i32()), - Member("b", non_storable), - }))); + auto* non_storable = Structure("nonstorable", { + Member("a", ty.i32()), + Member("b", ptr_ty), + }); + Structure("S", { + Member("a", ty.i32()), + Member("b", non_storable), + }); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ( + r()->error(), + R"(error: ptr cannot be used as the type of a structure member)"); } } // namespace diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc index b46e4fef75..a155ff424c 100644 --- a/src/resolver/resolver.cc +++ b/src/resolver/resolver.cc @@ -181,15 +181,13 @@ bool Resolver::IsStorable(const sem::Type* type) { if (auto* arr = type->As()) { return IsStorable(arr->type()); } - if (auto* str_ty = type->As()) { - if (auto* str = Structure(str_ty)) { - for (const auto* member : str->members) { - if (!IsStorable(member->Type())) { - return false; - } + if (auto* str = type->As()) { + for (const auto* member : str->Members()) { + if (!IsStorable(member->Type())) { + return false; } - return true; } + return true; } return false; } @@ -209,12 +207,8 @@ bool Resolver::IsHostShareable(const sem::Type* type) { if (auto* arr = type->As()) { return IsHostShareable(arr->type()); } - if (auto* str = type->As()) { - auto* info = Structure(str); - if (!info) { - return false; - } - for (auto* member : info->members) { + if (auto* str = type->As()) { + for (auto* member : str->Members()) { if (!IsHostShareable(member->Type())) { return false; } @@ -243,7 +237,7 @@ bool Resolver::IsValidAssignment(const sem::Type* lhs, const sem::Type* rhs) { bool Resolver::ResolveInternal() { Mark(&builder_->AST()); - auto register_named_type = [this](Symbol name, const sem::Type* type, + auto register_named_type = [this](Symbol name, sem::Type* type, const Source& source) { auto added = named_types_.emplace(name, type).second; if (!added) { @@ -312,9 +306,9 @@ bool Resolver::ResolveInternal() { return result; } -const sem::Type* Resolver::Type(const ast::Type* ty) { +sem::Type* Resolver::Type(const ast::Type* ty) { Mark(ty); - auto* s = [&]() -> const sem::Type* { + auto* s = [&]() -> sem::Type* { if (ty->Is()) { return builder_->create(); } @@ -357,8 +351,11 @@ const sem::Type* Resolver::Type(const ast::Type* ty) { } if (auto* t = ty->As()) { if (auto* el = Type(t->type())) { - return builder_->create(const_cast(el), - t->size(), t->decorations()); + auto* sem = builder_->create( + const_cast(el), t->size(), t->decorations()); + if (Array(sem, ty->source())) { + return sem; + } } return nullptr; } @@ -370,7 +367,7 @@ const sem::Type* Resolver::Type(const ast::Type* ty) { return nullptr; } if (auto* t = ty->As()) { - return builder_->create(const_cast(t)); + return Structure(t); } if (auto* t = ty->As()) { return builder_->create(t->kind()); @@ -417,35 +414,15 @@ const sem::Type* Resolver::Type(const ast::Type* ty) { return nullptr; }(); - if (s == nullptr) { - return nullptr; + if (s) { + builder_->Sem().Add(ty, s); } - if (!Type(s, ty->source())) { - return nullptr; - } - builder_->Sem().Add(ty, s); return s; } -// TODO(crbug.com/tint/724): This method should be merged into Type(ast::Type*) -bool Resolver::Type(const sem::Type* ty, const Source& source /* = {} */) { - ty = ty->UnwrapAliasIfNeeded(); - if (auto* str = ty->As()) { - if (!Structure(str)) { - return false; - } - } else if (auto* arr = ty->As()) { - if (!Array(arr, source)) { - return false; - } - } - return true; -} - -Resolver::VariableInfo* Resolver::Variable( - ast::Variable* var, - const sem::Type* type, /* = nullptr */ - std::string type_name /* = "" */) { +Resolver::VariableInfo* Resolver::Variable(ast::Variable* var, + sem::Type* type, /* = nullptr */ + std::string type_name /* = "" */) { auto it = variable_to_info_.find(var); if (it != variable_to_info_.end()) { return it->second; @@ -561,7 +538,7 @@ bool Resolver::ValidateGlobalVariable(const VariableInfo* info) { // attribute, satisfying the storage class constraints. auto* access = info->type->As(); - auto* str = access ? access->type()->As() : nullptr; + auto* str = access ? access->type()->As() : nullptr; if (!str) { diagnostics_.add_error( "variables declared in the storage class must be of an " @@ -574,7 +551,7 @@ bool Resolver::ValidateGlobalVariable(const VariableInfo* info) { diagnostics_.add_error( "structure used as a storage buffer must be declared with the " "[[block]] decoration", - str->impl()->source()); + str->Declaration()->source()); if (info->declaration->source().range.begin.line) { diagnostics_.add_note("structure used as storage buffer here", info->declaration->source()); @@ -588,7 +565,7 @@ bool Resolver::ValidateGlobalVariable(const VariableInfo* info) { // A variable in the uniform storage class is a uniform buffer variable. // Its store type must be a host-shareable structure type with block // attribute, satisfying the storage class constraints. - auto* str = info->type->As(); + auto* str = info->type->As(); if (!str) { diagnostics_.add_error( "variables declared in the storage class must be of a " @@ -601,7 +578,7 @@ bool Resolver::ValidateGlobalVariable(const VariableInfo* info) { diagnostics_.add_error( "structure used as a uniform buffer must be declared with the " "[[block]] decoration", - str->impl()->source()); + str->Declaration()->source()); if (info->declaration->source().range.begin.line) { diagnostics_.add_note("structure used as uniform buffer here", info->declaration->source()); @@ -781,7 +758,7 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func, }; // Inner lambda that is applied to a type and all of its members. auto validate_entry_point_decorations_inner = - [&](const ast::DecorationList& decos, const sem::Type* ty, Source source, + [&](const ast::DecorationList& decos, sem::Type* ty, Source source, ParamOrRetType param_or_ret, bool is_struct_member) { // Scan decorations for pipeline IO attributes. // Check for overlap with attributes that have been seen previously. @@ -834,7 +811,7 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func, } // Check that we saw a pipeline IO attribute iff we need one. - if (Canonical(ty)->Is()) { + if (Canonical(ty)->Is()) { if (pipeline_io_attribute) { diagnostics_.add_error( "entry point IO attributes must not be used on structure " + @@ -862,8 +839,7 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func, // Outer lambda for validating the entry point decorations for a type. auto validate_entry_point_decorations = [&](const ast::DecorationList& decos, - const sem::Type* ty, - Source source, + sem::Type* ty, Source source, ParamOrRetType param_or_ret) { // Validate the decorations for the type. if (!validate_entry_point_decorations_inner(decos, ty, source, param_or_ret, @@ -871,12 +847,12 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func, return false; } - if (auto* struct_ty = Canonical(ty)->As()) { + if (auto* str = Canonical(ty)->As()) { // Validate the decorations for each struct members, and also check for // invalid member types. - for (auto* member : Structure(struct_ty)->members) { + for (auto* member : str->Members()) { auto* member_ty = Canonical(member->Type()); - if (member_ty->Is()) { + if (member_ty->Is()) { diagnostics_.add_error( "entry point IO types cannot contain nested structures", member->Declaration()->source()); @@ -988,23 +964,16 @@ bool Resolver::Function(ast::Function* func) { return false; } - if (auto* str = param_info->type->As()) { - auto* str_info = Structure(str); - if (!str_info) { - return false; - } + if (auto* str = param_info->type->As()) { switch (func->pipeline_stage()) { case ast::PipelineStage::kVertex: - str_info->pipeline_stage_uses.emplace( - sem::PipelineStageUsage::kVertexInput); + str->AddUsage(sem::PipelineStageUsage::kVertexInput); break; case ast::PipelineStage::kFragment: - str_info->pipeline_stage_uses.emplace( - sem::PipelineStageUsage::kFragmentInput); + str->AddUsage(sem::PipelineStageUsage::kFragmentInput); break; case ast::PipelineStage::kCompute: - str_info->pipeline_stage_uses.emplace( - sem::PipelineStageUsage::kComputeInput); + str->AddUsage(sem::PipelineStageUsage::kComputeInput); break; case ast::PipelineStage::kNone: break; @@ -1026,7 +995,7 @@ bool Resolver::Function(ast::Function* func) { info->return_type = Canonical(info->return_type); - if (auto* str = info->return_type->As()) { + if (auto* str = info->return_type->As()) { if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, str, func->source())) { diagnostics_.add_note("while instantiating return type for " + @@ -1035,22 +1004,15 @@ bool Resolver::Function(ast::Function* func) { return false; } - auto* str_info = Structure(str); - if (!str_info) { - return false; - } switch (func->pipeline_stage()) { case ast::PipelineStage::kVertex: - str_info->pipeline_stage_uses.emplace( - sem::PipelineStageUsage::kVertexOutput); + str->AddUsage(sem::PipelineStageUsage::kVertexOutput); break; case ast::PipelineStage::kFragment: - str_info->pipeline_stage_uses.emplace( - sem::PipelineStageUsage::kFragmentOutput); + str->AddUsage(sem::PipelineStageUsage::kFragmentOutput); break; case ast::PipelineStage::kCompute: - str_info->pipeline_stage_uses.emplace( - sem::PipelineStageUsage::kComputeOutput); + str->AddUsage(sem::PipelineStageUsage::kComputeOutput); break; case ast::PipelineStage::kNone: break; @@ -1659,13 +1621,12 @@ bool Resolver::MemberAccessor(ast::MemberAccessorExpression* expr) { sem::Type* ret = nullptr; std::vector swizzle; - if (auto* ty = data_type->As()) { + if (auto* str = data_type->As()) { Mark(expr->member()); auto symbol = expr->member()->symbol(); - auto* str = Structure(ty); const sem::StructMember* member = nullptr; - for (auto* m : str->members) { + for (auto* m : str->Members()) { if (m->Declaration()->symbol() == symbol) { ret = m->Type(); member = m; @@ -1689,11 +1650,11 @@ bool Resolver::MemberAccessor(ast::MemberAccessorExpression* expr) { expr, ret, current_statement_, member)); } else if (auto* vec = data_type->As()) { Mark(expr->member()); - std::string str = builder_->Symbols().NameFor(expr->member()->symbol()); - auto size = str.size(); - swizzle.reserve(str.size()); + std::string s = builder_->Symbols().NameFor(expr->member()->symbol()); + auto size = s.size(); + swizzle.reserve(s.size()); - for (auto c : str) { + for (auto c : s) { switch (c) { case 'x': case 'r': @@ -1732,8 +1693,8 @@ bool Resolver::MemberAccessor(ast::MemberAccessorExpression* expr) { auto is_xyzw = [](char c) { return c == 'x' || c == 'y' || c == 'z' || c == 'w'; }; - if (!std::all_of(str.begin(), str.end(), is_rgba) && - !std::all_of(str.begin(), str.end(), is_xyzw)) { + if (!std::all_of(s.begin(), s.end(), is_rgba) && + !std::all_of(s.begin(), s.end(), is_xyzw)) { diagnostics_.add_error( "invalid mixing of vector swizzle characters rgba with xyzw", expr->member()->source()); @@ -2032,7 +1993,7 @@ bool Resolver::VariableDeclStatement(const ast::VariableDeclStatement* stmt) { // If the variable has a declared type, resolve it. std::string type_name; - const sem::Type* type = nullptr; + sem::Type* type = nullptr; if (auto* ast_ty = var->type()) { type_name = ast_ty->FriendlyName(builder_->Symbols()); type = Type(ast_ty); @@ -2122,7 +2083,7 @@ bool Resolver::VariableDeclStatement(const ast::VariableDeclStatement* stmt) { return true; } -const sem::Type* Resolver::TypeOf(const ast::Expression* expr) { +sem::Type* Resolver::TypeOf(const ast::Expression* expr) { auto it = expr_info_.find(expr); if (it != expr_info_.end()) { return it->second.type; @@ -2138,7 +2099,7 @@ std::string Resolver::TypeNameOf(const ast::Expression* expr) { return ""; } -const sem::Type* Resolver::TypeOf(const ast::Literal* lit) { +sem::Type* Resolver::TypeOf(const ast::Literal* lit) { if (lit->Is()) { return builder_->create(); } @@ -2273,17 +2234,6 @@ void Resolver::CreateSemanticNodes() const { builder_->create( const_cast(expr), info.type, info.statement)); } - - // Create semantic nodes for all structs - for (auto it : struct_info_) { - auto* str = it.first; - auto* info = it.second; - builder_->Sem().Add( - str, builder_->create( - const_cast(str), std::move(info->members), - info->align, info->size, info->size_no_padding, - info->storage_class_usage, info->pipeline_stage_uses)); - } } bool Resolver::DefaultAlignAndSize(const sem::Type* ty, @@ -2305,7 +2255,7 @@ bool Resolver::DefaultAlignAndSize(const sem::Type* ty, /*vec4*/ 16, }; - auto* cty = Canonical(ty); + auto* cty = Canonical(const_cast(ty)); if (cty->is_scalar()) { // Note: Also captures booleans, but these are not host-shareable. align = 4; @@ -2330,13 +2280,10 @@ bool Resolver::DefaultAlignAndSize(const sem::Type* ty, align = vector_align[mat->rows()]; size = vector_align[mat->rows()] * mat->columns(); return true; - } else if (auto* s = cty->As()) { - if (auto* si = Structure(s)) { - align = si->align; - size = si->size; - return true; - } - return false; + } else if (auto* s = cty->As()) { + align = s->Align(); + size = s->Size(); + return true; } else if (cty->Is()) { if (auto* sem = Array(ty->UnwrapAliasIfNeeded()->As(), source)) { @@ -2416,8 +2363,8 @@ bool Resolver::ValidateArray(const sem::ArrayType* arr, const Source& source) { return false; } - if (auto* el_str = el_ty->As()) { - if (el_str->impl()->IsBlockDecorated()) { + if (auto* el_str = el_ty->As()) { + if (el_str->IsBlockDecorated()) { // https://gpuweb.github.io/gpuweb/wgsl/#attributes // A structure type with the block attribute must not be: // * the element type of an array type @@ -2454,23 +2401,23 @@ bool Resolver::ValidateArrayStrideDecoration(const ast::StrideDecoration* deco, return true; } -bool Resolver::ValidateStructure(const StructInfo* st) { - for (auto* member : st->members) { +bool Resolver::ValidateStructure(const sem::Struct* str) { + for (auto* member : str->Members()) { if (auto* r = member->Type()->UnwrapAll()->As()) { if (r->IsRuntimeArray()) { - if (member != st->members.back()) { + if (member != str->Members().back()) { diagnostics_.add_error( "v-0015", "runtime arrays may only appear as the last member of a struct", member->Declaration()->source()); return false; } - if (!st->type->impl()->IsBlockDecorated()) { + if (!str->IsBlockDecorated()) { diagnostics_.add_error( "v-0015", "a struct containing a runtime-sized array " "requires the [[block]] attribute: '" + - builder_->Symbols().NameFor(st->type->impl()->name()) + "'", + builder_->Symbols().NameFor(str->Declaration()->name()) + "'", member->Declaration()->source()); return false; } @@ -2498,7 +2445,7 @@ bool Resolver::ValidateStructure(const StructInfo* st) { } } - for (auto* deco : st->type->impl()->decorations()) { + for (auto* deco : str->Declaration()->decorations()) { if (!(deco->Is())) { diagnostics_.add_error("decoration is not valid for struct declarations", deco->source()); @@ -2509,19 +2456,13 @@ bool Resolver::ValidateStructure(const StructInfo* st) { return true; } -Resolver::StructInfo* Resolver::Structure(const sem::StructType* str) { - auto info_it = struct_info_.find(str); - if (info_it != struct_info_.end()) { - // StructInfo already resolved for this structure type - return info_it->second; - } - - for (auto* deco : str->impl()->decorations()) { +sem::Struct* Resolver::Structure(const ast::Struct* str) { + for (auto* deco : str->decorations()) { Mark(deco); } sem::StructMemberList sem_members; - sem_members.reserve(str->impl()->members().size()); + sem_members.reserve(str->members().size()); // Calculate the effective size and alignment of each field, and the overall // size of the structure. @@ -2537,7 +2478,7 @@ Resolver::StructInfo* Resolver::Structure(const sem::StructType* str) { uint32_t struct_size = 0; uint32_t struct_align = 1; - for (auto* member : str->impl()->members()) { + for (auto* member : str->members()) { Mark(member); // Resolve member type @@ -2548,7 +2489,7 @@ Resolver::StructInfo* Resolver::Structure(const sem::StructType* str) { // Validate member type if (!IsStorable(type)) { - builder_->Diagnostics().add_error( + diagnostics_.add_error( type->FriendlyName(builder_->Symbols()) + " cannot be used as the type of a structure member"); return nullptr; @@ -2620,19 +2561,14 @@ Resolver::StructInfo* Resolver::Structure(const sem::StructType* str) { auto size_no_padding = struct_size; struct_size = utils::RoundUp(struct_align, struct_size); - auto* info = struct_infos_.Create(); - info->type = str; - info->members = std::move(sem_members); - info->align = struct_align; - info->size = struct_size; - info->size_no_padding = size_no_padding; - struct_info_.emplace(str, info); + auto* out = builder_->create( + str, std::move(sem_members), struct_align, struct_size, size_no_padding); - if (!ValidateStructure(info)) { + if (!ValidateStructure(out)) { return nullptr; } - return info; + return out; } bool Resolver::ValidateReturn(const ast::ReturnStatement* ret) { @@ -2828,20 +2764,18 @@ bool Resolver::Assignment(ast::AssignmentStatement* a) { } bool Resolver::ApplyStorageClassUsageToType(ast::StorageClass sc, - const sem::Type* ty, + sem::Type* ty, const Source& usage) { ty = ty->UnwrapIfNeeded(); - if (auto* str = ty->As()) { - auto* info = Structure(str); - if (!info) { - return false; - } - if (info->storage_class_usage.count(sc)) { + if (auto* str = ty->As()) { + if (str->StorageClassUsage().count(sc)) { return true; // Already applied } - info->storage_class_usage.emplace(sc); - for (auto* member : info->members) { + + str->AddUsage(sc); + + for (auto* member : str->Members()) { if (!ApplyStorageClassUsageToType(sc, member->Type(), usage)) { std::stringstream err; err << "while analysing structure member " @@ -2887,7 +2821,7 @@ std::string Resolver::VectorPretty(uint32_t size, sem::Type* element_type) { return vec_type.FriendlyName(builder_->Symbols()); } -const sem::Type* Resolver::Canonical(const sem::Type* type) { +sem::Type* Resolver::Canonical(sem::Type* type) { using AccessControl = sem::AccessControl; using Alias = sem::Alias; using Matrix = sem::Matrix; @@ -2899,17 +2833,16 @@ const sem::Type* Resolver::Canonical(const sem::Type* type) { return nullptr; } - std::function make_canonical; - make_canonical = [&](const Type* t) -> const sem::Type* { + std::function make_canonical; + make_canonical = [&](Type* t) -> sem::Type* { // Unwrap alias sequence - const Type* ct = t; + Type* ct = t; while (auto* p = ct->As()) { ct = p->type(); } if (auto* v = ct->As()) { - return builder_->create( - const_cast(make_canonical(v->type())), v->size()); + return builder_->create(make_canonical(v->type()), v->size()); } if (auto* m = ct->As()) { auto* column_type = @@ -2943,7 +2876,7 @@ void Resolver::Mark(const ast::Node* node) { } Resolver::VariableInfo::VariableInfo(const ast::Variable* decl, - const sem::Type* ctype, + sem::Type* ctype, const std::string& tn) : declaration(decl), type(ctype), @@ -2955,8 +2888,5 @@ Resolver::VariableInfo::~VariableInfo() = default; Resolver::FunctionInfo::FunctionInfo(ast::Function* decl) : declaration(decl) {} Resolver::FunctionInfo::~FunctionInfo() = default; -Resolver::StructInfo::StructInfo() = default; -Resolver::StructInfo::~StructInfo() = default; - } // namespace resolver } // namespace tint diff --git a/src/resolver/resolver.h b/src/resolver/resolver.h index 442613878c..4e94403060 100644 --- a/src/resolver/resolver.h +++ b/src/resolver/resolver.h @@ -49,9 +49,6 @@ namespace sem { class Array; class Statement; } // namespace sem -namespace sem { -class StructType; -} // namespace sem namespace resolver { @@ -90,19 +87,19 @@ class Resolver { /// @returns the canonical type for `type`; that is, a type with all aliases /// removed. For example, `Canonical(alias>>>)` is /// `vec3`. - const sem::Type* Canonical(const sem::Type* type); + sem::Type* Canonical(sem::Type* type); private: /// Structure holding semantic information about a variable. /// Used to build the sem::Variable nodes at the end of resolving. struct VariableInfo { VariableInfo(const ast::Variable* decl, - const sem::Type* type, + sem::Type* type, const std::string& type_name); ~VariableInfo(); ast::Variable const* const declaration; - sem::Type const* type; + sem::Type* type; std::string const type_name; ast::StorageClass storage_class; std::vector users; @@ -119,7 +116,7 @@ class Resolver { UniqueVector referenced_module_vars; UniqueVector local_referenced_module_vars; std::vector return_statements; - sem::Type const* return_type = nullptr; + sem::Type* return_type = nullptr; std::string return_type_name; // List of transitive calls this function makes @@ -129,7 +126,7 @@ class Resolver { /// Structure holding semantic information about an expression. /// Used to build the sem::Expression nodes at the end of resolving. struct ExpressionInfo { - sem::Type const* type; + sem::Type* type; std::string const type_name; // Declared type name sem::Statement* statement; }; @@ -142,21 +139,6 @@ class Resolver { sem::Statement* statement; }; - /// Structure holding semantic information about a struct. - /// Used to build the sem::Struct nodes at the end of resolving. - struct StructInfo { - StructInfo(); - ~StructInfo(); - - sem::StructType const* type = nullptr; - std::vector members; - uint32_t align = 0; - uint32_t size = 0; - uint32_t size_no_padding = 0; - std::unordered_set storage_class_usage; - std::unordered_set pipeline_stage_uses; - }; - /// Structure holding semantic information about a block (i.e. scope), such as /// parent block and variables declared in the block. /// Used to validate variable scoping rules. @@ -237,7 +219,6 @@ class Resolver { bool Statement(ast::Statement*); bool Statements(const ast::StatementList&); bool Switch(ast::SwitchStatement* s); - bool Type(const sem::Type* ty, const Source& source = {}); bool UnaryOp(ast::UnaryOpExpression*); bool VariableDeclStatement(const ast::VariableDeclStatement*); @@ -257,7 +238,7 @@ class Resolver { const sem::Matrix* matrix_type); bool ValidateParameter(const ast::Variable* param); bool ValidateReturn(const ast::ReturnStatement* ret); - bool ValidateStructure(const StructInfo* st); + bool ValidateStructure(const sem::Struct* str); bool ValidateSwitch(const ast::SwitchStatement* s); bool ValidateVariable(const ast::Variable* param); bool ValidateVectorConstructor(const ast::TypeConstructorExpression* ctor, @@ -267,7 +248,7 @@ class Resolver { /// hasn't been constructed already. If an error is raised, nullptr is /// returned. /// @param ty the ast::Type - const sem::Type* Type(const ast::Type* ty); + sem::Type* Type(const ast::Type* ty); /// @returns the semantic information for the array `arr`, building it if it /// hasn't been constructed already. If an error is raised, nullptr is @@ -276,9 +257,9 @@ class Resolver { /// @param source the Source of the ast node with this array as its type const sem::Array* Array(const sem::ArrayType* arr, const Source& source); - /// @returns the StructInfo for the structure `str`, building it if it hasn't - /// been constructed already. If an error is raised, nullptr is returned. - StructInfo* Structure(const sem::StructType* str); + /// @returns the sem::Struct for the AST structure `str`. If an error is + /// raised, nullptr is returned. + sem::Struct* Structure(const ast::Struct* str); /// @returns the VariableInfo for the variable `var`, building it if it hasn't /// been constructed already. If an error is raised, nullptr is returned. @@ -287,7 +268,7 @@ class Resolver { /// @param type_name optional type name of `var` to use instead of /// `var->type()->FriendlyName()`. VariableInfo* Variable(ast::Variable* var, - const sem::Type* type = nullptr, + sem::Type* type = nullptr, std::string type_name = ""); /// Records the storage class usage for the given type, and any transient @@ -299,7 +280,7 @@ class Resolver { /// given type and storage class. Used for generating sensible error messages. /// @returns true on success, false on error bool ApplyStorageClassUsageToType(ast::StorageClass sc, - const sem::Type* ty, + sem::Type* ty, const Source& usage); /// @param align the output default alignment in bytes for the type `ty` @@ -313,7 +294,7 @@ class Resolver { /// @returns the resolved type of the ast::Expression `expr` /// @param expr the expression - const sem::Type* TypeOf(const ast::Expression* expr); + sem::Type* TypeOf(const ast::Expression* expr); /// @returns the declared type name of the ast::Expression `expr` /// @param expr the type name @@ -321,7 +302,7 @@ class Resolver { /// @returns the semantic type of the AST literal `lit` /// @param lit the literal - const sem::Type* TypeOf(const ast::Literal* lit); + sem::Type* TypeOf(const ast::Literal* lit); /// Creates a sem::Expression node with the resolved type `type`, and /// assigns this semantic node to the expression `expr`. @@ -369,15 +350,13 @@ class Resolver { std::unordered_map variable_to_info_; std::unordered_map function_calls_; std::unordered_map expr_info_; - std::unordered_map struct_info_; - std::unordered_map type_to_canonical_; - std::unordered_map named_types_; + std::unordered_map type_to_canonical_; + std::unordered_map named_types_; std::unordered_set marked_; FunctionInfo* current_function_ = nullptr; sem::Statement* current_statement_ = nullptr; BlockAllocator variable_infos_; BlockAllocator function_infos_; - BlockAllocator struct_infos_; }; } // namespace resolver diff --git a/src/resolver/resolver_test.cc b/src/resolver/resolver_test.cc index f41639ef2e..32a900aa8e 100644 --- a/src/resolver/resolver_test.cc +++ b/src/resolver/resolver_test.cc @@ -764,8 +764,8 @@ TEST_F(ResolverTest, Function_Parameters) { } TEST_F(ResolverTest, Function_RegisterInputOutputVariables) { - auto s = Structure("S", {Member("m", ty.u32())}, - {create()}); + auto* s = Structure("S", {Member("m", ty.u32())}, + {create()}); auto a = ty.access(ast::AccessControl::kReadOnly, s); auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput); @@ -800,8 +800,8 @@ TEST_F(ResolverTest, Function_RegisterInputOutputVariables) { } TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) { - auto s = Structure("S", {Member("m", ty.u32())}, - {create()}); + auto* s = Structure("S", {Member("m", ty.u32())}, + {create()}); auto a = ty.access(ast::AccessControl::kReadOnly, s); auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput); @@ -884,8 +884,8 @@ TEST_F(ResolverTest, Function_ReturnStatements) { } TEST_F(ResolverTest, Expr_MemberAccessor_Struct) { - auto st = Structure("S", {Member("first_member", ty.i32()), - Member("second_member", ty.f32())}); + auto* st = Structure("S", {Member("first_member", ty.i32()), + Member("second_member", ty.f32())}); Global("my_struct", st, ast::StorageClass::kInput); auto* mem = MemberAccessor("my_struct", "second_member"); @@ -906,8 +906,8 @@ TEST_F(ResolverTest, Expr_MemberAccessor_Struct) { } TEST_F(ResolverTest, Expr_MemberAccessor_Struct_Alias) { - auto st = Structure("S", {Member("first_member", ty.i32()), - Member("second_member", ty.f32())}); + auto* st = Structure("S", {Member("first_member", ty.i32()), + Member("second_member", ty.f32())}); auto alias = ty.alias("alias", st); AST().AddConstructedType(alias); Global("my_struct", alias, ast::StorageClass::kInput); @@ -987,8 +987,8 @@ TEST_F(ResolverTest, Expr_Accessor_MultiLevel) { // } // - auto stB = Structure("B", {Member("foo", ty.vec4())}); - auto stA = Structure("A", {Member("mem", ty.vec(stB, 3))}); + auto* stB = Structure("B", {Member("foo", ty.vec4())}); + auto* stA = Structure("A", {Member("mem", ty.vec(stB, 3))}); Global("c", stA, ast::StorageClass::kInput); auto* mem = MemberAccessor( @@ -1006,8 +1006,8 @@ TEST_F(ResolverTest, Expr_Accessor_MultiLevel) { } TEST_F(ResolverTest, Expr_MemberAccessor_InBinaryOp) { - auto st = Structure("S", {Member("first_member", ty.f32()), - Member("second_member", ty.f32())}); + auto* st = Structure("S", {Member("first_member", ty.f32()), + Member("second_member", ty.f32())}); Global("my_struct", st, ast::StorageClass::kInput); auto* expr = Add(MemberAccessor("my_struct", "first_member"), diff --git a/src/resolver/storage_class_validation_test.cc b/src/resolver/storage_class_validation_test.cc index 875cffa0b2..db6be8eb9b 100644 --- a/src/resolver/storage_class_validation_test.cc +++ b/src/resolver/storage_class_validation_test.cc @@ -60,7 +60,7 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) { TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) { // var g : [[access(read)]] array; - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); auto a = ty.array(s, 3); auto ac = ty.access(ast::AccessControl::kReadOnly, a); Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kStorage); @@ -88,7 +88,7 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) { TEST_F(ResolverStorageClassValidationTest, StorageBufferNoAccessControl) { // var g : S; - auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}); + auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}); Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage); ASSERT_FALSE(r()->Resolve()); @@ -101,7 +101,7 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferNoAccessControl) { TEST_F(ResolverStorageClassValidationTest, StorageBufferNoBlockDecoration) { // struct S { x : i32 }; // var g : [[access(read)]] S; - auto s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())}); + auto* s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())}); auto a = ty.access(ast::AccessControl::kReadOnly, s); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); @@ -116,8 +116,8 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferNoBlockDecoration) { TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Basic) { // [[block]] struct S { x : i32 }; // var g : [[access(read)]] S; - auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, - {create()}); + auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, + {create()}); auto a = ty.access(ast::AccessControl::kReadOnly, s); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); @@ -129,8 +129,8 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Aliases) { // type a1 = S; // type a2 = [[access(read)]] a1; // var g : a2; - auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, - {create()}); + auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, + {create()}); auto a1 = ty.alias("a1", s); AST().AddConstructedType(a1); auto ac = ty.access(ast::AccessControl::kReadOnly, a1); @@ -168,7 +168,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferPointer) { TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) { // var g : [[access(read)]] array; - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); auto a = ty.array(s, 3); auto ac = ty.access(ast::AccessControl::kReadOnly, a); Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kUniform); @@ -197,7 +197,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferBoolAlias) { TEST_F(ResolverStorageClassValidationTest, UniformBufferNoBlockDecoration) { // struct S { x : i32 }; // var g : S; - auto s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())}); + auto* s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())}); Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform); ASSERT_FALSE(r()->Resolve()); @@ -211,8 +211,8 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferNoBlockDecoration) { TEST_F(ResolverStorageClassValidationTest, UniformBufferNoError_Basic) { // [[block]] struct S { x : i32 }; // var g : S; - auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, - {create()}); + auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, + {create()}); Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform); ASSERT_TRUE(r()->Resolve()); @@ -222,8 +222,8 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferNoError_Aliases) { // [[block]] struct S { x : i32 }; // type a1 = S; // var g : a1; - auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, - {create()}); + auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, + {create()}); auto a1 = ty.alias("a1", s); AST().AddConstructedType(a1); Global(Source{{56, 78}}, "g", a1, ast::StorageClass::kUniform); diff --git a/src/resolver/struct_layout_test.cc b/src/resolver/struct_layout_test.cc index 1a17706a2f..55d5d2e99b 100644 --- a/src/resolver/struct_layout_test.cc +++ b/src/resolver/struct_layout_test.cc @@ -26,15 +26,15 @@ namespace { using ResolverStructLayoutTest = ResolverTest; TEST_F(ResolverStructLayoutTest, Scalars) { - auto s = Structure("S", { - Member("a", ty.f32()), - Member("b", ty.u32()), - Member("c", ty.i32()), - }); + auto* s = Structure("S", { + Member("a", ty.f32()), + Member("b", ty.u32()), + Member("c", ty.i32()), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 12u); EXPECT_EQ(sem->SizeNoPadding(), 12u); @@ -57,14 +57,14 @@ TEST_F(ResolverStructLayoutTest, Alias) { auto alias_b = ty.alias("b", ty.f32()); AST().AddConstructedType(alias_b); - auto s = Structure("S", { - Member("a", alias_a), - Member("b", alias_b), - }); + auto* s = Structure("S", { + Member("a", alias_a), + Member("b", alias_b), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 8u); EXPECT_EQ(sem->SizeNoPadding(), 8u); @@ -79,15 +79,15 @@ TEST_F(ResolverStructLayoutTest, Alias) { } TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayStaticSize) { - auto s = Structure("S", { - Member("a", ty.array()), - Member("b", ty.array()), - Member("c", ty.array()), - }); + auto* s = Structure("S", { + Member("a", ty.array()), + Member("b", ty.array()), + Member("c", ty.array()), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 36u); EXPECT_EQ(sem->SizeNoPadding(), 36u); @@ -105,15 +105,15 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayStaticSize) { } TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayStaticSize) { - auto s = Structure("S", { - Member("a", ty.array(/*stride*/ 8)), - Member("b", ty.array(/*stride*/ 16)), - Member("c", ty.array(/*stride*/ 32)), - }); + auto* s = Structure("S", { + Member("a", ty.array(/*stride*/ 8)), + Member("b", ty.array(/*stride*/ 16)), + Member("c", ty.array(/*stride*/ 32)), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 136u); EXPECT_EQ(sem->SizeNoPadding(), 136u); @@ -131,15 +131,16 @@ TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayStaticSize) { } TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayRuntimeSized) { - auto s = Structure("S", - { - Member("c", ty.array()), - }, - ast::DecorationList{create()}); + auto* s = + Structure("S", + { + Member("c", ty.array()), + }, + ast::DecorationList{create()}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 4u); EXPECT_EQ(sem->SizeNoPadding(), 4u); @@ -151,15 +152,16 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayRuntimeSized) { } TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayRuntimeSized) { - auto s = Structure("S", - { - Member("c", ty.array(/*stride*/ 32)), - }, - ast::DecorationList{create()}); + auto* s = + Structure("S", + { + Member("c", ty.array(/*stride*/ 32)), + }, + ast::DecorationList{create()}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 32u); EXPECT_EQ(sem->SizeNoPadding(), 32u); @@ -173,13 +175,13 @@ TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayRuntimeSized) { TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfExplicitStrideArray) { auto inner = ty.array(/*stride*/ 16); // size: 32 auto outer = ty.array(inner, 12); // size: 12 * 32 - auto s = Structure("S", { - Member("c", outer), - }); + auto* s = Structure("S", { + Member("c", outer), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 384u); EXPECT_EQ(sem->SizeNoPadding(), 384u); @@ -191,19 +193,19 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfExplicitStrideArray) { } TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfStructure) { - auto inner = Structure("Inner", { - Member("a", ty.vec2()), - Member("b", ty.vec3()), - Member("c", ty.vec4()), - }); // size: 48 - auto outer = ty.array(inner, 12); // size: 12 * 48 - auto s = Structure("S", { - Member("c", outer), - }); + auto* inner = Structure("Inner", { + Member("a", ty.vec2()), + Member("b", ty.vec3()), + Member("c", ty.vec4()), + }); // size: 48 + auto outer = ty.array(inner, 12); // size: 12 * 48 + auto* s = Structure("S", { + Member("c", outer), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 576u); EXPECT_EQ(sem->SizeNoPadding(), 576u); @@ -215,15 +217,15 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfStructure) { } TEST_F(ResolverStructLayoutTest, Vector) { - auto s = Structure("S", { - Member("a", ty.vec2()), - Member("b", ty.vec3()), - Member("c", ty.vec4()), - }); + auto* s = Structure("S", { + Member("a", ty.vec2()), + Member("b", ty.vec3()), + Member("c", ty.vec4()), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 48u); EXPECT_EQ(sem->SizeNoPadding(), 48u); @@ -241,21 +243,21 @@ TEST_F(ResolverStructLayoutTest, Vector) { } TEST_F(ResolverStructLayoutTest, Matrix) { - auto s = Structure("S", { - Member("a", ty.mat2x2()), - Member("b", ty.mat2x3()), - Member("c", ty.mat2x4()), - Member("d", ty.mat3x2()), - Member("e", ty.mat3x3()), - Member("f", ty.mat3x4()), - Member("g", ty.mat4x2()), - Member("h", ty.mat4x3()), - Member("i", ty.mat4x4()), - }); + auto* s = Structure("S", { + Member("a", ty.mat2x2()), + Member("b", ty.mat2x3()), + Member("c", ty.mat2x4()), + Member("d", ty.mat3x2()), + Member("e", ty.mat3x3()), + Member("f", ty.mat3x4()), + Member("g", ty.mat4x2()), + Member("h", ty.mat4x3()), + Member("i", ty.mat4x4()), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 368u); EXPECT_EQ(sem->SizeNoPadding(), 368u); @@ -291,18 +293,18 @@ TEST_F(ResolverStructLayoutTest, Matrix) { } TEST_F(ResolverStructLayoutTest, NestedStruct) { - auto inner = Structure("Inner", { - Member("a", ty.mat3x3()), - }); - auto s = Structure("S", { - Member("a", ty.i32()), - Member("b", inner), - Member("c", ty.i32()), - }); + auto* inner = Structure("Inner", { + Member("a", ty.mat3x3()), + }); + auto* s = Structure("S", { + Member("a", ty.i32()), + Member("b", inner), + Member("c", ty.i32()), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 80u); EXPECT_EQ(sem->SizeNoPadding(), 68u); @@ -320,21 +322,21 @@ TEST_F(ResolverStructLayoutTest, NestedStruct) { } TEST_F(ResolverStructLayoutTest, SizeDecorations) { - auto inner = Structure("Inner", { - Member("a", ty.f32(), {MemberSize(8)}), - Member("b", ty.f32(), {MemberSize(16)}), - Member("c", ty.f32(), {MemberSize(8)}), - }); - auto s = Structure("S", { - Member("a", ty.f32(), {MemberSize(4)}), - Member("b", ty.u32(), {MemberSize(8)}), - Member("c", inner), - Member("d", ty.i32(), {MemberSize(32)}), - }); + auto* inner = Structure("Inner", { + Member("a", ty.f32(), {MemberSize(8)}), + Member("b", ty.f32(), {MemberSize(16)}), + Member("c", ty.f32(), {MemberSize(8)}), + }); + auto* s = Structure("S", { + Member("a", ty.f32(), {MemberSize(4)}), + Member("b", ty.u32(), {MemberSize(8)}), + Member("c", inner), + Member("d", ty.i32(), {MemberSize(32)}), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 76u); EXPECT_EQ(sem->SizeNoPadding(), 76u); @@ -355,21 +357,21 @@ TEST_F(ResolverStructLayoutTest, SizeDecorations) { } TEST_F(ResolverStructLayoutTest, AlignDecorations) { - auto inner = Structure("Inner", { - Member("a", ty.f32(), {MemberAlign(8)}), - Member("b", ty.f32(), {MemberAlign(16)}), - Member("c", ty.f32(), {MemberAlign(4)}), - }); - auto s = Structure("S", { - Member("a", ty.f32(), {MemberAlign(4)}), - Member("b", ty.u32(), {MemberAlign(8)}), - Member("c", inner), - Member("d", ty.i32(), {MemberAlign(32)}), - }); + auto* inner = Structure("Inner", { + Member("a", ty.f32(), {MemberAlign(8)}), + Member("b", ty.f32(), {MemberAlign(16)}), + Member("c", ty.f32(), {MemberAlign(4)}), + }); + auto* s = Structure("S", { + Member("a", ty.f32(), {MemberAlign(4)}), + Member("b", ty.u32(), {MemberAlign(8)}), + Member("c", inner), + Member("d", ty.i32(), {MemberAlign(32)}), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 96u); EXPECT_EQ(sem->SizeNoPadding(), 68u); @@ -390,13 +392,13 @@ TEST_F(ResolverStructLayoutTest, AlignDecorations) { } TEST_F(ResolverStructLayoutTest, StructWithLotsOfPadding) { - auto s = Structure("S", { - Member("a", ty.i32(), {MemberAlign(1024)}), - }); + auto* s = Structure("S", { + Member("a", ty.i32(), {MemberAlign(1024)}), + }); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_EQ(sem->Size(), 1024u); EXPECT_EQ(sem->SizeNoPadding(), 4u); diff --git a/src/resolver/struct_pipeline_stage_use_test.cc b/src/resolver/struct_pipeline_stage_use_test.cc index 35e7a533df..293076077e 100644 --- a/src/resolver/struct_pipeline_stage_use_test.cc +++ b/src/resolver/struct_pipeline_stage_use_test.cc @@ -28,41 +28,41 @@ namespace { using ResolverPipelineStageUseTest = ResolverTest; TEST_F(ResolverPipelineStageUseTest, UnusedStruct) { - auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); + auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_TRUE(sem->PipelineStageUses().empty()); } TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointParam) { - auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); + auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); Func("foo", {Param("param", s)}, ty.void_(), {}, {}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_TRUE(sem->PipelineStageUses().empty()); } TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointReturnType) { - auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); + auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); Func("foo", {}, s, {Return(Construct(s, Expr(0.f)))}, {}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_TRUE(sem->PipelineStageUses().empty()); } TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderParam) { - auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); + auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); Func("main", {Param("param", s)}, ty.vec4(), {Return(Construct(ty.vec4()))}, @@ -71,14 +71,14 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderParam) { ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->PipelineStageUses(), UnorderedElementsAre(sem::PipelineStageUsage::kVertexInput)); } TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderReturnType) { - auto s = Structure( + auto* s = Structure( "S", {Member("a", ty.f32(), {Builtin(ast::Builtin::kPosition)})}); Func("main", {}, s, {Return(Construct(s, Expr(0.f)))}, @@ -86,42 +86,42 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderReturnType) { ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->PipelineStageUses(), UnorderedElementsAre(sem::PipelineStageUsage::kVertexOutput)); } TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderParam) { - auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); + auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); Func("main", {Param("param", s)}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->PipelineStageUses(), UnorderedElementsAre(sem::PipelineStageUsage::kFragmentInput)); } TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderReturnType) { - auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); + auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); Func("main", {}, s, {Return(Construct(s, Expr(0.f)))}, {Stage(ast::PipelineStage::kFragment)}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->PipelineStageUses(), UnorderedElementsAre(sem::PipelineStageUsage::kFragmentOutput)); } TEST_F(ResolverPipelineStageUseTest, StructUsedAsComputeShaderParam) { - auto s = Structure( + auto* s = Structure( "S", {Member("a", ty.u32(), {Builtin(ast::Builtin::kLocalInvocationIndex)})}); @@ -130,14 +130,14 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsComputeShaderParam) { ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->PipelineStageUses(), UnorderedElementsAre(sem::PipelineStageUsage::kComputeInput)); } TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) { - auto s = Structure( + auto* s = Structure( "S", {Member("a", ty.f32(), {Builtin(ast::Builtin::kPosition)})}); Func("vert_main", {Param("param", s)}, s, {Return(Construct(s, Expr(0.f)))}, @@ -148,7 +148,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) { ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->PipelineStageUses(), UnorderedElementsAre(sem::PipelineStageUsage::kVertexInput, @@ -157,7 +157,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) { } TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamViaAlias) { - auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); + auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s_alias = ty.alias("S_alias", s); AST().AddConstructedType(s_alias); @@ -166,14 +166,14 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamViaAlias) { ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->PipelineStageUses(), UnorderedElementsAre(sem::PipelineStageUsage::kFragmentInput)); } TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeViaAlias) { - auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); + auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s_alias = ty.alias("S_alias", s); AST().AddConstructedType(s_alias); @@ -182,7 +182,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeViaAlias) { ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->PipelineStageUses(), UnorderedElementsAre(sem::PipelineStageUsage::kFragmentOutput)); diff --git a/src/resolver/struct_storage_class_use_test.cc b/src/resolver/struct_storage_class_use_test.cc index 9f6d2e4c6c..b41a5e3106 100644 --- a/src/resolver/struct_storage_class_use_test.cc +++ b/src/resolver/struct_storage_class_use_test.cc @@ -28,150 +28,150 @@ namespace { using ResolverStorageClassUseTest = ResolverTest; TEST_F(ResolverStorageClassUseTest, UnreachableStruct) { - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_TRUE(sem->StorageClassUsage().empty()); } TEST_F(ResolverStorageClassUseTest, StructReachableFromParameter) { - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); Func("f", {Param("param", s)}, ty.void_(), {}, {}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kNone)); } TEST_F(ResolverStorageClassUseTest, StructReachableFromReturnType) { - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); Func("f", {}, s, {Return(Construct(s))}, {}); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kNone)); } TEST_F(ResolverStorageClassUseTest, StructReachableFromGlobal) { - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); Global("g", s, ast::StorageClass::kPrivate); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kPrivate)); } TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalAlias) { - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); auto a = ty.alias("A", s); AST().AddConstructedType(a); Global("g", a, ast::StorageClass::kPrivate); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kPrivate)); } TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalStruct) { - auto s = Structure("S", {Member("a", ty.f32())}); - auto o = Structure("O", {Member("a", s)}); + auto* s = Structure("S", {Member("a", ty.f32())}); + auto* o = Structure("O", {Member("a", s)}); Global("g", o, ast::StorageClass::kPrivate); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kPrivate)); } TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalArray) { - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); auto a = ty.array(s, 3); Global("g", a, ast::StorageClass::kPrivate); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kPrivate)); } TEST_F(ResolverStorageClassUseTest, StructReachableFromLocal) { - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); WrapInFunction(Var("g", s, ast::StorageClass::kFunction)); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kFunction)); } TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalAlias) { - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); auto a = ty.alias("A", s); AST().AddConstructedType(a); WrapInFunction(Var("g", a, ast::StorageClass::kFunction)); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kFunction)); } TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalStruct) { - auto s = Structure("S", {Member("a", ty.f32())}); - auto o = Structure("O", {Member("a", s)}); + auto* s = Structure("S", {Member("a", ty.f32())}); + auto* o = Structure("O", {Member("a", s)}); WrapInFunction(Var("g", o, ast::StorageClass::kFunction)); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kFunction)); } TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalArray) { - auto s = Structure("S", {Member("a", ty.f32())}); + auto* s = Structure("S", {Member("a", ty.f32())}); auto a = ty.array(s, 3); WrapInFunction(Var("g", a, ast::StorageClass::kFunction)); ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kFunction)); } TEST_F(ResolverStorageClassUseTest, StructMultipleStorageClassUses) { - auto s = Structure("S", {Member("a", ty.f32())}, - {create()}); + auto* s = Structure("S", {Member("a", ty.f32())}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, s); Global("x", s, ast::StorageClass::kUniform); Global("y", ac, ast::StorageClass::kStorage); @@ -179,7 +179,7 @@ TEST_F(ResolverStorageClassUseTest, StructMultipleStorageClassUses) { ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* sem = Sem().Get(s.sem); + auto* sem = TypeOf(s)->As(); ASSERT_NE(sem, nullptr); EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kUniform, diff --git a/src/sem/access_control_type_test.cc b/src/sem/access_control_type_test.cc index cbc7cfd4c2..3b3138b564 100644 --- a/src/sem/access_control_type_test.cc +++ b/src/sem/access_control_type_test.cc @@ -44,7 +44,7 @@ TEST_F(AccessControlTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/alias_type_test.cc b/src/sem/alias_type_test.cc index 62b96a10ea..27d5084c8b 100644 --- a/src/sem/alias_type_test.cc +++ b/src/sem/alias_type_test.cc @@ -40,7 +40,7 @@ TEST_F(AliasTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/array_type_test.cc b/src/sem/array_type_test.cc index 6d2124988b..636520b9c9 100644 --- a/src/sem/array_type_test.cc +++ b/src/sem/array_type_test.cc @@ -54,7 +54,7 @@ TEST_F(ArrayTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/bool_type_test.cc b/src/sem/bool_type_test.cc index c11872da88..a76f1fb130 100644 --- a/src/sem/bool_type_test.cc +++ b/src/sem/bool_type_test.cc @@ -34,7 +34,7 @@ TEST_F(BoolTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/depth_texture_type_test.cc b/src/sem/depth_texture_type_test.cc index da779a5e08..3f1ddcd7d9 100644 --- a/src/sem/depth_texture_type_test.cc +++ b/src/sem/depth_texture_type_test.cc @@ -39,7 +39,7 @@ TEST_F(DepthTextureTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/external_texture_type_test.cc b/src/sem/external_texture_type_test.cc index 89bfa19747..afbb98eb8f 100644 --- a/src/sem/external_texture_type_test.cc +++ b/src/sem/external_texture_type_test.cc @@ -40,7 +40,7 @@ TEST_F(ExternalTextureTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/f32_type_test.cc b/src/sem/f32_type_test.cc index 402b95387f..bc18606140 100644 --- a/src/sem/f32_type_test.cc +++ b/src/sem/f32_type_test.cc @@ -34,7 +34,7 @@ TEST_F(F32Test, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/i32_type_test.cc b/src/sem/i32_type_test.cc index 1b6e1d3a00..3d14f35394 100644 --- a/src/sem/i32_type_test.cc +++ b/src/sem/i32_type_test.cc @@ -34,7 +34,7 @@ TEST_F(I32Test, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/matrix_type_test.cc b/src/sem/matrix_type_test.cc index 9b3df83b2e..4896ca2080 100644 --- a/src/sem/matrix_type_test.cc +++ b/src/sem/matrix_type_test.cc @@ -45,7 +45,7 @@ TEST_F(MatrixTest, Is) { EXPECT_TRUE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/multisampled_texture_type_test.cc b/src/sem/multisampled_texture_type_test.cc index 4f5a977e33..e35a2e9788 100644 --- a/src/sem/multisampled_texture_type_test.cc +++ b/src/sem/multisampled_texture_type_test.cc @@ -40,7 +40,7 @@ TEST_F(MultisampledTextureTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/pointer_type_test.cc b/src/sem/pointer_type_test.cc index 71fc47fd54..00cec4b0ae 100644 --- a/src/sem/pointer_type_test.cc +++ b/src/sem/pointer_type_test.cc @@ -42,7 +42,7 @@ TEST_F(PointerTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/sampled_texture_type_test.cc b/src/sem/sampled_texture_type_test.cc index b3dd053644..cb00b03d7d 100644 --- a/src/sem/sampled_texture_type_test.cc +++ b/src/sem/sampled_texture_type_test.cc @@ -39,7 +39,7 @@ TEST_F(SampledTextureTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/sampler_type_test.cc b/src/sem/sampler_type_test.cc index ccac4975e1..c419ee68b7 100644 --- a/src/sem/sampler_type_test.cc +++ b/src/sem/sampler_type_test.cc @@ -45,7 +45,7 @@ TEST_F(SamplerTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/struct_type_test.cc b/src/sem/sem_struct_test.cc similarity index 66% rename from src/sem/struct_type_test.cc rename to src/sem/sem_struct_test.cc index ab734087fb..0e5742a1ed 100644 --- a/src/sem/struct_type_test.cc +++ b/src/sem/sem_struct_test.cc @@ -13,6 +13,7 @@ // limitations under the License. #include "src/sem/access_control_type.h" +#include "src/sem/struct.h" #include "src/sem/test_helper.h" #include "src/sem/texture_type.h" @@ -20,22 +21,27 @@ namespace tint { namespace sem { namespace { -using StructTypeTest = TestHelper; +using StructTest = TestHelper; -TEST_F(StructTypeTest, Creation) { +TEST_F(StructTest, Creation) { auto name = Sym("S"); auto* impl = create(name, ast::StructMemberList{}, ast::DecorationList{}); auto* ptr = impl; - auto s = ty.struct_(impl); - EXPECT_EQ(s->impl(), ptr); + auto* s = create(impl, StructMemberList{}, 4 /* align */, + 8 /* size */, 16 /* size_no_padding */); + EXPECT_EQ(s->Declaration(), ptr); + EXPECT_EQ(s->Align(), 4u); + EXPECT_EQ(s->Size(), 8u); + EXPECT_EQ(s->SizeNoPadding(), 16u); } -TEST_F(StructTypeTest, Is) { +TEST_F(StructTest, Is) { auto name = Sym("S"); auto* impl = create(name, ast::StructMemberList{}, ast::DecorationList{}); - auto s = ty.struct_(impl); + auto* s = create(impl, StructMemberList{}, 4 /* align */, + 4 /* size */, 4 /* size_no_padding */); sem::Type* ty = s; EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); @@ -46,25 +52,27 @@ TEST_F(StructTypeTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_TRUE(ty->Is()); + EXPECT_TRUE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); } -TEST_F(StructTypeTest, TypeName) { +TEST_F(StructTest, TypeName) { auto name = Sym("my_struct"); auto* impl = create(name, ast::StructMemberList{}, ast::DecorationList{}); - auto s = ty.struct_(impl); + auto* s = create(impl, StructMemberList{}, 4 /* align */, + 4 /* size */, 4 /* size_no_padding */); EXPECT_EQ(s->type_name(), "__struct_$1"); } -TEST_F(StructTypeTest, FriendlyName) { +TEST_F(StructTest, FriendlyName) { auto name = Sym("my_struct"); auto* impl = create(name, ast::StructMemberList{}, ast::DecorationList{}); - auto s = ty.struct_(impl); + auto* s = create(impl, StructMemberList{}, 4 /* align */, + 4 /* size */, 4 /* size_no_padding */); EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct"); } diff --git a/src/sem/storage_texture_type_test.cc b/src/sem/storage_texture_type_test.cc index f36706bb72..77b8944d6e 100644 --- a/src/sem/storage_texture_type_test.cc +++ b/src/sem/storage_texture_type_test.cc @@ -41,7 +41,7 @@ TEST_F(StorageTextureTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/struct.cc b/src/sem/struct.cc index 85afa684a1..40f3e0649e 100644 --- a/src/sem/struct.cc +++ b/src/sem/struct.cc @@ -15,6 +15,7 @@ #include "src/sem/struct.h" #include "src/ast/struct_member.h" +#include #include TINT_INSTANTIATE_TYPEINFO(tint::sem::Struct); @@ -23,20 +24,16 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::StructMember); namespace tint { namespace sem { -Struct::Struct(sem::StructType* type, +Struct::Struct(const ast::Struct* declaration, StructMemberList members, uint32_t align, uint32_t size, - uint32_t size_no_padding, - std::unordered_set storage_class_usage, - std::unordered_set pipeline_stage_uses) - : type_(type), + uint32_t size_no_padding) + : declaration_(declaration), members_(std::move(members)), align_(align), size_(size), - size_no_padding_(size_no_padding), - storage_class_usage_(std::move(storage_class_usage)), - pipeline_stage_uses_(std::move(pipeline_stage_uses)) {} + size_no_padding_(size_no_padding) {} Struct::~Struct() = default; @@ -49,6 +46,14 @@ const StructMember* Struct::FindMember(Symbol name) const { return nullptr; } +std::string Struct::type_name() const { + return declaration_->type_name(); +} + +std::string Struct::FriendlyName(const SymbolTable& symbols) const { + return declaration_->FriendlyName(symbols); +} + StructMember::StructMember(ast::StructMember* declaration, sem::Type* type, uint32_t offset, diff --git a/src/sem/struct.h b/src/sem/struct.h index 1c1d1a876e..fda7b4f325 100644 --- a/src/sem/struct.h +++ b/src/sem/struct.h @@ -17,11 +17,14 @@ #include +#include #include #include #include "src/ast/storage_class.h" +#include "src/ast/struct.h" #include "src/sem/node.h" +#include "src/sem/type.h" #include "src/symbol.h" namespace tint { @@ -34,7 +37,6 @@ class StructMember; namespace sem { // Forward declarations -class StructType; class StructMember; class Type; @@ -52,30 +54,26 @@ enum class PipelineStageUsage { }; /// Struct holds the semantic information for structures. -class Struct : public Castable { +class Struct : public Castable { public: /// Constructor - /// @param type the structure type + /// @param declaration the AST structure declaration /// @param members the structure members /// @param align the byte alignment of the structure /// @param size the byte size of the structure /// @param size_no_padding size of the members without the end of structure /// alignment padding - /// @param storage_class_usage a set of all the storage class usages - /// @param pipeline_stage_uses a set of all the pipeline stage uses - Struct(sem::StructType* type, + Struct(const ast::Struct* declaration, StructMemberList members, uint32_t align, uint32_t size, - uint32_t size_no_padding, - std::unordered_set storage_class_usage, - std::unordered_set pipeline_stage_uses); + uint32_t size_no_padding); /// Destructor ~Struct() override; - /// @returns the structure type - sem::StructType* Type() const { return type_; } + /// @returns the struct + const ast::Struct* Declaration() const { return declaration_; } /// @returns the members of the structure const StructMemberList& Members() const { return members_; } @@ -100,6 +98,12 @@ class Struct : public Castable { /// alignment padding uint32_t SizeNoPadding() const { return size_no_padding_; } + /// Adds the StorageClass usage to the structure. + /// @param usage the storage usage + void AddUsage(ast::StorageClass usage) { + storage_class_usage_.emplace(usage); + } + /// @returns the set of storage class uses of this structure const std::unordered_set& StorageClassUsage() const { return storage_class_usage_; @@ -122,19 +126,38 @@ class Struct : public Castable { return false; } + /// Adds the pipeline stage usage to the structure. + /// @param usage the storage usage + void AddUsage(PipelineStageUsage usage) { + pipeline_stage_uses_.emplace(usage); + } + /// @returns the set of entry point uses of this structure const std::unordered_set& PipelineStageUses() const { return pipeline_stage_uses_; } + /// @returns true if the struct has a block decoration + bool IsBlockDecorated() const { return declaration_->IsBlockDecorated(); } + + /// @returns the name for the type + std::string type_name() const override; + + /// @param symbols the program's symbol table + /// @returns the name for this type that closely resembles how it would be + /// declared in WGSL. + std::string FriendlyName(const SymbolTable& symbols) const override; + private: - sem::StructType* const type_; + uint64_t LargestMemberBaseAlignment(MemoryLayout mem_layout) const; + + ast::Struct const* const declaration_; StructMemberList const members_; uint32_t const align_; uint32_t const size_; uint32_t const size_no_padding_; - std::unordered_set const storage_class_usage_; - std::unordered_set const pipeline_stage_uses_; + std::unordered_set storage_class_usage_; + std::unordered_set pipeline_stage_uses_; }; /// StructMember holds the semantic information for structure members. diff --git a/src/sem/struct_type.cc b/src/sem/struct_type.cc deleted file mode 100644 index 21ea67eb38..0000000000 --- a/src/sem/struct_type.cc +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/sem/struct_type.h" - -#include - -#include "src/program_builder.h" - -TINT_INSTANTIATE_TYPEINFO(tint::sem::StructType); - -namespace tint { -namespace sem { - -StructType::StructType(ast::Struct* impl) : struct_(impl) {} - -StructType::StructType(StructType&&) = default; - -StructType::~StructType() = default; - -std::string StructType::type_name() const { - return impl()->type_name(); -} - -std::string StructType::FriendlyName(const SymbolTable& symbols) const { - return impl()->FriendlyName(symbols); -} - -} // namespace sem -} // namespace tint diff --git a/src/sem/struct_type.h b/src/sem/struct_type.h deleted file mode 100644 index e39010a290..0000000000 --- a/src/sem/struct_type.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_SEM_STRUCT_TYPE_H_ -#define SRC_SEM_STRUCT_TYPE_H_ - -#include - -#include "src/ast/struct.h" -#include "src/sem/type.h" - -namespace tint { -namespace sem { - -/// A structure type -class StructType : public Castable { - public: - /// Constructor - /// @param impl the struct data - explicit StructType(ast::Struct* impl); - /// Move constructor - StructType(StructType&&); - ~StructType() override; - - /// @returns true if the struct has a block decoration - bool IsBlockDecorated() const { return struct_->IsBlockDecorated(); } - - /// @returns the struct - ast::Struct* impl() const { return struct_; } - - /// @returns the name for the type - std::string type_name() const override; - - /// @param symbols the program's symbol table - /// @returns the name for this type that closely resembles how it would be - /// declared in WGSL. - std::string FriendlyName(const SymbolTable& symbols) const override; - - private: - ast::Struct* const struct_; - - uint64_t LargestMemberBaseAlignment(MemoryLayout mem_layout) const; -}; - -} // namespace sem -} // namespace tint - -#endif // SRC_SEM_STRUCT_TYPE_H_ diff --git a/src/sem/type_mappings.h b/src/sem/type_mappings.h index 94bda9b9e1..e963a33bf6 100644 --- a/src/sem/type_mappings.h +++ b/src/sem/type_mappings.h @@ -41,7 +41,6 @@ class Function; class MemberAccessorExpression; class Statement; class Struct; -class StructType; class StructMember; class Type; class Variable; @@ -58,7 +57,6 @@ struct TypeMappings { Function* operator()(ast::Function*); MemberAccessorExpression* operator()(ast::MemberAccessorExpression*); Statement* operator()(ast::Statement*); - Struct* operator()(sem::StructType*); StructMember* operator()(ast::StructMember*); Type* operator()(ast::Type*); Variable* operator()(ast::Variable*); diff --git a/src/sem/u32_type_test.cc b/src/sem/u32_type_test.cc index 5e0bcc426b..bbb9e08419 100644 --- a/src/sem/u32_type_test.cc +++ b/src/sem/u32_type_test.cc @@ -34,7 +34,7 @@ TEST_F(U32Test, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/sem/vector_type_test.cc b/src/sem/vector_type_test.cc index c5402a9eee..6e52afb9a4 100644 --- a/src/sem/vector_type_test.cc +++ b/src/sem/vector_type_test.cc @@ -42,7 +42,7 @@ TEST_F(VectorTest, Is) { EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); + EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); diff --git a/src/transform/calculate_array_length.cc b/src/transform/calculate_array_length.cc index 8faad3e77b..c36acce30b 100644 --- a/src/transform/calculate_array_length.cc +++ b/src/transform/calculate_array_length.cc @@ -77,12 +77,12 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) { // get_buffer_size_intrinsic() emits the function decorated with // BufferSizeIntrinsic that is transformed by the HLSL writer into a call to // [RW]ByteAddressBuffer.GetDimensions(). - std::unordered_map buffer_size_intrinsics; - auto get_buffer_size_intrinsic = [&](sem::StructType* buffer_type) { + std::unordered_map buffer_size_intrinsics; + auto get_buffer_size_intrinsic = [&](sem::Struct* buffer_type) { return utils::GetOrCreate(buffer_size_intrinsics, buffer_type, [&] { auto name = ctx.dst->Sym(); auto* buffer_typename = - ctx.dst->ty.type_name(ctx.Clone(buffer_type->impl()->name())); + ctx.dst->ty.type_name(ctx.Clone(buffer_type->Declaration()->name())); auto* func = ctx.dst->create( name, ast::VariableList{ @@ -100,8 +100,8 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) { ctx.dst->ASTNodes().Create(ctx.dst->ID()), }, ast::DecorationList{}); - ctx.InsertAfter(ctx.src->AST().GlobalDeclarations(), buffer_type->impl(), - func); + ctx.InsertAfter(ctx.src->AST().GlobalDeclarations(), + buffer_type->Declaration(), func); return name; }); }; @@ -141,7 +141,7 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) { auto* storage_buffer_expr = accessor->structure(); auto* storage_buffer_sem = sem.Get(storage_buffer_expr); auto* storage_buffer_type = - storage_buffer_sem->Type()->UnwrapAll()->As(); + storage_buffer_sem->Type()->UnwrapAll()->As(); // Generate BufferSizeIntrinsic for this storage type if we haven't // already @@ -149,7 +149,7 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) { if (!storage_buffer_type) { TINT_ICE(ctx.dst->Diagnostics()) - << "arrayLength(X.Y) expected X to be sem::StructType, got " + << "arrayLength(X.Y) expected X to be sem::Struct, got " << storage_buffer_type->FriendlyName(ctx.src->Symbols()); break; } @@ -176,12 +176,8 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) { // First time this array length is used for this block. // Let's calculate it. - // Semantic info for the storage buffer structure - auto* storage_buffer_type_sem = - ctx.src->Sem().Get(storage_buffer_type); // Semantic info for the runtime array structure member - auto* array_member_sem = - storage_buffer_type_sem->Members().back(); + auto* array_member_sem = storage_buffer_type->Members().back(); // Construct the variable that'll hold the result of // RWByteAddressBuffer.GetDimensions() diff --git a/src/transform/canonicalize_entry_point_io.cc b/src/transform/canonicalize_entry_point_io.cc index ee9b73c999..3b0c59d1ea 100644 --- a/src/transform/canonicalize_entry_point_io.cc +++ b/src/transform/canonicalize_entry_point_io.cc @@ -110,12 +110,11 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) { std::function func_const_initializer; - if (auto* struct_ty = param_ty->As()) { - auto* str = ctx.src->Sem().Get(struct_ty); + if (auto* str = param_ty->As()) { // Pull out all struct members and build initializer list. std::vector member_names; for (auto* member : str->Members()) { - if (member->Type()->UnwrapAll()->Is()) { + if (member->Type()->UnwrapAll()->Is()) { TINT_ICE(ctx.dst->Diagnostics()) << "nested pipeline IO struct"; } @@ -202,11 +201,10 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) { } else { ast::StructMemberList new_struct_members; - if (auto* struct_ty = ret_type->As()) { - auto* str = ctx.src->Sem().Get(struct_ty); + if (auto* str = ret_type->As()) { // Rebuild struct with only the entry point IO attributes. for (auto* member : str->Members()) { - if (member->Type()->UnwrapAll()->Is()) { + if (member->Type()->UnwrapAll()->Is()) { TINT_ICE(ctx.dst->Diagnostics()) << "nested pipeline IO struct"; } @@ -251,7 +249,7 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) { }; ast::ExpressionList ret_values; - if (ret_type->Is()) { + if (ret_type->Is()) { if (!ret->value()->Is()) { // Create a const to hold the return value expression to avoid // re-evaluating it multiple times. diff --git a/src/transform/decompose_storage_access.cc b/src/transform/decompose_storage_access.cc index c3f28933d8..b4ff19bff8 100644 --- a/src/transform/decompose_storage_access.cc +++ b/src/transform/decompose_storage_access.cc @@ -331,7 +331,7 @@ void InsertGlobal(CloneContext& ctx, } /// @returns the unwrapped, user-declared constructed type of ty. -ast::NamedType* ConstructedTypeOf(sem::Type* ty) { +const ast::NamedType* ConstructedTypeOf(sem::Type* ty) { while (true) { if (auto* ptr = ty->As()) { ty = ptr->type(); @@ -341,8 +341,8 @@ ast::NamedType* ConstructedTypeOf(sem::Type* ty) { ty = access->type(); continue; } - if (auto* str = ty->As()) { - return str->impl(); + if (auto* str = ty->As()) { + return str->Declaration(); } // Not a constructed type return nullptr; @@ -421,7 +421,7 @@ struct DecomposeStorageAccess::State { /// @param el_ty the storage buffer element type /// @return the name of the function that performs the load Symbol LoadFunc(CloneContext& ctx, - ast::NamedType* insert_after, + const ast::NamedType* insert_after, sem::Type* buf_ty, sem::Type* el_ty) { return utils::GetOrCreate(load_funcs, TypePair{buf_ty, el_ty}, [&] { @@ -451,9 +451,7 @@ struct DecomposeStorageAccess::State { ctx.dst->Add("offset", i * MatrixColumnStride(mat_ty)); values.emplace_back(ctx.dst->Call(load, "buffer", offset)); } - } else if (auto* str_ty = el_ty->As()) { - auto& sem = ctx.src->Sem(); - auto* str = sem.Get(str_ty); + } else if (auto* str = el_ty->As()) { for (auto* member : str->Members()) { auto* offset = ctx.dst->Add("offset", member->Offset()); Symbol load = LoadFunc(ctx, insert_after, buf_ty, @@ -492,7 +490,7 @@ struct DecomposeStorageAccess::State { /// @param el_ty the storage buffer element type /// @return the name of the function that performs the store Symbol StoreFunc(CloneContext& ctx, - ast::NamedType* insert_after, + const ast::NamedType* insert_after, sem::Type* buf_ty, sem::Type* el_ty) { return utils::GetOrCreate(store_funcs, TypePair{buf_ty, el_ty}, [&] { @@ -525,9 +523,7 @@ struct DecomposeStorageAccess::State { auto* call = ctx.dst->Call(store, "buffer", offset, access); body.emplace_back(ctx.dst->create(call)); } - } else if (auto* str_ty = el_ty->As()) { - auto& sem = ctx.src->Sem(); - auto* str = sem.Get(str_ty); + } else if (auto* str = el_ty->As()) { for (auto* member : str->Members()) { auto* offset = ctx.dst->Add("offset", member->Offset()); auto* access = ctx.dst->MemberAccessor( @@ -676,9 +672,8 @@ Output DecomposeStorageAccess::Run(const Program* in, const DataMap&) { } } else { if (auto access = state.TakeAccess(accessor->structure())) { - auto* str_ty = access.type->As(); - auto* member = - sem.Get(str_ty)->FindMember(accessor->member()->symbol()); + auto* str_ty = access.type->As(); + auto* member = str_ty->FindMember(accessor->member()->symbol()); auto offset = member->Offset(); state.AddAccess(accessor, { diff --git a/src/transform/first_index_offset.cc b/src/transform/first_index_offset.cc index 1ef89e18ec..b8fb7c225e 100644 --- a/src/transform/first_index_offset.cc +++ b/src/transform/first_index_offset.cc @@ -133,7 +133,7 @@ Output FirstIndexOffset::Run(const Program* in, const DataMap& data) { instance_index_offset = offset; offset += 4; } - auto struct_type = + auto* struct_type = ctx.dst->Structure(ctx.dst->Sym(), std::move(members), {ctx.dst->create()}); diff --git a/src/transform/hlsl.cc b/src/transform/hlsl.cc index cb4f1e371d..d3d1656597 100644 --- a/src/transform/hlsl.cc +++ b/src/transform/hlsl.cc @@ -96,7 +96,7 @@ void Hlsl::PromoteInitializersToConstVar(CloneContext& ctx) const { } auto* src_ty = src_sem_expr->Type(); - if (src_ty->IsAnyOf()) { + if (src_ty->IsAnyOf()) { // Create a new symbol for the constant auto dst_symbol = ctx.dst->Sym(); // Clone the type diff --git a/src/transform/spirv.cc b/src/transform/spirv.cc index df9461ca09..0a8d45d886 100644 --- a/src/transform/spirv.cc +++ b/src/transform/spirv.cc @@ -288,7 +288,7 @@ Symbol Spirv::HoistToInputVariables( sem::Type* ty, ast::Type* declared_ty, const ast::DecorationList& decorations) const { - if (!ty->Is()) { + if (!ty->Is()) { // Base case: create a global variable and return. ast::DecorationList new_decorations = RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) { @@ -305,8 +305,8 @@ Symbol Spirv::HoistToInputVariables( // Recurse into struct members and build the initializer list. std::vector init_value_names; - auto* struct_ty = ty->As(); - for (auto* member : ctx.src->Sem().Get(struct_ty)->Members()) { + auto* struct_ty = ty->As(); + for (auto* member : struct_ty->Members()) { auto member_var = HoistToInputVariables( ctx, func, member->Type(), member->Declaration()->type(), member->Declaration()->decorations()); @@ -342,7 +342,7 @@ void Spirv::HoistToOutputVariables(CloneContext& ctx, Symbol store_value, ast::StatementList& stores) const { // Base case. - if (!ty->Is()) { + if (!ty->Is()) { // Create a global variable. ast::DecorationList new_decorations = RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) { @@ -366,8 +366,8 @@ void Spirv::HoistToOutputVariables(CloneContext& ctx, } // Recurse into struct members. - auto* struct_ty = ty->As(); - for (auto* member : ctx.src->Sem().Get(struct_ty)->Members()) { + auto* struct_ty = ty->As(); + for (auto* member : struct_ty->Members()) { member_accesses.push_back(ctx.Clone(member->Declaration()->symbol())); HoistToOutputVariables(ctx, func, member->Type(), member->Declaration()->type(), diff --git a/src/transform/transform.cc b/src/transform/transform.cc index def5478541..d53cd7a805 100644 --- a/src/transform/transform.cc +++ b/src/transform/transform.cc @@ -107,8 +107,9 @@ ast::Type* Transform::CreateASTTypeFor(CloneContext* ctx, const sem::Type* ty) { if (auto* a = ty->As()) { return ctx->dst->create(ctx->Clone(a->symbol())); } - if (auto* s = ty->As()) { - return ctx->dst->create(ctx->Clone(s->impl()->name())); + if (auto* s = ty->As()) { + return ctx->dst->create( + ctx->Clone(s->Declaration()->name())); } TINT_UNREACHABLE(ctx->dst->Diagnostics()) << "Unhandled type: " << ty->TypeInfo().name; diff --git a/src/transform/transform_test.cc b/src/transform/transform_test.cc index b83defc334..e36cacd439 100644 --- a/src/transform/transform_test.cc +++ b/src/transform/transform_test.cc @@ -98,7 +98,10 @@ TEST_F(CreateASTTypeForTest, Array) { TEST_F(CreateASTTypeForTest, AccessControl) { auto* ac = create([](ProgramBuilder& b) { - auto str = b.Structure("S", {}, {}); + auto* decl = b.Structure("S", {}, {}); + auto* str = + b.create(decl, sem::StructMemberList{}, 4 /* align */, + 4 /* size */, 4 /* size_no_padding */); return b.create(ast::AccessControl::kReadOnly, str); }); ASSERT_TRUE(ac->Is()); @@ -109,8 +112,9 @@ TEST_F(CreateASTTypeForTest, AccessControl) { TEST_F(CreateASTTypeForTest, Struct) { auto* str = create([](ProgramBuilder& b) { - auto* impl = b.Structure("S", {}, {}).ast; - return b.create(const_cast(impl)); + auto* decl = b.Structure("S", {}, {}); + return b.create(decl, sem::StructMemberList{}, 4 /* align */, + 4 /* size */, 4 /* size_no_padding */); }); ASSERT_TRUE(str->Is()); EXPECT_EQ( diff --git a/src/transform/vertex_pulling.cc b/src/transform/vertex_pulling.cc index 31523b4767..fb2a84d910 100644 --- a/src/transform/vertex_pulling.cc +++ b/src/transform/vertex_pulling.cc @@ -204,7 +204,7 @@ struct State { // Creating the struct type static const char kStructName[] = "TintVertexData"; - auto struct_type = ctx.dst->Structure( + auto* struct_type = ctx.dst->Structure( ctx.dst->Symbols().New(kStructName), { ctx.dst->Member(GetStructBufferName(), @@ -432,7 +432,7 @@ struct State { /// @param struct_ty the structure type void ProcessStructParameter(ast::Function* func, ast::Variable* param, - ast::Struct* struct_ty) { + const ast::Struct* struct_ty) { auto param_sym = ctx.Clone(param->symbol()); // Process the struct members. @@ -486,7 +486,7 @@ struct State { new_members.push_back( ctx.dst->Member(member_sym, member_type, std::move(member_decos))); } - auto new_struct = ctx.dst->Structure(ctx.dst->Sym(), new_members); + auto* new_struct = ctx.dst->Structure(ctx.dst->Sym(), new_members); // Create a new function parameter with this struct. auto* new_param = ctx.dst->Param(ctx.dst->Sym(), new_struct); @@ -513,8 +513,8 @@ struct State { // Process entry point parameters. for (auto* param : func->params()) { auto* sem = ctx.src->Sem().Get(param); - if (auto* str = sem->Type()->As()) { - ProcessStructParameter(func, param, str->impl()); + if (auto* str = sem->Type()->As()) { + ProcessStructParameter(func, param, str->Declaration()); } else { ProcessNonStructParameter(func, param); } diff --git a/src/typepair.h b/src/typepair.h index 422e72f344..d258dea38f 100644 --- a/src/typepair.h +++ b/src/typepair.h @@ -69,7 +69,7 @@ class Pointer; class Sampler; class SampledTexture; class StorageTexture; -class StructType; +class Struct; class Texture; class Type; class U32; @@ -254,7 +254,7 @@ using Pointer = TypePair; using Sampler = TypePair; using SampledTexture = TypePair; using StorageTexture = TypePair; -using Struct = TypePair; +using Struct = TypePair; using Texture = TypePair; using U32 = TypePair; using Vector = TypePair; @@ -271,7 +271,6 @@ inline auto MakeTypePair(AST* ast, SEM* sem) { return TypePair{ast, sem}; } - } // namespace typ } // namespace tint diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index 509d20a6fe..ebd29dec82 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc @@ -210,7 +210,7 @@ bool GeneratorImpl::EmitConstructedType(std::ostream& out, if (auto* alias = ty->As()) { // HLSL typedef is for intrinsic types only. For an alias'd struct, // generate a secondary struct with the new name. - if (auto* str = alias->type()->As()) { + if (auto* str = alias->type()->As()) { if (!EmitStructType(out, str, builder_.Symbols().NameFor(alias->symbol()))) { return false; @@ -223,9 +223,9 @@ bool GeneratorImpl::EmitConstructedType(std::ostream& out, } out << " " << builder_.Symbols().NameFor(alias->symbol()) << ";" << std::endl; - } else if (auto* str = ty->As()) { - if (!EmitStructType(out, str, - builder_.Symbols().NameFor(str->impl()->name()))) { + } else if (auto* str = ty->As()) { + if (!EmitStructType( + out, str, builder_.Symbols().NameFor(str->Declaration()->name()))) { return false; } } else { @@ -1325,7 +1325,7 @@ bool GeneratorImpl::EmitTypeConstructor(std::ostream& pre, } bool brackets = - type->UnwrapAliasIfNeeded()->IsAnyOf(); + type->UnwrapAliasIfNeeded()->IsAnyOf(); if (brackets) { out << "{"; @@ -1715,9 +1715,9 @@ bool GeneratorImpl::EmitEntryPointData( } auto* type = var->Type()->UnwrapIfNeeded(); - if (auto* strct = type->As()) { + if (auto* strct = type->As()) { out << "ConstantBuffer<" - << builder_.Symbols().NameFor(strct->impl()->name()) << "> " + << builder_.Symbols().NameFor(strct->Declaration()->name()) << "> " << builder_.Symbols().NameFor(decl->symbol()) << RegisterAndSpace('b', binding_point) << ";" << std::endl; } else { @@ -2038,7 +2038,7 @@ bool GeneratorImpl::EmitEntryPointFunction(std::ostream& out, for (auto* var : func->params()) { auto* sem = builder_.Sem().Get(var); auto* type = sem->Type(); - if (!type->Is()) { + if (!type->Is()) { TINT_ICE(diagnostics_) << "Unsupported non-struct entry point parameter"; } @@ -2140,10 +2140,10 @@ bool GeneratorImpl::EmitZeroValue(std::ostream& out, sem::Type* type) { return false; } } - } else if (auto* str = type->As()) { + } else if (auto* str = type->As()) { out << "{"; bool first = true; - for (auto* member : builder_.Sem().Get(str)->Members()) { + for (auto* member : str->Members()) { if (!first) { out << ", "; } @@ -2383,7 +2383,7 @@ bool GeneratorImpl::EmitSwitch(std::ostream& out, ast::SwitchStatement* stmt) { } bool GeneratorImpl::EmitType(std::ostream& out, - sem::Type* type, + const sem::Type* type, ast::StorageClass storage_class, const std::string& name) { auto* access = type->As(); @@ -2407,7 +2407,7 @@ bool GeneratorImpl::EmitType(std::ostream& out, if (auto* alias = type->As()) { out << builder_.Symbols().NameFor(alias->symbol()); } else if (auto* ary = type->As()) { - sem::Type* base_type = ary; + const sem::Type* base_type = ary; std::vector sizes; while (auto* arr = base_type->As()) { if (arr->IsRuntimeArray()) { @@ -2457,8 +2457,8 @@ bool GeneratorImpl::EmitType(std::ostream& out, out << "Comparison"; } out << "State"; - } else if (auto* str = type->As()) { - out << builder_.Symbols().NameFor(str->impl()->name()); + } else if (auto* str = type->As()) { + out << builder_.Symbols().NameFor(str->Declaration()->name()); } else if (auto* tex = type->As()) { auto* storage = tex->As(); auto* multism = tex->As(); @@ -2547,11 +2547,9 @@ bool GeneratorImpl::EmitType(std::ostream& out, } bool GeneratorImpl::EmitStructType(std::ostream& out, - const sem::StructType* str, + const sem::Struct* str, const std::string& name) { - auto* sem_str = builder_.Sem().Get(str); - - auto storage_class_uses = sem_str->StorageClassUsage(); + auto storage_class_uses = str->StorageClassUsage(); if (storage_class_uses.size() == storage_class_uses.count(ast::StorageClass::kStorage)) { // The only use of the structure is as a storage buffer. @@ -2563,7 +2561,7 @@ bool GeneratorImpl::EmitStructType(std::ostream& out, out << "struct " << name << " {" << std::endl; increment_indent(); - for (auto* mem : sem_str->Members()) { + for (auto* mem : str->Members()) { make_indent(out); // TODO(dsinclair): Handle [[offset]] annotation on structs // https://bugs.chromium.org/p/tint/issues/detail?id=184 @@ -2579,8 +2577,7 @@ bool GeneratorImpl::EmitStructType(std::ostream& out, for (auto* deco : mem->Declaration()->decorations()) { if (auto* location = deco->As()) { - auto& pipeline_stage_uses = - builder_.Sem().Get(str)->PipelineStageUses(); + auto& pipeline_stage_uses = str->PipelineStageUses(); if (pipeline_stage_uses.size() != 1) { TINT_ICE(diagnostics_) << "invalid entry point IO struct uses"; } diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h index 9a919c862f..b473ec084c 100644 --- a/src/writer/hlsl/generator_impl.h +++ b/src/writer/hlsl/generator_impl.h @@ -290,7 +290,7 @@ class GeneratorImpl : public TextGenerator { /// @param name the name of the variable, only used for array emission /// @returns true if the type is emitted bool EmitType(std::ostream& out, - sem::Type* type, + const sem::Type* type, ast::StorageClass storage_class, const std::string& name); /// Handles generating a structure declaration @@ -299,7 +299,7 @@ class GeneratorImpl : public TextGenerator { /// @param name the struct name /// @returns true if the struct is emitted bool EmitStructType(std::ostream& out, - const sem::StructType* ty, + const sem::Struct* ty, const std::string& name); /// Handles a unary op expression /// @param pre the preamble for the expression stream diff --git a/src/writer/hlsl/generator_impl_alias_type_test.cc b/src/writer/hlsl/generator_impl_alias_type_test.cc deleted file mode 100644 index b206b89d31..0000000000 --- a/src/writer/hlsl/generator_impl_alias_type_test.cc +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "gmock/gmock.h" -#include "src/writer/hlsl/test_helper.h" - -namespace tint { -namespace writer { -namespace hlsl { -namespace { - -using ::testing::HasSubstr; - -using HlslGeneratorImplTest_Alias = TestHelper; - -TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_F32) { - auto alias = ty.alias("a", ty.f32()); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.EmitConstructedType(out, alias)) << gen.error(); - EXPECT_EQ(result(), R"(typedef float a; -)"); -} - -TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_Struct) { - auto s = Structure("A", { - Member("a", ty.f32()), - Member("b", ty.i32()), - }); - auto alias = ty.alias("B", s); - AST().AddConstructedType(alias); - Global("g", alias, ast::StorageClass::kPrivate); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.EmitConstructedType(out, alias)) << gen.error(); - EXPECT_EQ(result(), R"(struct B { - float a; - int b; -}; -)"); -} - -} // namespace -} // namespace hlsl -} // namespace writer -} // namespace tint diff --git a/src/writer/hlsl/generator_impl_constructor_test.cc b/src/writer/hlsl/generator_impl_constructor_test.cc index ab0e64264e..2bee83b1cc 100644 --- a/src/writer/hlsl/generator_impl_constructor_test.cc +++ b/src/writer/hlsl/generator_impl_constructor_test.cc @@ -195,11 +195,11 @@ TEST_F(HlslGeneratorImplTest_Constructor, } TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct) { - auto str = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - Member("c", ty.vec3()), - }); + auto* str = Structure("S", { + Member("a", ty.i32()), + Member("b", ty.f32()), + Member("c", ty.vec3()), + }); WrapInFunction(Construct(str, 1, 2.0f, vec3(3, 4, 5))); @@ -212,11 +212,11 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct) { } TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct_Empty) { - auto str = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - Member("c", ty.vec3()), - }); + auto* str = Structure("S", { + Member("a", ty.i32()), + Member("b", ty.f32()), + Member("c", ty.vec3()), + }); WrapInFunction(Construct(str)); diff --git a/src/writer/hlsl/generator_impl_function_test.cc b/src/writer/hlsl/generator_impl_function_test.cc index e107792600..7551484f8f 100644 --- a/src/writer/hlsl/generator_impl_function_test.cc +++ b/src/writer/hlsl/generator_impl_function_test.cc @@ -179,7 +179,7 @@ TEST_F(HlslGeneratorImplTest_Function, // const g = inputs.col2; // const p = inputs.pos; // } - auto interface_struct = Structure( + auto* interface_struct = Structure( "Interface", { Member("pos", ty.vec4(), {Builtin(ast::Builtin::kPosition)}), @@ -252,7 +252,7 @@ TEST_F(HlslGeneratorImplTest_Function, // fn vert_main2() -> VertexOutput { // return foo(0.25); // } - auto vertex_output_struct = Structure( + auto* vertex_output_struct = Structure( "VertexOutput", {Member("pos", ty.vec4(), {Builtin(ast::Builtin::kPosition)})}); @@ -307,8 +307,8 @@ tint_symbol_2 vert_main2() { TEST_F(HlslGeneratorImplTest_Function, Emit_Decoration_EntryPoint_With_Uniform) { - auto ubo_ty = Structure("UBO", {Member("coord", ty.vec4())}, - {create()}); + auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4())}, + {create()}); auto* ubo = Global( "ubo", ubo_ty, ast::StorageClass::kUniform, nullptr, {create(0), create(1)}); @@ -359,8 +359,8 @@ void frag_main() { TEST_F(HlslGeneratorImplTest_Function, Emit_Decoration_EntryPoint_With_UniformStruct) { - auto s = Structure("Uniforms", {Member("coord", ty.vec4())}, - {create()}); + auto* s = Structure("Uniforms", {Member("coord", ty.vec4())}, + {create()}); Global("uniforms", s, ast::StorageClass::kUniform, nullptr, { @@ -401,12 +401,12 @@ void frag_main() { TEST_F(HlslGeneratorImplTest_Function, Emit_Decoration_EntryPoint_With_RW_StorageBuffer_Read) { - auto s = Structure("Data", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("Data", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kReadWrite, s); @@ -447,12 +447,12 @@ void frag_main() { TEST_F(HlslGeneratorImplTest_Function, Emit_Decoration_EntryPoint_With_RO_StorageBuffer_Read) { - auto s = Structure("Data", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("Data", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, s); @@ -493,12 +493,12 @@ void frag_main() { TEST_F(HlslGeneratorImplTest_Function, Emit_Decoration_EntryPoint_With_WO_StorageBuffer_Store) { - auto s = Structure("Data", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("Data", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kWriteOnly, s); @@ -536,12 +536,12 @@ void frag_main() { TEST_F(HlslGeneratorImplTest_Function, Emit_Decoration_EntryPoint_With_StorageBuffer_Store) { - auto s = Structure("Data", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("Data", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kReadWrite, s); @@ -742,8 +742,8 @@ ep_1_out ep_1(ep_1_in tint_in) { TEST_F(HlslGeneratorImplTest_Function, Emit_Decoration_Called_By_EntryPoint_With_Uniform) { - auto s = Structure("S", {Member("x", ty.f32())}, - {create()}); + auto* s = Structure("S", {Member("x", ty.f32())}, + {create()}); Global("coord", s, ast::StorageClass::kUniform, nullptr, { create(0), @@ -792,8 +792,8 @@ void frag_main() { TEST_F(HlslGeneratorImplTest_Function, Emit_Decoration_Called_By_EntryPoint_With_StorageBuffer) { - auto s = Structure("S", {Member("x", ty.f32())}, - {create()}); + auto* s = Structure("S", {Member("x", ty.f32())}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadWrite, s); Global("coord", ac, ast::StorageClass::kStorage, nullptr, { @@ -981,8 +981,8 @@ TEST_F(HlslGeneratorImplTest_Function, // return; // } - auto s = Structure("Data", {Member("d", ty.f32())}, - {create()}); + auto* s = Structure("Data", {Member("d", ty.f32())}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadWrite, s); diff --git a/src/writer/hlsl/generator_impl_member_accessor_test.cc b/src/writer/hlsl/generator_impl_member_accessor_test.cc index 515127bfca..9343a20d07 100644 --- a/src/writer/hlsl/generator_impl_member_accessor_test.cc +++ b/src/writer/hlsl/generator_impl_member_accessor_test.cc @@ -96,7 +96,7 @@ class HlslGeneratorImplTest_MemberAccessorBase : public BASE { void SetupStorageBuffer(ast::StructMemberList members) { ProgramBuilder& b = *this; - auto s = + auto* s = b.Structure("Data", members, {b.create()}); auto ac_ty = b.ty.access(ast::AccessControl::kReadWrite, s); @@ -125,7 +125,7 @@ using HlslGeneratorImplTest_MemberAccessorWithParam = HlslGeneratorImplTest_MemberAccessorBase>; TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) { - auto s = Structure("Data", {Member("mem", ty.f32())}); + auto* s = Structure("Data", {Member("mem", ty.f32())}); Global("str", s, ast::StorageClass::kPrivate); auto* expr = MemberAccessor("str", "mem"); @@ -522,10 +522,10 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_MultiLevel) { // var data : Pre; // data.c[2].b - auto inner = Structure("Inner", { - Member("a", ty.vec3()), - Member("b", ty.vec3()), - }); + auto* inner = Structure("Inner", { + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); SetupStorageBuffer({ Member("c", ty.array(inner, 4, 32)), @@ -568,10 +568,10 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, // var data : Pre; // data.c[2].b.xy - auto inner = Structure("Inner", { - Member("a", ty.vec3()), - Member("b", ty.vec3()), - }); + auto* inner = Structure("Inner", { + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); SetupStorageBuffer({ Member("c", ty.array(inner, 4, 32)), @@ -616,10 +616,10 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, // var data : Pre; // data.c[2].b.g - auto inner = Structure("Inner", { - Member("a", ty.vec3()), - Member("b", ty.vec3()), - }); + auto* inner = Structure("Inner", { + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); SetupStorageBuffer({ Member("c", ty.array(inner, 4, 32)), @@ -664,10 +664,10 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, // var data : Pre; // data.c[2].b[1] - auto inner = Structure("Inner", { - Member("a", ty.vec3()), - Member("b", ty.vec3()), - }); + auto* inner = Structure("Inner", { + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); SetupStorageBuffer({ Member("c", ty.array(inner, 4, 32)), @@ -711,10 +711,10 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_MultiLevel) { // var data : Pre; // data.c[2].b = vec3(1.f, 2.f, 3.f); - auto inner = Structure("Inner", { - Member("a", ty.vec3()), - Member("b", ty.vec3()), - }); + auto* inner = Structure("Inner", { + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); SetupStorageBuffer({ Member("c", ty.array(inner, 4, 32)), @@ -756,10 +756,10 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, // var data : Pre; // data.c[2].b.y = 1.f; - auto inner = Structure("Inner", { - Member("a", ty.vec3()), - Member("b", ty.vec3()), - }); + auto* inner = Structure("Inner", { + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); SetupStorageBuffer({ Member("c", ty.array(inner, 4, 32)), diff --git a/src/writer/hlsl/generator_impl_sanitizer_test.cc b/src/writer/hlsl/generator_impl_sanitizer_test.cc index 940b087190..6100f9fbc6 100644 --- a/src/writer/hlsl/generator_impl_sanitizer_test.cc +++ b/src/writer/hlsl/generator_impl_sanitizer_test.cc @@ -26,14 +26,14 @@ namespace { using HlslSanitizerTest = TestHelper; TEST_F(HlslSanitizerTest, ArrayLength) { - auto sb_ty = Structure("SB", - { - Member("x", ty.f32()), - Member("arr", ty.array(ty.vec4())), - }, - { - create(), - }); + auto* sb_ty = Structure("SB", + { + Member("x", ty.f32()), + Member("arr", ty.array(ty.vec4())), + }, + { + create(), + }); auto ac_ty = ty.access(ast::AccessControl::kReadOnly, sb_ty); Global("sb", ac_ty, ast::StorageClass::kStorage, nullptr, @@ -100,11 +100,11 @@ TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) { } TEST_F(HlslSanitizerTest, PromoteStructInitializerToConstVar) { - auto str = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.vec3()), - Member("c", ty.i32()), - }); + auto* str = Structure("S", { + Member("a", ty.i32()), + Member("b", ty.vec3()), + Member("c", ty.i32()), + }); auto* struct_init = Construct(str, 1, vec3(2.f, 3.f, 4.f), 4); auto* struct_access = MemberAccessor(struct_init, "b"); auto* pos = diff --git a/src/writer/hlsl/generator_impl_type_test.cc b/src/writer/hlsl/generator_impl_type_test.cc index 6a4bdbf270..e4cf34e12e 100644 --- a/src/writer/hlsl/generator_impl_type_test.cc +++ b/src/writer/hlsl/generator_impl_type_test.cc @@ -156,15 +156,16 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Pointer) { } TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) { - auto s = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - }); + auto* s = Structure("S", { + Member("a", ty.i32()), + Member("b", ty.f32()), + }); Global("g", s, ast::StorageClass::kPrivate); GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitStructType(out, s, "S")) << gen.error(); + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitStructType(out, sem_s, "S")) << gen.error(); EXPECT_EQ(result(), R"(struct S { int a; float b; @@ -173,31 +174,33 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) { } TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl_OmittedIfStorageBuffer) { - auto s = Structure("S", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("S", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); Global("g", ty.access(ast::AccessControl::kReadWrite, s), ast::StorageClass::kStorage); GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitStructType(out, s, "S")) << gen.error(); + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitStructType(out, sem_s, "S")) << gen.error(); EXPECT_EQ(result(), ""); } TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) { - auto s = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - }); + auto* s = Structure("S", { + Member("a", ty.i32()), + Member("b", ty.f32()), + }); Global("g", s, ast::StorageClass::kPrivate); GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitType(out, s, ast::StorageClass::kNone, "")) + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitType(out, sem_s, ast::StorageClass::kNone, "")) << gen.error(); EXPECT_EQ(result(), "S"); } @@ -205,7 +208,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) { /// TODO(bclayton): Enable this, fix it, add tests for vector, matrix, array and /// nested structures. TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_InjectPadding) { - auto s = Structure( + auto* s = Structure( "S", { Member("a", ty.i32(), {MemberSize(32)}), Member("b", ty.f32()), @@ -215,7 +218,8 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_InjectPadding) { GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitType(out, s, ast::StorageClass::kNone, "")) + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitType(out, sem_s, ast::StorageClass::kNone, "")) << gen.error(); EXPECT_EQ(gen.result(), R"(struct S { int a; @@ -229,10 +233,10 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_InjectPadding) { } TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) { - auto s = Structure("S", { - Member("double", ty.i32()), - Member("float", ty.f32()), - }); + auto* s = Structure("S", { + Member("double", ty.i32()), + Member("float", ty.f32()), + }); Global("g", s, ast::StorageClass::kPrivate); GeneratorImpl& gen = SanitizeAndBuild(); @@ -247,17 +251,18 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) { // TODO(dsinclair): How to translate [[block]] TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_WithDecoration) { - auto s = Structure("S", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("S", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); Global("g", s, ast::StorageClass::kPrivate); GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitStructType(out, s, "B")) << gen.error(); + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitStructType(out, sem_s, "B")) << gen.error(); EXPECT_EQ(result(), R"(struct B { int a; float b; diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc index 43093c89e4..a2d451348e 100644 --- a/src/writer/msl/generator_impl.cc +++ b/src/writer/msl/generator_impl.cc @@ -156,7 +156,7 @@ bool GeneratorImpl::EmitConstructedType(const sem::Type* ty) { } out_ << " " << program_->Symbols().NameFor(alias->symbol()) << ";" << std::endl; - } else if (auto* str = ty->As()) { + } else if (auto* str = ty->As()) { if (!EmitStructType(str)) { return false; } @@ -889,7 +889,7 @@ bool GeneratorImpl::EmitContinue(ast::ContinueStatement*) { bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) { auto* type = TypeOf(expr); - if (type->IsAnyOf()) { + if (type->IsAnyOf()) { out_ << "{"; } else { if (!EmitType(type, "")) { @@ -918,7 +918,7 @@ bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) { } } - if (type->IsAnyOf()) { + if (type->IsAnyOf()) { out_ << "}"; } else { out_ << ")"; @@ -948,7 +948,7 @@ bool GeneratorImpl::EmitZeroValue(typ::Type type) { return false; } out_ << "}"; - } else if (type->As()) { + } else if (type->As()) { out_ << "{}"; } else { diagnostics_.add_error("Invalid type for zero emission: " + @@ -1435,7 +1435,7 @@ bool GeneratorImpl::EmitEntryPointFunction(ast::Function* func) { out_ << " " << program_->Symbols().NameFor(var->symbol()); - if (type->Is()) { + if (type->Is()) { out_ << " [[stage_in]]"; } else { auto& decos = var->decorations(); @@ -1957,10 +1957,10 @@ bool GeneratorImpl::EmitType(typ::Type type, const std::string& name) { out_ << "*"; } else if (type->Is()) { out_ << "sampler"; - } else if (auto* str = type->As()) { + } else if (auto* str = type->As()) { // The struct type emits as just the name. The declaration would be emitted // as part of emitting the constructed types. - out_ << program_->Symbols().NameFor(str->impl()->name()); + out_ << program_->Symbols().NameFor(str->Declaration()->name()); } else if (auto* tex = type->As()) { if (tex->Is()) { out_ << "depth"; @@ -2056,20 +2056,14 @@ bool GeneratorImpl::EmitPackedType(typ::Type type, const std::string& name) { return EmitType(type, name); } -bool GeneratorImpl::EmitStructType(const sem::StructType* str) { +bool GeneratorImpl::EmitStructType(const sem::Struct* str) { // TODO(dsinclair): Block decoration? // if (str->impl()->decoration() != ast::Decoration::kNone) { // } - out_ << "struct " << program_->Symbols().NameFor(str->impl()->name()) << " {" - << std::endl; + out_ << "struct " << program_->Symbols().NameFor(str->Declaration()->name()) + << " {" << std::endl; - auto* sem_str = program_->Sem().Get(str); - if (!sem_str) { - TINT_ICE(diagnostics_) << "struct missing semantic info"; - return false; - } - - bool is_host_shareable = sem_str->IsHostShareable(); + bool is_host_shareable = str->IsHostShareable(); // Emits a `/* 0xnnnn */` byte offset comment for a struct member. auto add_byte_offset_comment = [&](uint32_t offset) { @@ -2084,14 +2078,14 @@ bool GeneratorImpl::EmitStructType(const sem::StructType* str) { std::string name; do { name = "tint_pad_" + std::to_string(pad_count++); - } while (sem_str->FindMember(program_->Symbols().Get(name))); + } while (str->FindMember(program_->Symbols().Get(name))); out_ << "int8_t " << name << "[" << size << "];" << std::endl; }; increment_indent(); uint32_t msl_offset = 0; - for (auto* mem : sem_str->Members()) { + for (auto* mem : str->Members()) { make_indent(); auto name = program_->Symbols().NameFor(mem->Declaration()->symbol()); @@ -2142,8 +2136,7 @@ bool GeneratorImpl::EmitStructType(const sem::StructType* str) { } out_ << " [[" << attr << "]]"; } else if (auto* loc = deco->As()) { - auto& pipeline_stage_uses = - program_->Sem().Get(str)->PipelineStageUses(); + auto& pipeline_stage_uses = str->PipelineStageUses(); if (pipeline_stage_uses.size() != 1) { TINT_ICE(diagnostics_) << "invalid entry point IO struct uses"; } @@ -2180,10 +2173,10 @@ bool GeneratorImpl::EmitStructType(const sem::StructType* str) { } } - if (is_host_shareable && sem_str->Size() != msl_offset) { + if (is_host_shareable && str->Size() != msl_offset) { make_indent(); add_byte_offset_comment(msl_offset); - add_padding(sem_str->Size() - msl_offset); + add_padding(str->Size() - msl_offset); } decrement_indent(); @@ -2353,15 +2346,10 @@ GeneratorImpl::SizeAndAlign GeneratorImpl::MslPackedTypeSizeAndAlign( return SizeAndAlign{el_size_align.size * num_els, el_size_align.align}; } - if (auto* str = ty->As()) { + if (auto* str = ty->As()) { // TODO(crbug.com/tint/650): There's an assumption here that MSL's default // structure size and alignment matches WGSL's. We need to confirm this. - auto* sem = program_->Sem().Get(str); - if (!sem) { - TINT_ICE(diagnostics_) << "Array missing semantic info"; - return {}; - } - return SizeAndAlign{sem->Size(), sem->Align()}; + return SizeAndAlign{str->Size(), str->Align()}; } TINT_UNREACHABLE(diagnostics_) << "Unhandled type " << ty->TypeInfo().name; diff --git a/src/writer/msl/generator_impl.h b/src/writer/msl/generator_impl.h index dea5bdf411..22e5d75099 100644 --- a/src/writer/msl/generator_impl.h +++ b/src/writer/msl/generator_impl.h @@ -35,7 +35,7 @@ #include "src/ast/unary_op_expression.h" #include "src/program.h" #include "src/scope_stack.h" -#include "src/sem/struct_type.h" +#include "src/sem/struct.h" #include "src/writer/text_generator.h" namespace tint { @@ -206,7 +206,7 @@ class GeneratorImpl : public TextGenerator { /// Handles generating a struct declaration /// @param str the struct to generate /// @returns true if the struct is emitted - bool EmitStructType(const sem::StructType* str); + bool EmitStructType(const sem::Struct* str); /// Handles emitting a type constructor /// @param expr the type constructor expression /// @returns true if the constructor is emitted diff --git a/src/writer/msl/generator_impl_alias_type_test.cc b/src/writer/msl/generator_impl_alias_type_test.cc deleted file mode 100644 index 4d41d2d243..0000000000 --- a/src/writer/msl/generator_impl_alias_type_test.cc +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/writer/msl/test_helper.h" - -namespace tint { -namespace writer { -namespace msl { -namespace { - -using MslGeneratorImplTest = TestHelper; - -TEST_F(MslGeneratorImplTest, EmitConstructedType_F32) { - auto alias = ty.alias("a", ty.f32()); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error(); - EXPECT_EQ(gen.result(), R"(typedef float a; -)"); -} - -TEST_F(MslGeneratorImplTest, EmitConstructedType_Struct) { - auto s = Structure("a", { - Member("a", ty.f32()), - Member("b", ty.i32()), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.EmitConstructedType(s)) << gen.error(); - EXPECT_EQ(gen.result(), R"(struct a { - float a; - int b; -}; -)"); -} - -TEST_F(MslGeneratorImplTest, EmitConstructedType_AliasStructIdent) { - auto s = Structure("b", { - Member("a", ty.f32()), - Member("b", ty.i32()), - }); - - auto alias = ty.alias("a", s); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error(); - EXPECT_EQ(gen.result(), R"(typedef b a; -)"); -} - -} // namespace -} // namespace msl -} // namespace writer -} // namespace tint diff --git a/src/writer/msl/generator_impl_constructor_test.cc b/src/writer/msl/generator_impl_constructor_test.cc index 6ce7924faf..18a49885e7 100644 --- a/src/writer/msl/generator_impl_constructor_test.cc +++ b/src/writer/msl/generator_impl_constructor_test.cc @@ -145,7 +145,7 @@ TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Array) { } TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Struct) { - auto str = Structure("S", { + auto* str = Structure("S", { Member("a", ty.i32()), Member("b", ty.f32()), Member("c", ty.vec3()), diff --git a/src/writer/msl/generator_impl_function_test.cc b/src/writer/msl/generator_impl_function_test.cc index 8a20007f6e..1848625bf7 100644 --- a/src/writer/msl/generator_impl_function_test.cc +++ b/src/writer/msl/generator_impl_function_test.cc @@ -170,7 +170,7 @@ TEST_F(MslGeneratorImplTest, // const r = colors.col1; // const g = colors.col2; // } - auto interface_struct = Structure( + auto* interface_struct = Structure( "Interface", { Member("col1", ty.f32(), {Location(1)}), @@ -245,7 +245,7 @@ TEST_F(MslGeneratorImplTest, // fn vert_main2() -> VertexOutput { // return foo(0.25); // } - auto vertex_output_struct = Structure( + auto* vertex_output_struct = Structure( "VertexOutput", {Member("pos", ty.vec4(), {Builtin(ast::Builtin::kPosition)})}); @@ -300,12 +300,12 @@ vertex tint_symbol_2 vert_main2() { TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_EntryPoint_With_RW_StorageBuffer) { - auto s = Structure("Data", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("Data", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kReadWrite, s); @@ -345,12 +345,12 @@ fragment void frag_main(device Data& coord [[buffer(0)]]) { TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_EntryPoint_With_RO_StorageBuffer) { - auto s = Structure("Data", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("Data", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, s); @@ -550,8 +550,8 @@ fragment ep_1_out ep_1(float4 coord [[position]]) { TEST_F(MslGeneratorImplTest, Emit_Decoration_Called_By_EntryPoint_With_Uniform) { - auto ubo_ty = Structure("UBO", {Member("coord", ty.vec4())}, - {create()}); + auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4())}, + {create()}); auto* ubo = Global( "ubo", ubo_ty, ast::StorageClass::kUniform, nullptr, {create(0), create(1)}); @@ -601,12 +601,12 @@ fragment void frag_main(constant UBO& ubo [[buffer(0)]]) { TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_Called_By_EntryPoint_With_RW_StorageBuffer) { - auto s = Structure("Data", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("Data", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kReadWrite, s); @@ -657,12 +657,12 @@ fragment void frag_main(device Data& coord [[buffer(0)]]) { TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_Called_By_EntryPoint_With_RO_StorageBuffer) { - auto s = Structure("Data", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("Data", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, s); @@ -796,8 +796,8 @@ TEST_F(MslGeneratorImplTest, // return; // } - auto s = Structure("Data", {Member("d", ty.f32())}, - {create()}); + auto* s = Structure("Data", {Member("d", ty.f32())}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadWrite, s); diff --git a/src/writer/msl/generator_impl_type_test.cc b/src/writer/msl/generator_impl_type_test.cc index 901cfbc53b..7e28db8fdc 100644 --- a/src/writer/msl/generator_impl_type_test.cc +++ b/src/writer/msl/generator_impl_type_test.cc @@ -173,10 +173,10 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Pointer) { } TEST_F(MslGeneratorImplTest, EmitType_Struct) { - auto s = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - }); + auto* s = Structure("S", { + Member("a", ty.i32()), + Member("b", ty.f32()), + }); GeneratorImpl& gen = Build(); @@ -185,14 +185,15 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct) { } TEST_F(MslGeneratorImplTest, EmitType_StructDecl) { - auto s = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - }); + auto* s = Structure("S", { + Member("a", ty.i32()), + Member("b", ty.f32()), + }); GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitStructType(s)) << gen.error(); + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitStructType(sem_s)) << gen.error(); EXPECT_EQ(gen.result(), R"(struct S { int a; float b; @@ -201,7 +202,7 @@ TEST_F(MslGeneratorImplTest, EmitType_StructDecl) { } TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_NonComposites) { - auto s = + auto* s = Structure("S", { Member("a", ty.i32(), {MemberSize(32)}), @@ -238,7 +239,8 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_NonComposites) { GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitStructType(s)) << gen.error(); + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitStructType(sem_s)) << gen.error(); // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, NAME, SUFFIX) // for each field of the structure s. @@ -315,35 +317,36 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_NonComposites) { TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_Structures) { // inner_x: size(1024), align(512) - auto inner_x = + auto* inner_x = Structure("inner_x", { Member("a", ty.i32()), Member("b", ty.f32(), {MemberAlign(512)}), }); // inner_y: size(516), align(4) - auto inner_y = + auto* inner_y = Structure("inner_y", { Member("a", ty.i32(), {MemberSize(512)}), Member("b", ty.f32()), }); - auto s = Structure("S", - { - Member("a", ty.i32()), - Member("b", inner_x), - Member("c", ty.f32()), - Member("d", inner_y), - Member("e", ty.f32()), - }, - {create()}); + auto* s = Structure("S", + { + Member("a", ty.i32()), + Member("b", inner_x), + Member("c", ty.f32()), + Member("d", inner_y), + Member("e", ty.f32()), + }, + {create()}); Global("G", ty.access(ast::AccessControl::kReadOnly, s), ast::StorageClass::kStorage); GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitStructType(s)) << gen.error(); + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitStructType(sem_s)) << gen.error(); // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, NAME, SUFFIX) // for each field of the structure s. @@ -401,10 +404,11 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_Structures) { TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) { // inner: size(1024), align(512) - auto inner = Structure("inner", { - Member("a", ty.i32()), - Member("b", ty.f32(), {MemberAlign(512)}), - }); + auto* inner = + Structure("inner", { + Member("a", ty.i32()), + Member("b", ty.f32(), {MemberAlign(512)}), + }); // array_x: size(28), align(4) auto array_x = ty.array(); @@ -415,23 +419,25 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) { // array_z: size(4), align(4) auto array_z = ty.array(); - auto s = Structure("S", - { - Member("a", ty.i32()), - Member("b", array_x), - Member("c", ty.f32()), - Member("d", array_y), - Member("e", ty.f32()), - Member("f", array_z), - }, - ast::DecorationList{create()}); + auto* s = + Structure("S", + { + Member("a", ty.i32()), + Member("b", array_x), + Member("c", ty.f32()), + Member("d", array_y), + Member("e", ty.f32()), + Member("f", array_z), + }, + ast::DecorationList{create()}); Global("G", ty.access(ast::AccessControl::kReadOnly, s), ast::StorageClass::kStorage); GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitStructType(s)) << gen.error(); + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitStructType(sem_s)) << gen.error(); // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, NAME, SUFFIX) // for each field of the structure s. @@ -495,7 +501,7 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) { } TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) { - auto s = Structure( + auto* s = Structure( "S", { // uses symbols tint_pad_[0..9] and tint_pad_[20..35] @@ -533,7 +539,8 @@ TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) { GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitStructType(s)) << gen.error(); + auto* sem_s = program->TypeOf(s)->As(); + ASSERT_TRUE(gen.EmitStructType(sem_s)) << gen.error(); EXPECT_EQ(gen.result(), R"(struct S { /* 0x0000 */ int tint_pad_2; /* 0x0004 */ int8_t tint_pad_10[124]; @@ -582,12 +589,12 @@ TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) { // TODO(dsinclair): How to translate [[block]] TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) { - auto s = Structure("S", - { - Member("a", ty.i32()), - Member("b", ty.f32()), - }, - {create()}); + auto* s = Structure("S", + { + Member("a", ty.i32()), + Member("b", ty.f32()), + }, + {create()}); Global("G", ty.access(ast::AccessControl::kReadOnly, s), ast::StorageClass::kStorage); diff --git a/src/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/writer/msl/generator_impl_variable_decl_statement_test.cc index 98b2b8120f..64fa23fa31 100644 --- a/src/writer/msl/generator_impl_variable_decl_statement_test.cc +++ b/src/writer/msl/generator_impl_variable_decl_statement_test.cc @@ -65,10 +65,10 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Array) { } TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) { - auto s = Structure("S", { - Member("a", ty.f32()), - Member("b", ty.f32()), - }); + auto* s = Structure("S", { + Member("a", ty.f32()), + Member("b", ty.f32()), + }); auto* var = Var("a", s, ast::StorageClass::kNone); auto* stmt = Decl(var); diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 7148a78374..27fed86c59 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -886,13 +886,13 @@ bool Builder::GenerateMemberAccessor(ast::MemberAccessorExpression* expr, // If the data_type is a structure we're accessing a member, if it's a // vector we're accessing a swizzle. - if (data_type->Is()) { - auto* strct = data_type->As()->impl(); + if (auto* str = data_type->As()) { + auto* impl = str->Declaration(); auto symbol = expr->member()->symbol(); uint32_t idx = 0; - for (; idx < strct->members().size(); ++idx) { - auto* member = strct->members()[idx]; + for (; idx < impl->members().size(); ++idx) { + auto* member = impl->members()[idx]; if (member->symbol() == symbol) { break; } @@ -1294,8 +1294,8 @@ bool Builder::is_constructor_const(ast::Expression* expr, bool is_global_init) { subtype = mat->type()->UnwrapAll(); } else if (auto* arr = subtype->As()) { subtype = arr->type()->UnwrapAll(); - } else if (auto* str = subtype->As()) { - subtype = builder_.Sem().Get(str)->Members()[i]->Type()->UnwrapAll(); + } else if (auto* str = subtype->As()) { + subtype = str->Members()[i]->Type()->UnwrapAll(); } if (subtype != TypeOf(sc)->UnwrapAll()) { return false; @@ -1373,8 +1373,7 @@ uint32_t Builder::GenerateTypeConstructorExpression( // If the result is not a vector then we should have validated that the // value type is a correctly sized vector so we can just use it directly. if (result_type == value_type || result_type->Is() || - result_type->Is() || - result_type->Is()) { + result_type->Is() || result_type->Is()) { out << "_" << id; ops.push_back(Operand::Int(id)); @@ -2024,14 +2023,14 @@ uint32_t Builder::GenerateIntrinsic(ast::CallExpression* call, params.push_back(Operand::Int(struct_id)); auto* type = TypeOf(accessor->structure())->UnwrapAll(); - if (!type->Is()) { + if (!type->Is()) { error_ = "invalid type (" + type->type_name() + ") for runtime array length"; return 0; } // Runtime array must be the last member in the structure - params.push_back(Operand::Int( - uint32_t(type->As()->impl()->members().size() - 1))); + params.push_back(Operand::Int(uint32_t( + type->As()->Declaration()->members().size() - 1))); if (!push_function_inst(spv::Op::OpArrayLength, params)) { return 0; @@ -2978,7 +2977,7 @@ uint32_t Builder::GenerateTypeIfNeeded(const sem::Type* type) { return GenerateTypeIfNeeded(alias->type()); } if (auto* ac = type->As()) { - if (!ac->type()->UnwrapIfNeeded()->Is()) { + if (!ac->type()->UnwrapIfNeeded()->Is()) { return GenerateTypeIfNeeded(ac->type()); } } @@ -2993,8 +2992,8 @@ uint32_t Builder::GenerateTypeIfNeeded(const sem::Type* type) { if (auto* ac = type->As()) { // The non-struct case was handled above. auto* subtype = ac->type()->UnwrapIfNeeded(); - if (!GenerateStructType(subtype->As(), - ac->access_control(), result)) { + if (!GenerateStructType(subtype->As(), ac->access_control(), + result)) { return 0; } } else if (auto* arr = type->As()) { @@ -3015,7 +3014,7 @@ uint32_t Builder::GenerateTypeIfNeeded(const sem::Type* type) { if (!GeneratePointerType(ptr, result)) { return 0; } - } else if (auto* str = type->As()) { + } else if (auto* str = type->As()) { if (!GenerateStructType(str, ast::AccessControl::kReadWrite, result)) { return 0; } @@ -3190,16 +3189,16 @@ bool Builder::GeneratePointerType(const sem::Pointer* ptr, return true; } -bool Builder::GenerateStructType(const sem::StructType* struct_type, +bool Builder::GenerateStructType(const sem::Struct* struct_type, ast::AccessControl::Access access_control, const Operand& result) { auto struct_id = result.to_i(); - auto* impl = struct_type->impl(); + auto* impl = struct_type->Declaration(); - if (struct_type->impl()->name().IsValid()) { - push_debug(spv::Op::OpName, {Operand::Int(struct_id), - Operand::String(builder_.Symbols().NameFor( - struct_type->impl()->name()))}); + if (impl->name().IsValid()) { + push_debug(spv::Op::OpName, + {Operand::Int(struct_id), + Operand::String(builder_.Symbols().NameFor(impl->name()))}); } OperandList ops; diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h index e8c2a5d265..82d27a30fb 100644 --- a/src/writer/spirv/builder.h +++ b/src/writer/spirv/builder.h @@ -449,7 +449,7 @@ class Builder { /// @param access_control the access controls to assign to the struct /// @param result the result operand /// @returns true if the vector was successfully generated - bool GenerateStructType(const sem::StructType* struct_type, + bool GenerateStructType(const sem::Struct* struct_type, ast::AccessControl::Access access_control, const Operand& result); /// Generates a struct member diff --git a/src/writer/spirv/builder_accessor_expression_test.cc b/src/writer/spirv/builder_accessor_expression_test.cc index 80819a0867..f1d4a89af9 100644 --- a/src/writer/spirv/builder_accessor_expression_test.cc +++ b/src/writer/spirv/builder_accessor_expression_test.cc @@ -219,10 +219,10 @@ TEST_F(BuilderTest, MemberAccessor) { // var ident : my_struct // ident.b - auto s = Structure("my_struct", { - Member("a", ty.f32()), - Member("b", ty.f32()), - }); + auto* s = Structure("my_struct", { + Member("a", ty.f32()), + Member("b", ty.f32()), + }); auto* var = Global("ident", s, ast::StorageClass::kFunction); @@ -263,12 +263,12 @@ TEST_F(BuilderTest, MemberAccessor_Nested) { // // var ident : my_struct // ident.inner.a - auto inner_struct = Structure("Inner", { - Member("a", ty.f32()), - Member("b", ty.f32()), - }); + auto* inner_struct = Structure("Inner", { + Member("a", ty.f32()), + Member("b", ty.f32()), + }); - auto s_type = Structure("my_struct", {Member("inner", inner_struct)}); + auto* s_type = Structure("my_struct", {Member("inner", inner_struct)}); auto* var = Global("ident", s_type, ast::StorageClass::kFunction); auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "b"); @@ -307,10 +307,10 @@ TEST_F(BuilderTest, MemberAccessor_NonPointer) { // let ident : my_struct = my_struct(); // ident.b - auto s = Structure("my_struct", { - Member("a", ty.f32()), - Member("b", ty.f32()), - }); + auto* s = Structure("my_struct", { + Member("a", ty.f32()), + Member("b", ty.f32()), + }); auto* var = GlobalConst("ident", s, Construct(s, 0.f, 0.f)); @@ -345,12 +345,12 @@ TEST_F(BuilderTest, MemberAccessor_Nested_NonPointer) { // // let ident : my_struct = my_struct(); // ident.inner.a - auto inner_struct = Structure("Inner", { - Member("a", ty.f32()), - Member("b", ty.f32()), - }); + auto* inner_struct = Structure("Inner", { + Member("a", ty.f32()), + Member("b", ty.f32()), + }); - auto s_type = Structure("my_struct", {Member("inner", inner_struct)}); + auto* s_type = Structure("my_struct", {Member("inner", inner_struct)}); auto* var = GlobalConst("ident", s_type, Construct(s_type, Construct(inner_struct, 0.f, 0.f))); @@ -388,13 +388,13 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) { // // var ident : my_struct // ident.inner.a - auto inner_struct = Structure("Inner", { - Member("a", ty.f32()), - Member("b", ty.f32()), - }); + auto* inner_struct = Structure("Inner", { + Member("a", ty.f32()), + Member("b", ty.f32()), + }); auto alias = ty.alias("Inner", inner_struct); - auto s_type = Structure("Outer", {Member("inner", alias)}); + auto* s_type = Structure("Outer", {Member("inner", alias)}); auto* var = Global("ident", s_type, ast::StorageClass::kFunction); auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a"); @@ -434,12 +434,12 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) { // // var ident : my_struct // ident.inner.a = 2.0f; - auto inner_struct = Structure("Inner", { - Member("a", ty.f32()), - Member("b", ty.f32()), - }); + auto* inner_struct = Structure("Inner", { + Member("a", ty.f32()), + Member("b", ty.f32()), + }); - auto s_type = Structure("my_struct", {Member("inner", inner_struct)}); + auto* s_type = Structure("my_struct", {Member("inner", inner_struct)}); auto* var = Global("ident", s_type, ast::StorageClass::kFunction); auto* expr = @@ -483,12 +483,12 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) { // var ident : my_struct // var store : f32 = ident.inner.a - auto inner_struct = Structure("Inner", { - Member("a", ty.f32()), - Member("b", ty.f32()), - }); + auto* inner_struct = Structure("Inner", { + Member("a", ty.f32()), + Member("b", ty.f32()), + }); - auto s_type = Structure("my_struct", {Member("inner", inner_struct)}); + auto* s_type = Structure("my_struct", {Member("inner", inner_struct)}); auto* var = Global("ident", s_type, ast::StorageClass::kFunction); auto* store = Global("store", ty.f32(), ast::StorageClass::kFunction); @@ -693,11 +693,11 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) { // var index : array // index[0].foo[2].bar.baz.yx - auto c_type = Structure("C", {Member("baz", ty.vec3())}); + auto* c_type = Structure("C", {Member("baz", ty.vec3())}); - auto b_type = Structure("B", {Member("bar", c_type)}); + auto* b_type = Structure("B", {Member("bar", c_type)}); auto b_ary_type = ty.array(b_type, 3); - auto a_type = Structure("A", {Member("foo", b_ary_type)}); + auto* a_type = Structure("A", {Member("foo", b_ary_type)}); auto a_ary_type = ty.array(a_type, 2); auto* var = Global("index", a_ary_type, ast::StorageClass::kFunction); diff --git a/src/writer/spirv/builder_assign_test.cc b/src/writer/spirv/builder_assign_test.cc index dfad65eef9..c3facfe9b9 100644 --- a/src/writer/spirv/builder_assign_test.cc +++ b/src/writer/spirv/builder_assign_test.cc @@ -176,10 +176,10 @@ TEST_F(BuilderTest, Assign_StructMember) { // var ident : my_struct // ident.b = 4.0; - auto s = Structure("my_struct", { - Member("a", ty.f32()), - Member("b", ty.f32()), - }); + auto* s = Structure("my_struct", { + Member("a", ty.f32()), + Member("b", ty.f32()), + }); auto* v = Global("ident", s, ast::StorageClass::kFunction); diff --git a/src/writer/spirv/builder_constructor_expression_test.cc b/src/writer/spirv/builder_constructor_expression_test.cc index 6c2ea8f7bb..1e735356f7 100644 --- a/src/writer/spirv/builder_constructor_expression_test.cc +++ b/src/writer/spirv/builder_constructor_expression_test.cc @@ -1052,10 +1052,10 @@ TEST_F(SpvBuilderConstructorTest, CommonInitializer_Array_VecArray) { } TEST_F(SpvBuilderConstructorTest, Type_Struct) { - auto s = Structure("my_struct", { - Member("a", ty.f32()), - Member("b", ty.vec3()), - }); + auto* s = Structure("my_struct", { + Member("a", ty.f32()), + Member("b", ty.vec3()), + }); auto* t = Construct(s, 2.0f, vec3(2.0f, 2.0f, 2.0f)); WrapInFunction(t); @@ -1202,7 +1202,7 @@ TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Array) { } TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Struct) { - auto s = Structure("my_struct", {Member("a", ty.f32())}); + auto* s = Structure("my_struct", {Member("a", ty.f32())}); auto* t = Construct(s); WrapInFunction(t); @@ -1622,10 +1622,10 @@ TEST_F(SpvBuilderConstructorTest, IsConstructorConst_BitCastScalars) { } TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct) { - auto s = Structure("my_struct", { - Member("a", ty.f32()), - Member("b", ty.vec3()), - }); + auto* s = Structure("my_struct", { + Member("a", ty.f32()), + Member("b", ty.vec3()), + }); auto* t = Construct(s, 2.f, vec3(2.f, 2.f, 2.f)); WrapInFunction(t); @@ -1638,10 +1638,10 @@ TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct) { TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct_WithIdentSubExpression) { - auto s = Structure("my_struct", { - Member("a", ty.f32()), - Member("b", ty.vec3()), - }); + auto* s = Structure("my_struct", { + Member("a", ty.f32()), + Member("b", ty.vec3()), + }); Global("a", ty.f32(), ast::StorageClass::kPrivate); Global("b", ty.f32(), ast::StorageClass::kPrivate); diff --git a/src/writer/spirv/builder_entry_point_test.cc b/src/writer/spirv/builder_entry_point_test.cc index 5771b4e224..b76d0c54f9 100644 --- a/src/writer/spirv/builder_entry_point_test.cc +++ b/src/writer/spirv/builder_entry_point_test.cc @@ -188,7 +188,7 @@ TEST_F(BuilderTest, EntryPoint_SharedStruct) { // return inputs.value; // } - auto interface = Structure( + auto* interface = Structure( "Interface", { Member("value", ty.f32(), ast::DecorationList{Location(1u)}), diff --git a/src/writer/spirv/builder_function_test.cc b/src/writer/spirv/builder_function_test.cc index cf717cc6c9..ac8a5be88b 100644 --- a/src/writer/spirv/builder_function_test.cc +++ b/src/writer/spirv/builder_function_test.cc @@ -201,8 +201,8 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) { // return; // } - auto s = Structure("Data", {Member("d", ty.f32())}, - {create()}); + auto* s = Structure("Data", {Member("d", ty.f32())}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadWrite, s); diff --git a/src/writer/spirv/builder_global_variable_test.cc b/src/writer/spirv/builder_global_variable_test.cc index c264fc5014..7b77349296 100644 --- a/src/writer/spirv/builder_global_variable_test.cc +++ b/src/writer/spirv/builder_global_variable_test.cc @@ -376,12 +376,12 @@ TEST_F(BuilderTest, GlobalVar_DeclReadOnly) { // }; // var b : [[access(read)]] A - auto A = Structure("A", - { - Member("a", ty.i32()), - Member("b", ty.i32()), - }, - {create()}); + auto* A = Structure("A", + { + Member("a", ty.i32()), + Member("b", ty.i32()), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, A); auto* var = Global("b", ac, ast::StorageClass::kStorage); @@ -415,8 +415,8 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasDeclReadOnly) { // type B = A; // var b : [[access(read)]] B - auto A = Structure("A", {Member("a", ty.i32())}, - {create()}); + auto* A = Structure("A", {Member("a", ty.i32())}, + {create()}); auto B = ty.alias("B", A); AST().AddConstructedType(B); auto ac = ty.access(ast::AccessControl::kReadOnly, B); @@ -448,8 +448,8 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasAssignReadOnly) { // type B = [[access(read)]] A; // var b : B - auto A = Structure("A", {Member("a", ty.i32())}, - {create()}); + auto* A = Structure("A", {Member("a", ty.i32())}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, A); auto B = ty.alias("B", ac); AST().AddConstructedType(B); @@ -481,8 +481,8 @@ TEST_F(BuilderTest, GlobalVar_TwoVarDeclReadOnly) { // var b : [[access(read)]] A // var c : [[access(read_write)]] A - auto A = Structure("A", {Member("a", ty.i32())}, - {create()}); + auto* A = Structure("A", {Member("a", ty.i32())}, + {create()}); auto read = ty.access(ast::AccessControl::kReadOnly, A); auto rw = ty.access(ast::AccessControl::kReadWrite, A); diff --git a/src/writer/spirv/builder_intrinsic_test.cc b/src/writer/spirv/builder_intrinsic_test.cc index a020a5983f..911d2430e7 100644 --- a/src/writer/spirv/builder_intrinsic_test.cc +++ b/src/writer/spirv/builder_intrinsic_test.cc @@ -1379,8 +1379,8 @@ OpFunctionEnd } TEST_F(IntrinsicBuilderTest, Call_ArrayLength) { - auto s = Structure("my_struct", {Member(0, "a", ty.array(4))}, - {create()}); + auto* s = Structure("my_struct", {Member(0, "a", ty.array(4))}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, s); Global("b", ac, ast::StorageClass::kStorage, nullptr, ast::DecorationList{ @@ -1425,12 +1425,12 @@ TEST_F(IntrinsicBuilderTest, Call_ArrayLength) { } TEST_F(IntrinsicBuilderTest, Call_ArrayLength_OtherMembersInStruct) { - auto s = Structure("my_struct", - { - Member(0, "z", ty.f32()), - Member(4, "a", ty.array(4)), - }, - {create()}); + auto* s = Structure("my_struct", + { + Member(0, "z", ty.f32()), + Member(4, "a", ty.array(4)), + }, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, s); Global("b", ac, ast::StorageClass::kStorage, nullptr, ast::DecorationList{ diff --git a/src/writer/spirv/builder_type_test.cc b/src/writer/spirv/builder_type_test.cc index 72ad6b200b..3fdf1ad360 100644 --- a/src/writer/spirv/builder_type_test.cc +++ b/src/writer/spirv/builder_type_test.cc @@ -59,8 +59,8 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedAlias) { TEST_F(BuilderTest_Type, GenerateRuntimeArray) { auto ary = ty.array(ty.i32(), 0); - auto str = Structure("S", {Member("x", ary)}, - {create()}); + auto* str = Structure("S", {Member("x", ary)}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, str); Global("a", ac, ast::StorageClass::kStorage); @@ -77,8 +77,8 @@ TEST_F(BuilderTest_Type, GenerateRuntimeArray) { TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) { auto ary = ty.array(ty.i32(), 0); - auto str = Structure("S", {Member("x", ary)}, - {create()}); + auto* str = Structure("S", {Member("x", ary)}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, str); Global("a", ac, ast::StorageClass::kStorage); @@ -285,11 +285,11 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) { } TEST_F(BuilderTest_Type, GenerateStruct_Empty) { - auto s = Structure("S", {}); + auto* s = Structure("S", {}); spirv::Builder& b = Build(); - auto id = b.GenerateTypeIfNeeded(s); + auto id = b.GenerateTypeIfNeeded(program->TypeOf(s)); ASSERT_FALSE(b.has_error()) << b.error(); EXPECT_EQ(id, 1u); @@ -301,11 +301,11 @@ TEST_F(BuilderTest_Type, GenerateStruct_Empty) { } TEST_F(BuilderTest_Type, GenerateStruct) { - auto s = Structure("my_struct", {Member("a", ty.f32())}); + auto* s = Structure("my_struct", {Member("a", ty.f32())}); spirv::Builder& b = Build(); - auto id = b.GenerateTypeIfNeeded(s); + auto id = b.GenerateTypeIfNeeded(program->TypeOf(s)); ASSERT_FALSE(b.has_error()) << b.error(); EXPECT_EQ(id, 1u); @@ -318,12 +318,12 @@ OpMemberName %1 0 "a" } TEST_F(BuilderTest_Type, GenerateStruct_Decorated) { - auto s = Structure("my_struct", {Member("a", ty.f32())}, - {create()}); + auto* s = Structure("my_struct", {Member("a", ty.f32())}, + {create()}); spirv::Builder& b = Build(); - auto id = b.GenerateTypeIfNeeded(s); + auto id = b.GenerateTypeIfNeeded(program->TypeOf(s)); ASSERT_FALSE(b.has_error()) << b.error(); EXPECT_EQ(id, 1u); @@ -339,14 +339,14 @@ OpMemberDecorate %1 0 Offset 0 } TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers) { - auto s = Structure("S", { - Member("a", ty.f32()), - Member("b", ty.f32(), {MemberAlign(8)}), - }); + auto* s = Structure("S", { + Member("a", ty.f32()), + Member("b", ty.f32(), {MemberAlign(8)}), + }); spirv::Builder& b = Build(); - auto id = b.GenerateTypeIfNeeded(s); + auto id = b.GenerateTypeIfNeeded(program->TypeOf(s)); ASSERT_FALSE(b.has_error()) << b.error(); EXPECT_EQ(id, 1u); @@ -363,15 +363,15 @@ OpMemberDecorate %1 1 Offset 8 } TEST_F(BuilderTest_Type, GenerateStruct_NonLayout_Matrix) { - auto s = Structure("S", { - Member("a", ty.mat2x2()), - Member("b", ty.mat2x3()), - Member("c", ty.mat4x4()), - }); + auto* s = Structure("S", { + Member("a", ty.mat2x2()), + Member("b", ty.mat2x3()), + Member("c", ty.mat4x4()), + }); spirv::Builder& b = Build(); - auto id = b.GenerateTypeIfNeeded(s); + auto id = b.GenerateTypeIfNeeded(program->TypeOf(s)); ASSERT_FALSE(b.has_error()) << b.error(); EXPECT_EQ(id, 1u); @@ -403,15 +403,15 @@ OpMemberDecorate %1 2 MatrixStride 16 TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutMatrix) { // We have to infer layout for matrix when it also has an offset. - auto s = Structure("S", { - Member("a", ty.mat2x2()), - Member("b", ty.mat2x3()), - Member("c", ty.mat4x4()), - }); + auto* s = Structure("S", { + Member("a", ty.mat2x2()), + Member("b", ty.mat2x3()), + Member("c", ty.mat4x4()), + }); spirv::Builder& b = Build(); - auto id = b.GenerateTypeIfNeeded(s); + auto id = b.GenerateTypeIfNeeded(program->TypeOf(s)); ASSERT_FALSE(b.has_error()) << b.error(); EXPECT_EQ(id, 1u); @@ -449,17 +449,18 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutArraysOfMatrix) { auto arr_arr_mat2x3 = ty.array(ty.mat2x3(), 1); // Doubly nested array auto rtarr_mat4x4 = ty.array(ty.mat4x4(), 0); // Runtime array - auto s = Structure("S", - { - Member("a", arr_mat2x2), - Member("b", arr_arr_mat2x3), - Member("c", rtarr_mat4x4), - }, - ast::DecorationList{create()}); + auto* s = + Structure("S", + { + Member("a", arr_mat2x2), + Member("b", arr_arr_mat2x3), + Member("c", rtarr_mat4x4), + }, + ast::DecorationList{create()}); spirv::Builder& b = Build(); - auto id = b.GenerateTypeIfNeeded(s); + auto id = b.GenerateTypeIfNeeded(program->TypeOf(s)); ASSERT_FALSE(b.has_error()) << b.error(); EXPECT_EQ(id, 1u); diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc index 7fe0b2e105..46a16e7c4b 100644 --- a/src/writer/wgsl/generator_impl.cc +++ b/src/writer/wgsl/generator_impl.cc @@ -147,8 +147,8 @@ bool GeneratorImpl::EmitConstructedType(typ::Type type) { return false; } out_ << ";" << std::endl; - } else if (auto* str = ty->As()) { - if (!EmitStructType(str->impl())) { + } else if (auto* str = ty->As()) { + if (!EmitStructType(str->Declaration())) { return false; } } else { @@ -599,10 +599,10 @@ bool GeneratorImpl::EmitType(typ::Type type) { if (sampler->IsComparison()) { out_ << "_comparison"; } - } else if (auto* str = ty->As()) { + } else if (auto* str = ty->As()) { // The struct, as a type, is just the name. We should have already emitted // the declaration through a call to |EmitStructType| earlier. - out_ << program_->Symbols().NameFor(str->impl()->name()); + out_ << program_->Symbols().NameFor(str->Declaration()->name()); } else if (auto* texture = ty->As()) { out_ << "texture_"; if (texture->Is()) { diff --git a/src/writer/wgsl/generator_impl.h b/src/writer/wgsl/generator_impl.h index 8e1f5e2d2d..96636122cf 100644 --- a/src/writer/wgsl/generator_impl.h +++ b/src/writer/wgsl/generator_impl.h @@ -35,7 +35,7 @@ #include "src/ast/unary_op_expression.h" #include "src/program.h" #include "src/sem/storage_texture_type.h" -#include "src/sem/struct_type.h" +#include "src/sem/struct.h" #include "src/writer/text_generator.h" namespace tint { diff --git a/src/writer/wgsl/generator_impl_alias_type_test.cc b/src/writer/wgsl/generator_impl_alias_type_test.cc index 4e0025c3c9..2735aa044e 100644 --- a/src/writer/wgsl/generator_impl_alias_type_test.cc +++ b/src/writer/wgsl/generator_impl_alias_type_test.cc @@ -31,10 +31,10 @@ TEST_F(WgslGeneratorImplTest, EmitAlias_F32) { } TEST_F(WgslGeneratorImplTest, EmitConstructedType_Struct) { - auto s = Structure("A", { - Member("a", ty.f32()), - Member("b", ty.i32()), - }); + auto* s = Structure("A", { + Member("a", ty.f32()), + Member("b", ty.i32()), + }); auto alias = ty.alias("B", s); @@ -51,10 +51,10 @@ type B = A; } TEST_F(WgslGeneratorImplTest, EmitAlias_ToStruct) { - auto s = Structure("A", { - Member("a", ty.f32()), - Member("b", ty.i32()), - }); + auto* s = Structure("A", { + Member("a", ty.f32()), + Member("b", ty.i32()), + }); auto alias = ty.alias("B", s); diff --git a/src/writer/wgsl/generator_impl_function_test.cc b/src/writer/wgsl/generator_impl_function_test.cc index 1e829f0500..bf831b0495 100644 --- a/src/writer/wgsl/generator_impl_function_test.cc +++ b/src/writer/wgsl/generator_impl_function_test.cc @@ -202,8 +202,8 @@ TEST_F(WgslGeneratorImplTest, // return; // } - auto s = Structure("Data", {Member("d", ty.f32())}, - {create()}); + auto* s = Structure("Data", {Member("d", ty.f32())}, + {create()}); auto ac = ty.access(ast::AccessControl::kReadWrite, s); diff --git a/src/writer/wgsl/generator_impl_global_decl_test.cc b/src/writer/wgsl/generator_impl_global_decl_test.cc index 53ad8b8e52..491cad1655 100644 --- a/src/writer/wgsl/generator_impl_global_decl_test.cc +++ b/src/writer/wgsl/generator_impl_global_decl_test.cc @@ -48,7 +48,7 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalDeclAfterFunction) { TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) { Global("a0", ty.f32(), ast::StorageClass::kPrivate); - auto s0 = Structure("S0", {Member("a", ty.i32())}); + auto* s0 = Structure("S0", {Member("a", ty.i32())}); Func("func", ast::VariableList{}, ty.f32(), ast::StatementList{ @@ -58,7 +58,7 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) { Global("a1", ty.f32(), ast::StorageClass::kOutput); - auto s1 = Structure("S1", {Member("a", ty.i32())}); + auto* s1 = Structure("S1", {Member("a", ty.i32())}); Func("main", ast::VariableList{}, ty.void_(), ast::StatementList{ diff --git a/src/writer/wgsl/generator_impl_member_accessor_test.cc b/src/writer/wgsl/generator_impl_member_accessor_test.cc index 14aa9577a2..1a2801164a 100644 --- a/src/writer/wgsl/generator_impl_member_accessor_test.cc +++ b/src/writer/wgsl/generator_impl_member_accessor_test.cc @@ -22,7 +22,7 @@ namespace { using WgslGeneratorImplTest = TestHelper; TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) { - auto s = Structure("Data", {Member("mem", ty.f32())}); + auto* s = Structure("Data", {Member("mem", ty.f32())}); Global("str", s, ast::StorageClass::kPrivate); auto* expr = MemberAccessor("str", "mem"); diff --git a/src/writer/wgsl/generator_impl_type_test.cc b/src/writer/wgsl/generator_impl_type_test.cc index edd7e27076..1afdba609b 100644 --- a/src/writer/wgsl/generator_impl_type_test.cc +++ b/src/writer/wgsl/generator_impl_type_test.cc @@ -47,8 +47,8 @@ TEST_F(WgslGeneratorImplTest, EmitType_Array) { } TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_Read) { - auto s = Structure("S", {Member("a", ty.i32())}, - {create()}); + auto* s = Structure("S", {Member("a", ty.i32())}, + {create()}); auto a = ty.access(ast::AccessControl::kReadOnly, s); AST().AddConstructedType(ty.alias("make_type_reachable", a)); @@ -60,8 +60,8 @@ TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_Read) { } TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_ReadWrite) { - auto s = Structure("S", {Member("a", ty.i32())}, - {create()}); + auto* s = Structure("S", {Member("a", ty.i32())}, + {create()}); auto a = ty.access(ast::AccessControl::kReadWrite, s); AST().AddConstructedType(ty.alias("make_type_reachable", a)); @@ -143,10 +143,10 @@ TEST_F(WgslGeneratorImplTest, EmitType_Pointer) { } TEST_F(WgslGeneratorImplTest, EmitType_Struct) { - auto s = Structure("S", { - Member("a", ty.i32()), - Member("b", ty.f32()), - }); + auto* s = Structure("S", { + Member("a", ty.i32()), + Member("b", ty.f32()), + }); GeneratorImpl& gen = Build(); @@ -155,10 +155,10 @@ TEST_F(WgslGeneratorImplTest, EmitType_Struct) { } TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl) { - auto s = Structure("S", { - Member("a", ty.i32(), {MemberOffset(8)}), - Member("b", ty.f32(), {MemberOffset(16)}), - }); + auto* s = Structure("S", { + Member("a", ty.i32(), {MemberOffset(8)}), + Member("b", ty.f32(), {MemberOffset(16)}), + }); GeneratorImpl& gen = Build(); @@ -175,7 +175,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl) { } TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl_WithSymbolCollisions) { - auto s = + auto* s = Structure("S", { Member("tint_0_padding", ty.i32(), {MemberOffset(8)}), Member("tint_2_padding", ty.f32(), {MemberOffset(16)}), @@ -196,10 +196,10 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl_WithSymbolCollisions) { } TEST_F(WgslGeneratorImplTest, EmitType_StructAlignDecl) { - auto s = Structure("S", { - Member("a", ty.i32(), {MemberAlign(8)}), - Member("b", ty.f32(), {MemberAlign(16)}), - }); + auto* s = Structure("S", { + Member("a", ty.i32(), {MemberAlign(8)}), + Member("b", ty.f32(), {MemberAlign(16)}), + }); GeneratorImpl& gen = Build(); @@ -214,10 +214,10 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructAlignDecl) { } TEST_F(WgslGeneratorImplTest, EmitType_StructSizeDecl) { - auto s = Structure("S", { - Member("a", ty.i32(), {MemberSize(16)}), - Member("b", ty.f32(), {MemberSize(32)}), - }); + auto* s = Structure("S", { + Member("a", ty.i32(), {MemberSize(16)}), + Member("b", ty.f32(), {MemberSize(32)}), + }); GeneratorImpl& gen = Build(); @@ -232,12 +232,12 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructSizeDecl) { } TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithDecoration) { - auto s = Structure("S", - { - Member("a", ty.i32()), - Member("b", ty.f32(), {MemberAlign(8)}), - }, - {create()}); + auto* s = Structure("S", + { + Member("a", ty.i32()), + Member("b", ty.f32(), {MemberAlign(8)}), + }, + {create()}); GeneratorImpl& gen = Build(); @@ -255,7 +255,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithEntryPointDecorations) { ast::DecorationList decos; decos.push_back(create()); - auto s = Structure( + auto* s = Structure( "S", ast::StructMemberList{ Member("a", ty.u32(), {Builtin(ast::Builtin::kVertexIndex)}), diff --git a/test/BUILD.gn b/test/BUILD.gn index f53b746253..a985eb9888 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -281,8 +281,8 @@ tint_unittests_source_set("tint_unittests_core_src") { "../src/sem/pointer_type_test.cc", "../src/sem/sampled_texture_type_test.cc", "../src/sem/sampler_type_test.cc", + "../src/sem/sem_struct_test.cc", "../src/sem/storage_texture_type_test.cc", - "../src/sem/struct_type_test.cc", "../src/sem/texture_type_test.cc", "../src/sem/type_manager_test.cc", "../src/sem/u32_type_test.cc", @@ -521,7 +521,6 @@ tint_unittests_source_set("tint_unittests_wgsl_writer_src") { tint_unittests_source_set("tint_unittests_msl_writer_src") { sources = [ "../src/transform/msl_test.cc", - "../src/writer/msl/generator_impl_alias_type_test.cc", "../src/writer/msl/generator_impl_array_accessor_test.cc", "../src/writer/msl/generator_impl_assign_test.cc", "../src/writer/msl/generator_impl_binary_test.cc", @@ -560,7 +559,6 @@ tint_unittests_source_set("tint_unittests_msl_writer_src") { tint_unittests_source_set("tint_unittests_hlsl_writer_src") { sources = [ "../src/transform/hlsl_test.cc", - "../src/writer/hlsl/generator_impl_alias_type_test.cc", "../src/writer/hlsl/generator_impl_array_accessor_test.cc", "../src/writer/hlsl/generator_impl_assign_test.cc", "../src/writer/hlsl/generator_impl_binary_test.cc",