sem: Remove Type::type_name.

Remove last remaining uses, and fix up a whole lot of tests.

Bug: tint:1383
Change-Id: Id2a11fc2d748b72823f4a077bcd6ba7be705a02b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/82744
Reviewed-by: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2022-03-07 18:34:57 +00:00 committed by Tint LUCI CQ
parent 4391975f72
commit dc0e31cfaa
70 changed files with 709 additions and 427 deletions

View File

@ -51,8 +51,6 @@ class Any : public Castable<Any, sem::Type> {
// Stub implementations for sem::Type conformance.
size_t Hash() const override { return 0; }
bool Equals(const sem::Type&) const override { return false; }
std::string type_name() const override { return "<any>"; }
std::string FriendlyName(const SymbolTable&) const override {
return "<any>";
}

View File

@ -200,7 +200,7 @@ TEST_F(ResolverIndexAccessorTest, Array_Constant) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(acc), nullptr);
EXPECT_TRUE(TypeOf(acc)->Is<sem::F32>()) << TypeOf(acc)->type_name();
EXPECT_TRUE(TypeOf(acc)->Is<sem::F32>());
}
TEST_F(ResolverIndexAccessorTest, Array_Dynamic_I32) {

View File

@ -60,17 +60,6 @@ bool Array::IsConstructible() const {
return constructible_;
}
std::string Array::type_name() const {
std::string type_name = "__array" + element_->type_name();
type_name += "_count_" + std::to_string(count_);
type_name += "_align_" + std::to_string(align_);
type_name += "_size_" + std::to_string(size_);
type_name += "_stride_" + std::to_string(stride_);
// Note: implicit_stride is not part of the type_name string as this is
// derived from the element type
return type_name;
}
std::string Array::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
if (!IsStrideImplicit()) {

View File

@ -96,9 +96,6 @@ class Array : public Castable<Array, Type> {
/// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
bool IsConstructible() const override;
/// @returns the name for the 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.

View File

@ -38,12 +38,6 @@ bool Atomic::Equals(const sem::Type& other) const {
return false;
}
std::string Atomic::type_name() const {
std::ostringstream out;
out << "__atomic" << subtype_->type_name();
return out.str();
}
std::string Atomic::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "atomic<" << subtype_->FriendlyName(symbols) << ">";

View File

@ -43,9 +43,6 @@ class Atomic : public Castable<Atomic, Type> {
/// @returns the atomic type
const sem::Type* Type() const { return subtype_; }
/// @returns the 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.

View File

@ -24,12 +24,28 @@ using AtomicTest = TestHelper;
TEST_F(AtomicTest, Creation) {
auto* a = create<Atomic>(create<I32>());
auto* b = create<Atomic>(create<I32>());
auto* c = create<Atomic>(create<U32>());
EXPECT_TRUE(a->Type()->Is<sem::I32>());
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
}
TEST_F(AtomicTest, TypeName) {
TEST_F(AtomicTest, Hash) {
auto* a = create<Atomic>(create<I32>());
EXPECT_EQ(a->type_name(), "__atomic__i32");
auto* b = create<Atomic>(create<I32>());
auto* c = create<Atomic>(create<U32>());
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
}
TEST_F(AtomicTest, Equals) {
auto* a = create<Atomic>(create<I32>());
auto* b = create<Atomic>(create<I32>());
auto* c = create<Atomic>(create<U32>());
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(AtomicTest, FriendlyName) {

View File

@ -35,10 +35,6 @@ bool Bool::Equals(const Type& other) const {
return other.Is<Bool>();
}
std::string Bool::type_name() const {
return "__bool";
}
std::string Bool::FriendlyName(const SymbolTable&) const {
return "bool";
}

View File

@ -44,9 +44,6 @@ class Bool : public Castable<Bool, Type> {
/// @returns true if the this type is equal to the given type
bool Equals(const Type& other) const override;
/// @returns the 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.

View File

@ -21,9 +21,23 @@ namespace {
using BoolTest = TestHelper;
TEST_F(BoolTest, TypeName) {
Bool b;
EXPECT_EQ(b.type_name(), "__bool");
TEST_F(BoolTest, Creation) {
auto* a = create<Bool>();
auto* b = create<Bool>();
EXPECT_EQ(a, b);
}
TEST_F(BoolTest, Hash) {
auto* a = create<Bool>();
auto* b = create<Bool>();
EXPECT_EQ(a->Hash(), b->Hash());
}
TEST_F(BoolTest, Equals) {
auto* a = create<Bool>();
auto* b = create<Bool>();
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(BoolTest, FriendlyName) {

View File

@ -32,7 +32,7 @@ const Type* ElemType(const Type* ty, size_t num_elements) {
if (num_elements != 1) {
TINT_ICE(Semantic, diag)
<< "sem::Constant() type <-> num_element mismatch. type: '"
<< ty->type_name() << "' num_elements: " << num_elements;
<< ty->TypeInfo().name << "' num_elements: " << num_elements;
}
return ty;
}
@ -40,7 +40,7 @@ const Type* ElemType(const Type* ty, size_t num_elements) {
if (num_elements != vec->Width()) {
TINT_ICE(Semantic, diag)
<< "sem::Constant() type <-> num_element mismatch. type: '"
<< ty->type_name() << "' num_elements: " << num_elements;
<< ty->TypeInfo().name << "' num_elements: " << num_elements;
}
TINT_ASSERT(Semantic, vec->type()->is_scalar());
return vec->type();

View File

@ -122,7 +122,7 @@ class Constant {
}
diag::List diags;
TINT_UNREACHABLE(Semantic, diags)
<< "invalid scalar type " << type_->type_name();
<< "invalid scalar type " << type_->TypeInfo().name;
return func(~0);
}

View File

@ -51,12 +51,6 @@ bool DepthMultisampledTexture::Equals(const sem::Type& other) const {
return false;
}
std::string DepthMultisampledTexture::type_name() const {
std::ostringstream out;
out << "__depth_multisampled_texture_" << dim();
return out.str();
}
std::string DepthMultisampledTexture::FriendlyName(const SymbolTable&) const {
std::ostringstream out;
out << "texture_depth_multisampled_" << dim();

View File

@ -40,9 +40,6 @@ class DepthMultisampledTexture
/// @returns true if the this type is equal to the given type
bool Equals(const Type& other) const override;
/// @returns the 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.

View File

@ -26,16 +26,34 @@ namespace {
using DepthMultisampledTextureTest = TestHelper;
TEST_F(DepthMultisampledTextureTest, Creation) {
auto* a = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
auto* b = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
EXPECT_EQ(a, b);
}
TEST_F(DepthMultisampledTextureTest, Hash) {
auto* a = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
auto* b = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
EXPECT_EQ(a->Hash(), b->Hash());
}
TEST_F(DepthMultisampledTextureTest, Equals) {
auto* a = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
auto* b = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
EXPECT_TRUE(a->Equals(*a));
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(DepthMultisampledTextureTest, Dim) {
DepthMultisampledTexture d(ast::TextureDimension::k2d);
EXPECT_EQ(d.dim(), ast::TextureDimension::k2d);
}
TEST_F(DepthMultisampledTextureTest, TypeName) {
DepthMultisampledTexture d(ast::TextureDimension::k2d);
EXPECT_EQ(d.type_name(), "__depth_multisampled_texture_2d");
}
TEST_F(DepthMultisampledTextureTest, FriendlyName) {
DepthMultisampledTexture d(ast::TextureDimension::k2d);
EXPECT_EQ(d.FriendlyName(Symbols()), "texture_depth_multisampled_2d");

View File

@ -51,12 +51,6 @@ bool DepthTexture::Equals(const sem::Type& other) const {
return false;
}
std::string DepthTexture::type_name() const {
std::ostringstream out;
out << "__depth_texture_" << dim();
return out.str();
}
std::string DepthTexture::FriendlyName(const SymbolTable&) const {
std::ostringstream out;
out << "texture_depth_" << dim();

View File

@ -39,9 +39,6 @@ class DepthTexture : public Castable<DepthTexture, Texture> {
/// @returns true if the this type is equal to the given type
bool Equals(const Type& other) const override;
/// @returns the 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.

View File

@ -26,6 +26,34 @@ namespace {
using DepthTextureTest = TestHelper;
TEST_F(DepthTextureTest, Creation) {
auto* a = create<DepthTexture>(ast::TextureDimension::k2d);
auto* b = create<DepthTexture>(ast::TextureDimension::k2d);
auto* c = create<DepthTexture>(ast::TextureDimension::k2dArray);
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
}
TEST_F(DepthTextureTest, Hash) {
auto* a = create<DepthTexture>(ast::TextureDimension::k2d);
auto* b = create<DepthTexture>(ast::TextureDimension::k2d);
auto* c = create<DepthTexture>(ast::TextureDimension::k2dArray);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
}
TEST_F(DepthTextureTest, Equals) {
auto* a = create<DepthTexture>(ast::TextureDimension::k2d);
auto* b = create<DepthTexture>(ast::TextureDimension::k2d);
auto* c = create<DepthTexture>(ast::TextureDimension::k2dArray);
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(DepthTextureTest, IsTexture) {
DepthTexture d(ast::TextureDimension::kCube);
Texture* ty = &d;
@ -40,11 +68,6 @@ TEST_F(DepthTextureTest, Dim) {
EXPECT_EQ(d.dim(), ast::TextureDimension::kCube);
}
TEST_F(DepthTextureTest, TypeName) {
DepthTexture d(ast::TextureDimension::kCube);
EXPECT_EQ(d.type_name(), "__depth_texture_cube");
}
TEST_F(DepthTextureTest, FriendlyName) {
DepthTexture d(ast::TextureDimension::kCube);
EXPECT_EQ(d.FriendlyName(Symbols()), "texture_depth_cube");

View File

@ -35,10 +35,6 @@ bool ExternalTexture::Equals(const sem::Type& other) const {
return other.Is<ExternalTexture>();
}
std::string ExternalTexture::type_name() const {
return "__external_texture";
}
std::string ExternalTexture::FriendlyName(const SymbolTable&) const {
return "texture_external";
}

View File

@ -39,9 +39,6 @@ class ExternalTexture : public Castable<ExternalTexture, Texture> {
/// @returns true if the this type is equal to the given type
bool Equals(const Type& other) const override;
/// @returns the 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.

View File

@ -26,6 +26,25 @@ namespace {
using ExternalTextureTest = TestHelper;
TEST_F(ExternalTextureTest, Creation) {
auto* a = create<ExternalTexture>();
auto* b = create<ExternalTexture>();
EXPECT_EQ(a, b);
}
TEST_F(ExternalTextureTest, Hash) {
auto* a = create<ExternalTexture>();
auto* b = create<ExternalTexture>();
EXPECT_EQ(a->Hash(), b->Hash());
}
TEST_F(ExternalTextureTest, Equals) {
auto* a = create<ExternalTexture>();
auto* b = create<ExternalTexture>();
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(ExternalTextureTest, IsTexture) {
F32 f32;
ExternalTexture s;
@ -43,12 +62,6 @@ TEST_F(ExternalTextureTest, Dim) {
EXPECT_EQ(s.dim(), ast::TextureDimension::k2d);
}
TEST_F(ExternalTextureTest, TypeName) {
F32 f32;
ExternalTexture s;
EXPECT_EQ(s.type_name(), "__external_texture");
}
TEST_F(ExternalTextureTest, FriendlyName) {
ExternalTexture s;
EXPECT_EQ(s.FriendlyName(Symbols()), "texture_external");

View File

@ -35,10 +35,6 @@ bool F32::Equals(const Type& other) const {
return other.Is<F32>();
}
std::string F32::type_name() const {
return "__f32";
}
std::string F32::FriendlyName(const SymbolTable&) const {
return "f32";
}

View File

@ -38,9 +38,6 @@ class F32 : public Castable<F32, Type> {
/// @returns true if the this type is equal to the given type
bool Equals(const Type& other) const override;
/// @returns the 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.

View File

@ -21,9 +21,23 @@ namespace {
using F32Test = TestHelper;
TEST_F(F32Test, TypeName) {
F32 f;
EXPECT_EQ(f.type_name(), "__f32");
TEST_F(F32Test, Creation) {
auto* a = create<F32>();
auto* b = create<F32>();
EXPECT_EQ(a, b);
}
TEST_F(F32Test, Hash) {
auto* a = create<F32>();
auto* b = create<F32>();
EXPECT_EQ(a->Hash(), b->Hash());
}
TEST_F(F32Test, Equals) {
auto* a = create<F32>();
auto* b = create<F32>();
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(F32Test, FriendlyName) {

View File

@ -35,10 +35,6 @@ bool I32::Equals(const Type& other) const {
return other.Is<I32>();
}
std::string I32::type_name() const {
return "__i32";
}
std::string I32::FriendlyName(const SymbolTable&) const {
return "i32";
}

View File

@ -38,9 +38,6 @@ class I32 : public Castable<I32, Type> {
/// @returns true if the this type is equal to the given type
bool Equals(const Type& other) const override;
/// @returns the 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.

View File

@ -21,9 +21,23 @@ namespace {
using I32Test = TestHelper;
TEST_F(I32Test, TypeName) {
I32 i;
EXPECT_EQ(i.type_name(), "__i32");
TEST_F(I32Test, Creation) {
auto* a = create<I32>();
auto* b = create<I32>();
EXPECT_EQ(a, b);
}
TEST_F(I32Test, Hash) {
auto* a = create<I32>();
auto* b = create<I32>();
EXPECT_EQ(a->Hash(), b->Hash());
}
TEST_F(I32Test, Equals) {
auto* a = create<I32>();
auto* b = create<I32>();
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(I32Test, FriendlyName) {

View File

@ -51,11 +51,6 @@ bool Matrix::Equals(const Type& other) const {
return false;
}
std::string Matrix::type_name() const {
return "__mat_" + std::to_string(rows_) + "_" + std::to_string(columns_) +
subtype_->type_name();
}
std::string Matrix::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "mat" << columns_ << "x" << rows_ << "<"

View File

@ -53,9 +53,6 @@ class Matrix : public Castable<Matrix, Type> {
/// @returns the column-vector type of the matrix
const Vector* ColumnType() const { return column_type_; }
/// @returns the 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.

View File

@ -22,19 +22,47 @@ namespace {
using MatrixTest = TestHelper;
TEST_F(MatrixTest, Creation) {
I32 i32;
Vector c{&i32, 2};
Matrix m{&c, 4};
EXPECT_EQ(m.type(), &i32);
EXPECT_EQ(m.rows(), 2u);
EXPECT_EQ(m.columns(), 4u);
auto* a = create<Matrix>(create<Vector>(create<I32>(), 3u), 4u);
auto* b = create<Matrix>(create<Vector>(create<I32>(), 3u), 4u);
auto* c = create<Matrix>(create<Vector>(create<F32>(), 3u), 4u);
auto* d = create<Matrix>(create<Vector>(create<I32>(), 2u), 4u);
auto* e = create<Matrix>(create<Vector>(create<I32>(), 3u), 2u);
EXPECT_EQ(a->type(), create<I32>());
EXPECT_EQ(a->rows(), 3u);
EXPECT_EQ(a->columns(), 4u);
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
EXPECT_NE(a, d);
EXPECT_NE(a, e);
}
TEST_F(MatrixTest, TypeName) {
I32 i32;
Vector c{&i32, 2};
Matrix m{&c, 3};
EXPECT_EQ(m.type_name(), "__mat_2_3__i32");
TEST_F(MatrixTest, Hash) {
auto* a = create<Matrix>(create<Vector>(create<I32>(), 3u), 4u);
auto* b = create<Matrix>(create<Vector>(create<I32>(), 3u), 4u);
auto* c = create<Matrix>(create<Vector>(create<F32>(), 3u), 4u);
auto* d = create<Matrix>(create<Vector>(create<I32>(), 2u), 4u);
auto* e = create<Matrix>(create<Vector>(create<I32>(), 3u), 2u);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
EXPECT_NE(a->Hash(), d->Hash());
EXPECT_NE(a->Hash(), e->Hash());
}
TEST_F(MatrixTest, Equals) {
auto* a = create<Matrix>(create<Vector>(create<I32>(), 3u), 4u);
auto* b = create<Matrix>(create<Vector>(create<I32>(), 3u), 4u);
auto* c = create<Matrix>(create<Vector>(create<F32>(), 3u), 4u);
auto* d = create<Matrix>(create<Vector>(create<I32>(), 2u), 4u);
auto* e = create<Matrix>(create<Vector>(create<I32>(), 3u), 2u);
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(*d));
EXPECT_FALSE(a->Equals(*e));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(MatrixTest, FriendlyName) {

View File

@ -44,12 +44,6 @@ bool MultisampledTexture::Equals(const sem::Type& other) const {
return false;
}
std::string MultisampledTexture::type_name() const {
std::ostringstream out;
out << "__multisampled_texture_" << dim() << type_->type_name();
return out.str();
}
std::string MultisampledTexture::FriendlyName(
const SymbolTable& symbols) const {
std::ostringstream out;

View File

@ -43,9 +43,6 @@ class MultisampledTexture : public Castable<MultisampledTexture, Texture> {
/// @returns the subtype of the sampled texture
const Type* type() const { return type_; }
/// @returns the 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.

View File

@ -26,6 +26,49 @@ namespace {
using MultisampledTextureTest = TestHelper;
TEST_F(MultisampledTextureTest, Creation) {
auto* a =
create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* b =
create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* c =
create<MultisampledTexture>(ast::TextureDimension::k3d, create<F32>());
auto* d =
create<MultisampledTexture>(ast::TextureDimension::k2d, create<I32>());
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
EXPECT_NE(a, d);
}
TEST_F(MultisampledTextureTest, Hash) {
auto* a =
create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* b =
create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* c =
create<MultisampledTexture>(ast::TextureDimension::k3d, create<F32>());
auto* d =
create<MultisampledTexture>(ast::TextureDimension::k2d, create<I32>());
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
EXPECT_NE(a->Hash(), d->Hash());
}
TEST_F(MultisampledTextureTest, Equals) {
auto* a =
create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* b =
create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* c =
create<MultisampledTexture>(ast::TextureDimension::k3d, create<F32>());
auto* d =
create<MultisampledTexture>(ast::TextureDimension::k2d, create<I32>());
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(*d));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(MultisampledTextureTest, IsTexture) {
F32 f32;
MultisampledTexture s(ast::TextureDimension::kCube, &f32);
@ -49,12 +92,6 @@ TEST_F(MultisampledTextureTest, Type) {
EXPECT_EQ(s.type(), &f32);
}
TEST_F(MultisampledTextureTest, TypeName) {
F32 f32;
MultisampledTexture s(ast::TextureDimension::k3d, &f32);
EXPECT_EQ(s.type_name(), "__multisampled_texture_3d__f32");
}
TEST_F(MultisampledTextureTest, FriendlyName) {
F32 f32;
MultisampledTexture s(ast::TextureDimension::k3d, &f32);

View File

@ -44,12 +44,6 @@ bool Pointer::Equals(const sem::Type& other) const {
return false;
}
std::string Pointer::type_name() const {
std::ostringstream out;
out << "__ptr_" << storage_class_ << subtype_->type_name() << "__" << access_;
return out.str();
}
std::string Pointer::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "ptr<";

View File

@ -55,9 +55,6 @@ class Pointer : public Castable<Pointer, Type> {
/// @returns the access control of the reference
ast::Access Access() const { return access_; }
/// @returns the 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.

View File

@ -22,17 +22,62 @@ namespace {
using PointerTest = TestHelper;
TEST_F(PointerTest, Creation) {
auto* r = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
auto* a = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
EXPECT_TRUE(r->StoreType()->Is<sem::I32>());
EXPECT_EQ(r->StorageClass(), ast::StorageClass::kStorage);
EXPECT_EQ(r->Access(), ast::Access::kReadWrite);
auto* b = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* c = create<Pointer>(create<F32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* d = create<Pointer>(create<I32>(), ast::StorageClass::kPrivate,
ast::Access::kReadWrite);
auto* e = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kRead);
EXPECT_TRUE(a->StoreType()->Is<sem::I32>());
EXPECT_EQ(a->StorageClass(), ast::StorageClass::kStorage);
EXPECT_EQ(a->Access(), ast::Access::kReadWrite);
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
EXPECT_NE(a, d);
EXPECT_NE(a, e);
}
TEST_F(PointerTest, TypeName) {
auto* r = create<Pointer>(create<I32>(), ast::StorageClass::kWorkgroup,
TEST_F(PointerTest, Hash) {
auto* a = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
EXPECT_EQ(r->type_name(), "__ptr_workgroup__i32__read_write");
auto* b = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* c = create<Pointer>(create<F32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* d = create<Pointer>(create<I32>(), ast::StorageClass::kPrivate,
ast::Access::kReadWrite);
auto* e = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kRead);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
EXPECT_NE(a->Hash(), d->Hash());
EXPECT_NE(a->Hash(), e->Hash());
}
TEST_F(PointerTest, Equals) {
auto* a = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* b = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* c = create<Pointer>(create<F32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* d = create<Pointer>(create<I32>(), ast::StorageClass::kPrivate,
ast::Access::kReadWrite);
auto* e = create<Pointer>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kRead);
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(*d));
EXPECT_FALSE(a->Equals(*e));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(PointerTest, FriendlyName) {

View File

@ -43,12 +43,6 @@ bool Reference::Equals(const sem::Type& other) const {
return false;
}
std::string Reference::type_name() const {
std::ostringstream out;
out << "__ref_" << storage_class_ << subtype_->type_name() << "__" << access_;
return out.str();
}
std::string Reference::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "ref<";

View File

@ -55,9 +55,6 @@ class Reference : public Castable<Reference, Type> {
/// @returns the resolved access control of the reference.
ast::Access Access() const { return access_; }
/// @returns the 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.

View File

@ -22,17 +22,62 @@ namespace {
using ReferenceTest = TestHelper;
TEST_F(ReferenceTest, Creation) {
auto* r = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
auto* a = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
EXPECT_TRUE(r->StoreType()->Is<sem::I32>());
EXPECT_EQ(r->StorageClass(), ast::StorageClass::kStorage);
EXPECT_EQ(r->Access(), ast::Access::kReadWrite);
auto* b = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* c = create<Reference>(create<F32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* d = create<Reference>(create<I32>(), ast::StorageClass::kPrivate,
ast::Access::kReadWrite);
auto* e = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kRead);
EXPECT_TRUE(a->StoreType()->Is<sem::I32>());
EXPECT_EQ(a->StorageClass(), ast::StorageClass::kStorage);
EXPECT_EQ(a->Access(), ast::Access::kReadWrite);
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
EXPECT_NE(a, d);
EXPECT_NE(a, e);
}
TEST_F(ReferenceTest, TypeName) {
auto* r = create<Reference>(create<I32>(), ast::StorageClass::kWorkgroup,
TEST_F(ReferenceTest, Hash) {
auto* a = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
EXPECT_EQ(r->type_name(), "__ref_workgroup__i32__read_write");
auto* b = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* c = create<Reference>(create<F32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* d = create<Reference>(create<I32>(), ast::StorageClass::kPrivate,
ast::Access::kReadWrite);
auto* e = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kRead);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
EXPECT_NE(a->Hash(), d->Hash());
EXPECT_NE(a->Hash(), e->Hash());
}
TEST_F(ReferenceTest, Equals) {
auto* a = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* b = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* c = create<Reference>(create<F32>(), ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* d = create<Reference>(create<I32>(), ast::StorageClass::kPrivate,
ast::Access::kReadWrite);
auto* e = create<Reference>(create<I32>(), ast::StorageClass::kStorage,
ast::Access::kRead);
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(*d));
EXPECT_FALSE(a->Equals(*e));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(ReferenceTest, FriendlyName) {

View File

@ -43,12 +43,6 @@ bool SampledTexture::Equals(const sem::Type& other) const {
return false;
}
std::string SampledTexture::type_name() const {
std::ostringstream out;
out << "__sampled_texture_" << dim() << type_->type_name();
return out.str();
}
std::string SampledTexture::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "texture_" << dim() << "<" << type_->FriendlyName(symbols) << ">";

View File

@ -43,9 +43,6 @@ class SampledTexture : public Castable<SampledTexture, Texture> {
/// @returns the subtype of the sampled texture
Type* type() const { return const_cast<Type*>(type_); }
/// @returns the 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.

View File

@ -25,6 +25,43 @@ namespace {
using SampledTextureTest = TestHelper;
TEST_F(SampledTextureTest, Creation) {
auto* a = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
auto* b = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
auto* c = create<SampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* d = create<SampledTexture>(ast::TextureDimension::kCube, create<I32>());
EXPECT_TRUE(a->type()->Is<F32>());
EXPECT_EQ(a->dim(), ast::TextureDimension::kCube);
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
EXPECT_NE(a, d);
}
TEST_F(SampledTextureTest, Hash) {
auto* a = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
auto* b = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
auto* c = create<SampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* d = create<SampledTexture>(ast::TextureDimension::kCube, create<I32>());
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
EXPECT_NE(a->Hash(), d->Hash());
}
TEST_F(SampledTextureTest, Equals) {
auto* a = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
auto* b = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
auto* c = create<SampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* d = create<SampledTexture>(ast::TextureDimension::kCube, create<I32>());
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(*d));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(SampledTextureTest, IsTexture) {
F32 f32;
SampledTexture s(ast::TextureDimension::kCube, &f32);
@ -47,12 +84,6 @@ TEST_F(SampledTextureTest, Type) {
EXPECT_EQ(s.type(), &f32);
}
TEST_F(SampledTextureTest, TypeName) {
F32 f32;
SampledTexture s(ast::TextureDimension::k3d, &f32);
EXPECT_EQ(s.type_name(), "__sampled_texture_3d__f32");
}
TEST_F(SampledTextureTest, FriendlyName) {
F32 f32;
SampledTexture s(ast::TextureDimension::k3d, &f32);

View File

@ -39,11 +39,6 @@ bool Sampler::Equals(const sem::Type& other) const {
return false;
}
std::string Sampler::type_name() const {
return std::string("__sampler_") +
(kind_ == ast::SamplerKind::kSampler ? "sampler" : "comparison");
}
std::string Sampler::FriendlyName(const SymbolTable&) const {
return kind_ == ast::SamplerKind::kSampler ? "sampler" : "sampler_comparison";
}

View File

@ -48,9 +48,6 @@ class Sampler : public Castable<Sampler, Type> {
return kind_ == ast::SamplerKind::kComparisonSampler;
}
/// @returns the 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.

View File

@ -23,24 +23,37 @@ namespace {
using SamplerTest = TestHelper;
TEST_F(SamplerTest, Creation) {
Sampler s{ast::SamplerKind::kSampler};
EXPECT_EQ(s.kind(), ast::SamplerKind::kSampler);
auto* a = create<Sampler>(ast::SamplerKind::kSampler);
auto* b = create<Sampler>(ast::SamplerKind::kSampler);
auto* c = create<Sampler>(ast::SamplerKind::kComparisonSampler);
EXPECT_EQ(a->kind(), ast::SamplerKind::kSampler);
EXPECT_EQ(c->kind(), ast::SamplerKind::kComparisonSampler);
EXPECT_FALSE(a->IsComparison());
EXPECT_TRUE(c->IsComparison());
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
}
TEST_F(SamplerTest, Creation_ComparisonSampler) {
Sampler s{ast::SamplerKind::kComparisonSampler};
EXPECT_EQ(s.kind(), ast::SamplerKind::kComparisonSampler);
EXPECT_TRUE(s.IsComparison());
TEST_F(SamplerTest, Hash) {
auto* a = create<Sampler>(ast::SamplerKind::kSampler);
auto* b = create<Sampler>(ast::SamplerKind::kSampler);
auto* c = create<Sampler>(ast::SamplerKind::kComparisonSampler);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
}
TEST_F(SamplerTest, TypeName_Sampler) {
Sampler s{ast::SamplerKind::kSampler};
EXPECT_EQ(s.type_name(), "__sampler_sampler");
}
TEST_F(SamplerTest, Equals) {
auto* a = create<Sampler>(ast::SamplerKind::kSampler);
auto* b = create<Sampler>(ast::SamplerKind::kSampler);
auto* c = create<Sampler>(ast::SamplerKind::kComparisonSampler);
TEST_F(SamplerTest, TypeName_Comparison) {
Sampler s{ast::SamplerKind::kComparisonSampler};
EXPECT_EQ(s.type_name(), "__sampler_comparison");
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(SamplerTest, FriendlyNameSampler) {

View File

@ -22,35 +22,88 @@ namespace {
using ArrayTest = TestHelper;
TEST_F(ArrayTest, CreateSizedArray) {
U32 u32;
auto* arr = create<Array>(&u32, 2u, 4u, 8u, 32u, 16u);
EXPECT_EQ(arr->ElemType(), &u32);
EXPECT_EQ(arr->Count(), 2u);
EXPECT_EQ(arr->Align(), 4u);
EXPECT_EQ(arr->Size(), 8u);
EXPECT_EQ(arr->Stride(), 32u);
EXPECT_EQ(arr->ImplicitStride(), 16u);
EXPECT_FALSE(arr->IsStrideImplicit());
EXPECT_FALSE(arr->IsRuntimeSized());
auto* a = create<Array>(create<U32>(), 2u, 4u, 8u, 32u, 16u);
auto* b = create<Array>(create<U32>(), 2u, 4u, 8u, 32u, 16u);
auto* c = create<Array>(create<U32>(), 3u, 4u, 8u, 32u, 16u);
auto* d = create<Array>(create<U32>(), 2u, 5u, 8u, 32u, 16u);
auto* e = create<Array>(create<U32>(), 2u, 4u, 9u, 32u, 16u);
auto* f = create<Array>(create<U32>(), 2u, 4u, 8u, 33u, 16u);
auto* g = create<Array>(create<U32>(), 2u, 4u, 8u, 33u, 17u);
EXPECT_EQ(a->ElemType(), create<U32>());
EXPECT_EQ(a->Count(), 2u);
EXPECT_EQ(a->Align(), 4u);
EXPECT_EQ(a->Size(), 8u);
EXPECT_EQ(a->Stride(), 32u);
EXPECT_EQ(a->ImplicitStride(), 16u);
EXPECT_FALSE(a->IsStrideImplicit());
EXPECT_FALSE(a->IsRuntimeSized());
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
EXPECT_NE(a, d);
EXPECT_NE(a, e);
EXPECT_NE(a, f);
EXPECT_NE(a, g);
}
TEST_F(ArrayTest, CreateRuntimeArray) {
U32 u32;
auto* arr = create<Array>(&u32, 0u, 4u, 8u, 32u, 32u);
EXPECT_EQ(arr->ElemType(), &u32);
EXPECT_EQ(arr->Count(), 0u);
EXPECT_EQ(arr->Align(), 4u);
EXPECT_EQ(arr->Size(), 8u);
EXPECT_EQ(arr->Stride(), 32u);
EXPECT_EQ(arr->ImplicitStride(), 32u);
EXPECT_TRUE(arr->IsStrideImplicit());
EXPECT_TRUE(arr->IsRuntimeSized());
auto* a = create<Array>(create<U32>(), 0u, 4u, 8u, 32u, 32u);
auto* b = create<Array>(create<U32>(), 0u, 4u, 8u, 32u, 32u);
auto* c = create<Array>(create<U32>(), 0u, 5u, 8u, 32u, 32u);
auto* d = create<Array>(create<U32>(), 0u, 4u, 9u, 32u, 32u);
auto* e = create<Array>(create<U32>(), 0u, 4u, 8u, 33u, 32u);
auto* f = create<Array>(create<U32>(), 0u, 4u, 8u, 33u, 17u);
EXPECT_EQ(a->ElemType(), create<U32>());
EXPECT_EQ(a->Count(), 0u);
EXPECT_EQ(a->Align(), 4u);
EXPECT_EQ(a->Size(), 8u);
EXPECT_EQ(a->Stride(), 32u);
EXPECT_EQ(a->ImplicitStride(), 32u);
EXPECT_TRUE(a->IsStrideImplicit());
EXPECT_TRUE(a->IsRuntimeSized());
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
EXPECT_NE(a, d);
EXPECT_NE(a, e);
EXPECT_NE(a, f);
}
TEST_F(ArrayTest, TypeName) {
I32 i32;
auto* arr = create<Array>(&i32, 2u, 0u, 4u, 4u, 4u);
EXPECT_EQ(arr->type_name(), "__array__i32_count_2_align_0_size_4_stride_4");
TEST_F(ArrayTest, Hash) {
auto* a = create<Array>(create<U32>(), 2u, 4u, 8u, 32u, 16u);
auto* b = create<Array>(create<U32>(), 2u, 4u, 8u, 32u, 16u);
auto* c = create<Array>(create<U32>(), 3u, 4u, 8u, 32u, 16u);
auto* d = create<Array>(create<U32>(), 2u, 5u, 8u, 32u, 16u);
auto* e = create<Array>(create<U32>(), 2u, 4u, 9u, 32u, 16u);
auto* f = create<Array>(create<U32>(), 2u, 4u, 8u, 33u, 16u);
auto* g = create<Array>(create<U32>(), 2u, 4u, 8u, 33u, 17u);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
EXPECT_NE(a->Hash(), d->Hash());
EXPECT_NE(a->Hash(), e->Hash());
EXPECT_NE(a->Hash(), f->Hash());
EXPECT_NE(a->Hash(), g->Hash());
}
TEST_F(ArrayTest, Equals) {
auto* a = create<Array>(create<U32>(), 2u, 4u, 8u, 32u, 16u);
auto* b = create<Array>(create<U32>(), 2u, 4u, 8u, 32u, 16u);
auto* c = create<Array>(create<U32>(), 3u, 4u, 8u, 32u, 16u);
auto* d = create<Array>(create<U32>(), 2u, 5u, 8u, 32u, 16u);
auto* e = create<Array>(create<U32>(), 2u, 4u, 9u, 32u, 16u);
auto* f = create<Array>(create<U32>(), 2u, 4u, 8u, 33u, 16u);
auto* g = create<Array>(create<U32>(), 2u, 4u, 8u, 33u, 17u);
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(*d));
EXPECT_FALSE(a->Equals(*e));
EXPECT_FALSE(a->Equals(*f));
EXPECT_FALSE(a->Equals(*g));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(ArrayTest, FriendlyNameRuntimeSized) {
@ -73,12 +126,6 @@ TEST_F(ArrayTest, FriendlyNameStaticSizedNonImplicitStride) {
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(8) array<i32, 5>");
}
TEST_F(ArrayTest, TypeName_RuntimeArray) {
I32 i32;
auto* arr = create<Array>(&i32, 2u, 4u, 8u, 16u, 16u);
EXPECT_EQ(arr->type_name(), "__array__i32_count_2_align_4_size_8_stride_16");
}
} // namespace
} // namespace sem
} // namespace tint

View File

@ -36,14 +36,36 @@ TEST_F(StructTest, Creation) {
EXPECT_EQ(s->SizeNoPadding(), 16u);
}
TEST_F(StructTest, TypeName) {
auto name = Sym("my_struct");
auto* impl =
create<ast::Struct>(name, ast::StructMemberList{}, ast::AttributeList{});
auto* s =
create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
4u /* size */, 4u /* size_no_padding */);
EXPECT_EQ(s->type_name(), "__struct_$1");
TEST_F(StructTest, Hash) {
auto* a_impl = create<ast::Struct>(Sym("a"), ast::StructMemberList{},
ast::AttributeList{});
auto* a = create<sem::Struct>(a_impl, a_impl->name, StructMemberList{},
4u /* align */, 4u /* size */,
4u /* size_no_padding */);
auto* b_impl = create<ast::Struct>(Sym("b"), ast::StructMemberList{},
ast::AttributeList{});
auto* b = create<sem::Struct>(b_impl, b_impl->name, StructMemberList{},
4u /* align */, 4u /* size */,
4u /* size_no_padding */);
EXPECT_NE(a->Hash(), b->Hash());
}
TEST_F(StructTest, Equals) {
auto* a_impl = create<ast::Struct>(Sym("a"), ast::StructMemberList{},
ast::AttributeList{});
auto* a = create<sem::Struct>(a_impl, a_impl->name, StructMemberList{},
4u /* align */, 4u /* size */,
4u /* size_no_padding */);
auto* b_impl = create<ast::Struct>(Sym("b"), ast::StructMemberList{},
ast::AttributeList{});
auto* b = create<sem::Struct>(b_impl, b_impl->name, StructMemberList{},
4u /* align */, 4u /* size */,
4u /* size_no_padding */);
EXPECT_TRUE(a->Equals(*a));
EXPECT_FALSE(a->Equals(*b));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(StructTest, FriendlyName) {

View File

@ -45,13 +45,6 @@ bool StorageTexture::Equals(const sem::Type& other) const {
return false;
}
std::string StorageTexture::type_name() const {
std::ostringstream out;
out << "__storage_texture_" << dim() << "_" << texel_format_ << "_"
<< access_;
return out.str();
}
std::string StorageTexture::FriendlyName(const SymbolTable&) const {
std::ostringstream out;
out << "texture_storage_" << dim() << "<" << texel_format_ << ", " << access_

View File

@ -59,9 +59,6 @@ class StorageTexture : public Castable<StorageTexture, Texture> {
/// @returns the access control
ast::Access access() const { return access_; }
/// @returns the 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.

View File

@ -23,52 +23,95 @@ namespace tint {
namespace sem {
namespace {
using StorageTextureTest = TestHelper;
struct StorageTextureTest : public TestHelper {
StorageTexture* Create(ast::TextureDimension dims,
ast::TexelFormat fmt,
ast::Access access) {
auto* subtype = StorageTexture::SubtypeFor(fmt, Types());
return create<StorageTexture>(dims, fmt, access, subtype);
}
};
TEST_F(StorageTextureTest, Creation) {
auto* a = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
auto* b = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
auto* c = Create(ast::TextureDimension::k2d, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
auto* d = Create(ast::TextureDimension::kCube, ast::TexelFormat::kR32Float,
ast::Access::kReadWrite);
auto* e = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kRead);
EXPECT_TRUE(a->type()->Is<F32>());
EXPECT_EQ(a->dim(), ast::TextureDimension::kCube);
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
EXPECT_NE(a, d);
EXPECT_NE(a, e);
}
TEST_F(StorageTextureTest, Hash) {
auto* a = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
auto* b = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
auto* c = Create(ast::TextureDimension::k2d, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
auto* d = Create(ast::TextureDimension::kCube, ast::TexelFormat::kR32Float,
ast::Access::kReadWrite);
auto* e = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kRead);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
EXPECT_NE(a->Hash(), d->Hash());
EXPECT_NE(a->Hash(), e->Hash());
}
TEST_F(StorageTextureTest, Equals) {
auto* a = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
auto* b = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
auto* c = Create(ast::TextureDimension::k2d, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
auto* d = Create(ast::TextureDimension::kCube, ast::TexelFormat::kR32Float,
ast::Access::kReadWrite);
auto* e = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kRead);
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(*d));
EXPECT_FALSE(a->Equals(*e));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(StorageTextureTest, Dim) {
auto* subtype =
StorageTexture::SubtypeFor(ast::TexelFormat::kRgba32Float, Types());
auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite, subtype);
auto* s = Create(ast::TextureDimension::k2dArray,
ast::TexelFormat::kRgba32Float, ast::Access::kReadWrite);
EXPECT_EQ(s->dim(), ast::TextureDimension::k2dArray);
}
TEST_F(StorageTextureTest, Format) {
auto* subtype =
StorageTexture::SubtypeFor(ast::TexelFormat::kRgba32Float, Types());
auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite, subtype);
auto* s = Create(ast::TextureDimension::k2dArray,
ast::TexelFormat::kRgba32Float, ast::Access::kReadWrite);
EXPECT_EQ(s->texel_format(), ast::TexelFormat::kRgba32Float);
}
TEST_F(StorageTextureTest, TypeName) {
auto* subtype =
StorageTexture::SubtypeFor(ast::TexelFormat::kRgba32Float, Types());
auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite, subtype);
EXPECT_EQ(s->type_name(),
"__storage_texture_2d_array_rgba32float_read_write");
}
TEST_F(StorageTextureTest, FriendlyName) {
auto* subtype =
StorageTexture::SubtypeFor(ast::TexelFormat::kRgba32Float, Types());
auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite, subtype);
auto* s = Create(ast::TextureDimension::k2dArray,
ast::TexelFormat::kRgba32Float, ast::Access::kReadWrite);
EXPECT_EQ(s->FriendlyName(Symbols()),
"texture_storage_2d_array<rgba32float, read_write>");
}
TEST_F(StorageTextureTest, F32) {
auto* subtype =
sem::StorageTexture::SubtypeFor(ast::TexelFormat::kRgba32Float, Types());
Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite, subtype);
Type* s = Create(ast::TextureDimension::k2dArray,
ast::TexelFormat::kRgba32Float, ast::Access::kReadWrite);
auto program = Build();

View File

@ -72,10 +72,6 @@ const StructMember* Struct::FindMember(Symbol name) const {
return nullptr;
}
std::string Struct::type_name() const {
return "__struct_" + name_.to_str();
}
uint32_t Struct::Align() const {
return align_;
}

View File

@ -149,9 +149,6 @@ class Struct : public Castable<Struct, Type> {
return pipeline_stage_uses_;
}
/// @returns the name for the 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.

View File

@ -44,10 +44,6 @@ class Type : public Castable<Type, Node> {
/// @returns true if the this type is equal to the given type
virtual bool Equals(const Type&) const = 0;
/// [DEPRECATED]
/// @returns the name for this type. The type name is unique over all types.
virtual std::string type_name() const = 0;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.

View File

@ -35,10 +35,6 @@ bool U32::Equals(const Type& other) const {
return other.Is<U32>();
}
std::string U32::type_name() const {
return "__u32";
}
std::string U32::FriendlyName(const SymbolTable&) const {
return "u32";
}

View File

@ -38,9 +38,6 @@ class U32 : public Castable<U32, Type> {
/// @returns true if the this type is equal to the given type
bool Equals(const Type& other) const override;
/// @returns the name for th 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.

View File

@ -21,9 +21,23 @@ namespace {
using U32Test = TestHelper;
TEST_F(U32Test, TypeName) {
U32 u;
EXPECT_EQ(u.type_name(), "__u32");
TEST_F(U32Test, Creation) {
auto* a = create<U32>();
auto* b = create<U32>();
EXPECT_EQ(a, b);
}
TEST_F(U32Test, Hash) {
auto* a = create<U32>();
auto* b = create<U32>();
EXPECT_EQ(a->Hash(), b->Hash());
}
TEST_F(U32Test, Equals) {
auto* a = create<U32>();
auto* b = create<U32>();
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(U32Test, FriendlyName) {

View File

@ -43,10 +43,6 @@ bool Vector::Equals(const Type& other) const {
return false;
}
std::string Vector::type_name() const {
return "__vec_" + std::to_string(width_) + subtype_->type_name();
}
std::string Vector::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "vec" << width_ << "<" << subtype_->FriendlyName(symbols) << ">";

View File

@ -43,9 +43,6 @@ class Vector : public Castable<Vector, Type> {
/// @returns the type of the vector elements
const Type* type() const { return subtype_; }
/// @returns the name for th 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.

View File

@ -22,16 +22,40 @@ namespace {
using VectorTest = TestHelper;
TEST_F(VectorTest, Creation) {
I32 i32;
Vector v{&i32, 2};
EXPECT_EQ(v.type(), &i32);
EXPECT_EQ(v.Width(), 2u);
auto* a = create<Vector>(create<I32>(), 2u);
auto* b = create<Vector>(create<I32>(), 2u);
auto* c = create<Vector>(create<F32>(), 2u);
auto* d = create<Vector>(create<F32>(), 3u);
EXPECT_EQ(a->type(), create<I32>());
EXPECT_EQ(a->Width(), 2u);
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
EXPECT_NE(a, d);
}
TEST_F(VectorTest, TypeName) {
auto* i32 = create<I32>();
auto* v = create<Vector>(i32, 3u);
EXPECT_EQ(v->type_name(), "__vec_3__i32");
TEST_F(VectorTest, Hash) {
auto* a = create<Vector>(create<I32>(), 2u);
auto* b = create<Vector>(create<I32>(), 2u);
auto* c = create<Vector>(create<F32>(), 2u);
auto* d = create<Vector>(create<F32>(), 3u);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
EXPECT_NE(a->Hash(), d->Hash());
}
TEST_F(VectorTest, Equals) {
auto* a = create<Vector>(create<I32>(), 2u);
auto* b = create<Vector>(create<I32>(), 2u);
auto* c = create<Vector>(create<F32>(), 2u);
auto* d = create<Vector>(create<F32>(), 3u);
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
EXPECT_FALSE(a->Equals(*d));
EXPECT_FALSE(a->Equals(Void{}));
}
TEST_F(VectorTest, FriendlyName) {

View File

@ -35,10 +35,6 @@ bool Void::Equals(const Type& other) const {
return other.Is<Void>();
}
std::string Void::type_name() const {
return "__void";
}
std::string Void::FriendlyName(const SymbolTable&) const {
return "void";
}

View File

@ -38,9 +38,6 @@ class Void : public Castable<Void, Type> {
/// @returns true if the this type is equal to the given type
bool Equals(const Type& other) const override;
/// @returns the 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.

View File

@ -264,7 +264,7 @@ DecomposeMemoryAccess::Intrinsic* IntrinsicAtomicFor(ProgramBuilder* builder,
default:
TINT_ICE(Transform, builder->Diagnostics())
<< "invalid IntrinsicType for DecomposeMemoryAccess::Intrinsic: "
<< ty->type_name();
<< ty->TypeInfo().name;
break;
}
@ -672,7 +672,7 @@ struct DecomposeMemoryAccess::State {
if (atomic == nullptr) {
TINT_ICE(Transform, b.Diagnostics())
<< "IntrinsicAtomicFor() returned nullptr for op " << op
<< " and type " << el_ty->type_name();
<< " and type " << el_ty->TypeInfo().name;
}
auto* ret_ty = CreateASTTypeFor(ctx, intrinsic->ReturnType());

View File

@ -119,8 +119,8 @@ struct Robustness::State {
auto* idx_sem = ctx.src->Sem().Get(expr->index);
auto* idx_ty = idx_sem->Type()->UnwrapRef();
if (!idx_ty->IsAnyOf<sem::I32, sem::U32>()) {
TINT_ICE(Transform, b.Diagnostics())
<< "index must be u32 or i32, got " << idx_sem->Type()->type_name();
TINT_ICE(Transform, b.Diagnostics()) << "index must be u32 or i32, got "
<< idx_sem->Type()->TypeInfo().name;
return nullptr;
}
@ -133,10 +133,9 @@ struct Robustness::State {
idx.u32 = idx_constant.Elements()[0].u32;
idx.is_signed = false;
} else {
b.Diagnostics().add_error(diag::System::Transform,
"unsupported constant value for accessor: " +
idx_constant.Type()->type_name(),
expr->source);
TINT_ICE(Transform, b.Diagnostics())
<< "unsupported constant value for accessor "
<< idx_constant.Type()->TypeInfo().name;
return nullptr;
}
} else {

View File

@ -326,7 +326,8 @@ struct ZeroInitWorkgroupMemory::State {
}
TINT_UNREACHABLE(Transform, b.Diagnostics())
<< "could not zero workgroup type: " << ty->type_name();
<< "could not zero workgroup type: "
<< ty->FriendlyName(ctx.src->Symbols());
}
/// DeclareArrayIndices returns a list of statements that contain the `let`

View File

@ -241,9 +241,9 @@ bool GeneratorImpl::EmitBitcast(std::ostream& out,
if (!dst_type->is_integer_scalar_or_vector() &&
!dst_type->is_float_scalar_or_vector()) {
diagnostics_.add_error(
diag::System::Writer,
"Unable to do bitcast to type " + dst_type->type_name());
diagnostics_.add_error(diag::System::Writer,
"Unable to do bitcast to type " +
dst_type->FriendlyName(builder_.Symbols()));
return false;
}
@ -2217,9 +2217,9 @@ bool GeneratorImpl::EmitZeroValue(std::ostream& out, const sem::Type* type) {
}
out << ")";
} else {
diagnostics_.add_error(
diag::System::Writer,
"Invalid type for zero emission: " + type->type_name());
diagnostics_.add_error(diag::System::Writer,
"Invalid type for zero emission: " +
type->FriendlyName(builder_.Symbols()));
return false;
}
return true;

View File

@ -573,7 +573,8 @@ bool GeneratorImpl::EmitBitcast(std::ostream& out,
if (!type->is_integer_scalar() && !type->is_float_scalar()) {
diagnostics_.add_error(diag::System::Writer,
"Unable to do bitcast to type " + type->type_name());
"Unable to do bitcast to type " +
type->FriendlyName(builder_.Symbols()));
return false;
}
@ -3208,9 +3209,9 @@ bool GeneratorImpl::EmitValue(std::ostream& out,
ast::Access::kUndefined, "");
},
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
"Invalid type for value emission: " + type->type_name());
diagnostics_.add_error(diag::System::Writer,
"Invalid type for value emission: " +
type->FriendlyName(builder_.Symbols()));
return false;
});
}

View File

@ -281,8 +281,9 @@ bool GeneratorImpl::EmitTypeDecl(const sem::Type* ty) {
return false;
}
} else {
diagnostics_.add_error(diag::System::Writer,
"unknown alias type: " + ty->type_name());
diagnostics_.add_error(
diag::System::Writer,
"unknown alias type: " + ty->FriendlyName(builder_.Symbols()));
return false;
}
@ -1539,9 +1540,9 @@ bool GeneratorImpl::EmitZeroValue(std::ostream& out, const sem::Type* type) {
return true;
},
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
"Invalid type for zero emission: " + type->type_name());
diagnostics_.add_error(diag::System::Writer,
"Invalid type for zero emission: " +
type->FriendlyName(builder_.Symbols()));
return false;
});
}
@ -2267,7 +2268,8 @@ bool GeneratorImpl::EmitType(std::ostream& out,
return true;
}
TINT_ICE(Writer, diagnostics_)
<< "unhandled atomic type " << atomic->Type()->type_name();
<< "unhandled atomic type "
<< atomic->Type()->FriendlyName(builder_.Symbols());
return false;
},
[&](const sem::Array* ary) {
@ -2459,9 +2461,9 @@ bool GeneratorImpl::EmitType(std::ostream& out,
return true;
},
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
"unknown type in EmitType: " + type->type_name());
diagnostics_.add_error(diag::System::Writer,
"unknown type in EmitType: " +
type->FriendlyName(builder_.Symbols()));
return false;
});
}

View File

@ -1677,7 +1677,8 @@ uint32_t Builder::GenerateCastOrCopyOrPassthrough(
if (op == spv::Op::OpNop) {
error_ = "unable to determine conversion type for cast, from: " +
from_type->type_name() + " to: " + to_type->type_name();
from_type->FriendlyName(builder_.Symbols()) +
" to: " + to_type->FriendlyName(builder_.Symbols());
return 0;
}
@ -1809,20 +1810,13 @@ uint32_t Builder::GenerateConstantNullIfNeeded(const sem::Type* type) {
return 0;
}
auto name = type->type_name();
return utils::GetOrCreate(const_null_to_id_, type, [&] {
auto result = result_op();
auto it = const_null_to_id_.find(name);
if (it != const_null_to_id_.end()) {
return it->second;
}
push_type(spv::Op::OpConstantNull, {Operand::Int(type_id), result});
auto result = result_op();
auto result_id = result.to_i();
push_type(spv::Op::OpConstantNull, {Operand::Int(type_id), result});
const_null_to_id_[name] = result_id;
return result_id;
return result.to_i();
});
}
uint32_t Builder::GenerateConstantVectorSplatIfNeeded(const sem::Vector* type,
@ -2434,8 +2428,8 @@ uint32_t Builder::GenerateBuiltinCall(const sem::Call* call,
auto* type = TypeOf(accessor->structure)->UnwrapRef();
if (!type->Is<sem::Struct>()) {
error_ =
"invalid type (" + type->type_name() + ") for runtime array length";
error_ = "invalid type (" + type->FriendlyName(builder_.Symbols()) +
") for runtime array length";
return 0;
}
// Runtime array must be the last member in the structure
@ -3344,22 +3338,15 @@ bool Builder::GenerateAtomicBuiltin(const sem::Call* call,
uint32_t Builder::GenerateSampledImage(const sem::Type* texture_type,
Operand texture_operand,
Operand sampler_operand) {
uint32_t sampled_image_type_id = 0;
auto val = texture_type_name_to_sampled_image_type_id_.find(
texture_type->type_name());
if (val != texture_type_name_to_sampled_image_type_id_.end()) {
// The sampled image type is already created.
sampled_image_type_id = val->second;
} else {
// We need to create the sampled image type and cache the result.
auto sampled_image_type = result_op();
sampled_image_type_id = sampled_image_type.to_i();
auto texture_type_id = GenerateTypeIfNeeded(texture_type);
push_type(spv::Op::OpTypeSampledImage,
{sampled_image_type, Operand::Int(texture_type_id)});
texture_type_name_to_sampled_image_type_id_[texture_type->type_name()] =
sampled_image_type_id;
}
uint32_t sampled_image_type_id = utils::GetOrCreate(
texture_type_to_sampled_image_type_id_, texture_type, [&] {
// We need to create the sampled image type and cache the result.
auto sampled_image_type = result_op();
auto texture_type_id = GenerateTypeIfNeeded(texture_type);
push_type(spv::Op::OpTypeSampledImage,
{sampled_image_type, Operand::Int(texture_type_id)});
return sampled_image_type.to_i();
});
auto sampled_image = result_op();
if (!push_function_inst(spv::Op::OpSampledImage,
@ -3389,7 +3376,7 @@ uint32_t Builder::GenerateBitcastExpression(
// Bitcast does not allow same types, just emit a CopyObject
auto* to_type = TypeOf(expr)->UnwrapRef();
auto* from_type = TypeOf(expr->expr)->UnwrapRef();
if (to_type->type_name() == from_type->type_name()) {
if (to_type == from_type) {
if (!push_function_inst(
spv::Op::OpCopyObject,
{Operand::Int(result_type_id), result, Operand::Int(val_id)})) {
@ -3816,20 +3803,15 @@ uint32_t Builder::GenerateTypeIfNeeded(const sem::Type* type) {
// definitions in the generated SPIR-V. Note that nested pointers and
// references are not legal in WGSL, so only considering the top-level type is
// fine.
std::string type_name;
if (auto* ptr = type->As<sem::Pointer>()) {
type_name =
sem::Pointer(ptr->StoreType(), ptr->StorageClass(), ast::kReadWrite)
.type_name();
type = builder_.create<sem::Pointer>(ptr->StoreType(), ptr->StorageClass(),
ast::kReadWrite);
} else if (auto* ref = type->As<sem::Reference>()) {
type_name =
sem::Pointer(ref->StoreType(), ref->StorageClass(), ast::kReadWrite)
.type_name();
} else {
type_name = type->type_name();
type = builder_.create<sem::Pointer>(ref->StoreType(), ref->StorageClass(),
ast::kReadWrite);
}
return utils::GetOrCreate(type_name_to_id_, type_name, [&]() -> uint32_t {
return utils::GetOrCreate(type_to_id_, type, [&]() -> uint32_t {
auto result = result_op();
auto id = result.to_i();
bool ok = Switch(
@ -3882,37 +3864,37 @@ uint32_t Builder::GenerateTypeIfNeeded(const sem::Type* type) {
// Register all three access types of StorageTexture names. In
// SPIR-V, we must output a single type, while the variable is
// annotated with the access type. Doing this ensures we de-dupe.
type_name_to_id_[builder_
.create<sem::StorageTexture>(
tex->dim(), tex->texel_format(),
ast::Access::kRead, tex->type())
->type_name()] = id;
type_name_to_id_[builder_
.create<sem::StorageTexture>(
tex->dim(), tex->texel_format(),
ast::Access::kWrite, tex->type())
->type_name()] = id;
type_name_to_id_[builder_
.create<sem::StorageTexture>(
tex->dim(), tex->texel_format(),
ast::Access::kReadWrite, tex->type())
->type_name()] = id;
type_to_id_[builder_.create<sem::StorageTexture>(
tex->dim(), tex->texel_format(), ast::Access::kRead,
tex->type())] = id;
type_to_id_[builder_.create<sem::StorageTexture>(
tex->dim(), tex->texel_format(), ast::Access::kWrite,
tex->type())] = id;
type_to_id_[builder_.create<sem::StorageTexture>(
tex->dim(), tex->texel_format(), ast::Access::kReadWrite,
tex->type())] = id;
return true;
},
[&](const sem::Texture* tex) {
return GenerateTextureType(tex, result);
},
[&](const sem::Sampler*) {
[&](const sem::Sampler* s) {
push_type(spv::Op::OpTypeSampler, {result});
// Register both of the sampler type names. In SPIR-V they're the same
// sampler type, so we need to match that when we do the dedup check.
type_name_to_id_["__sampler_sampler"] = id;
type_name_to_id_["__sampler_comparison"] = id;
if (s->kind() == ast::SamplerKind::kSampler) {
type_to_id_[builder_.create<sem::Sampler>(
ast::SamplerKind::kComparisonSampler)] = id;
} else {
type_to_id_[builder_.create<sem::Sampler>(
ast::SamplerKind::kSampler)] = id;
}
return true;
},
[&](Default) {
error_ = "unable to convert type: " + type->type_name();
error_ = "unable to convert type: " +
type->FriendlyName(builder_.Symbols());
return false;
});

View File

@ -614,13 +614,13 @@ class Builder {
std::unordered_map<std::string, uint32_t> import_name_to_id_;
std::unordered_map<Symbol, uint32_t> func_symbol_to_id_;
std::unordered_map<sem::CallTargetSignature, uint32_t> func_sig_to_id_;
std::unordered_map<std::string, uint32_t> type_name_to_id_;
std::unordered_map<const sem::Type*, uint32_t> type_to_id_;
std::unordered_map<ScalarConstant, uint32_t> const_to_id_;
std::unordered_map<std::string, uint32_t> type_constructor_to_id_;
std::unordered_map<std::string, uint32_t> const_null_to_id_;
std::unordered_map<const sem::Type*, uint32_t> const_null_to_id_;
std::unordered_map<uint64_t, uint32_t> const_splat_to_id_;
std::unordered_map<std::string, uint32_t>
texture_type_name_to_sampled_image_type_id_;
std::unordered_map<const sem::Type*, uint32_t>
texture_type_to_sampled_image_type_id_;
ScopeStack<uint32_t> scope_stack_;
std::unordered_map<uint32_t, const ast::Variable*> spirv_id_to_variable_;
std::vector<uint32_t> merge_stack_;

View File

@ -929,34 +929,35 @@ TEST_F(BuilderTest_Type,
}
TEST_F(BuilderTest_Type, Sampler) {
sem::Sampler sampler(ast::SamplerKind::kSampler);
auto* sampler = create<sem::Sampler>(ast::SamplerKind::kSampler);
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(&sampler), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(sampler), 1u);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
}
TEST_F(BuilderTest_Type, ComparisonSampler) {
sem::Sampler sampler(ast::SamplerKind::kComparisonSampler);
auto* sampler = create<sem::Sampler>(ast::SamplerKind::kComparisonSampler);
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(&sampler), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(sampler), 1u);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
}
TEST_F(BuilderTest_Type, Dedup_Sampler_And_ComparisonSampler) {
sem::Sampler comp_sampler(ast::SamplerKind::kComparisonSampler);
sem::Sampler sampler(ast::SamplerKind::kSampler);
auto* comp_sampler =
create<sem::Sampler>(ast::SamplerKind::kComparisonSampler);
auto* sampler = create<sem::Sampler>(ast::SamplerKind::kSampler);
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(&comp_sampler), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(comp_sampler), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(&sampler), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(sampler), 1u);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");