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:
parent
e87ba1fd37
commit
32a4f957b4
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue