diff --git a/src/intrinsic_table.cc b/src/intrinsic_table.cc index 74c22426a9..f43d6e9e2d 100644 --- a/src/intrinsic_table.cc +++ b/src/intrinsic_table.cc @@ -96,10 +96,7 @@ class Matcher { /// 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, type::Type* argument_type) const { - auto* unwrapped = argument_type; - while (auto* alias = unwrapped->As()) { - unwrapped = alias->type(); - } + auto* unwrapped = argument_type->UnwrapAliasIfNeeded(); return MatchUnwrapped(state, unwrapped); } diff --git a/src/type/alias_type_test.cc b/src/type/alias_type_test.cc index d39b2014f7..470f390f69 100644 --- a/src/type/alias_type_test.cc +++ b/src/type/alias_type_test.cc @@ -225,6 +225,13 @@ TEST_F(AliasTest, BaseAlignmentStruct) { EXPECT_EQ(4u, alias->BaseAlignment(MemoryLayout::kStorageBuffer)); } +TEST_F(AliasTest, UnwrapAliasIfNeeded) { + auto* alias1 = ty.alias("alias1", ty.f32()); + auto* alias2 = ty.alias("alias2", alias1); + auto* alias3 = ty.alias("alias3", alias2); + EXPECT_EQ(alias3->UnwrapAliasIfNeeded(), ty.f32()); +} + } // namespace } // namespace type } // namespace tint diff --git a/src/type/type.cc b/src/type/type.cc index 679e4e3d42..2f089a0b7c 100644 --- a/src/type/type.cc +++ b/src/type/type.cc @@ -49,6 +49,14 @@ Type* Type::UnwrapPtrIfNeeded() { return this; } +Type* Type::UnwrapAliasIfNeeded() { + Type* unwrapped = this; + while (auto* ptr = unwrapped->As()) { + unwrapped = ptr->type(); + } + return unwrapped; +} + Type* Type::UnwrapIfNeeded() { auto* where = this; while (true) { diff --git a/src/type/type.h b/src/type/type.h index 7c747c919b..2cb4c21ed8 100644 --- a/src/type/type.h +++ b/src/type/type.h @@ -64,6 +64,10 @@ class Type : public Castable { /// @returns the pointee type if this is a pointer, `this` otherwise Type* UnwrapPtrIfNeeded(); + /// @returns the most deeply nested aliased type if this is an alias, `this` + /// otherwise + Type* UnwrapAliasIfNeeded(); + /// Removes all levels of aliasing and 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