diff --git a/src/BUILD.gn b/src/BUILD.gn index 4cb65636e9..af5eb73154 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -447,8 +447,6 @@ libtint_source_set("libtint_core_all_src") { "scope_stack.h", "sem/access_control_type.cc", "sem/access_control_type.h", - "sem/alias_type.cc", - "sem/alias_type.h", "sem/array.h", "sem/bool_type.cc", "sem/bool_type.h", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b2467dae0..2a90384f41 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -287,8 +287,6 @@ set(TINT_LIB_SRCS transform/vertex_pulling.h sem/access_control_type.cc sem/access_control_type.h - sem/alias_type.cc - sem/alias_type.h sem/bool_type.cc sem/bool_type.h sem/depth_texture_type.cc @@ -567,7 +565,6 @@ if(${TINT_BUILD_TESTS}) transform/transform_test.cc test_main.cc sem/access_control_type_test.cc - sem/alias_type_test.cc sem/bool_type_test.cc sem/depth_texture_type_test.cc sem/external_texture_type_test.cc diff --git a/src/intrinsic_table.cc b/src/intrinsic_table.cc index ec28a4f8c2..9881c20700 100644 --- a/src/intrinsic_table.cc +++ b/src/intrinsic_table.cc @@ -89,13 +89,10 @@ class Matcher { virtual ~Matcher() = default; /// Checks whether the given argument type matches. - /// Aliases are automatically unwrapped before matching. /// Match may add to, or compare against the open types and numbers in state. /// @returns true if the argument type is as expected. - bool Match(MatchState& state, const sem::Type* argument_type) const { - auto* unwrapped = argument_type->UnwrapAliasIfNeeded(); - return MatchUnwrapped(state, unwrapped); - } + virtual bool Match(MatchState& state, + const sem::Type* argument_type) const = 0; /// @return true if the matcher is expecting a pointer. If this method returns /// false and the argument is a pointer type, then the argument should be @@ -107,12 +104,6 @@ class Matcher { virtual std::string str() const = 0; protected: - /// Checks whether the given alias-unwrapped argument type matches. - /// Match may add to, or compare against the open types and numbers in state. - /// @returns true if the argument type is as expected. - virtual bool MatchUnwrapped(MatchState& state, - const sem::Type* argument_type) const = 0; - /// Checks `state.open_type` to see if the OpenType `t` is equal to the type /// `ty`. If `state.open_type` does not contain an entry for `t`, then `ty` /// is added and returns true. @@ -167,7 +158,7 @@ class OpenTypeBuilder : public Builder { public: explicit OpenTypeBuilder(OpenType open_type) : open_type_(open_type) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { return MatchOpenType(state, open_type_, ty); } @@ -184,7 +175,7 @@ class OpenTypeBuilder : public Builder { /// VoidBuilder is a Matcher / Builder for void types. class VoidBuilder : public Builder { public: - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { return ty->Is(); } sem::Type* Build(BuildState& state) const override { @@ -196,7 +187,7 @@ class VoidBuilder : public Builder { /// BoolBuilder is a Matcher / Builder for boolean types. class BoolBuilder : public Builder { public: - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { return ty->Is(); } sem::Type* Build(BuildState& state) const override { @@ -208,7 +199,7 @@ class BoolBuilder : public Builder { /// F32Builder is a Matcher / Builder for f32 types. class F32Builder : public Builder { public: - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { return ty->Is(); } sem::Type* Build(BuildState& state) const override { @@ -220,7 +211,7 @@ class F32Builder : public Builder { /// U32Builder is a Matcher / Builder for u32 types. class U32Builder : public Builder { public: - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { return ty->Is(); } sem::Type* Build(BuildState& state) const override { @@ -232,7 +223,7 @@ class U32Builder : public Builder { /// I32Builder is a Matcher / Builder for i32 types. class I32Builder : public Builder { public: - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { return ty->Is(); } sem::Type* Build(BuildState& state) const override { @@ -244,7 +235,7 @@ class I32Builder : public Builder { /// IU32Matcher is a Matcher for i32 or u32 types. class IU32Matcher : public Matcher { public: - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { return ty->Is() || ty->Is(); } std::string str() const override { return "i32 or u32"; } @@ -253,7 +244,7 @@ class IU32Matcher : public Matcher { /// FIU32Matcher is a Matcher for f32, i32 or u32 types. class FIU32Matcher : public Matcher { public: - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { return ty->Is() || ty->Is() || ty->Is(); } std::string str() const override { return "f32, i32 or u32"; } @@ -262,7 +253,7 @@ class FIU32Matcher : public Matcher { /// ScalarMatcher is a Matcher for f32, i32, u32 or boolean types. class ScalarMatcher : public Matcher { public: - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { return ty->is_scalar(); } std::string str() const override { return "scalar"; } @@ -275,7 +266,7 @@ class OpenSizeVecBuilder : public Builder { OpenSizeVecBuilder(OpenNumber size, Builder* element_builder) : size_(size), element_builder_(element_builder) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { if (auto* vec = ty->As()) { if (!MatchOpenNumber(state, size_, vec->size())) { return false; @@ -307,7 +298,7 @@ class VecBuilder : public Builder { VecBuilder(uint32_t size, Builder* element_builder) : size_(size), element_builder_(element_builder) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { if (auto* vec = ty->As()) { if (vec->size() == size_) { return element_builder_->Match(state, vec->type()); @@ -339,7 +330,7 @@ class OpenSizeMatBuilder : public Builder { Builder* element_builder) : columns_(columns), rows_(rows), element_builder_(element_builder) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { if (auto* mat = ty->As()) { if (!MatchOpenNumber(state, columns_, mat->columns())) { return false; @@ -378,7 +369,7 @@ class PtrBuilder : public Builder { explicit PtrBuilder(Builder* element_builder) : element_builder_(element_builder) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { if (auto* ptr = ty->As()) { return element_builder_->Match(state, ptr->type()); } @@ -407,7 +398,7 @@ class ArrayBuilder : public Builder { explicit ArrayBuilder(Builder* element_builder) : element_builder_(element_builder) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { if (auto* arr = ty->As()) { if (arr->IsRuntimeSized()) { return element_builder_->Match(state, arr->ElemType()); @@ -436,7 +427,7 @@ class SampledTextureBuilder : public Builder { Builder* type_builder) : dimensions_(dimensions), type_builder_(type_builder) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { if (auto* tex = ty->As()) { if (tex->dim() == dimensions_) { return type_builder_->Match(state, tex->type()); @@ -469,7 +460,7 @@ class MultisampledTextureBuilder : public Builder { Builder* type_builder) : dimensions_(dimensions), type_builder_(type_builder) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { if (auto* tex = ty->As()) { if (tex->dim() == dimensions_) { return type_builder_->Match(state, tex->type()); @@ -501,7 +492,7 @@ class DepthTextureBuilder : public Builder { explicit DepthTextureBuilder(ast::TextureDimension dimensions) : dimensions_(dimensions) {} - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { if (auto* tex = ty->As()) { return tex->dim() == dimensions_; } @@ -534,7 +525,7 @@ class StorageTextureBuilder : public Builder { texel_format_(texel_format), channel_format_(channel_format) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { if (auto* ac = ty->As()) { // If we have an storage texture argument that's got an access control // type wrapped around it, accept it. Signatures that don't include an @@ -579,7 +570,7 @@ class ExternalTextureBuilder : public Builder { public: ExternalTextureBuilder() {} - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { return ty->Is(); } @@ -595,7 +586,7 @@ class SamplerBuilder : public Builder { public: explicit SamplerBuilder(ast::SamplerKind kind) : kind_(kind) {} - bool MatchUnwrapped(MatchState&, const sem::Type* ty) const override { + bool Match(MatchState&, const sem::Type* ty) const override { if (auto* sampler = ty->As()) { return sampler->kind() == kind_; } @@ -627,7 +618,7 @@ class AccessControlBuilder : public Builder { Builder* type) : access_control_(access_control), type_(type) {} - bool MatchUnwrapped(MatchState& state, const sem::Type* ty) const override { + bool Match(MatchState& state, const sem::Type* ty) const override { if (auto* ac = ty->As()) { if (ac->access_control() == access_control_) { return type_->Match(state, ty); diff --git a/src/intrinsic_table_test.cc b/src/intrinsic_table_test.cc index 3f7874a2ae..b0e465e2d5 100644 --- a/src/intrinsic_table_test.cc +++ b/src/intrinsic_table_test.cc @@ -352,35 +352,6 @@ TEST_F(IntrinsicTableTest, MatchAutoPointerDereference) { EXPECT_THAT(result.intrinsic->Parameters(), ElementsAre(Parameter{ty.f32()})); } -TEST_F(IntrinsicTableTest, MatchWithAliasUnwrapping) { - auto alias_a = ty.alias("alias_a", ty.f32()); - auto alias_b = ty.alias("alias_b", alias_a); - auto alias_c = ty.alias("alias_c", alias_b); - auto result = table->Lookup(*this, IntrinsicType::kCos, {alias_c}, Source{}); - ASSERT_NE(result.intrinsic, nullptr); - ASSERT_EQ(result.diagnostics.str(), ""); - EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kCos); - EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32()); - EXPECT_THAT(result.intrinsic->Parameters(), ElementsAre(Parameter{ty.f32()})); -} - -TEST_F(IntrinsicTableTest, MatchWithNestedAliasUnwrapping) { - auto alias_a = ty.alias("alias_a", ty.bool_()); - auto alias_b = ty.alias("alias_b", alias_a); - auto alias_c = ty.alias("alias_c", alias_b); - auto vec4_of_c = ty.vec4(alias_c); - auto alias_d = ty.alias("alias_d", vec4_of_c); - auto alias_e = ty.alias("alias_e", alias_d); - - auto result = table->Lookup(*this, IntrinsicType::kAll, {alias_e}, Source{}); - ASSERT_NE(result.intrinsic, nullptr); - ASSERT_EQ(result.diagnostics.str(), ""); - EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kAll); - EXPECT_THAT(result.intrinsic->ReturnType(), ty.bool_()); - EXPECT_THAT(result.intrinsic->Parameters(), - ElementsAre(Parameter{ty.vec4()})); -} - TEST_F(IntrinsicTableTest, MatchOpenType) { auto result = table->Lookup(*this, IntrinsicType::kClamp, {ty.f32(), ty.f32(), ty.f32()}, Source{}); diff --git a/src/program_builder.h b/src/program_builder.h index 41d3842837..53ad9cb796 100644 --- a/src/program_builder.h +++ b/src/program_builder.h @@ -60,7 +60,6 @@ #include "src/program.h" #include "src/program_id.h" #include "src/sem/access_control_type.h" -#include "src/sem/alias_type.h" #include "src/sem/array.h" #include "src/sem/bool_type.h" #include "src/sem/depth_texture_type.h" @@ -682,13 +681,10 @@ class ProgramBuilder { /// @param type the alias type /// @returns the alias pointer template - typ::Alias alias(NAME&& name, typ::Type type) const { + ast::Alias* alias(NAME&& name, typ::Type type) const { type = MaybeCreateTypename(type); auto sym = builder->Sym(std::forward(name)); - return { - type.ast ? builder->create(sym, type) : nullptr, - type.sem ? builder->create(sym, type) : nullptr, - }; + return builder->create(sym, type); } /// Creates an alias type @@ -697,13 +693,10 @@ class ProgramBuilder { /// @param type the alias type /// @returns the alias pointer template - typ::Alias alias(const Source& source, NAME&& name, typ::Type type) const { + ast::Alias* alias(const Source& source, NAME&& name, typ::Type type) const { type = MaybeCreateTypename(type); auto sym = builder->Sym(std::forward(name)); - return { - type.ast ? builder->create(source, sym, type) : nullptr, - type.sem ? builder->create(sym, type) : nullptr, - }; + return builder->create(source, sym, type); } /// Creates an access control qualifier type diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc index 368b257b8d..06878cf310 100644 --- a/src/reader/spirv/parser_impl.cc +++ b/src/reader/spirv/parser_impl.cc @@ -1206,7 +1206,7 @@ const Type* ParserImpl::MaybeGenerateAlias( } const auto name = namer_.GetName(type_id); const auto sym = builder_.Symbols().Register(name); - auto ast_alias_type = + auto* ast_alias_type = builder_.ty.alias(sym, ast_underlying_type->Build(builder_)); // Record this new alias as the AST type for this SPIR-V ID. diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc index 90e4c8bf56..3ea562a3a5 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc @@ -985,8 +985,8 @@ Maybe ParserImpl::type_alias() { if (!type.matched) return add_error(peek(), "invalid type alias"); - auto alias = builder_.ty.alias(make_source_range_from(t.source()), name.value, - type.value); + auto* alias = builder_.ty.alias(make_source_range_from(t.source()), + name.value, type.value); register_constructed(name.value, alias); return alias; } diff --git a/src/reader/wgsl/parser_impl_type_decl_test.cc b/src/reader/wgsl/parser_impl_type_decl_test.cc index af10a76331..295106fb0d 100644 --- a/src/reader/wgsl/parser_impl_type_decl_test.cc +++ b/src/reader/wgsl/parser_impl_type_decl_test.cc @@ -37,7 +37,7 @@ TEST_F(ParserImplTest, TypeDecl_Identifier) { auto p = parser("A"); auto& builder = p->builder(); - auto alias_type = builder.ty.alias("A", builder.ty.i32()); + auto* alias_type = builder.ty.alias("A", builder.ty.i32()); p->register_constructed("A", alias_type); auto t = p->type_decl(); diff --git a/src/resolver/assignment_validation_test.cc b/src/resolver/assignment_validation_test.cc index be90145e25..52782a1ff3 100644 --- a/src/resolver/assignment_validation_test.cc +++ b/src/resolver/assignment_validation_test.cc @@ -166,7 +166,7 @@ TEST_F(ResolverAssignmentValidationTest, // alias myint = i32; // var a :myint = 2; // a = 2 - auto myint = ty.alias("myint", ty.i32()); + auto* myint = ty.alias("myint", ty.i32()); AST().AddConstructedType(myint); auto* var = Var("a", myint, ast::StorageClass::kNone, Expr(2)); diff --git a/src/resolver/control_block_validation_test.cc b/src/resolver/control_block_validation_test.cc index 3b4a35840a..a999fbbf52 100644 --- a/src/resolver/control_block_validation_test.cc +++ b/src/resolver/control_block_validation_test.cc @@ -294,7 +294,7 @@ TEST_F(ResolverControlBlockValidationTest, SwitchCaseAlias_Pass) { // default: {} // } - auto my_int = ty.alias("MyInt", ty.u32()); + auto* my_int = ty.alias("MyInt", ty.u32()); auto* var = Var("a", my_int, ast::StorageClass::kNone, Expr(2u)); ast::CaseSelectorList default_csl; diff --git a/src/resolver/function_validation_test.cc b/src/resolver/function_validation_test.cc index 542ed2d5f6..ab2d2c79ad 100644 --- a/src/resolver/function_validation_test.cc +++ b/src/resolver/function_validation_test.cc @@ -157,7 +157,7 @@ TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeF32Alias_pass) { // type myf32 = f32; // fn func -> myf32 { return 2.0; } - auto myf32 = ty.alias("myf32", ty.f32()); + auto* myf32 = ty.alias("myf32", ty.f32()); AST().AddConstructedType(myf32); Func("func", ast::VariableList{}, myf32, ast::StatementList{ @@ -172,7 +172,7 @@ TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeF32Alias_fail) { // type myf32 = f32; // fn func -> myf32 { return 2; } - auto myf32 = ty.alias("myf32", ty.f32()); + auto* myf32 = ty.alias("myf32", ty.f32()); AST().AddConstructedType(myf32); Func("func", ast::VariableList{}, myf32, ast::StatementList{ diff --git a/src/resolver/host_shareable_validation_test.cc b/src/resolver/host_shareable_validation_test.cc index 5bbde0e77e..25bcfa5c6b 100644 --- a/src/resolver/host_shareable_validation_test.cc +++ b/src/resolver/host_shareable_validation_test.cc @@ -57,12 +57,12 @@ TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) { } TEST_F(ResolverHostShareableValidationTest, Aliases) { - auto a1 = ty.alias("a1", ty.bool_()); + auto* a1 = ty.alias("a1", ty.bool_()); AST().AddConstructedType(a1); 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); + auto* a2 = ty.alias("a2", ac); AST().AddConstructedType(a2); Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage); @@ -104,14 +104,14 @@ TEST_F(ResolverHostShareableValidationTest, NoError) { Member(Source{{2, 1}}, "y1", ty.vec3()), Member(Source{{3, 1}}, "z1", ty.array()), }); - auto a1 = ty.alias("a1", i1); + 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 a2 = ty.alias("a2", i2); + auto* a2 = ty.alias("a2", i2); AST().AddConstructedType(a2); auto* i3 = Structure("I3", { Member(Source{{4, 1}}, "x3", a1), diff --git a/src/resolver/is_host_shareable_test.cc b/src/resolver/is_host_shareable_test.cc index 7f50b06bda..cb27133dda 100644 --- a/src/resolver/is_host_shareable_test.cc +++ b/src/resolver/is_host_shareable_test.cc @@ -79,14 +79,6 @@ TEST_F(ResolverIsHostShareable, Pointer) { r()->IsHostShareable(ty.pointer(ast::StorageClass::kPrivate))); } -TEST_F(ResolverIsHostShareable, AliasVoid) { - EXPECT_FALSE(r()->IsHostShareable(ty.alias("a", ty.void_()))); -} - -TEST_F(ResolverIsHostShareable, AliasI32) { - EXPECT_TRUE(r()->IsHostShareable(ty.alias("a", ty.i32()))); -} - TEST_F(ResolverIsHostShareable, AccessControlVoid) { EXPECT_FALSE(r()->IsHostShareable( ty.access(ast::AccessControl::kReadOnly, ty.void_()))); diff --git a/src/resolver/is_storeable_test.cc b/src/resolver/is_storeable_test.cc index 62010e9637..35362d6915 100644 --- a/src/resolver/is_storeable_test.cc +++ b/src/resolver/is_storeable_test.cc @@ -63,14 +63,6 @@ TEST_F(ResolverIsStorableTest, Pointer) { EXPECT_FALSE(r()->IsStorable(ty.pointer(ast::StorageClass::kPrivate))); } -TEST_F(ResolverIsStorableTest, AliasVoid) { - EXPECT_FALSE(r()->IsStorable(ty.alias("a", ty.void_()))); -} - -TEST_F(ResolverIsStorableTest, AliasI32) { - EXPECT_TRUE(r()->IsStorable(ty.alias("a", ty.i32()))); -} - TEST_F(ResolverIsStorableTest, AccessControlVoid) { EXPECT_FALSE(r()->IsStorable( create(ast::AccessControl::kReadOnly, ty.void_()))); diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc index 658fca881a..3e863c6167 100644 --- a/src/resolver/resolver.cc +++ b/src/resolver/resolver.cc @@ -430,8 +430,8 @@ Resolver::VariableInfo* Resolver::Variable( return nullptr; } - auto* ctype = Canonical(const_cast(type)); - auto* info = variable_infos_.Create(var, ctype, type_name); + auto* info = + variable_infos_.Create(var, const_cast(type), type_name); variable_to_info_.emplace(var, info); return info; @@ -797,7 +797,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 (ty->Is()) { if (pipeline_io_attribute) { diagnostics_.add_error( "entry point IO attributes must not be used on structure " + @@ -823,7 +823,7 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func, // of numeric scalars. // Testing for being a struct is handled by the if portion above. if (!pipeline_io_attribute->Is()) { - if (!Canonical(ty)->is_numeric_scalar_or_vector()) { + if (!ty->is_numeric_scalar_or_vector()) { diagnostics_.add_error( "User defined entry point IO types must be a numeric scalar, " "a numeric vector, or a structure", @@ -846,12 +846,11 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func, return false; } - if (auto* str = Canonical(ty)->As()) { + if (auto* str = ty->As()) { // Validate the decorations for each struct members, and also check for // invalid member types. for (auto* member : str->Members()) { - auto* member_ty = Canonical(member->Type()); - if (member_ty->Is()) { + if (member->Type()->Is()) { diagnostics_.add_error( "entry point IO types cannot contain nested structures", member->Declaration()->source()); @@ -859,7 +858,9 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func, builder_->Symbols().NameFor(func->symbol()), func->source()); return false; - } else if (auto* arr = member_ty->As()) { + } + + if (auto* arr = member->Type()->As()) { if (arr->IsRuntimeSized()) { diagnostics_.add_error( "entry point IO types cannot contain runtime sized arrays", @@ -873,7 +874,7 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func, } if (!validate_entry_point_decorations_inner( - member->Declaration()->decorations(), member_ty, + member->Declaration()->decorations(), member->Type(), member->Declaration()->source(), param_or_ret, true)) { diagnostics_.add_note("while analysing entry point " + builder_->Symbols().NameFor(func->symbol()), @@ -992,8 +993,6 @@ bool Resolver::Function(ast::Function* func) { info->return_type->FriendlyName(builder_->Symbols()); } - info->return_type = Canonical(info->return_type); - if (auto* str = info->return_type->As()) { if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, str, func->source())) { @@ -1746,11 +1745,8 @@ bool Resolver::ValidateBinary(ast::BinaryExpression* expr) { using Matrix = sem::Matrix; using Vector = sem::Vector; - auto* lhs_declared_type = TypeOf(expr->lhs())->UnwrapAll(); - auto* rhs_declared_type = TypeOf(expr->rhs())->UnwrapAll(); - - auto* lhs_type = Canonical(const_cast(lhs_declared_type)); - auto* rhs_type = Canonical(const_cast(rhs_declared_type)); + auto* lhs_type = const_cast(TypeOf(expr->lhs())->UnwrapAll()); + auto* rhs_type = const_cast(TypeOf(expr->rhs())->UnwrapAll()); auto* lhs_vec = lhs_type->As(); auto* lhs_vec_elem_type = lhs_vec ? lhs_vec->type() : nullptr; @@ -1895,9 +1891,9 @@ bool Resolver::ValidateBinary(ast::BinaryExpression* expr) { diagnostics_.add_error( "Binary expression operand types are invalid for this operation: " + - lhs_declared_type->FriendlyName(builder_->Symbols()) + " " + + lhs_type->FriendlyName(builder_->Symbols()) + " " + FriendlyName(expr->op()) + " " + - rhs_declared_type->FriendlyName(builder_->Symbols()), + rhs_type->FriendlyName(builder_->Symbols()), expr->source()); return false; } @@ -2142,7 +2138,6 @@ void Resolver::SetType(ast::Expression* expr, TINT_ICE(builder_->Diagnostics()) << "SetType() called twice for the same expression"; } - type = Canonical(type); expr_info_.emplace(expr, ExpressionInfo{type, type_name, current_statement_}); } @@ -2262,13 +2257,12 @@ bool Resolver::DefaultAlignAndSize(const sem::Type* ty, /*vec4*/ 16, }; - auto* cty = Canonical(const_cast(ty)); - if (cty->is_scalar()) { + if (ty->is_scalar()) { // Note: Also captures booleans, but these are not host-shareable. align = 4; size = 4; return true; - } else if (auto* vec = cty->As()) { + } else if (auto* vec = ty->As()) { if (vec->size() < 2 || vec->size() > 4) { TINT_UNREACHABLE(diagnostics_) << "Invalid vector size: vec" << vec->size(); @@ -2277,7 +2271,7 @@ bool Resolver::DefaultAlignAndSize(const sem::Type* ty, align = vector_align[vec->size()]; size = vector_size[vec->size()]; return true; - } else if (auto* mat = cty->As()) { + } else if (auto* mat = ty->As()) { if (mat->columns() < 2 || mat->columns() > 4 || mat->rows() < 2 || mat->rows() > 4) { TINT_UNREACHABLE(diagnostics_) @@ -2287,11 +2281,11 @@ 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()) { + } else if (auto* s = ty->As()) { align = s->Align(); size = s->Size(); return true; - } else if (auto* a = cty->As()) { + } else if (auto* a = ty->As()) { align = a->Align(); size = a->SizeInBytes(); return true; @@ -2818,45 +2812,6 @@ std::string Resolver::VectorPretty(uint32_t size, return vec_type.FriendlyName(builder_->Symbols()); } -sem::Type* Resolver::Canonical(sem::Type* type) { - using AccessControl = sem::AccessControl; - using Alias = sem::Alias; - using Matrix = sem::Matrix; - using Type = sem::Type; - using Vector = sem::Vector; - - if (!type) { - TINT_ICE(diagnostics_) << "Canonical() called with nullptr"; - return nullptr; - } - - std::function make_canonical; - make_canonical = [&](Type* t) -> sem::Type* { - // Unwrap alias sequence - Type* ct = t; - while (auto* p = ct->As()) { - ct = p->type(); - } - - if (auto* v = ct->As()) { - return builder_->create(make_canonical(v->type()), v->size()); - } - if (auto* m = ct->As()) { - auto* column_type = - builder_->create(make_canonical(m->type()), m->rows()); - return builder_->create(column_type, m->columns()); - } - if (auto* ac = ct->As()) { - return builder_->create(ac->access_control(), - make_canonical(ac->type())); - } - return ct; - }; - - return utils::GetOrCreate(type_to_canonical_, type, - [&] { return make_canonical(type); }); -} - void Resolver::Mark(const ast::Node* node) { if (node == nullptr) { TINT_ICE(diagnostics_) << "Resolver::Mark() called with nullptr"; diff --git a/src/resolver/resolver.h b/src/resolver/resolver.h index a5f72f8289..378927bc79 100644 --- a/src/resolver/resolver.h +++ b/src/resolver/resolver.h @@ -83,12 +83,6 @@ class Resolver { /// structure member or array element of type `lhs` static bool IsValidAssignment(const sem::Type* lhs, const sem::Type* rhs); - /// @param type the input type - /// @returns the canonical type for `type`; that is, a type with all aliases - /// removed. For example, `Canonical(alias>>>)` is - /// `vec3`. - 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. @@ -351,7 +345,6 @@ class Resolver { std::unordered_map variable_to_info_; std::unordered_map function_calls_; std::unordered_map expr_info_; - std::unordered_map type_to_canonical_; std::unordered_map named_types_; std::unordered_set marked_; FunctionInfo* current_function_ = nullptr; diff --git a/src/resolver/resolver_test.cc b/src/resolver/resolver_test.cc index 1d6f22f87e..fe8d221946 100644 --- a/src/resolver/resolver_test.cc +++ b/src/resolver/resolver_test.cc @@ -260,7 +260,7 @@ TEST_F(ResolverTest, Stmt_VariableDecl) { } TEST_F(ResolverTest, Stmt_VariableDecl_Alias) { - auto my_int = ty.alias("MyInt", ty.i32()); + auto* my_int = ty.alias("MyInt", ty.i32()); AST().AddConstructedType(my_int); auto* var = Var("my_var", my_int, ast::StorageClass::kNone, Expr(2)); auto* init = var->constructor(); @@ -408,7 +408,7 @@ TEST_F(ResolverTest, Expr_ArrayAccessor_Array) { } TEST_F(ResolverTest, Expr_ArrayAccessor_Alias_Array) { - auto aary = ty.alias("myarrty", ty.array()); + auto* aary = ty.alias("myarrty", ty.array()); AST().AddConstructedType(aary); Global("my_var", aary, ast::StorageClass::kFunction); @@ -909,7 +909,7 @@ 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 alias = ty.alias("alias", st); + auto* alias = ty.alias("alias", st); AST().AddConstructedType(alias); Global("my_struct", alias, ast::StorageClass::kInput); @@ -1234,18 +1234,18 @@ TEST_P(Expr_Binary_Test_WithAlias_Valid, All) { // For vectors and matrices, wrap the sub type in an alias auto make_alias = [this](ast::Type* type) -> ast::Type* { if (auto* v = type->As()) { - auto alias = ty.alias(Symbols().New(), v->type()); + auto* alias = ty.alias(Symbols().New(), v->type()); AST().AddConstructedType(alias); return ty.vec(alias, v->size()); } if (auto* m = type->As()) { - auto alias = ty.alias(Symbols().New(), m->type()); + auto* alias = ty.alias(Symbols().New(), m->type()); AST().AddConstructedType(alias); return ty.mat(alias, m->columns(), m->rows()); } - auto alias = ty.alias(Symbols().New(), type); + auto* alias = ty.alias(Symbols().New(), type); AST().AddConstructedType(alias); - return ty.type_name(alias.ast->name()); + return ty.type_name(alias->name()); }; // Wrap in alias diff --git a/src/resolver/storage_class_validation_test.cc b/src/resolver/storage_class_validation_test.cc index 9ee35479c9..9c36597bf3 100644 --- a/src/resolver/storage_class_validation_test.cc +++ b/src/resolver/storage_class_validation_test.cc @@ -75,7 +75,7 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) { TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) { // type a = bool; // var g : [[access(read)]] a; - auto a = ty.alias("a", ty.bool_()); + auto* a = ty.alias("a", ty.bool_()); AST().AddConstructedType(a); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); @@ -131,10 +131,10 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Aliases) { // var g : a2; auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, {create()}); - auto a1 = ty.alias("a1", s); + auto* a1 = ty.alias("a1", s); AST().AddConstructedType(a1); auto ac = ty.access(ast::AccessControl::kReadOnly, a1); - auto a2 = ty.alias("a2", ac); + auto* a2 = ty.alias("a2", ac); AST().AddConstructedType(a2); Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage); @@ -183,7 +183,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) { TEST_F(ResolverStorageClassValidationTest, UniformBufferBoolAlias) { // type a = bool; // var g : [[access(read)]] a; - auto a = ty.alias("a", ty.bool_()); + auto* a = ty.alias("a", ty.bool_()); AST().AddConstructedType(a); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform); @@ -224,7 +224,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferNoError_Aliases) { // var g : a1; auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, {create()}); - auto a1 = ty.alias("a1", s); + 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 c0d0507dde..667020cf4c 100644 --- a/src/resolver/struct_layout_test.cc +++ b/src/resolver/struct_layout_test.cc @@ -52,9 +52,9 @@ TEST_F(ResolverStructLayoutTest, Scalars) { } TEST_F(ResolverStructLayoutTest, Alias) { - auto alias_a = ty.alias("a", ty.f32()); + auto* alias_a = ty.alias("a", ty.f32()); AST().AddConstructedType(alias_a); - auto alias_b = ty.alias("b", ty.f32()); + auto* alias_b = ty.alias("b", ty.f32()); AST().AddConstructedType(alias_b); auto* s = Structure("S", { diff --git a/src/resolver/struct_pipeline_stage_use_test.cc b/src/resolver/struct_pipeline_stage_use_test.cc index 293076077e..b6d565512b 100644 --- a/src/resolver/struct_pipeline_stage_use_test.cc +++ b/src/resolver/struct_pipeline_stage_use_test.cc @@ -158,7 +158,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamViaAlias) { auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); - auto s_alias = ty.alias("S_alias", s); + auto* s_alias = ty.alias("S_alias", s); AST().AddConstructedType(s_alias); Func("main", {Param("param", s_alias)}, ty.void_(), {}, @@ -174,7 +174,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamViaAlias) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeViaAlias) { auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); - auto s_alias = ty.alias("S_alias", s); + auto* s_alias = ty.alias("S_alias", s); AST().AddConstructedType(s_alias); Func("main", {}, s_alias, {Return(Construct(s_alias, Expr(0.f)))}, diff --git a/src/resolver/struct_storage_class_use_test.cc b/src/resolver/struct_storage_class_use_test.cc index d087069389..b432833964 100644 --- a/src/resolver/struct_storage_class_use_test.cc +++ b/src/resolver/struct_storage_class_use_test.cc @@ -78,7 +78,7 @@ TEST_F(ResolverStorageClassUseTest, StructReachableFromGlobal) { TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalAlias) { auto* s = Structure("S", {Member("a", ty.f32())}); - auto a = ty.alias("A", s); + auto* a = ty.alias("A", s); AST().AddConstructedType(a); Global("g", a, ast::StorageClass::kPrivate); @@ -131,7 +131,7 @@ TEST_F(ResolverStorageClassUseTest, StructReachableFromLocal) { TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalAlias) { auto* s = Structure("S", {Member("a", ty.f32())}); - auto a = ty.alias("A", s); + auto* a = ty.alias("A", s); AST().AddConstructedType(a); WrapInFunction(Var("g", a, ast::StorageClass::kFunction)); diff --git a/src/resolver/type_validation_test.cc b/src/resolver/type_validation_test.cc index 5d12b814d0..b5dfcc1ea7 100644 --- a/src/resolver/type_validation_test.cc +++ b/src/resolver/type_validation_test.cc @@ -431,7 +431,7 @@ TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsNotLast_Fail) { // a: u32; //} - auto alias = ty.alias("RTArr", ty.array()); + auto* alias = ty.alias("RTArr", ty.array()); AST().AddConstructedType(alias); Structure("s", @@ -458,7 +458,7 @@ TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsLast_Pass) { // b: RTArr; //} - auto alias = ty.alias("RTArr", ty.array()); + auto* alias = ty.alias("RTArr", ty.array()); AST().AddConstructedType(alias); Structure("s", diff --git a/src/resolver/validation_test.cc b/src/resolver/validation_test.cc index 6ad9df8ca0..7889f8d588 100644 --- a/src/resolver/validation_test.cc +++ b/src/resolver/validation_test.cc @@ -178,7 +178,7 @@ TEST_F(ResolverValidationTest, TEST_F(ResolverValidationTest, Stmt_VariableDecl_MismatchedTypeScalarConstructor_Alias) { - auto my_int = ty.alias("MyInt", ty.i32()); + auto* my_int = ty.alias("MyInt", ty.i32()); AST().AddConstructedType(my_int); u32 unsigned_value = 2u; // Type does not match variable type auto* var = @@ -1699,7 +1699,7 @@ TEST_F(ResolverValidationTest, } TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Error) { - auto alias = ty.alias("UnsignedInt", ty.u32()); + auto* alias = ty.alias("UnsignedInt", ty.u32()); AST().AddConstructedType(alias); Global("uint_var", alias, ast::StorageClass::kInput); @@ -1713,8 +1713,8 @@ TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Error) { } TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) { - auto f32_alias = ty.alias("Float32", ty.f32()); - auto vec2_alias = ty.alias("VectorFloat2", ty.vec2()); + auto* f32_alias = ty.alias("Float32", ty.f32()); + auto* vec2_alias = ty.alias("VectorFloat2", ty.vec2()); AST().AddConstructedType(f32_alias); AST().AddConstructedType(vec2_alias); Global("my_f32", f32_alias, ast::StorageClass::kInput); @@ -1726,7 +1726,7 @@ TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) { } TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ElementTypeAlias_Error) { - auto f32_alias = ty.alias("Float32", ty.f32()); + auto* f32_alias = ty.alias("Float32", ty.f32()); AST().AddConstructedType(f32_alias); // vec2(1.0f, 1u) @@ -1745,7 +1745,7 @@ TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ElementTypeAlias_Error) { TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ElementTypeAlias_Success) { - auto f32_alias = ty.alias("Float32", ty.f32()); + auto* f32_alias = ty.alias("Float32", ty.f32()); AST().AddConstructedType(f32_alias); // vec2(1.0f, 1.0f) @@ -1759,7 +1759,7 @@ TEST_F(ResolverValidationTest, TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ArgumentElementTypeAlias_Error) { - auto f32_alias = ty.alias("Float32", ty.f32()); + auto* f32_alias = ty.alias("Float32", ty.f32()); AST().AddConstructedType(f32_alias); // vec3(vec(), 1.0f) @@ -1777,7 +1777,7 @@ TEST_F(ResolverValidationTest, TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ArgumentElementTypeAlias_Success) { - auto f32_alias = ty.alias("Float32", ty.f32()); + auto* f32_alias = ty.alias("Float32", ty.f32()); AST().AddConstructedType(f32_alias); // vec3(vec(), 1.0f) @@ -2008,7 +2008,7 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Error) { // matNxM(vecM(), ...); with N arguments const auto param = GetParam(); - auto f32_alias = ty.alias("Float32", ty.f32()); + auto* f32_alias = ty.alias("Float32", ty.f32()); AST().AddConstructedType(f32_alias); ast::ExpressionList args; @@ -2034,7 +2034,7 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Success) { // matNxM(vecM(), ...); with N arguments const auto param = GetParam(); - auto f32_alias = ty.alias("Float32", ty.f32()); + auto* f32_alias = ty.alias("Float32", ty.f32()); AST().AddConstructedType(f32_alias); ast::ExpressionList args; @@ -2053,7 +2053,7 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Success) { } TEST_F(ResolverValidationTest, Expr_MatrixConstructor_ArgumentTypeAlias_Error) { - auto alias = ty.alias("VectorUnsigned2", ty.vec2()); + auto* alias = ty.alias("VectorUnsigned2", ty.vec2()); AST().AddConstructedType(alias); auto* tc = mat2x2( create( @@ -2071,7 +2071,7 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) { const auto param = GetParam(); auto matrix_type = ty.mat(param.columns, param.rows); auto vec_type = ty.vec(param.rows); - auto vec_alias = ty.alias("VectorFloat2", vec_type); + auto* vec_alias = ty.alias("VectorFloat2", vec_type); AST().AddConstructedType(vec_alias); ast::ExpressionList args; @@ -2090,7 +2090,7 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) { TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Error) { const auto param = GetParam(); auto matrix_type = ty.mat(param.columns, param.rows); - auto f32_alias = ty.alias("UnsignedInt", ty.u32()); + auto* f32_alias = ty.alias("UnsignedInt", ty.u32()); AST().AddConstructedType(f32_alias); ast::ExpressionList args; @@ -2114,7 +2114,7 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Error) { TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Success) { const auto param = GetParam(); - auto f32_alias = ty.alias("Float32", ty.f32()); + auto* f32_alias = ty.alias("Float32", ty.f32()); AST().AddConstructedType(f32_alias); ast::ExpressionList args; diff --git a/src/sem/access_control_type_test.cc b/src/sem/access_control_type_test.cc index 828b721a81..f62a50ab3d 100644 --- a/src/sem/access_control_type_test.cc +++ b/src/sem/access_control_type_test.cc @@ -36,7 +36,6 @@ TEST_F(AccessControlTest, Is) { AccessControl at{ast::AccessControl::kReadOnly, &i32}; Type* ty = &at; EXPECT_TRUE(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.cc b/src/sem/alias_type.cc deleted file mode 100644 index 26b05c02bc..0000000000 --- a/src/sem/alias_type.cc +++ /dev/null @@ -1,44 +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/alias_type.h" - -#include "src/program_builder.h" - -TINT_INSTANTIATE_TYPEINFO(tint::sem::Alias); - -namespace tint { -namespace sem { - -Alias::Alias(const Symbol& sym, const Type* subtype) - : symbol_(sym), - subtype_(subtype), - type_name_("__alias_" + sym.to_str() + subtype->type_name()) { - TINT_ASSERT(subtype_); -} - -Alias::Alias(Alias&&) = default; - -Alias::~Alias() = default; - -std::string Alias::type_name() const { - return type_name_; -} - -std::string Alias::FriendlyName(const SymbolTable& symbols) const { - return symbols.NameFor(symbol_); -} - -} // namespace sem -} // namespace tint diff --git a/src/sem/alias_type.h b/src/sem/alias_type.h deleted file mode 100644 index 927234a941..0000000000 --- a/src/sem/alias_type.h +++ /dev/null @@ -1,60 +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_ALIAS_TYPE_H_ -#define SRC_SEM_ALIAS_TYPE_H_ - -#include - -#include "src/sem/type.h" -#include "src/symbol.h" - -namespace tint { -namespace sem { - -/// A type alias type. Holds a name and pointer to another type. -class Alias : public Castable { - public: - /// Constructor - /// @param sym the symbol for the alias - /// @param subtype the alias'd type - Alias(const Symbol& sym, const Type* subtype); - /// Move constructor - Alias(Alias&&); - /// Destructor - ~Alias() override; - - /// @returns the alias symbol - Symbol symbol() const { return symbol_; } - /// @returns the alias type - Type* type() const { return const_cast(subtype_); } - - /// @returns the type_name for this 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: - Symbol const symbol_; - Type const* const subtype_; - std::string const type_name_; -}; - -} // namespace sem -} // namespace tint - -#endif // SRC_SEM_ALIAS_TYPE_H_ diff --git a/src/sem/alias_type_test.cc b/src/sem/alias_type_test.cc deleted file mode 100644 index ed8d6113be..0000000000 --- a/src/sem/alias_type_test.cc +++ /dev/null @@ -1,162 +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/access_control_type.h" -#include "src/sem/test_helper.h" -#include "src/sem/texture_type.h" - -namespace tint { -namespace sem { -namespace { - -using AliasTest = TestHelper; - -TEST_F(AliasTest, Create) { - auto* a = create(Sym("a_type"), ty.u32()); - EXPECT_EQ(a->symbol(), Symbol(1, ID())); - EXPECT_EQ(a->type(), ty.u32()); -} - -TEST_F(AliasTest, Is) { - auto* at = create(Sym("a"), ty.i32()); - sem::Type* ty = at; - 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()); - EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); -} - -// Check for linear-time evaluation of Alias::type_name(). -// If type_name() is non-linear, this test should noticeably stall. -// See: crbug.com/1200936 -TEST_F(AliasTest, TypeName_LinearTime) { - Type* type = ty.i32(); - for (int i = 0; i < 1024; i++) { - type = create(Symbols().New(), type); - } - for (int i = 0; i < 16384; i++) { - type->type_name(); - } -} - -TEST_F(AliasTest, TypeName) { - auto* at = create(Sym("Particle"), ty.i32()); - EXPECT_EQ(at->type_name(), "__alias_$1__i32"); -} - -TEST_F(AliasTest, FriendlyName) { - auto* at = create(Sym("Particle"), ty.i32()); - EXPECT_EQ(at->FriendlyName(Symbols()), "Particle"); -} - -TEST_F(AliasTest, UnwrapIfNeeded_Alias) { - auto* a = create(Sym("a_type"), ty.u32()); - EXPECT_EQ(a->symbol(), Symbol(1, ID())); - EXPECT_EQ(a->type(), ty.u32()); - EXPECT_EQ(a->UnwrapIfNeeded(), ty.u32()); - EXPECT_EQ(ty.u32()->UnwrapIfNeeded(), ty.u32()); -} - -TEST_F(AliasTest, UnwrapIfNeeded_AccessControl) { - auto* a = create(ast::AccessControl::kReadOnly, ty.u32()); - EXPECT_EQ(a->type(), ty.u32()); - EXPECT_EQ(a->UnwrapIfNeeded(), ty.u32()); -} - -TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel) { - auto* a = create(Sym("a_type"), ty.u32()); - auto* aa = create(Sym("aa_type"), a); - - EXPECT_EQ(aa->symbol(), Symbol(2, ID())); - EXPECT_EQ(aa->type(), a); - EXPECT_EQ(aa->UnwrapIfNeeded(), ty.u32()); -} - -TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel_AliasAccessControl) { - auto* a = create(Sym("a_type"), ty.u32()); - auto* aa = create(ast::AccessControl::kReadWrite, a); - EXPECT_EQ(aa->type(), a); - EXPECT_EQ(aa->UnwrapIfNeeded(), ty.u32()); -} - -TEST_F(AliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) { - auto* u32 = create(); - auto* a = create(Sym(Sym("a_type")), u32); - auto* aa = create(Sym("aa_type"), a); - auto* paa = create(aa, ast::StorageClass::kUniform); - auto* apaa = create(Sym("paa_type"), paa); - auto* aapaa = create(Sym("aapaa_type"), apaa); - - EXPECT_EQ(aapaa->symbol(), Symbol(4, ID())); - EXPECT_EQ(aapaa->type(), apaa); - EXPECT_EQ(aapaa->UnwrapAll(), ty.u32()); -} - -TEST_F(AliasTest, UnwrapAll_SecondConsecutivePointerBlocksUnrapping) { - auto* a = create(Sym("a_type"), ty.u32()); - auto* aa = create(Sym("aa_type"), a); - - auto* paa = create(aa, ast::StorageClass::kUniform); - auto* ppaa = create(paa, ast::StorageClass::kUniform); - auto* appaa = create(Sym("appaa_type"), ppaa); - EXPECT_EQ(appaa->UnwrapAll(), paa); -} - -TEST_F(AliasTest, UnwrapAll_SecondNonConsecutivePointerBlocksUnrapping) { - auto* a = create(Sym("a_type"), ty.u32()); - auto* aa = create(Sym("aa_type"), a); - auto* paa = create(aa, ast::StorageClass::kUniform); - - auto* apaa = create(Sym("apaa_type"), paa); - auto* aapaa = create(Sym("aapaa_type"), apaa); - auto* paapaa = create(aapaa, ast::StorageClass::kUniform); - auto* apaapaa = create(Sym("apaapaa_type"), paapaa); - - EXPECT_EQ(apaapaa->UnwrapAll(), paa); -} - -TEST_F(AliasTest, UnwrapAll_AccessControlPointer) { - auto* a = create(ast::AccessControl::kReadOnly, ty.u32()); - auto* pa = create(a, ast::StorageClass::kUniform); - EXPECT_EQ(pa->type(), a); - EXPECT_EQ(pa->UnwrapAll(), ty.u32()); -} - -TEST_F(AliasTest, UnwrapAll_PointerAccessControl) { - auto* p = create(ty.u32(), ast::StorageClass::kUniform); - auto* a = create(ast::AccessControl::kReadOnly, p); - - EXPECT_EQ(a->type(), p); - EXPECT_EQ(a->UnwrapAll(), ty.u32()); -} - -TEST_F(AliasTest, UnwrapAliasIfNeeded) { - auto* alias1 = create(Sym("alias1"), ty.f32()); - auto* alias2 = create(Sym("alias2"), alias1); - auto* alias3 = create(Sym("alias3"), alias2); - EXPECT_EQ(alias3->UnwrapAliasIfNeeded(), ty.f32()); -} - -} // namespace -} // namespace sem -} // namespace tint diff --git a/src/sem/bool_type_test.cc b/src/sem/bool_type_test.cc index 51d6ef0530..96dbdda209 100644 --- a/src/sem/bool_type_test.cc +++ b/src/sem/bool_type_test.cc @@ -26,7 +26,6 @@ TEST_F(BoolTest, Is) { Bool b; Type* ty = &b; 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/depth_texture_type_test.cc b/src/sem/depth_texture_type_test.cc index e51ebfcc31..fe6131dbec 100644 --- a/src/sem/depth_texture_type_test.cc +++ b/src/sem/depth_texture_type_test.cc @@ -31,7 +31,6 @@ TEST_F(DepthTextureTest, Is) { DepthTexture d(ast::TextureDimension::kCube); Type* ty = &d; 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/external_texture_type_test.cc b/src/sem/external_texture_type_test.cc index 3e48ea8b6b..d44cf5831e 100644 --- a/src/sem/external_texture_type_test.cc +++ b/src/sem/external_texture_type_test.cc @@ -32,7 +32,6 @@ TEST_F(ExternalTextureTest, Is) { ExternalTexture s; Type* ty = &s; 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/f32_type_test.cc b/src/sem/f32_type_test.cc index 670d83170e..cb1cd2e289 100644 --- a/src/sem/f32_type_test.cc +++ b/src/sem/f32_type_test.cc @@ -26,7 +26,6 @@ TEST_F(F32Test, Is) { F32 f; Type* ty = &f; EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_TRUE(ty->Is()); diff --git a/src/sem/i32_type_test.cc b/src/sem/i32_type_test.cc index 437aa169f4..34ddf9b0dc 100644 --- a/src/sem/i32_type_test.cc +++ b/src/sem/i32_type_test.cc @@ -26,7 +26,6 @@ TEST_F(I32Test, Is) { I32 i; Type* ty = &i; 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 dbcb898cdf..c1b071ad6d 100644 --- a/src/sem/matrix_type_test.cc +++ b/src/sem/matrix_type_test.cc @@ -37,7 +37,6 @@ TEST_F(MatrixTest, Is) { Matrix m{&c, 4}; Type* ty = &m; 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 d202970202..bd4d1beb8e 100644 --- a/src/sem/multisampled_texture_type_test.cc +++ b/src/sem/multisampled_texture_type_test.cc @@ -32,7 +32,6 @@ TEST_F(MultisampledTextureTest, Is) { MultisampledTexture s(ast::TextureDimension::kCube, &f32); Type* ty = &s; 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/pointer_type_test.cc b/src/sem/pointer_type_test.cc index e9f0893d67..8c331f9c2a 100644 --- a/src/sem/pointer_type_test.cc +++ b/src/sem/pointer_type_test.cc @@ -34,7 +34,6 @@ TEST_F(PointerTest, Is) { Pointer p{&i32, ast::StorageClass::kFunction}; Type* ty = &p; 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 85b8e2b8fa..92bfcf47b3 100644 --- a/src/sem/sampled_texture_type_test.cc +++ b/src/sem/sampled_texture_type_test.cc @@ -31,7 +31,6 @@ TEST_F(SampledTextureTest, Is) { SampledTexture s(ast::TextureDimension::kCube, &f32); Type* ty = &s; 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/sampler_type_test.cc b/src/sem/sampler_type_test.cc index 9ee25d3a18..fece8da32e 100644 --- a/src/sem/sampler_type_test.cc +++ b/src/sem/sampler_type_test.cc @@ -37,7 +37,6 @@ TEST_F(SamplerTest, Is) { Sampler s{ast::SamplerKind::kSampler}; Type* ty = &s; 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/sem_array_test.cc b/src/sem/sem_array_test.cc index 9620af937a..05ac10a306 100644 --- a/src/sem/sem_array_test.cc +++ b/src/sem/sem_array_test.cc @@ -51,7 +51,6 @@ TEST_F(ArrayTest, Is) { Type* ty = create(&i32, 2, 4, 8, 4, true); 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/sem_struct_test.cc b/src/sem/sem_struct_test.cc index 88309fac5a..e6aa671cc3 100644 --- a/src/sem/sem_struct_test.cc +++ b/src/sem/sem_struct_test.cc @@ -44,7 +44,6 @@ TEST_F(StructTest, Is) { 4 /* size */, 4 /* size_no_padding */); sem::Type* ty = s; 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/storage_texture_type_test.cc b/src/sem/storage_texture_type_test.cc index 3fef3ef66a..fc7e8b86a4 100644 --- a/src/sem/storage_texture_type_test.cc +++ b/src/sem/storage_texture_type_test.cc @@ -33,7 +33,6 @@ TEST_F(StorageTextureTest, Is) { ast::ImageFormat::kRgba32Float, subtype); Type* ty = s; 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/type.cc b/src/sem/type.cc index 349506c79f..e730e726f2 100644 --- a/src/sem/type.cc +++ b/src/sem/type.cc @@ -15,7 +15,6 @@ #include "src/sem/type.h" #include "src/sem/access_control_type.h" -#include "src/sem/alias_type.h" #include "src/sem/bool_type.h" #include "src/sem/f32_type.h" #include "src/sem/i32_type.h" @@ -38,36 +37,34 @@ Type::Type(Type&&) = default; Type::~Type() = default; const Type* Type::UnwrapPtrIfNeeded() const { - if (auto* ptr = As()) { - return ptr->type(); + auto* type = this; + while (auto* ptr = type->As()) { + type = ptr->type(); } - return this; -} - -const Type* Type::UnwrapAliasIfNeeded() const { - const Type* unwrapped = this; - while (auto* ptr = unwrapped->As()) { - unwrapped = ptr->type(); - } - return unwrapped; + return type; } const Type* Type::UnwrapIfNeeded() const { - auto* where = this; - while (true) { - if (auto* alias = where->As()) { - where = alias->type(); - } else if (auto* access = where->As()) { - where = access->type(); - } else { - break; - } + auto* type = this; + while (auto* access = type->As()) { + type = access->type(); } - return where; + return type; } const Type* Type::UnwrapAll() const { - return UnwrapIfNeeded()->UnwrapPtrIfNeeded()->UnwrapIfNeeded(); + auto* type = this; + while (true) { + if (auto* ptr = type->As()) { + type = ptr->type(); + continue; + } + if (auto* access = type->As()) { + type = access->type(); + continue; + } + return type; + } } bool Type::is_scalar() const { diff --git a/src/sem/type.h b/src/sem/type.h index 45de49caf5..f4a7835315 100644 --- a/src/sem/type.h +++ b/src/sem/type.h @@ -48,11 +48,7 @@ class Type : public Castable { /// @returns the pointee type if this is a pointer, `this` otherwise const Type* UnwrapPtrIfNeeded() const; - /// @returns the most deeply nested aliased type if this is an alias, `this` - /// otherwise - const Type* UnwrapAliasIfNeeded() const; - - /// Removes all levels of aliasing and access control. + /// Removes all levels of access control. /// This is just enough to assist with WGSL translation /// in that you want see through one level of pointer to get from an /// identifier-like expression as an l-value to its corresponding r-value, @@ -60,10 +56,8 @@ class Type : public Castable { /// @returns the completely unaliased type. const Type* UnwrapIfNeeded() const; - /// Returns the type found after: - /// - removing all layers of aliasing and access control if they exist, then - /// - removing the pointer, if it exists, then - /// - removing all further layers of aliasing or access control, if they exist + /// Returns the type found after removing all layers of access control and + /// pointer. /// @returns the unwrapped type const Type* UnwrapAll() const; diff --git a/src/sem/u32_type_test.cc b/src/sem/u32_type_test.cc index 00d04284ee..07866e37f1 100644 --- a/src/sem/u32_type_test.cc +++ b/src/sem/u32_type_test.cc @@ -26,7 +26,6 @@ TEST_F(U32Test, Is) { U32 u; Type* ty = &u; 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/vector_type_test.cc b/src/sem/vector_type_test.cc index 78b1e09b62..81fec62a49 100644 --- a/src/sem/vector_type_test.cc +++ b/src/sem/vector_type_test.cc @@ -34,7 +34,6 @@ TEST_F(VectorTest, Is) { Vector v{&i32, 4}; Type* ty = &v; EXPECT_FALSE(ty->Is()); - EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); EXPECT_FALSE(ty->Is()); diff --git a/src/transform/canonicalize_entry_point_io.cc b/src/transform/canonicalize_entry_point_io.cc index 3b0c59d1ea..281078197e 100644 --- a/src/transform/canonicalize_entry_point_io.cc +++ b/src/transform/canonicalize_entry_point_io.cc @@ -194,7 +194,7 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) { } // Handle return type. - auto* ret_type = func->ReturnType()->UnwrapAliasIfNeeded(); + auto* ret_type = func->ReturnType(); std::function new_ret_type; if (ret_type->Is()) { new_ret_type = [&ctx] { return ctx.dst->ty.void_(); }; diff --git a/src/transform/decompose_storage_access.cc b/src/transform/decompose_storage_access.cc index 9d51bbbe10..cc1c4a2d5f 100644 --- a/src/transform/decompose_storage_access.cc +++ b/src/transform/decompose_storage_access.cc @@ -349,11 +349,6 @@ const ast::NamedType* ConstructedTypeOf(const sem::Type* ty) { } } -/// @returns the given type with all pointers and aliases removed. -const sem::Type* UnwrapPtrAndAlias(const sem::Type* ty) { - return ty->UnwrapPtrIfNeeded()->UnwrapAliasIfNeeded()->UnwrapPtrIfNeeded(); -} - /// StorageBufferAccess describes a single storage buffer access struct StorageBufferAccess { sem::Expression const* var = nullptr; // Storage buffer variable @@ -751,7 +746,7 @@ Output DecomposeStorageAccess::Run(const Program* in, const DataMap&) { auto* buf = access.var->Declaration(); auto* offset = access.offset->Build(ctx); - auto* buf_ty = UnwrapPtrAndAlias(access.var->Type()); + auto* buf_ty = access.var->Type()->UnwrapPtrIfNeeded(); auto* el_ty = access.type->UnwrapAll(); auto* insert_after = ConstructedTypeOf(access.var->Type()); Symbol func = state.LoadFunc(ctx, insert_after, buf_ty, el_ty); @@ -765,7 +760,7 @@ Output DecomposeStorageAccess::Run(const Program* in, const DataMap&) { for (auto& store : state.stores) { auto* buf = store.target.var->Declaration(); auto* offset = store.target.offset->Build(ctx); - auto* buf_ty = UnwrapPtrAndAlias(store.target.var->Type()); + auto* buf_ty = store.target.var->Type()->UnwrapPtrIfNeeded(); auto* el_ty = store.target.type->UnwrapAll(); auto* value = store.assignment->rhs(); auto* insert_after = ConstructedTypeOf(store.target.var->Type()); diff --git a/src/transform/transform.cc b/src/transform/transform.cc index 804566dfc5..b82a70681a 100644 --- a/src/transform/transform.cc +++ b/src/transform/transform.cc @@ -107,9 +107,6 @@ ast::Type* Transform::CreateASTTypeFor(CloneContext* ctx, const sem::Type* ty) { auto* el = CreateASTTypeFor(ctx, ac->type()); return ctx->dst->create(ac->access_control(), el); } - 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->Declaration()->name())); diff --git a/src/typepair.h b/src/typepair.h index 2e6d679a35..bc3e98bce3 100644 --- a/src/typepair.h +++ b/src/typepair.h @@ -33,7 +33,6 @@ namespace tint { namespace ast { class AccessControl; -class Alias; class Array; class Bool; class DepthTexture; @@ -56,7 +55,6 @@ class Void; namespace sem { class AccessControl; -class Alias; class Array; class Bool; class DepthTexture; @@ -240,7 +238,6 @@ bool operator!=(std::nullptr_t, const TypePair& rhs) { using Type = TypePair; using AccessControl = TypePair; -using Alias = TypePair; using Array = TypePair; using Bool = TypePair; using DepthTexture = TypePair; diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index 1fb4c42e34..a98e6e585a 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc @@ -207,23 +207,7 @@ bool GeneratorImpl::EmitConstructedType(std::ostream& out, const sem::Type* ty) { make_indent(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 (!EmitStructType(out, str, - builder_.Symbols().NameFor(alias->symbol()))) { - return false; - } - return true; - } - out << "typedef "; - if (!EmitType(out, alias->type(), ast::StorageClass::kNone, "")) { - return false; - } - out << " " << builder_.Symbols().NameFor(alias->symbol()) << ";" - << std::endl; - } else if (auto* str = ty->As()) { + if (auto* str = ty->As()) { if (!EmitStructType( out, str, builder_.Symbols().NameFor(str->Declaration()->name()))) { return false; @@ -1324,8 +1308,7 @@ bool GeneratorImpl::EmitTypeConstructor(std::ostream& pre, return EmitZeroValue(out, type); } - bool brackets = - type->UnwrapAliasIfNeeded()->IsAnyOf(); + bool brackets = type->IsAnyOf(); if (brackets) { out << "{"; @@ -1918,7 +1901,7 @@ bool GeneratorImpl::EmitEntryPointData( if (!EmitType(out, var->Type(), var->StorageClass(), name)) { return false; } - if (!var->Type()->UnwrapAliasIfNeeded()->Is()) { + if (!var->Type()->Is()) { out << " " << name; } @@ -2404,9 +2387,7 @@ bool GeneratorImpl::EmitType(std::ostream& out, return true; } - if (auto* alias = type->As()) { - out << builder_.Symbols().NameFor(alias->symbol()); - } else if (auto* ary = type->As()) { + if (auto* ary = type->As()) { const sem::Type* base_type = ary; std::vector sizes; while (auto* arr = base_type->As()) { diff --git a/src/writer/hlsl/generator_impl_type_test.cc b/src/writer/hlsl/generator_impl_type_test.cc index 9015afe835..0905be086a 100644 --- a/src/writer/hlsl/generator_impl_type_test.cc +++ b/src/writer/hlsl/generator_impl_type_test.cc @@ -32,16 +32,6 @@ using ::testing::HasSubstr; using HlslGeneratorImplTest_Type = TestHelper; -TEST_F(HlslGeneratorImplTest_Type, EmitType_Alias) { - auto alias = ty.alias("alias", ty.f32()); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.EmitType(out, alias, ast::StorageClass::kNone, "")) - << gen.error(); - EXPECT_EQ(result(), "alias"); -} - TEST_F(HlslGeneratorImplTest_Type, EmitType_Array) { auto* arr = ty.array(); Global("G", arr, ast::StorageClass::kPrivate); diff --git a/src/writer/hlsl/generator_impl_workgroup_var_test.cc b/src/writer/hlsl/generator_impl_workgroup_var_test.cc index 525adbe0ca..a488f100b3 100644 --- a/src/writer/hlsl/generator_impl_workgroup_var_test.cc +++ b/src/writer/hlsl/generator_impl_workgroup_var_test.cc @@ -39,7 +39,7 @@ TEST_F(HlslGeneratorImplTest_WorkgroupVar, Basic) { } TEST_F(HlslGeneratorImplTest_WorkgroupVar, Aliased) { - auto alias = ty.alias("F32", ty.f32()); + auto* alias = ty.alias("F32", ty.f32()); AST().AddConstructedType(alias); Global("wg", alias, ast::StorageClass::kWorkgroup); diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc index 15d3946ced..ffc6c12819 100644 --- a/src/writer/msl/generator_impl.cc +++ b/src/writer/msl/generator_impl.cc @@ -31,7 +31,6 @@ #include "src/ast/variable_decl_statement.h" #include "src/ast/void.h" #include "src/sem/access_control_type.h" -#include "src/sem/alias_type.h" #include "src/sem/array.h" #include "src/sem/bool_type.h" #include "src/sem/call.h" @@ -151,14 +150,7 @@ bool GeneratorImpl::Generate() { bool GeneratorImpl::EmitConstructedType(const sem::Type* ty) { make_indent(); - if (auto* alias = ty->As()) { - out_ << "typedef "; - if (!EmitType(alias->type(), "")) { - return false; - } - out_ << " " << program_->Symbols().NameFor(alias->symbol()) << ";" - << std::endl; - } else if (auto* str = ty->As()) { + if (auto* str = ty->As()) { if (!EmitStructType(str)) { return false; } @@ -186,7 +178,7 @@ bool GeneratorImpl::EmitArrayAccessor(ast::ArrayAccessorExpression* expr) { bool GeneratorImpl::EmitBitcast(ast::BitcastExpression* expr) { out_ << "as_type<"; - if (!EmitType(expr->type(), "")) { + if (!EmitType(TypeOf(expr), "")) { return false; } @@ -1224,7 +1216,7 @@ bool GeneratorImpl::EmitFunctionInternal(ast::Function* func, auto* func_sem = program_->Sem().Get(func); auto name = func->symbol().to_str(); - if (!EmitType(func->return_type(), "")) { + if (!EmitType(func_sem->ReturnType(), "")) { return false; } @@ -1899,11 +1891,7 @@ bool GeneratorImpl::EmitSwitch(ast::SwitchStatement* stmt) { return true; } -bool GeneratorImpl::EmitType(typ::Type type, const std::string& name) { - if (!type.sem) { - type.sem = program_->Sem().Get(type.ast); - } - +bool GeneratorImpl::EmitType(const sem::Type* type, const std::string& name) { std::string access_str = ""; if (auto* ac = type->As()) { if (ac->access_control() == ast::AccessControl::kReadOnly) { @@ -1918,9 +1906,7 @@ bool GeneratorImpl::EmitType(typ::Type type, const std::string& name) { type = ac->type(); } - if (auto* alias = type->As()) { - out_ << program_->Symbols().NameFor(alias->symbol()); - } else if (auto* ary = type->As()) { + if (auto* ary = type->As()) { const sem::Type* base_type = ary; std::vector sizes; while (auto* arr = base_type->As()) { @@ -2037,15 +2023,8 @@ bool GeneratorImpl::EmitType(typ::Type type, const std::string& name) { return true; } -bool GeneratorImpl::EmitPackedType(typ::Type type, const std::string& name) { - if (!type.sem) { - type.sem = program_->Sem().Get(type.ast); - } - - if (auto* alias = type->As()) { - return EmitPackedType(alias->type(), name); - } - +bool GeneratorImpl::EmitPackedType(const sem::Type* type, + const std::string& name) { if (auto* vec = type->As()) { out_ << "packed_"; if (!EmitType(vec->type(), "")) { @@ -2121,7 +2100,7 @@ bool GeneratorImpl::EmitStructType(const sem::Struct* str) { } } - auto* ty = mem->Type()->UnwrapAliasIfNeeded(); + auto* ty = mem->Type(); // Array member name will be output with the type if (!ty->Is()) { @@ -2287,8 +2266,6 @@ bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) { GeneratorImpl::SizeAndAlign GeneratorImpl::MslPackedTypeSizeAndAlign( const sem::Type* ty) { - ty = ty->UnwrapAliasIfNeeded(); - if (ty->IsAnyOf()) { // https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf // 2.1 Scalar Data Types diff --git a/src/writer/msl/generator_impl.h b/src/writer/msl/generator_impl.h index b4fa982d9a..f701dc274e 100644 --- a/src/writer/msl/generator_impl.h +++ b/src/writer/msl/generator_impl.h @@ -195,14 +195,14 @@ class GeneratorImpl : public TextGenerator { /// @param type the type to generate /// @param name the name of the variable, only used for array emission /// @returns true if the type is emitted - bool EmitType(typ::Type type, const std::string& name); + bool EmitType(const sem::Type* type, const std::string& name); /// Handles generating an MSL-packed storage type. /// If the type does not have a packed form, the standard non-packed form is /// emitted. /// @param type the type to generate /// @param name the name of the variable, only used for array emission /// @returns true if the type is emitted - bool EmitPackedType(typ::Type type, const std::string& name); + bool EmitPackedType(const sem::Type* type, const std::string& name); /// Handles generating a struct declaration /// @param str the struct to generate /// @returns true if the struct is emitted diff --git a/src/writer/msl/generator_impl_type_test.cc b/src/writer/msl/generator_impl_type_test.cc index fd35026ec0..a726ff7b76 100644 --- a/src/writer/msl/generator_impl_type_test.cc +++ b/src/writer/msl/generator_impl_type_test.cc @@ -57,15 +57,6 @@ using uint = unsigned int; using MslGeneratorImplTest = TestHelper; -TEST_F(MslGeneratorImplTest, EmitType_Alias) { - auto alias = ty.alias("alias", ty.f32()); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.EmitType(alias, "")) << gen.error(); - EXPECT_EQ(gen.result(), "alias"); -} - TEST_F(MslGeneratorImplTest, EmitType_Array) { auto* arr = ty.array(); Global("G", arr, ast::StorageClass::kPrivate); @@ -186,7 +177,7 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct) { GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitType(s, "")) << gen.error(); + ASSERT_TRUE(gen.EmitType(program->TypeOf(s), "")) << gen.error(); EXPECT_EQ(gen.result(), "S"); } @@ -607,7 +598,7 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) { GeneratorImpl& gen = Build(); - ASSERT_TRUE(gen.EmitType(s, "")) << gen.error(); + ASSERT_TRUE(gen.EmitType(program->TypeOf(s), "")) << gen.error(); EXPECT_EQ(gen.result(), R"(struct { /* 0x0000 */ int a; /* 0x0004 */ float b; diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 935387dcab..570d131f51 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -2930,10 +2930,6 @@ uint32_t Builder::GenerateTypeIfNeeded(const sem::Type* type) { return 0; } - // The alias is a wrapper around the subtype, so emit the subtype - if (auto* alias = type->As()) { - return GenerateTypeIfNeeded(alias->type()); - } if (auto* ac = type->As()) { if (!ac->type()->UnwrapIfNeeded()->Is()) { return GenerateTypeIfNeeded(ac->type()); diff --git a/src/writer/spirv/builder_accessor_expression_test.cc b/src/writer/spirv/builder_accessor_expression_test.cc index 00919e0018..2c5303b523 100644 --- a/src/writer/spirv/builder_accessor_expression_test.cc +++ b/src/writer/spirv/builder_accessor_expression_test.cc @@ -393,7 +393,7 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) { Member("b", ty.f32()), }); - auto alias = ty.alias("Inner", inner_struct); + auto* alias = ty.alias("Inner", inner_struct); auto* s_type = Structure("Outer", {Member("inner", alias)}); auto* var = Global("ident", s_type, ast::StorageClass::kFunction); diff --git a/src/writer/spirv/builder_constructor_expression_test.cc b/src/writer/spirv/builder_constructor_expression_test.cc index 1e735356f7..3b69501fce 100644 --- a/src/writer/spirv/builder_constructor_expression_test.cc +++ b/src/writer/spirv/builder_constructor_expression_test.cc @@ -93,7 +93,7 @@ TEST_F(SpvBuilderConstructorTest, Type_WithAlias) { // type Int = i32 // cast(2.3f) - auto alias = ty.alias("Int", ty.i32()); + auto* alias = ty.alias("Int", ty.i32()); AST().AddConstructedType(alias); auto* cast = Construct(alias, 2.3f); WrapInFunction(cast); diff --git a/src/writer/spirv/builder_global_variable_test.cc b/src/writer/spirv/builder_global_variable_test.cc index 7b77349296..dadc9b40be 100644 --- a/src/writer/spirv/builder_global_variable_test.cc +++ b/src/writer/spirv/builder_global_variable_test.cc @@ -417,7 +417,7 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasDeclReadOnly) { auto* A = Structure("A", {Member("a", ty.i32())}, {create()}); - auto B = ty.alias("B", A); + auto* B = ty.alias("B", A); AST().AddConstructedType(B); auto ac = ty.access(ast::AccessControl::kReadOnly, B); auto* var = Global("b", ac, ast::StorageClass::kStorage); @@ -451,7 +451,7 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasAssignReadOnly) { auto* A = Structure("A", {Member("a", ty.i32())}, {create()}); auto ac = ty.access(ast::AccessControl::kReadOnly, A); - auto B = ty.alias("B", ac); + auto* B = ty.alias("B", ac); AST().AddConstructedType(B); auto* var = Global("b", B, ast::StorageClass::kStorage); diff --git a/src/writer/spirv/builder_type_test.cc b/src/writer/spirv/builder_type_test.cc index 3de7d994d2..bf158d9b4e 100644 --- a/src/writer/spirv/builder_type_test.cc +++ b/src/writer/spirv/builder_type_test.cc @@ -26,37 +26,6 @@ namespace { using BuilderTest_Type = TestHelper; -TEST_F(BuilderTest_Type, GenerateAlias) { - auto alias_type = ty.alias("my_type", ty.f32()); - - spirv::Builder& b = Build(); - - auto id = b.GenerateTypeIfNeeded(alias_type); - ASSERT_FALSE(b.has_error()) << b.error(); - EXPECT_EQ(id, 1u); - - EXPECT_EQ(b.types().size(), 1u); - EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32 -)"); -} - -TEST_F(BuilderTest_Type, ReturnsGeneratedAlias) { - auto i32 = ty.i32(); - auto f32 = ty.f32(); - auto alias_type = ty.alias("my_type", f32); - - spirv::Builder& b = Build(); - - EXPECT_EQ(b.GenerateTypeIfNeeded(alias_type), 1u); - ASSERT_FALSE(b.has_error()) << b.error(); - EXPECT_EQ(b.GenerateTypeIfNeeded(i32), 2u); - ASSERT_FALSE(b.has_error()) << b.error(); - EXPECT_EQ(b.GenerateTypeIfNeeded(alias_type), 1u); - ASSERT_FALSE(b.has_error()) << b.error(); - EXPECT_EQ(b.GenerateTypeIfNeeded(f32), 1u); - ASSERT_FALSE(b.has_error()) << b.error(); -} - TEST_F(BuilderTest_Type, GenerateRuntimeArray) { auto* ary = ty.array(ty.i32(), 0); auto* str = Structure("S", {Member("x", ary)}, diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc index 2030f7bfa7..b337f95f40 100644 --- a/src/writer/wgsl/generator_impl.cc +++ b/src/writer/wgsl/generator_impl.cc @@ -48,7 +48,6 @@ #include "src/ast/void.h" #include "src/ast/workgroup_decoration.h" #include "src/sem/access_control_type.h" -#include "src/sem/alias_type.h" #include "src/sem/array.h" #include "src/sem/bool_type.h" #include "src/sem/depth_texture_type.h" diff --git a/src/writer/wgsl/generator_impl_alias_type_test.cc b/src/writer/wgsl/generator_impl_alias_type_test.cc index 2735aa044e..a1ecefa400 100644 --- a/src/writer/wgsl/generator_impl_alias_type_test.cc +++ b/src/writer/wgsl/generator_impl_alias_type_test.cc @@ -22,7 +22,7 @@ namespace { using WgslGeneratorImplTest = TestHelper; TEST_F(WgslGeneratorImplTest, EmitAlias_F32) { - auto alias = ty.alias("a", ty.f32()); + auto* alias = ty.alias("a", ty.f32()); GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error(); @@ -36,7 +36,7 @@ TEST_F(WgslGeneratorImplTest, EmitConstructedType_Struct) { Member("b", ty.i32()), }); - auto alias = ty.alias("B", s); + auto* alias = ty.alias("B", s); GeneratorImpl& gen = Build(); @@ -56,7 +56,7 @@ TEST_F(WgslGeneratorImplTest, EmitAlias_ToStruct) { Member("b", ty.i32()), }); - auto alias = ty.alias("B", s); + auto* alias = ty.alias("B", s); GeneratorImpl& gen = Build(); diff --git a/src/writer/wgsl/generator_impl_type_test.cc b/src/writer/wgsl/generator_impl_type_test.cc index c311247acd..d4d76911f4 100644 --- a/src/writer/wgsl/generator_impl_type_test.cc +++ b/src/writer/wgsl/generator_impl_type_test.cc @@ -27,7 +27,7 @@ namespace { using WgslGeneratorImplTest = TestHelper; TEST_F(WgslGeneratorImplTest, EmitType_Alias) { - auto alias = ty.alias("alias", ty.f32()); + auto* alias = ty.alias("alias", ty.f32()); AST().AddConstructedType(alias); GeneratorImpl& gen = Build(); diff --git a/test/BUILD.gn b/test/BUILD.gn index b6919972bc..c5cd555dc1 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -269,7 +269,6 @@ tint_unittests_source_set("tint_unittests_core_src") { "../src/resolver/validation_test.cc", "../src/scope_stack_test.cc", "../src/sem/access_control_type_test.cc", - "../src/sem/alias_type_test.cc", "../src/sem/bool_type_test.cc", "../src/sem/depth_texture_type_test.cc", "../src/sem/external_texture_type_test.cc",