Remove sem::Alias

With the parsers now using ast::Types, nothing should be producing these any more.

This change also removes Resolver::Canonical(), which is now unneeded as there are no sem::Aliases to remove.

Bug: tint:724
Change-Id: I0c1a49f49372c1fcc37864502f07c5c76328d471
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50304
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton
2021-05-10 17:38:01 +00:00
committed by Commit Bot service account
parent cbbe576415
commit a34fa0ecb7
63 changed files with 143 additions and 661 deletions

View File

@@ -36,7 +36,6 @@ TEST_F(AccessControlTest, Is) {
AccessControl at{ast::AccessControl::kReadOnly, &i32};
Type* ty = &at;
EXPECT_TRUE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -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

View File

@@ -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 <string>
#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<Alias, Type> {
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<Type*>(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_

View File

@@ -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<Alias>(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<Alias>(Sym("a"), ty.i32());
sem::Type* ty = at;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_TRUE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());
EXPECT_FALSE(ty->Is<I32>());
EXPECT_FALSE(ty->Is<Matrix>());
EXPECT_FALSE(ty->Is<Pointer>());
EXPECT_FALSE(ty->Is<Sampler>());
EXPECT_FALSE(ty->Is<Struct>());
EXPECT_FALSE(ty->Is<Texture>());
EXPECT_FALSE(ty->Is<U32>());
EXPECT_FALSE(ty->Is<Vector>());
}
// 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<Alias>(Symbols().New(), type);
}
for (int i = 0; i < 16384; i++) {
type->type_name();
}
}
TEST_F(AliasTest, TypeName) {
auto* at = create<Alias>(Sym("Particle"), ty.i32());
EXPECT_EQ(at->type_name(), "__alias_$1__i32");
}
TEST_F(AliasTest, FriendlyName) {
auto* at = create<Alias>(Sym("Particle"), ty.i32());
EXPECT_EQ(at->FriendlyName(Symbols()), "Particle");
}
TEST_F(AliasTest, UnwrapIfNeeded_Alias) {
auto* a = create<Alias>(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<AccessControl>(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<Alias>(Sym("a_type"), ty.u32());
auto* aa = create<Alias>(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<Alias>(Sym("a_type"), ty.u32());
auto* aa = create<AccessControl>(ast::AccessControl::kReadWrite, a);
EXPECT_EQ(aa->type(), a);
EXPECT_EQ(aa->UnwrapIfNeeded(), ty.u32());
}
TEST_F(AliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) {
auto* u32 = create<U32>();
auto* a = create<Alias>(Sym(Sym("a_type")), u32);
auto* aa = create<Alias>(Sym("aa_type"), a);
auto* paa = create<Pointer>(aa, ast::StorageClass::kUniform);
auto* apaa = create<Alias>(Sym("paa_type"), paa);
auto* aapaa = create<Alias>(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<Alias>(Sym("a_type"), ty.u32());
auto* aa = create<Alias>(Sym("aa_type"), a);
auto* paa = create<Pointer>(aa, ast::StorageClass::kUniform);
auto* ppaa = create<Pointer>(paa, ast::StorageClass::kUniform);
auto* appaa = create<Alias>(Sym("appaa_type"), ppaa);
EXPECT_EQ(appaa->UnwrapAll(), paa);
}
TEST_F(AliasTest, UnwrapAll_SecondNonConsecutivePointerBlocksUnrapping) {
auto* a = create<Alias>(Sym("a_type"), ty.u32());
auto* aa = create<Alias>(Sym("aa_type"), a);
auto* paa = create<Pointer>(aa, ast::StorageClass::kUniform);
auto* apaa = create<Alias>(Sym("apaa_type"), paa);
auto* aapaa = create<Alias>(Sym("aapaa_type"), apaa);
auto* paapaa = create<Pointer>(aapaa, ast::StorageClass::kUniform);
auto* apaapaa = create<Alias>(Sym("apaapaa_type"), paapaa);
EXPECT_EQ(apaapaa->UnwrapAll(), paa);
}
TEST_F(AliasTest, UnwrapAll_AccessControlPointer) {
auto* a = create<AccessControl>(ast::AccessControl::kReadOnly, ty.u32());
auto* pa = create<Pointer>(a, ast::StorageClass::kUniform);
EXPECT_EQ(pa->type(), a);
EXPECT_EQ(pa->UnwrapAll(), ty.u32());
}
TEST_F(AliasTest, UnwrapAll_PointerAccessControl) {
auto* p = create<Pointer>(ty.u32(), ast::StorageClass::kUniform);
auto* a = create<AccessControl>(ast::AccessControl::kReadOnly, p);
EXPECT_EQ(a->type(), p);
EXPECT_EQ(a->UnwrapAll(), ty.u32());
}
TEST_F(AliasTest, UnwrapAliasIfNeeded) {
auto* alias1 = create<Alias>(Sym("alias1"), ty.f32());
auto* alias2 = create<Alias>(Sym("alias2"), alias1);
auto* alias3 = create<Alias>(Sym("alias3"), alias2);
EXPECT_EQ(alias3->UnwrapAliasIfNeeded(), ty.f32());
}
} // namespace
} // namespace sem
} // namespace tint

View File

@@ -26,7 +26,6 @@ TEST_F(BoolTest, Is) {
Bool b;
Type* ty = &b;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_TRUE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -31,7 +31,6 @@ TEST_F(DepthTextureTest, Is) {
DepthTexture d(ast::TextureDimension::kCube);
Type* ty = &d;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -32,7 +32,6 @@ TEST_F(ExternalTextureTest, Is) {
ExternalTexture s;
Type* ty = &s;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -26,7 +26,6 @@ TEST_F(F32Test, Is) {
F32 f;
Type* ty = &f;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_TRUE(ty->Is<F32>());

View File

@@ -26,7 +26,6 @@ TEST_F(I32Test, Is) {
I32 i;
Type* ty = &i;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -37,7 +37,6 @@ TEST_F(MatrixTest, Is) {
Matrix m{&c, 4};
Type* ty = &m;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -32,7 +32,6 @@ TEST_F(MultisampledTextureTest, Is) {
MultisampledTexture s(ast::TextureDimension::kCube, &f32);
Type* ty = &s;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -34,7 +34,6 @@ TEST_F(PointerTest, Is) {
Pointer p{&i32, ast::StorageClass::kFunction};
Type* ty = &p;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -31,7 +31,6 @@ TEST_F(SampledTextureTest, Is) {
SampledTexture s(ast::TextureDimension::kCube, &f32);
Type* ty = &s;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -37,7 +37,6 @@ TEST_F(SamplerTest, Is) {
Sampler s{ast::SamplerKind::kSampler};
Type* ty = &s;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -51,7 +51,6 @@ TEST_F(ArrayTest, Is) {
Type* ty = create<Array>(&i32, 2, 4, 8, 4, true);
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_TRUE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -44,7 +44,6 @@ TEST_F(StructTest, Is) {
4 /* size */, 4 /* size_no_padding */);
sem::Type* ty = s;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -33,7 +33,6 @@ TEST_F(StorageTextureTest, Is) {
ast::ImageFormat::kRgba32Float, subtype);
Type* ty = s;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -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<sem::Pointer>()) {
return ptr->type();
auto* type = this;
while (auto* ptr = type->As<sem::Pointer>()) {
type = ptr->type();
}
return this;
}
const Type* Type::UnwrapAliasIfNeeded() const {
const Type* unwrapped = this;
while (auto* ptr = unwrapped->As<sem::Alias>()) {
unwrapped = ptr->type();
}
return unwrapped;
return type;
}
const Type* Type::UnwrapIfNeeded() const {
auto* where = this;
while (true) {
if (auto* alias = where->As<sem::Alias>()) {
where = alias->type();
} else if (auto* access = where->As<sem::AccessControl>()) {
where = access->type();
} else {
break;
}
auto* type = this;
while (auto* access = type->As<sem::AccessControl>()) {
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<sem::Pointer>()) {
type = ptr->type();
continue;
}
if (auto* access = type->As<sem::AccessControl>()) {
type = access->type();
continue;
}
return type;
}
}
bool Type::is_scalar() const {

View File

@@ -48,11 +48,7 @@ class Type : public Castable<Type, Node> {
/// @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<Type, Node> {
/// @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;

View File

@@ -26,7 +26,6 @@ TEST_F(U32Test, Is) {
U32 u;
Type* ty = &u;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());

View File

@@ -34,7 +34,6 @@ TEST_F(VectorTest, Is) {
Vector v{&i32, 4};
Type* ty = &v;
EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>());
EXPECT_FALSE(ty->Is<Bool>());
EXPECT_FALSE(ty->Is<F32>());