Add type alias unwrapping methods

Change-Id: I8dbd3bba48ae95d76f75a5eba3e97ed4e091ed01
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/23580
Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
David Neto 2020-06-22 20:30:33 +00:00
parent e87ba1fd37
commit 32a4f957b4
6 changed files with 90 additions and 13 deletions

View File

@ -38,10 +38,7 @@ Expression::~Expression() = default;
void Expression::set_result_type(type::Type* type) {
// The expression result should never be an alias type
while (type->IsAlias()) {
type = type->AsAlias()->type();
}
result_type_ = type;
result_type_ = type->UnwrapAliasesIfNeeded();
}
bool Expression::IsArrayAccessor() const {

View File

@ -15,7 +15,9 @@
#include "src/ast/type/alias_type.h"
#include "gtest/gtest.h"
#include "src/ast/storage_class.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/pointer_type.h"
#include "src/ast/type/u32_type.h"
namespace tint {
@ -54,6 +56,61 @@ TEST_F(AliasTypeTest, TypeName) {
EXPECT_EQ(at.type_name(), "__alias_Particle__i32");
}
TEST_F(AliasTypeTest, UnwrapAliasesIfNeeded) {
U32Type u32;
AliasType a{"a_type", &u32};
EXPECT_EQ(a.name(), "a_type");
EXPECT_EQ(a.type(), &u32);
EXPECT_EQ(a.UnwrapAliasesIfNeeded(), &u32);
EXPECT_EQ(u32.UnwrapAliasesIfNeeded(), &u32);
}
TEST_F(AliasTypeTest, UnwrapAliasesIfNeeded_MultiLevel) {
U32Type u32;
AliasType a{"a_type", &u32};
AliasType aa{"aa_type", &a};
EXPECT_EQ(aa.name(), "aa_type");
EXPECT_EQ(aa.type(), &a);
EXPECT_EQ(aa.UnwrapAliasesIfNeeded(), &u32);
}
TEST_F(AliasTypeTest, UnwrapAliasPtrAlias_TwiceAliasPointerTwiceAlias) {
U32Type u32;
AliasType a{"a_type", &u32};
AliasType aa{"aa_type", &a};
PointerType paa{&aa, StorageClass::kUniform};
AliasType apaa{"paa_type", &paa};
AliasType aapaa{"aapaa_type", &apaa};
EXPECT_EQ(aapaa.name(), "aapaa_type");
EXPECT_EQ(aapaa.type(), &apaa);
EXPECT_EQ(aapaa.UnwrapAliasPtrAlias(), &u32);
EXPECT_EQ(u32.UnwrapAliasPtrAlias(), &u32);
}
TEST_F(AliasTypeTest,
UnwrapAliasPtrAlias_SecondConsecutivePointerBlocksWUnrapping) {
U32Type u32;
AliasType a{"a_type", &u32};
AliasType aa{"aa_type", &a};
PointerType paa{&aa, StorageClass::kUniform};
PointerType ppaa{&paa, StorageClass::kUniform};
AliasType appaa{"appaa_type", &ppaa};
EXPECT_EQ(appaa.UnwrapAliasPtrAlias(), &paa);
}
TEST_F(AliasTypeTest,
UnwrapAliasPtrAlias_SecondNonConsecutivePointerBlocksWUnrapping) {
U32Type u32;
AliasType a{"a_type", &u32};
AliasType aa{"aa_type", &a};
PointerType paa{&aa, StorageClass::kUniform};
AliasType apaa{"apaa_type", &paa};
AliasType aapaa{"aapaa_type", &apaa};
PointerType paapaa{&aapaa, StorageClass::kUniform};
AliasType apaapaa{"apaapaa_type", &paapaa};
EXPECT_EQ(apaapaa.UnwrapAliasPtrAlias(), &paa);
}
} // namespace
} // namespace type
} // namespace ast

View File

@ -43,6 +43,18 @@ Type* Type::UnwrapPtrIfNeeded() {
return this;
}
Type* Type::UnwrapAliasesIfNeeded() {
auto* where = this;
while (where->IsAlias()) {
where = where->AsAlias()->type();
}
return where;
}
Type* Type::UnwrapAliasPtrAlias() {
return UnwrapAliasesIfNeeded()->UnwrapPtrIfNeeded()->UnwrapAliasesIfNeeded();
}
bool Type::IsAlias() const {
return false;
}

View File

@ -69,6 +69,21 @@ class Type {
/// @returns the pointee type if this is a pointer, |this| otherwise
Type* UnwrapPtrIfNeeded();
/// Removes all levels of aliasing, if this is an alias type. Otherwise
/// returns |this|. 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,
/// plus see through the aliases on either side.
/// @returns the completely unaliased type.
Type* UnwrapAliasesIfNeeded();
/// Returns the type found after:
/// - removing all layers of aliasing if they exist, then
/// - removing the pointer, if it exists, then
/// - removing all further layers of aliasing, if they exist
/// @returns the unwrapped type
Type* UnwrapAliasPtrAlias();
/// @returns true if this type is a float scalar
bool is_float_scalar();
/// @returns true if this type is a float matrix

View File

@ -586,11 +586,7 @@ bool TypeDeterminer::DetermineMemberAccessor(
}
auto* res = expr->structure()->result_type();
auto* data_type = res->UnwrapPtrIfNeeded();
while (data_type->IsAlias()) {
data_type = data_type->AsAlias()->type();
}
auto* data_type = res->UnwrapPtrIfNeeded()->UnwrapAliasesIfNeeded();
ast::type::Type* ret = nullptr;
if (data_type->IsStruct()) {

View File

@ -642,10 +642,10 @@ bool Builder::GenerateArrayAccessor(ast::ArrayAccessorExpression* expr,
bool Builder::GenerateMemberAccessor(ast::MemberAccessorExpression* expr,
AccessorInfo* info) {
auto* data_type = expr->structure()->result_type()->UnwrapPtrIfNeeded();
while (data_type->IsAlias()) {
data_type = data_type->AsAlias()->type();
}
auto* data_type = expr->structure()
->result_type()
->UnwrapPtrIfNeeded()
->UnwrapAliasesIfNeeded();
// If the data_type is a structure we're accessing a member, if it's a
// vector we're accessing a swizzle.