tint: Use type::Struct where possible

type::Struct does not have an ast::Struct declaration, so use that for
builtin structures.

Fix up logic that assumed sem::Struct for both user-declared and builtin
structures to use type::Struct instead.

Assert in the sem::Struct and sem::StructMember that the AST node is not
nullptr.

Change-Id: Ic8fcf27d5610c814ea3b504694c6a94db6cf1191
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/129483
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2023-04-27 18:31:44 +00:00 committed by Dawn LUCI CQ
parent 576ba1c493
commit bc9e422728
54 changed files with 319 additions and 321 deletions

View File

@ -33,19 +33,18 @@ struct NameAndType {
const type::Type* type;
};
sem::Struct* BuildStruct(ProgramBuilder& b,
builtin::Builtin name,
std::initializer_list<NameAndType> member_names_and_types) {
type::Struct* BuildStruct(ProgramBuilder& b,
builtin::Builtin name,
std::initializer_list<NameAndType> member_names_and_types) {
uint32_t offset = 0;
uint32_t max_align = 0;
utils::Vector<const sem::StructMember*, 4> members;
utils::Vector<const type::StructMember*, 4> members;
for (auto& m : member_names_and_types) {
uint32_t align = std::max<uint32_t>(m.type->Align(), 1);
uint32_t size = m.type->Size();
offset = utils::RoundUp(align, offset);
max_align = std::max(max_align, align);
members.Push(b.create<sem::StructMember>(
/* declaration */ nullptr,
members.Push(b.create<type::StructMember>(
/* source */ Source{},
/* name */ b.Sym(m.name),
/* type */ m.type,
@ -58,8 +57,7 @@ sem::Struct* BuildStruct(ProgramBuilder& b,
}
uint32_t size_without_padding = offset;
uint32_t size_with_padding = utils::RoundUp(max_align, offset);
return b.create<sem::Struct>(
/* declaration */ nullptr,
return b.create<type::Struct>(
/* source */ Source{},
/* name */ b.Sym(name),
/* members */ std::move(members),
@ -85,7 +83,7 @@ constexpr std::array kModfVecAbstractNames{
builtin::Builtin::kModfResultVec4Abstract,
};
sem::Struct* CreateModfResult(ProgramBuilder& b, const type::Type* ty) {
type::Struct* CreateModfResult(ProgramBuilder& b, const type::Type* ty) {
return Switch(
ty,
[&](const type::F32*) {
@ -157,7 +155,7 @@ constexpr std::array kFrexpVecAbstractNames{
builtin::Builtin::kFrexpResultVec3Abstract,
builtin::Builtin::kFrexpResultVec4Abstract,
};
sem::Struct* CreateFrexpResult(ProgramBuilder& b, const type::Type* ty) {
type::Struct* CreateFrexpResult(ProgramBuilder& b, const type::Type* ty) {
return Switch(
ty, //
[&](const type::F32*) {
@ -222,7 +220,7 @@ sem::Struct* CreateFrexpResult(ProgramBuilder& b, const type::Type* ty) {
});
}
sem::Struct* CreateAtomicCompareExchangeResult(ProgramBuilder& b, const type::Type* ty) {
type::Struct* CreateAtomicCompareExchangeResult(ProgramBuilder& b, const type::Type* ty) {
return Switch(
ty, //
[&](const type::I32*) {

View File

@ -19,10 +19,8 @@
namespace tint {
class ProgramBuilder;
} // namespace tint
namespace tint::sem {
class Struct;
} // namespace tint::sem
namespace tint::type {
class Struct;
class Type;
} // namespace tint::type
@ -32,19 +30,19 @@ namespace tint::resolver {
* @param ty the type of the `fract` and `whole` struct members.
* @return the builtin struct type for a modf() builtin call.
*/
sem::Struct* CreateModfResult(ProgramBuilder& b, const type::Type* ty);
type::Struct* CreateModfResult(ProgramBuilder& b, const type::Type* ty);
/**
* @param fract the type of the `fract` struct member.
* @return the builtin struct type for a frexp() builtin call.
*/
sem::Struct* CreateFrexpResult(ProgramBuilder& b, const type::Type* fract);
type::Struct* CreateFrexpResult(ProgramBuilder& b, const type::Type* fract);
/**
* @param ty the type of the `old_value` struct member.
* @return the builtin struct type for a atomic_compare_exchange() builtin call.
*/
sem::Struct* CreateAtomicCompareExchangeResult(ProgramBuilder& b, const type::Type* ty);
type::Struct* CreateAtomicCompareExchangeResult(ProgramBuilder& b, const type::Type* ty);
} // namespace tint::resolver

View File

@ -34,10 +34,10 @@ TEST_P(ResolverBuiltinStructs, Resolve) {
auto* var = GlobalVar("p", ty(GetParam()), builtin::AddressSpace::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* str = As<sem::Struct>(TypeOf(var)->UnwrapRef());
auto* str = As<type::Struct>(TypeOf(var)->UnwrapRef());
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Name().Name(), utils::ToString(GetParam()));
EXPECT_EQ(str->Declaration(), nullptr);
EXPECT_FALSE(Is<sem::Struct>(str));
}
INSTANTIATE_TEST_SUITE_P(,

View File

@ -925,7 +925,7 @@ TEST_F(ResolverBuiltinFloatTest, FrexpScalar_f32) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(call), nullptr);
auto* ty = TypeOf(call)->As<sem::Struct>();
auto* ty = TypeOf(call)->As<type::Struct>();
ASSERT_NE(ty, nullptr);
ASSERT_EQ(ty->Members().Length(), 2u);
@ -956,7 +956,7 @@ TEST_F(ResolverBuiltinFloatTest, FrexpScalar_f16) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(call), nullptr);
auto* ty = TypeOf(call)->As<sem::Struct>();
auto* ty = TypeOf(call)->As<type::Struct>();
ASSERT_NE(ty, nullptr);
ASSERT_EQ(ty->Members().Length(), 2u);
@ -985,7 +985,7 @@ TEST_F(ResolverBuiltinFloatTest, FrexpVector_f32) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(call), nullptr);
auto* ty = TypeOf(call)->As<sem::Struct>();
auto* ty = TypeOf(call)->As<type::Struct>();
ASSERT_NE(ty, nullptr);
ASSERT_EQ(ty->Members().Length(), 2u);
@ -1020,7 +1020,7 @@ TEST_F(ResolverBuiltinFloatTest, FrexpVector_f16) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(call), nullptr);
auto* ty = TypeOf(call)->As<sem::Struct>();
auto* ty = TypeOf(call)->As<type::Struct>();
ASSERT_NE(ty, nullptr);
ASSERT_EQ(ty->Members().Length(), 2u);
@ -1174,7 +1174,7 @@ TEST_F(ResolverBuiltinFloatTest, ModfScalar_f32) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(call), nullptr);
auto* ty = TypeOf(call)->As<sem::Struct>();
auto* ty = TypeOf(call)->As<type::Struct>();
ASSERT_NE(ty, nullptr);
ASSERT_EQ(ty->Members().Length(), 2u);
@ -1205,7 +1205,7 @@ TEST_F(ResolverBuiltinFloatTest, ModfScalar_f16) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(call), nullptr);
auto* ty = TypeOf(call)->As<sem::Struct>();
auto* ty = TypeOf(call)->As<type::Struct>();
ASSERT_NE(ty, nullptr);
ASSERT_EQ(ty->Members().Length(), 2u);
@ -1234,7 +1234,7 @@ TEST_F(ResolverBuiltinFloatTest, ModfVector_f32) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(call), nullptr);
auto* ty = TypeOf(call)->As<sem::Struct>();
auto* ty = TypeOf(call)->As<type::Struct>();
ASSERT_NE(ty, nullptr);
ASSERT_EQ(ty->Members().Length(), 2u);
@ -1269,7 +1269,7 @@ TEST_F(ResolverBuiltinFloatTest, ModfVector_f16) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(call), nullptr);
auto* ty = TypeOf(call)->As<sem::Struct>();
auto* ty = TypeOf(call)->As<type::Struct>();
ASSERT_NE(ty, nullptr);
ASSERT_EQ(ty->Members().Length(), 2u);

View File

@ -948,7 +948,7 @@ TEST_F(ResolverBuiltinsValidationTest, Frexp_Scalar) {
WrapInFunction(builtin);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
auto* res_ty = TypeOf(builtin)->As<type::Struct>();
ASSERT_TRUE(res_ty != nullptr);
auto members = res_ty->Members();
ASSERT_EQ(members.Length(), 2u);
@ -961,7 +961,7 @@ TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec2) {
WrapInFunction(builtin);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
auto* res_ty = TypeOf(builtin)->As<type::Struct>();
ASSERT_TRUE(res_ty != nullptr);
auto members = res_ty->Members();
ASSERT_EQ(members.Length(), 2u);
@ -978,7 +978,7 @@ TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec3) {
WrapInFunction(builtin);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
auto* res_ty = TypeOf(builtin)->As<type::Struct>();
ASSERT_TRUE(res_ty != nullptr);
auto members = res_ty->Members();
ASSERT_EQ(members.Length(), 2u);
@ -995,7 +995,7 @@ TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec4) {
WrapInFunction(builtin);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
auto* res_ty = TypeOf(builtin)->As<type::Struct>();
ASSERT_TRUE(res_ty != nullptr);
auto members = res_ty->Members();
ASSERT_EQ(members.Length(), 2u);
@ -1012,7 +1012,7 @@ TEST_F(ResolverBuiltinsValidationTest, Modf_Scalar) {
WrapInFunction(builtin);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
auto* res_ty = TypeOf(builtin)->As<type::Struct>();
ASSERT_TRUE(res_ty != nullptr);
auto members = res_ty->Members();
ASSERT_EQ(members.Length(), 2u);
@ -1025,7 +1025,7 @@ TEST_F(ResolverBuiltinsValidationTest, Modf_Vec2) {
WrapInFunction(builtin);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
auto* res_ty = TypeOf(builtin)->As<type::Struct>();
ASSERT_TRUE(res_ty != nullptr);
auto members = res_ty->Members();
ASSERT_EQ(members.Length(), 2u);
@ -1042,7 +1042,7 @@ TEST_F(ResolverBuiltinsValidationTest, Modf_Vec3) {
WrapInFunction(builtin);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
auto* res_ty = TypeOf(builtin)->As<type::Struct>();
ASSERT_TRUE(res_ty != nullptr);
auto members = res_ty->Members();
ASSERT_EQ(members.Length(), 2u);
@ -1059,7 +1059,7 @@ TEST_F(ResolverBuiltinsValidationTest, Modf_Vec4) {
WrapInFunction(builtin);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
auto* res_ty = TypeOf(builtin)->As<type::Struct>();
ASSERT_TRUE(res_ty != nullptr);
auto members = res_ty->Members();
ASSERT_EQ(members.Length(), 2u);

View File

@ -166,7 +166,7 @@ TEST_P(ResolverConstEvalBuiltinTest, Test) {
ASSERT_NE(value, nullptr);
EXPECT_TYPE(value->Type(), sem->Type());
if (value->Type()->Is<sem::Struct>()) {
if (value->Type()->Is<type::Struct>()) {
// The result type of the constant-evaluated expression is a structure.
// Compare each of the fields individually.
for (size_t i = 0; i < expected_case.values.Length(); i++) {

View File

@ -1445,7 +1445,7 @@ TEST_F(ResolverConstEvalTest, Array_Struct_f32_Zero) {
ASSERT_NE(sem, nullptr);
auto* arr = sem->Type()->As<type::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::Struct>());
EXPECT_TRUE(arr->ElemType()->Is<type::Struct>());
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->AllZero());
@ -1662,7 +1662,7 @@ TEST_F(ResolverConstEvalTest, Array_Struct_f32_Elements) {
ASSERT_NE(sem, nullptr);
auto* arr = sem->Type()->As<type::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::Struct>());
EXPECT_TRUE(arr->ElemType()->Is<type::Struct>());
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->AllZero());
@ -1787,7 +1787,7 @@ TEST_F(ResolverConstEvalTest, Struct_I32s_ZeroInit) {
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
auto* str = sem->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 3u);
ASSERT_NE(sem->ConstantValue(), nullptr);
@ -1828,7 +1828,7 @@ TEST_F(ResolverConstEvalTest, Struct_MixedScalars_ZeroInit) {
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
auto* str = sem->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 5u);
ASSERT_NE(sem->ConstantValue(), nullptr);
@ -1875,7 +1875,7 @@ TEST_F(ResolverConstEvalTest, Struct_VectorF32s_ZeroInit) {
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
auto* str = sem->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 3u);
ASSERT_NE(sem->ConstantValue(), nullptr);
@ -1928,7 +1928,7 @@ TEST_F(ResolverConstEvalTest, Struct_MixedVectors_ZeroInit) {
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
auto* str = sem->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 5u);
ASSERT_NE(sem->ConstantValue(), nullptr);
@ -1999,7 +1999,7 @@ TEST_F(ResolverConstEvalTest, Struct_Struct_ZeroInit) {
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
auto* str = sem->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 2u);
ASSERT_NE(sem->ConstantValue(), nullptr);
@ -2009,14 +2009,14 @@ TEST_F(ResolverConstEvalTest, Struct_Struct_ZeroInit) {
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::Struct>());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<type::Struct>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->ValueAs<i32>(), 0_i);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->ValueAs<u32>(), 0_u);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(2)->ValueAs<f32>(), 0_f);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::Struct>());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<type::Struct>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->ValueAs<i32>(), 0_i);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->ValueAs<u32>(), 0_u);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->ValueAs<f32>(), 0_f);
@ -2039,7 +2039,7 @@ TEST_F(ResolverConstEvalTest, Struct_MixedScalars_Construct) {
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
auto* str = sem->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 5u);
ASSERT_NE(sem->ConstantValue(), nullptr);
@ -2091,7 +2091,7 @@ TEST_F(ResolverConstEvalTest, Struct_MixedVectors_Construct) {
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
auto* str = sem->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 5u);
ASSERT_NE(sem->ConstantValue(), nullptr);
@ -2163,7 +2163,7 @@ TEST_F(ResolverConstEvalTest, Struct_Struct_Construct) {
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
auto* str = sem->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 2u);
ASSERT_NE(sem->ConstantValue(), nullptr);
@ -2173,14 +2173,14 @@ TEST_F(ResolverConstEvalTest, Struct_Struct_Construct) {
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::Struct>());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<type::Struct>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->ValueAs<i32>(), 1_i);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->ValueAs<u32>(), 2_u);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(2)->ValueAs<f32>(), 3_f);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::Struct>());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<type::Struct>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->ValueAs<i32>(), 4_i);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->ValueAs<u32>(), 0_u);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->ValueAs<f32>(), 6_f);
@ -2199,7 +2199,7 @@ TEST_F(ResolverConstEvalTest, Struct_Array_Construct) {
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
auto* str = sem->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 2u);
ASSERT_NE(sem->ConstantValue(), nullptr);

View File

@ -41,7 +41,7 @@ TEST_F(ResolverConstEvalTest, StructMemberAccess) {
auto* outer = Sem().Get(outer_expr);
ASSERT_NE(outer, nullptr);
auto* str = outer->Type()->As<sem::Struct>();
auto* str = outer->Type()->As<type::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().Length(), 2u);
ASSERT_NE(outer->ConstantValue(), nullptr);
@ -53,7 +53,7 @@ TEST_F(ResolverConstEvalTest, StructMemberAccess) {
ASSERT_NE(o1->ConstantValue(), nullptr);
EXPECT_FALSE(o1->ConstantValue()->AnyZero());
EXPECT_FALSE(o1->ConstantValue()->AllZero());
EXPECT_TRUE(o1->ConstantValue()->Type()->Is<sem::Struct>());
EXPECT_TRUE(o1->ConstantValue()->Type()->Is<type::Struct>());
EXPECT_EQ(o1->ConstantValue()->Index(0)->ValueAs<i32>(), 1_i);
EXPECT_EQ(o1->ConstantValue()->Index(1)->ValueAs<u32>(), 2_u);
EXPECT_EQ(o1->ConstantValue()->Index(2)->ValueAs<f32>(), 3_f);

View File

@ -820,25 +820,25 @@ bool match_atomic_compare_exchange_result(MatchState&, const type::Type* ty, con
return false;
}
const sem::Struct* build_modf_result(MatchState& state, const type::Type* el) {
const type::Struct* build_modf_result(MatchState& state, const type::Type* el) {
return CreateModfResult(state.builder, el);
}
const sem::Struct* build_modf_result_vec(MatchState& state, Number& n, const type::Type* el) {
const type::Struct* build_modf_result_vec(MatchState& state, Number& n, const type::Type* el) {
auto* vec = state.builder.create<type::Vector>(el, n.Value());
return CreateModfResult(state.builder, vec);
}
const sem::Struct* build_frexp_result(MatchState& state, const type::Type* el) {
const type::Struct* build_frexp_result(MatchState& state, const type::Type* el) {
return CreateFrexpResult(state.builder, el);
}
const sem::Struct* build_frexp_result_vec(MatchState& state, Number& n, const type::Type* el) {
const type::Struct* build_frexp_result_vec(MatchState& state, Number& n, const type::Type* el) {
auto* vec = state.builder.create<type::Vector>(el, n.Value());
return CreateFrexpResult(state.builder, vec);
}
const sem::Struct* build_atomic_compare_exchange_result(MatchState& state, const type::Type* ty) {
const type::Struct* build_atomic_compare_exchange_result(MatchState& state, const type::Type* ty) {
return CreateAtomicCompareExchangeResult(state.builder, ty);
}

View File

@ -1253,11 +1253,11 @@ TEST_F(MaterializeAbstractStructure, Modf_Scalar_DefaultType) {
auto* sem = Sem().Get(call);
ASSERT_TRUE(sem->Is<sem::Materialize>());
auto* materialize = sem->As<sem::Materialize>();
ASSERT_TRUE(materialize->Type()->Is<sem::Struct>());
auto* concrete_str = materialize->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Type()->Is<type::Struct>());
auto* concrete_str = materialize->Type()->As<type::Struct>();
ASSERT_TRUE(concrete_str->Members()[0]->Type()->Is<type::F32>());
ASSERT_TRUE(materialize->Expr()->Type()->Is<sem::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Expr()->Type()->Is<type::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<type::Struct>();
ASSERT_TRUE(abstract_str->Members()[0]->Type()->Is<type::AbstractFloat>());
}
@ -1269,12 +1269,12 @@ TEST_F(MaterializeAbstractStructure, Modf_Vector_DefaultType) {
auto* sem = Sem().Get(call);
ASSERT_TRUE(sem->Is<sem::Materialize>());
auto* materialize = sem->As<sem::Materialize>();
ASSERT_TRUE(materialize->Type()->Is<sem::Struct>());
auto* concrete_str = materialize->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Type()->Is<type::Struct>());
auto* concrete_str = materialize->Type()->As<type::Struct>();
ASSERT_TRUE(concrete_str->Members()[0]->Type()->Is<type::Vector>());
ASSERT_TRUE(concrete_str->Members()[0]->Type()->As<type::Vector>()->type()->Is<type::F32>());
ASSERT_TRUE(materialize->Expr()->Type()->Is<sem::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Expr()->Type()->Is<type::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<type::Struct>();
ASSERT_TRUE(abstract_str->Members()[0]->Type()->Is<type::Vector>());
ASSERT_TRUE(
abstract_str->Members()[0]->Type()->As<type::Vector>()->type()->Is<type::AbstractFloat>());
@ -1291,11 +1291,11 @@ TEST_F(MaterializeAbstractStructure, Modf_Scalar_ExplicitType) {
auto* sem = Sem().Get(call);
ASSERT_TRUE(sem->Is<sem::Materialize>());
auto* materialize = sem->As<sem::Materialize>();
ASSERT_TRUE(materialize->Type()->Is<sem::Struct>());
auto* concrete_str = materialize->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Type()->Is<type::Struct>());
auto* concrete_str = materialize->Type()->As<type::Struct>();
ASSERT_TRUE(concrete_str->Members()[0]->Type()->Is<type::F16>());
ASSERT_TRUE(materialize->Expr()->Type()->Is<sem::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Expr()->Type()->Is<type::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<type::Struct>();
ASSERT_TRUE(abstract_str->Members()[0]->Type()->Is<type::AbstractFloat>());
}
@ -1309,12 +1309,12 @@ TEST_F(MaterializeAbstractStructure, Modf_Vector_ExplicitType) {
auto* sem = Sem().Get(call);
ASSERT_TRUE(sem->Is<sem::Materialize>());
auto* materialize = sem->As<sem::Materialize>();
ASSERT_TRUE(materialize->Type()->Is<sem::Struct>());
auto* concrete_str = materialize->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Type()->Is<type::Struct>());
auto* concrete_str = materialize->Type()->As<type::Struct>();
ASSERT_TRUE(concrete_str->Members()[0]->Type()->Is<type::Vector>());
ASSERT_TRUE(concrete_str->Members()[0]->Type()->As<type::Vector>()->type()->Is<type::F16>());
ASSERT_TRUE(materialize->Expr()->Type()->Is<sem::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Expr()->Type()->Is<type::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<type::Struct>();
ASSERT_TRUE(abstract_str->Members()[0]->Type()->Is<type::Vector>());
ASSERT_TRUE(
abstract_str->Members()[0]->Type()->As<type::Vector>()->type()->Is<type::AbstractFloat>());
@ -1328,12 +1328,12 @@ TEST_F(MaterializeAbstractStructure, Frexp_Scalar_DefaultType) {
auto* sem = Sem().Get(call);
ASSERT_TRUE(sem->Is<sem::Materialize>());
auto* materialize = sem->As<sem::Materialize>();
ASSERT_TRUE(materialize->Type()->Is<sem::Struct>());
auto* concrete_str = materialize->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Type()->Is<type::Struct>());
auto* concrete_str = materialize->Type()->As<type::Struct>();
ASSERT_TRUE(concrete_str->Members()[0]->Type()->Is<type::F32>());
ASSERT_TRUE(concrete_str->Members()[1]->Type()->Is<type::I32>());
ASSERT_TRUE(materialize->Expr()->Type()->Is<sem::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Expr()->Type()->Is<type::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<type::Struct>();
ASSERT_TRUE(abstract_str->Members()[0]->Type()->Is<type::AbstractFloat>());
ASSERT_TRUE(abstract_str->Members()[1]->Type()->Is<type::AbstractInt>());
}
@ -1346,14 +1346,14 @@ TEST_F(MaterializeAbstractStructure, Frexp_Vector_DefaultType) {
auto* sem = Sem().Get(call);
ASSERT_TRUE(sem->Is<sem::Materialize>());
auto* materialize = sem->As<sem::Materialize>();
ASSERT_TRUE(materialize->Type()->Is<sem::Struct>());
auto* concrete_str = materialize->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Type()->Is<type::Struct>());
auto* concrete_str = materialize->Type()->As<type::Struct>();
ASSERT_TRUE(concrete_str->Members()[0]->Type()->Is<type::Vector>());
ASSERT_TRUE(concrete_str->Members()[1]->Type()->Is<type::Vector>());
ASSERT_TRUE(concrete_str->Members()[0]->Type()->As<type::Vector>()->type()->Is<type::F32>());
ASSERT_TRUE(concrete_str->Members()[1]->Type()->As<type::Vector>()->type()->Is<type::I32>());
ASSERT_TRUE(materialize->Expr()->Type()->Is<sem::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Expr()->Type()->Is<type::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<type::Struct>();
ASSERT_TRUE(abstract_str->Members()[0]->Type()->Is<type::Vector>());
ASSERT_TRUE(
abstract_str->Members()[0]->Type()->As<type::Vector>()->type()->Is<type::AbstractFloat>());
@ -1372,12 +1372,12 @@ TEST_F(MaterializeAbstractStructure, Frexp_Scalar_ExplicitType) {
auto* sem = Sem().Get(call);
ASSERT_TRUE(sem->Is<sem::Materialize>());
auto* materialize = sem->As<sem::Materialize>();
ASSERT_TRUE(materialize->Type()->Is<sem::Struct>());
auto* concrete_str = materialize->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Type()->Is<type::Struct>());
auto* concrete_str = materialize->Type()->As<type::Struct>();
ASSERT_TRUE(concrete_str->Members()[0]->Type()->Is<type::F16>());
ASSERT_TRUE(concrete_str->Members()[1]->Type()->Is<type::I32>());
ASSERT_TRUE(materialize->Expr()->Type()->Is<sem::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Expr()->Type()->Is<type::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<type::Struct>();
ASSERT_TRUE(abstract_str->Members()[0]->Type()->Is<type::AbstractFloat>());
ASSERT_TRUE(abstract_str->Members()[1]->Type()->Is<type::AbstractInt>());
}
@ -1392,14 +1392,14 @@ TEST_F(MaterializeAbstractStructure, Frexp_Vector_ExplicitType) {
auto* sem = Sem().Get(call);
ASSERT_TRUE(sem->Is<sem::Materialize>());
auto* materialize = sem->As<sem::Materialize>();
ASSERT_TRUE(materialize->Type()->Is<sem::Struct>());
auto* concrete_str = materialize->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Type()->Is<type::Struct>());
auto* concrete_str = materialize->Type()->As<type::Struct>();
ASSERT_TRUE(concrete_str->Members()[0]->Type()->Is<type::Vector>());
ASSERT_TRUE(concrete_str->Members()[1]->Type()->Is<type::Vector>());
ASSERT_TRUE(concrete_str->Members()[0]->Type()->As<type::Vector>()->type()->Is<type::F16>());
ASSERT_TRUE(concrete_str->Members()[1]->Type()->As<type::Vector>()->type()->Is<type::I32>());
ASSERT_TRUE(materialize->Expr()->Type()->Is<sem::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<sem::Struct>();
ASSERT_TRUE(materialize->Expr()->Type()->Is<type::Struct>());
auto* abstract_str = materialize->Expr()->Type()->As<type::Struct>();
ASSERT_TRUE(abstract_str->Members()[0]->Type()->Is<type::Vector>());
ASSERT_TRUE(
abstract_str->Members()[0]->Type()->As<type::Vector>()->type()->Is<type::AbstractFloat>());

View File

@ -997,7 +997,7 @@ sem::Function* Resolver::Function(const ast::Function* decl) {
func->AddParameter(p);
auto* p_ty = const_cast<type::Type*>(p->Type());
if (auto* str = p_ty->As<sem::Struct>()) {
if (auto* str = p_ty->As<type::Struct>()) {
switch (decl->PipelineStage()) {
case ast::PipelineStage::kVertex:
str->AddUsage(type::PipelineStageUsage::kVertexInput);
@ -1096,7 +1096,7 @@ sem::Function* Resolver::Function(const ast::Function* decl) {
}
}
if (auto* str = return_type->As<sem::Struct>()) {
if (auto* str = return_type->As<type::Struct>()) {
if (!ApplyAddressSpaceUsageToType(builtin::AddressSpace::kUndefined, str, decl->source)) {
AddNote("while instantiating return type for " + decl->name->symbol.Name(),
decl->source);
@ -1761,7 +1761,7 @@ const type::Type* Resolver::ConcreteType(const type::Type* ty,
}
return nullptr;
},
[&](const sem::Struct* s) -> const type::Type* {
[&](const type::Struct* s) -> const type::Type* {
if (auto tys = s->ConcreteTypes(); !tys.IsEmpty()) {
return target_ty ? target_ty : tys[0];
}
@ -2143,7 +2143,7 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
}
return call;
},
[&](const sem::Struct* str) -> sem::Call* {
[&](const type::Struct* str) -> sem::Call* {
auto* call_target = struct_ctors_.GetOrCreate(
StructConstructorSig{{str, args.Length(), args_stage}},
[&]() -> sem::ValueConstructor* {
@ -3248,10 +3248,10 @@ sem::ValueExpression* Resolver::MemberAccessor(const ast::MemberAccessorExpressi
return Switch(
storage_ty, //
[&](const sem::Struct* str) -> sem::ValueExpression* {
[&](const type::Struct* str) -> sem::ValueExpression* {
auto symbol = expr->member->symbol;
const sem::StructMember* member = nullptr;
const type::StructMember* member = nullptr;
for (auto* m : str->Members()) {
if (m->Name() == symbol) {
member = m;

View File

@ -560,7 +560,7 @@ class Resolver {
// It is a tuple of the structure type, number of arguments provided and earliest evaluation
// stage.
using StructConstructorSig =
utils::UnorderedKeyWrapper<std::tuple<const sem::Struct*, size_t, sem::EvaluationStage>>;
utils::UnorderedKeyWrapper<std::tuple<const type::Struct*, size_t, sem::EvaluationStage>>;
/// ExprEvalStageConstraint describes a constraint on when expressions can be evaluated.
struct ExprEvalStageConstraint {

View File

@ -1265,7 +1265,7 @@ TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
EXPECT_TRUE(sma->Member()->Type()->Is<type::F32>());
EXPECT_EQ(sma->Object()->Declaration(), mem->object);
EXPECT_EQ(sma->Member()->Index(), 1u);
EXPECT_EQ(sma->Member()->Declaration()->name->symbol, Symbols().Get("second_member"));
EXPECT_EQ(sma->Member()->Name().Name(), "second_member");
}
TEST_F(ResolverTest, Expr_MemberAccessor_Struct_Alias) {

View File

@ -32,7 +32,7 @@ TEST_F(ResolverAddressSpaceUseTest, UnreachableStruct) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->AddressSpaceUsage().empty());
}
@ -44,7 +44,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableFromParameter) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kUndefined));
}
@ -56,7 +56,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableFromReturnType) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kUndefined));
}
@ -68,7 +68,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableFromGlobal) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kPrivate));
}
@ -80,7 +80,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableViaGlobalAlias) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kPrivate));
}
@ -92,7 +92,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableViaGlobalStruct) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kPrivate));
}
@ -104,7 +104,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableViaGlobalArray) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kPrivate));
}
@ -116,7 +116,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableFromLocal) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kFunction));
}
@ -128,7 +128,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableViaLocalAlias) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kFunction));
}
@ -140,7 +140,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableViaLocalStruct) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kFunction));
}
@ -152,7 +152,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructReachableViaLocalArray) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kFunction));
}
@ -166,7 +166,7 @@ TEST_F(ResolverAddressSpaceUseTest, StructMultipleAddressSpaceUses) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(builtin::AddressSpace::kUniform,
builtin::AddressSpace::kStorage,

View File

@ -34,7 +34,7 @@ TEST_F(ResolverPipelineStageUseTest, UnusedStruct) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->PipelineStageUses().empty());
}
@ -46,7 +46,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointParam) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->PipelineStageUses().empty());
}
@ -59,7 +59,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointReturnType) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->PipelineStageUses().empty());
}
@ -74,7 +74,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderParam) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(type::PipelineStageUsage::kVertexInput));
@ -90,7 +90,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderReturnType) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(type::PipelineStageUsage::kVertexOutput));
@ -104,7 +104,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderParam) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(type::PipelineStageUsage::kFragmentInput));
@ -118,7 +118,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderReturnType) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(type::PipelineStageUsage::kFragmentOutput));
@ -135,7 +135,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsComputeShaderParam) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(type::PipelineStageUsage::kComputeInput));
@ -154,7 +154,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(type::PipelineStageUsage::kVertexOutput,
@ -170,7 +170,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamViaAlias) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(type::PipelineStageUsage::kFragmentInput));
@ -184,7 +184,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamLocationSet) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
ASSERT_EQ(1u, sem->Members().Length());
EXPECT_EQ(3u, sem->Members()[0]->Attributes().location);
@ -200,7 +200,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeViaAlias) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(type::PipelineStageUsage::kFragmentOutput));
@ -214,7 +214,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeLocationSet) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
auto* sem = TypeOf(s)->As<type::Struct>();
ASSERT_NE(sem, nullptr);
ASSERT_EQ(1u, sem->Members().Length());
EXPECT_EQ(3u, sem->Members()[0]->Attributes().location);

View File

@ -200,7 +200,7 @@ bool Validator::AddDiagnostic(builtin::DiagnosticRule rule,
// https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section
bool Validator::IsPlain(const type::Type* type) const {
return type->is_scalar() ||
type->IsAnyOf<type::Atomic, type::Vector, type::Matrix, type::Array, sem::Struct>();
type->IsAnyOf<type::Atomic, type::Vector, type::Matrix, type::Array, type::Struct>();
}
// https://gpuweb.github.io/gpuweb/wgsl/#fixed-footprint-types
@ -214,7 +214,7 @@ bool Validator::IsFixedFootprint(const type::Type* type) const {
return !arr->Count()->Is<type::RuntimeArrayCount>() &&
IsFixedFootprint(arr->ElemType());
},
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
for (auto* member : str->Members()) {
if (!IsFixedFootprint(member->Type())) {
return false;
@ -235,7 +235,7 @@ bool Validator::IsHostShareable(const type::Type* type) const {
[&](const type::Vector* vec) { return IsHostShareable(vec->type()); },
[&](const type::Matrix* mat) { return IsHostShareable(mat->type()); },
[&](const type::Array* arr) { return IsHostShareable(arr->ElemType()); },
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
for (auto* member : str->Members()) {
if (!IsHostShareable(member->Type())) {
return false;
@ -397,11 +397,11 @@ bool Validator::AddressSpaceLayout(const type::Type* store_ty,
auto is_uniform_struct_or_array = [address_space](const type::Type* ty) {
return address_space == builtin::AddressSpace::kUniform &&
ty->IsAnyOf<type::Array, sem::Struct>();
ty->IsAnyOf<type::Array, type::Struct>();
};
auto is_uniform_struct = [address_space](const type::Type* ty) {
return address_space == builtin::AddressSpace::kUniform && ty->Is<sem::Struct>();
return address_space == builtin::AddressSpace::kUniform && ty->Is<type::Struct>();
};
auto required_alignment_of = [&](const type::Type* ty) {
@ -413,7 +413,7 @@ bool Validator::AddressSpaceLayout(const type::Type* store_ty,
return required_align;
};
auto member_name_of = [](const sem::StructMember* sm) { return sm->Name().Name(); };
auto member_name_of = [](const type::StructMember* sm) { return sm->Name().Name(); };
// Only validate the [type + address space] once
if (!valid_type_storage_layouts_.Add(TypeAndAddressSpace{store_ty, address_space})) {
@ -1138,12 +1138,12 @@ bool Validator::EntryPoint(const sem::Function* func, ast::PipelineStage stage)
}
if (IsValidationEnabled(attrs, ast::DisabledValidation::kEntryPointParameter)) {
if (is_struct_member && ty->Is<sem::Struct>()) {
if (is_struct_member && ty->Is<type::Struct>()) {
AddError("nested structures cannot be used for entry point IO", source);
return false;
}
if (!ty->Is<sem::Struct>() && !pipeline_io_attribute) {
if (!ty->Is<type::Struct>() && !pipeline_io_attribute) {
std::string err = "missing entry point IO attribute";
if (!is_struct_member) {
err += (param_or_ret == ParamOrRetType::kParameter ? " on parameter"
@ -1763,7 +1763,7 @@ bool Validator::FunctionCall(const sem::Call* call, sem::Statement* current_stat
}
bool Validator::StructureInitializer(const ast::CallExpression* ctor,
const sem::Struct* struct_type) const {
const type::Struct* struct_type) const {
if (!struct_type->IsConstructible()) {
AddError("structure constructor has non-constructible type", ctor->source);
return false;
@ -2564,8 +2564,8 @@ bool Validator::CheckTypeAccessAddressSpace(
}
return true;
},
[&](const sem::Struct*) { return check_sub_atomics(); }, //
[&](const type::Array*) { return check_sub_atomics(); }, //
[&](const type::Struct*) { return check_sub_atomics(); }, //
[&](const type::Array*) { return check_sub_atomics(); }, //
[&](Default) { return true; });
}

View File

@ -397,7 +397,7 @@ class Validator {
/// @param struct_type the type of the structure
/// @returns true on success, false otherwise
bool StructureInitializer(const ast::CallExpression* ctor,
const sem::Struct* struct_type) const;
const type::Struct* struct_type) const;
/// Validates a switch statement
/// @param s the switch to validate

View File

@ -81,8 +81,8 @@ TEST_F(ResolverVariableTest, LocalVar_NoInitializer) {
EXPECT_TRUE(TypeOf(f)->As<type::Reference>()->StoreType()->Is<type::F32>());
EXPECT_TRUE(TypeOf(h)->As<type::Reference>()->StoreType()->Is<type::F16>());
EXPECT_TRUE(TypeOf(b)->As<type::Reference>()->StoreType()->Is<type::Bool>());
EXPECT_TRUE(TypeOf(s)->As<type::Reference>()->StoreType()->Is<sem::Struct>());
EXPECT_TRUE(TypeOf(a)->As<type::Reference>()->StoreType()->Is<sem::Struct>());
EXPECT_TRUE(TypeOf(s)->As<type::Reference>()->StoreType()->Is<type::Struct>());
EXPECT_TRUE(TypeOf(a)->As<type::Reference>()->StoreType()->Is<type::Struct>());
EXPECT_EQ(Sem().Get(i)->Initializer(), nullptr);
EXPECT_EQ(Sem().Get(u)->Initializer(), nullptr);
@ -161,8 +161,8 @@ TEST_F(ResolverVariableTest, LocalVar_WithInitializer) {
EXPECT_TRUE(TypeOf(f)->As<type::Reference>()->StoreType()->Is<type::F32>());
EXPECT_TRUE(TypeOf(h)->As<type::Reference>()->StoreType()->Is<type::F16>());
EXPECT_TRUE(TypeOf(b)->As<type::Reference>()->StoreType()->Is<type::Bool>());
EXPECT_TRUE(TypeOf(s)->As<type::Reference>()->StoreType()->Is<sem::Struct>());
EXPECT_TRUE(TypeOf(a)->As<type::Reference>()->StoreType()->Is<sem::Struct>());
EXPECT_TRUE(TypeOf(s)->As<type::Reference>()->StoreType()->Is<type::Struct>());
EXPECT_TRUE(TypeOf(a)->As<type::Reference>()->StoreType()->Is<type::Struct>());
EXPECT_EQ(Sem().Get(i)->Initializer()->Declaration(), i_c);
EXPECT_EQ(Sem().Get(u)->Initializer()->Declaration(), u_c);
@ -444,8 +444,8 @@ TEST_F(ResolverVariableTest, LocalLet) {
ASSERT_TRUE(TypeOf(f)->Is<type::F32>());
ASSERT_TRUE(TypeOf(h)->Is<type::F16>());
ASSERT_TRUE(TypeOf(b)->Is<type::Bool>());
ASSERT_TRUE(TypeOf(s)->Is<sem::Struct>());
ASSERT_TRUE(TypeOf(a)->Is<sem::Struct>());
ASSERT_TRUE(TypeOf(s)->Is<type::Struct>());
ASSERT_TRUE(TypeOf(a)->Is<type::Struct>());
ASSERT_TRUE(TypeOf(p)->Is<type::Pointer>());
ASSERT_TRUE(TypeOf(p)->As<type::Pointer>()->StoreType()->Is<type::I32>());
@ -924,7 +924,7 @@ TEST_F(ResolverVariableTest, LocalConst_ExplicitType_Decls) {
ASSERT_TRUE(TypeOf(c_vu32)->Is<type::Vector>());
ASSERT_TRUE(TypeOf(c_vf32)->Is<type::Vector>());
ASSERT_TRUE(TypeOf(c_mf32)->Is<type::Matrix>());
ASSERT_TRUE(TypeOf(c_s)->Is<sem::Struct>());
ASSERT_TRUE(TypeOf(c_s)->Is<type::Struct>());
EXPECT_TRUE(Sem().Get(c_i32)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_u32)->ConstantValue()->AllZero());
@ -987,7 +987,7 @@ TEST_F(ResolverVariableTest, LocalConst_ImplicitType_Decls) {
ASSERT_TRUE(TypeOf(c_vaf)->Is<type::Vector>());
ASSERT_TRUE(TypeOf(c_mf32)->Is<type::Matrix>());
ASSERT_TRUE(TypeOf(c_maf32)->Is<type::Matrix>());
ASSERT_TRUE(TypeOf(c_s)->Is<sem::Struct>());
ASSERT_TRUE(TypeOf(c_s)->Is<type::Struct>());
EXPECT_TRUE(Sem().Get(c_i32)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_u32)->ConstantValue()->AllZero());

View File

@ -41,7 +41,7 @@ StructMemberAccess::StructMemberAccess(const ast::MemberAccessorExpression* decl
const Statement* statement,
const constant::Value* constant,
const ValueExpression* object,
const StructMember* member,
const type::StructMember* member,
bool has_side_effects,
const Variable* root_ident /* = nullptr */)
: Base(declaration,

View File

@ -22,9 +22,9 @@
namespace tint::ast {
class MemberAccessorExpression;
} // namespace tint::ast
namespace tint::sem {
namespace tint::type {
class StructMember;
} // namespace tint::sem
} // namespace tint::type
namespace tint::sem {
@ -81,7 +81,7 @@ class StructMemberAccess final
const Statement* statement,
const constant::Value* constant,
const ValueExpression* object,
const StructMember* member,
const type::StructMember* member,
bool has_side_effects,
const Variable* root_ident = nullptr);
@ -89,10 +89,10 @@ class StructMemberAccess final
~StructMemberAccess() override;
/// @returns the structure member
StructMember const* Member() const { return member_; }
type::StructMember const* Member() const { return member_; }
private:
StructMember const* const member_;
type::StructMember const* const member_;
};
/// Swizzle holds the semantic information for a ast::MemberAccessorExpression

View File

@ -28,7 +28,9 @@ Struct::Struct(const ast::Struct* declaration,
uint32_t align,
uint32_t size,
uint32_t size_no_padding)
: Base(source, name, members, align, size, size_no_padding), declaration_(declaration) {}
: Base(source, name, members, align, size, size_no_padding), declaration_(declaration) {
TINT_ASSERT(Semantic, declaration != nullptr);
}
Struct::~Struct() = default;
@ -41,7 +43,9 @@ StructMember::StructMember(const ast::StructMember* declaration,
uint32_t align,
uint32_t size,
const type::StructMemberAttributes& attributes)
: Base(source, name, type, index, offset, align, size, attributes), declaration_(declaration) {}
: Base(source, name, type, index, offset, align, size, attributes), declaration_(declaration) {
TINT_ASSERT(Semantic, declaration != nullptr);
}
StructMember::~StructMember() = default;

View File

@ -38,6 +38,7 @@ class StructMember;
namespace tint::sem {
/// Struct holds the semantic information for structures.
/// Unlike type::Struct, sem::Struct has an AST declaration node.
class Struct final : public utils::Castable<Struct, type::Struct> {
public:
/// Constructor
@ -47,8 +48,7 @@ class Struct final : public utils::Castable<Struct, type::Struct> {
/// @param members the structure members
/// @param align the byte alignment of the structure
/// @param size the byte size of the structure
/// @param size_no_padding size of the members without the end of structure
/// alignment padding
/// @param size_no_padding size of the members without the end of structure alignment padding
Struct(const ast::Struct* declaration,
tint::Source source,
Symbol name,
@ -73,6 +73,7 @@ class Struct final : public utils::Castable<Struct, type::Struct> {
};
/// StructMember holds the semantic information for structure members.
/// Unlike type::StructMember, sem::StructMember has an AST declaration node.
class StructMember final : public utils::Castable<StructMember, type::StructMember> {
public:
/// Constructor

View File

@ -147,7 +147,7 @@ struct ArrayLengthFromUniform::State {
const ast::Expression* total_size = total_storage_buffer_size;
auto* storage_buffer_type = storage_buffer_sem->Type()->UnwrapRef();
const type::Array* array_type = nullptr;
if (auto* str = storage_buffer_type->As<sem::Struct>()) {
if (auto* str = storage_buffer_type->As<type::Struct>()) {
// The variable is a struct, so subtract the byte offset of the array
// member.
auto* array_member_sem = str->Members().Back();

View File

@ -204,7 +204,7 @@ Transform::ApplyResult CalculateArrayLength::Apply(const Program* src,
const type::Array* array_type = Switch(
storage_buffer_type->StoreType(),
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
// The variable is a struct, so subtract the byte offset of
// the array member.
auto* array_member_sem = str->Members().Back();

View File

@ -371,7 +371,7 @@ struct CanonicalizeEntryPointIO::State {
// list to pass them through to the inner function.
utils::Vector<const ast::Expression*, 8> inner_struct_values;
for (auto* member : str->Members()) {
if (TINT_UNLIKELY(member->Type()->Is<sem::Struct>())) {
if (TINT_UNLIKELY(member->Type()->Is<type::Struct>())) {
TINT_ICE(Transform, ctx.dst->Diagnostics()) << "nested IO struct";
continue;
}
@ -400,7 +400,7 @@ struct CanonicalizeEntryPointIO::State {
bool do_interpolate = func_ast->PipelineStage() != ast::PipelineStage::kFragment;
if (auto* str = inner_ret_type->As<sem::Struct>()) {
for (auto* member : str->Members()) {
if (TINT_UNLIKELY(member->Type()->Is<sem::Struct>())) {
if (TINT_UNLIKELY(member->Type()->Is<type::Struct>())) {
TINT_ICE(Transform, ctx.dst->Diagnostics()) << "nested IO struct";
continue;
}
@ -639,7 +639,7 @@ struct CanonicalizeEntryPointIO::State {
// aggregated into a single structure.
if (!func_sem->Parameters().IsEmpty()) {
for (auto* param : func_sem->Parameters()) {
if (param->Type()->Is<sem::Struct>()) {
if (param->Type()->Is<type::Struct>()) {
ProcessStructParameter(param);
} else {
ProcessNonStructParameter(param);

View File

@ -522,7 +522,7 @@ struct DecomposeMemoryAccess::State {
auto* offset = b.Add("offset", u32(i * mat_ty->ColumnStride()));
values.Push(b.Call(load, offset));
}
} else if (auto* str = el_ty->As<sem::Struct>()) {
} else if (auto* str = el_ty->As<type::Struct>()) {
for (auto* member : str->Members()) {
auto* offset = b.Add("offset", u32(member->Offset()));
Symbol load = LoadFunc(member->Type()->UnwrapRef(), address_space, buffer);
@ -607,7 +607,7 @@ struct DecomposeMemoryAccess::State {
}
return stmts;
},
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
utils::Vector<const ast::Statement*, 8> stmts;
for (auto* member : str->Members()) {
auto* offset = b.Add("offset", u32(member->Offset()));
@ -660,8 +660,8 @@ struct DecomposeMemoryAccess::State {
// For intrinsics that return a struct, there is no AST node for it, so create one now.
if (intrinsic->Type() == builtin::Function::kAtomicCompareExchangeWeak) {
auto* str = intrinsic->ReturnType()->As<sem::Struct>();
TINT_ASSERT(Transform, str && str->Declaration() == nullptr);
auto* str = intrinsic->ReturnType()->As<type::Struct>();
TINT_ASSERT(Transform, str);
utils::Vector<const ast::StructMember*, 8> ast_members;
ast_members.Reserve(str->Members().Length());
@ -869,7 +869,7 @@ Transform::ApplyResult DecomposeMemoryAccess::Apply(const Program* src,
}
} else {
if (auto access = state.TakeAccess(accessor->object)) {
auto* str_ty = access.type->As<sem::Struct>();
auto* str_ty = access.type->As<type::Struct>();
auto* member = str_ty->FindMember(accessor->member->symbol);
auto offset = member->Offset();
state.AddAccess(accessor, {

View File

@ -70,7 +70,7 @@ Transform::ApplyResult DecomposeStridedMatrix::Apply(const Program* src,
// Scan the program for all storage and uniform structure matrix members with
// a custom stride attribute. Replace these matrices with an equivalent array,
// and populate the `decomposed` map with the members that have been replaced.
utils::Hashmap<const ast::StructMember*, MatrixInfo, 8> decomposed;
utils::Hashmap<const type::StructMember*, MatrixInfo, 8> decomposed;
for (auto* node : src->ASTNodes().Objects()) {
if (auto* str = node->As<ast::Struct>()) {
auto* str_ty = src->Sem().Get(str);
@ -98,7 +98,7 @@ Transform::ApplyResult DecomposeStridedMatrix::Apply(const Program* src,
auto* replacement =
b.Member(member->Offset(), ctx.Clone(member->Name()), info.array(ctx.dst));
ctx.Replace(member->Declaration(), replacement);
decomposed.Add(member->Declaration(), info);
decomposed.Add(member, info);
}
}
}
@ -114,7 +114,7 @@ Transform::ApplyResult DecomposeStridedMatrix::Apply(const Program* src,
ctx.ReplaceAll(
[&](const ast::IndexAccessorExpression* expr) -> const ast::IndexAccessorExpression* {
if (auto* access = src->Sem().Get<sem::StructMemberAccess>(expr->object)) {
if (decomposed.Contains(access->Member()->Declaration())) {
if (decomposed.Contains(access->Member())) {
auto* obj = ctx.CloneWithoutTransform(expr->object);
auto* idx = ctx.Clone(expr->index);
return b.IndexAccessor(obj, idx);
@ -131,7 +131,7 @@ Transform::ApplyResult DecomposeStridedMatrix::Apply(const Program* src,
std::unordered_map<MatrixInfo, Symbol, MatrixInfo::Hasher> mat_to_arr;
ctx.ReplaceAll([&](const ast::AssignmentStatement* stmt) -> const ast::Statement* {
if (auto* access = src->Sem().Get<sem::StructMemberAccess>(stmt->lhs)) {
if (auto info = decomposed.Find(access->Member()->Declaration())) {
if (auto info = decomposed.Find(access->Member())) {
auto fn = utils::GetOrCreate(mat_to_arr, *info, [&] {
auto name =
b.Symbols().New("mat" + std::to_string(info->matrix->columns()) + "x" +
@ -170,7 +170,7 @@ Transform::ApplyResult DecomposeStridedMatrix::Apply(const Program* src,
std::unordered_map<MatrixInfo, Symbol, MatrixInfo::Hasher> arr_to_mat;
ctx.ReplaceAll([&](const ast::MemberAccessorExpression* expr) -> const ast::Expression* {
if (auto* access = src->Sem().Get(expr)->UnwrapLoad()->As<sem::StructMemberAccess>()) {
if (auto info = decomposed.Find(access->Member()->Declaration())) {
if (auto info = decomposed.Find(access->Member())) {
auto fn = utils::GetOrCreate(arr_to_mat, *info, [&] {
auto name =
b.Symbols().New("arr_to_mat" + std::to_string(info->matrix->columns()) +

View File

@ -186,7 +186,7 @@ Transform::ApplyResult DemoteToHelper::Apply(const Program* src, const DataMap&,
// original member values over to it.
// Declare a struct to hold the result values.
auto* result_struct = sem_call->Type()->As<sem::Struct>();
auto* result_struct = sem_call->Type()->As<type::Struct>();
auto* atomic_ty = result_struct->Members()[0]->Type();
result_ty = b.ty(
utils::GetOrCreate(atomic_cmpxchg_result_types, atomic_ty, [&]() {

View File

@ -79,7 +79,7 @@ Transform::ApplyResult FirstIndexOffset::Apply(const Program* src,
// Map of builtin usages
std::unordered_map<const sem::Variable*, const char*> builtin_vars;
std::unordered_map<const sem::StructMember*, const char*> builtin_members;
std::unordered_map<const type::StructMember*, const char*> builtin_members;
bool has_vertex_or_instance_index = false;

View File

@ -60,7 +60,7 @@ struct LocalizeStructArrayAssignment::State {
continue;
}
auto og = GetOriginatingTypeAndAddressSpace(assign_stmt);
if (!(og.first->Is<sem::Struct>() &&
if (!(og.first->Is<type::Struct>() &&
(og.second == builtin::AddressSpace::kFunction ||
og.second == builtin::AddressSpace::kPrivate))) {
continue;

View File

@ -54,7 +54,7 @@ bool ContainsMatrix(const type::Type* type) {
return true;
} else if (auto* ary = type->As<type::Array>()) {
return ContainsMatrix(ary->ElemType());
} else if (auto* str = type->As<sem::Struct>()) {
} else if (auto* str = type->As<type::Struct>()) {
for (auto* member : str->Members()) {
if (ContainsMatrix(member->Type())) {
return true;
@ -85,11 +85,6 @@ struct ModuleScopeVarToEntryPointParam::State {
return;
}
if (!str->Declaration()) {
// The struct is a built-in structure that we do not need to declare.
return;
}
// Recurse into members.
for (auto* member : str->Members()) {
CloneStructTypes(member->Type());

View File

@ -99,10 +99,7 @@ Transform::ApplyResult NumWorkgroupsFromUniform::Apply(const Program* src,
}
for (auto* member : str->Members()) {
auto* builtin =
ast::GetAttribute<ast::BuiltinAttribute>(member->Declaration()->attributes);
if (!builtin ||
src->Sem().Get(builtin)->Value() != builtin::BuiltinValue::kNumWorkgroups) {
if (member->Attributes().builtin != builtin::BuiltinValue::kNumWorkgroups) {
continue;
}

View File

@ -159,7 +159,7 @@ struct PackedVec3::State {
}
return {};
},
[&](const sem::Struct* str) -> ast::Type {
[&](const type::Struct* str) -> ast::Type {
if (ContainsVec3(str)) {
auto name = rewritten_structs.GetOrCreate(str, [&]() {
utils::Vector<const ast::StructMember*, 4> members;
@ -170,12 +170,14 @@ struct PackedVec3::State {
// Copy the member attributes.
bool needs_align = true;
utils::Vector<const ast::Attribute*, 4> attributes;
for (auto* attr : member->Declaration()->attributes) {
if (attr->IsAnyOf<ast::StructMemberAlignAttribute,
ast::StructMemberOffsetAttribute>()) {
needs_align = false;
if (auto* sem_mem = member->As<sem::StructMember>()) {
for (auto* attr : sem_mem->Declaration()->attributes) {
if (attr->IsAnyOf<ast::StructMemberAlignAttribute,
ast::StructMemberOffsetAttribute>()) {
needs_align = false;
}
attributes.Push(ctx.Clone(attr));
}
attributes.Push(ctx.Clone(attr));
}
// If the alignment wasn't already specified, add an attribute to
// make sure that we don't alter the alignment when using the packed
@ -187,12 +189,17 @@ struct PackedVec3::State {
std::move(attributes)));
} else {
// No vec3s, just clone the member as is.
members.Push(ctx.Clone(member->Declaration()));
if (auto* sem_mem = member->As<sem::StructMember>()) {
members.Push(ctx.Clone(sem_mem->Declaration()));
} else {
members.Push(b.Member(ctx.Clone(member->Name()), new_type,
utils::Empty));
}
}
}
// Create the new structure.
auto struct_name = b.Symbols().New(str->Declaration()->name->symbol.Name() +
"_tint_packed_vec3");
auto struct_name =
b.Symbols().New(str->Name().Name() + "_tint_packed_vec3");
b.Structure(struct_name, std::move(members));
return struct_name;
});
@ -246,7 +253,7 @@ struct PackedVec3::State {
[&](const type::Matrix* mat) {
copy_array_elements(mat->columns(), mat->ColumnType());
},
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
// Copy the struct members over one at a time, packing/unpacking as necessary.
for (auto* member : str->Members()) {
const ast::Expression* element =

View File

@ -4328,7 +4328,7 @@ fn main() {
// The first member should have an alignment of 16 bytes, a size of 12 bytes, and the second
// member should have an offset of 12 bytes.
auto* sem_str = got.program.Sem().Get(vars[0]);
auto* str_ty = sem_str->Type()->UnwrapRef()->As<sem::Struct>();
auto* str_ty = sem_str->Type()->UnwrapRef()->As<type::Struct>();
ASSERT_NE(str_ty, nullptr);
ASSERT_EQ(str_ty->Members().Length(), 2u);
EXPECT_EQ(str_ty->Members()[0]->Align(), 16u);

View File

@ -84,7 +84,7 @@ Transform::ApplyResult PadStructs::Apply(const Program* src, const DataMap&, Dat
new_members.Push(b.Member(name, type));
uint32_t size = ty->Size();
if (ty->Is<sem::Struct>() && str->UsedAs(builtin::AddressSpace::kUniform)) {
if (ty->Is<type::Struct>() && str->UsedAs(builtin::AddressSpace::kUniform)) {
// std140 structs should be padded out to 16 bytes.
size = utils::RoundUp(16u, size);
} else if (auto* array_ty = ty->As<type::Array>()) {

View File

@ -160,12 +160,12 @@ struct PreservePadding::State {
return body;
});
},
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
// Call a helper function that assigns each member separately.
return call_helper([&]() {
utils::Vector<const ast::Statement*, 8> body;
for (auto member : str->Members()) {
auto name = member->Declaration()->name->symbol.Name();
auto name = member->Name().Name();
body.Push(MakeAssignment(member->Type(),
b.MemberAccessor(b.Deref(kDestParamName), name),
b.MemberAccessor(kValueParamName, name)));
@ -199,7 +199,7 @@ struct PreservePadding::State {
}
return HasPadding(col_ty);
},
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
uint32_t current_offset = 0;
for (auto* member : str->Members()) {
if (member->Offset() > current_offset) {

View File

@ -1281,8 +1281,8 @@ Transform::ApplyResult Renamer::Apply(const Program* src,
if (sem->Is<sem::Swizzle>()) {
preserved_identifiers.Add(accessor->member);
} else if (auto* str_expr = src->Sem().GetVal(accessor->object)) {
if (auto* ty = str_expr->Type()->UnwrapRef()->As<sem::Struct>()) {
if (ty->Declaration() == nullptr) { // Builtin structure
if (auto* ty = str_expr->Type()->UnwrapRef()->As<type::Struct>()) {
if (!ty->Is<sem::Struct>()) { // Builtin structure
preserved_identifiers.Add(accessor->member);
}
}

View File

@ -53,7 +53,7 @@ struct SpirvAtomic::State {
ProgramBuilder b;
/// The clone context
CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
std::unordered_map<const ast::Struct*, ForkedStruct> forked_structs;
std::unordered_map<const type::Struct*, ForkedStruct> forked_structs;
std::unordered_set<const sem::Variable*> atomic_variables;
utils::UniqueVector<const sem::ValueExpression*, 8> atomic_expressions;
@ -123,7 +123,8 @@ struct SpirvAtomic::State {
if (!forked_structs.empty()) {
ctx.ReplaceAll([&](const ast::Struct* str) {
// Is `str` a structure we need to fork?
if (auto it = forked_structs.find(str); it != forked_structs.end()) {
auto* str_ty = ctx.src->Sem().Get(str);
if (auto it = forked_structs.find(str_ty); it != forked_structs.end()) {
const auto& forked = it->second;
// Re-create the structure swapping in the atomic-flavoured members
@ -154,10 +155,10 @@ struct SpirvAtomic::State {
}
private:
ForkedStruct& Fork(const ast::Struct* str) {
ForkedStruct& Fork(const type::Struct* str) {
auto& forked = forked_structs[str];
if (!forked.name.IsValid()) {
forked.name = b.Symbols().New(str->name->symbol.Name() + "_atomic");
forked.name = b.Symbols().New(str->Name().Name() + "_atomic");
}
return forked;
}
@ -179,7 +180,7 @@ struct SpirvAtomic::State {
// Fork the struct (the first time) and mark member(s) that need to be made
// atomic.
auto* member = access->Member();
Fork(member->Struct()->Declaration()).atomic_members.emplace(member->Index());
Fork(member->Struct()).atomic_members.emplace(member->Index());
atomic_expressions.Add(access->Object());
},
[&](const sem::IndexAccessorExpression* index) {
@ -198,7 +199,7 @@ struct SpirvAtomic::State {
ty, //
[&](const type::I32*) { return b.ty.atomic(CreateASTTypeFor(ctx, ty)); },
[&](const type::U32*) { return b.ty.atomic(CreateASTTypeFor(ctx, ty)); },
[&](const sem::Struct* str) { return b.ty(Fork(str->Declaration()).name); },
[&](const type::Struct* str) { return b.ty(Fork(str).name); },
[&](const type::Array* arr) {
if (arr->Count()->Is<type::RuntimeArrayCount>()) {
return b.ty.array(AtomicTypeFor(arr->ElemType()));
@ -231,7 +232,7 @@ struct SpirvAtomic::State {
(atomic_variables.count(e->RootIdentifier()) != 0)) {
// If it's a struct member, make sure it's one we marked as atomic
if (auto* ma = e->As<sem::StructMemberAccess>()) {
auto it = forked_structs.find(ma->Member()->Struct()->Declaration());
auto it = forked_structs.find(ma->Member()->Struct());
if (it != forked_structs.end()) {
auto& forked = it->second;
return forked.atomic_members.count(ma->Member()->Index()) != 0;

View File

@ -144,7 +144,7 @@ struct Std140::State {
// Scan structures for members that need forking
for (auto* ty : src->Types()) {
if (auto* str = ty->As<sem::Struct>()) {
if (auto* str = ty->As<type::Struct>()) {
if (str->UsedAs(builtin::AddressSpace::kUniform)) {
for (auto* member : str->Members()) {
if (needs_fork(member->Type())) {
@ -226,11 +226,11 @@ struct Std140::State {
utils::Hashset<const sem::Variable*, 8> std140_uniforms;
// Map of original structure to 'std140' forked structure
utils::Hashmap<const sem::Struct*, Symbol, 8> std140_structs;
utils::Hashmap<const type::Struct*, Symbol, 8> std140_structs;
// Map of structure member in src of a matrix type, to list of decomposed column
// members in ctx.dst.
utils::Hashmap<const sem::StructMember*, utils::Vector<const ast::StructMember*, 4>, 8>
utils::Hashmap<const type::StructMember*, utils::Vector<const ast::StructMember*, 4>, 8>
std140_mat_members;
/// Describes a matrix that has been forked to a std140-structure holding the decomposed column
@ -403,7 +403,7 @@ struct Std140::State {
ast::Type Std140Type(const type::Type* ty) {
return Switch(
ty, //
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
if (auto std140 = std140_structs.Find(str)) {
return b.ty(*std140);
}
@ -631,7 +631,7 @@ struct Std140::State {
const std::string ConvertSuffix(const type::Type* ty) {
return Switch(
ty, //
[&](const sem::Struct* str) { return str->Name().Name(); },
[&](const type::Struct* str) { return str->Name().Name(); },
[&](const type::Array* arr) {
auto count = arr->ConstantCount();
if (TINT_UNLIKELY(!count)) {
@ -694,7 +694,7 @@ struct Std140::State {
Switch(
ty, //
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
// Convert each of the structure members using either a converter function
// call, or by reassembling a std140 matrix from column vector members.
utils::Vector<const ast::Expression*, 8> args;
@ -832,7 +832,7 @@ struct Std140::State {
// As this is accessing only part of the matrix, we just need to pick the right column
// vector member.
auto column_idx = std::get<u32>(chain.indices[std140_mat_idx + 1]);
if (auto* str = tint::As<sem::Struct>(ty)) {
if (auto* str = tint::As<type::Struct>(ty)) {
// Structure member matrix. The columns are decomposed into the structure.
auto mat_member_idx = std::get<u32>(chain.indices[std140_mat_idx]);
auto* mat_member = str->Members()[mat_member_idx];
@ -913,7 +913,7 @@ struct Std140::State {
}
}
if (auto* str = tint::As<sem::Struct>(ty)) {
if (auto* str = tint::As<type::Struct>(ty)) {
// Structure member matrix. The columns are decomposed into the structure.
auto mat_member_idx = std::get<u32>(chain.indices[std140_mat_idx]);
auto* mat_member = str->Members()[mat_member_idx];
@ -1012,7 +1012,7 @@ struct Std140::State {
stmts.Push(b.Decl(let));
utils::Vector<const ast::MemberAccessorExpression*, 4> columns;
if (auto* str = tint::As<sem::Struct>(ty)) {
if (auto* str = tint::As<type::Struct>(ty)) {
// Structure member matrix. The columns are decomposed into the structure.
auto mat_member_idx = std::get<u32>(chain.indices[std140_mat_idx]);
auto* mat_member = str->Members()[mat_member_idx];
@ -1133,7 +1133,7 @@ struct Std140::State {
auto idx = std::get<u32>(access);
return Switch(
ty, //
[&](const sem::Struct* str) -> ExprTypeName {
[&](const type::Struct* str) -> ExprTypeName {
auto* member = str->Members()[idx];
auto member_name = member->Name().Name();
auto* expr = b.MemberAccessor(lhs, member_name);

View File

@ -143,7 +143,7 @@ ast::Type Transform::CreateASTTypeFor(CloneContext& ctx, const type::Type* ty) {
}
return ctx.dst->ty.array(el, u32(count.value()), std::move(attrs));
}
if (auto* s = ty->As<sem::Struct>()) {
if (auto* s = ty->As<type::Struct>()) {
return ctx.dst->ty(ctx.Clone(s->Name()));
}
if (auto* s = ty->As<type::Reference>()) {

View File

@ -168,19 +168,16 @@ struct ZeroInitWorkgroupMemory::State {
}
}
if (auto* str = sem.Get(param)->Type()->As<sem::Struct>()) {
if (auto* str = sem.Get(param)->Type()->As<type::Struct>()) {
for (auto* member : str->Members()) {
if (auto* builtin_attr = ast::GetAttribute<ast::BuiltinAttribute>(
member->Declaration()->attributes)) {
auto builtin = sem.Get(builtin_attr)->Value();
if (builtin == builtin::BuiltinValue::kLocalInvocationIndex) {
local_index = [=] {
auto* param_expr = b.Expr(ctx.Clone(param->name->symbol));
auto* member_name = ctx.Clone(member->Declaration()->name);
return b.MemberAccessor(param_expr, member_name);
};
break;
}
if (member->Attributes().builtin ==
builtin::BuiltinValue::kLocalInvocationIndex) {
local_index = [=] {
auto* param_expr = b.Expr(ctx.Clone(param->name->symbol));
auto member_name = ctx.Clone(member->Name());
return b.MemberAccessor(param_expr, member_name);
};
break;
}
}
}
@ -318,9 +315,9 @@ struct ZeroInitWorkgroupMemory::State {
return true;
}
if (auto* str = ty->As<sem::Struct>()) {
if (auto* str = ty->As<type::Struct>()) {
for (auto* member : str->Members()) {
auto name = ctx.Clone(member->Declaration()->name->symbol);
auto name = ctx.Clone(member->Name());
auto get_member = [&](uint32_t num_values) {
auto s = get_expr(num_values);
if (!s) {
@ -444,7 +441,7 @@ struct ZeroInitWorkgroupMemory::State {
if (ty->Is<type::Atomic>()) {
return false;
}
if (auto* str = ty->As<sem::Struct>()) {
if (auto* str = ty->As<type::Struct>()) {
for (auto* member : str->Members()) {
if (!CanTriviallyZero(member->Type())) {
return false;

View File

@ -814,7 +814,7 @@ void GeneratorImpl::EmitWorkgroupAtomicCall(utils::StringStream& out,
return;
}
case builtin::Function::kAtomicCompareExchangeWeak: {
EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>());
EmitStructType(&helpers_, builtin->ReturnType()->As<type::Struct>());
auto* dest = expr->args[0];
auto* compare_value = expr->args[1];
@ -1043,7 +1043,7 @@ void GeneratorImpl::EmitModfCall(utils::StringStream& out,
[&](TextBuffer* b, const std::vector<std::string>& params) {
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>());
EmitStructType(&helpers_, builtin->ReturnType()->As<type::Struct>());
{
auto l = line(b);
@ -1064,7 +1064,7 @@ void GeneratorImpl::EmitFrexpCall(utils::StringStream& out,
[&](TextBuffer* b, const std::vector<std::string>& params) {
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>());
EmitStructType(&helpers_, builtin->ReturnType()->As<type::Struct>());
{
auto l = line(b);
@ -1769,7 +1769,7 @@ void GeneratorImpl::EmitGlobalVariable(const ast::Variable* global) {
void GeneratorImpl::EmitUniformVariable(const ast::Var* var, const sem::Variable* sem) {
auto* type = sem->Type()->UnwrapRef();
auto* str = type->As<sem::Struct>();
auto* str = type->As<type::Struct>();
if (TINT_UNLIKELY(!str)) {
TINT_ICE(Writer, builder_.Diagnostics()) << "storage variable must be of struct type";
return;
@ -1788,7 +1788,7 @@ void GeneratorImpl::EmitUniformVariable(const ast::Var* var, const sem::Variable
void GeneratorImpl::EmitStorageVariable(const ast::Var* var, const sem::Variable* sem) {
auto* type = sem->Type()->UnwrapRef();
auto* str = type->As<sem::Struct>();
auto* str = type->As<type::Struct>();
if (TINT_UNLIKELY(!str)) {
TINT_ICE(Writer, builder_.Diagnostics()) << "storage variable must be of struct type";
return;
@ -2040,7 +2040,7 @@ void GeneratorImpl::EmitEntryPointFunction(const ast::Function* func) {
for (auto* var : func->params) {
auto* sem = builder_.Sem().Get(var);
auto* type = sem->Type();
if (TINT_UNLIKELY(!type->Is<sem::Struct>())) {
if (TINT_UNLIKELY(!type->Is<type::Struct>())) {
// ICE likely indicates that the CanonicalizeEntryPointIO transform was
// not run, or a builtin parameter was added after it was run.
TINT_ICE(Writer, diagnostics_) << "Unsupported non-struct entry point parameter";
@ -2132,7 +2132,7 @@ void GeneratorImpl::EmitConstant(utils::StringStream& out, const constant::Value
EmitConstant(out, constant->Index(i));
}
},
[&](const sem::Struct* s) {
[&](const type::Struct* s) {
EmitStructType(&helpers_, s);
out << StructName(s);
@ -2210,7 +2210,7 @@ void GeneratorImpl::EmitZeroValue(utils::StringStream& out, const type::Type* ty
}
EmitZeroValue(out, mat->type());
}
} else if (auto* str = type->As<sem::Struct>()) {
} else if (auto* str = type->As<type::Struct>()) {
EmitType(out, type, builtin::AddressSpace::kUndefined, builtin::Access::kUndefined, "");
bool first = true;
ScopedParen sp(out);
@ -2568,7 +2568,7 @@ void GeneratorImpl::EmitType(utils::StringStream& out,
TINT_ICE(Writer, diagnostics_) << "Attempting to emit pointer type. These should have been "
"removed with the SimplifyPointers transform";
} else if (type->Is<type::Sampler>()) {
} else if (auto* str = type->As<sem::Struct>()) {
} else if (auto* str = type->As<type::Struct>()) {
out << StructName(str);
} else if (auto* tex = type->As<type::Texture>()) {
if (TINT_UNLIKELY(tex->Is<type::ExternalTexture>())) {
@ -2669,7 +2669,7 @@ void GeneratorImpl::EmitTypeAndName(utils::StringStream& out,
}
}
void GeneratorImpl::EmitStructType(TextBuffer* b, const sem::Struct* str) {
void GeneratorImpl::EmitStructType(TextBuffer* b, const type::Struct* str) {
auto it = emitted_structs_.emplace(str);
if (!it.second) {
return;
@ -2682,7 +2682,7 @@ void GeneratorImpl::EmitStructType(TextBuffer* b, const sem::Struct* str) {
line(b);
}
void GeneratorImpl::EmitStructMembers(TextBuffer* b, const sem::Struct* str) {
void GeneratorImpl::EmitStructMembers(TextBuffer* b, const type::Struct* str) {
ScopedIndent si(b);
for (auto* mem : str->Members()) {
auto name = mem->Name().Name();

View File

@ -383,11 +383,11 @@ class GeneratorImpl : public TextGenerator {
/// this function will simply return `true` without emitting anything.
/// @param buffer the text buffer that the type declaration will be written to
/// @param ty the struct to generate
void EmitStructType(TextBuffer* buffer, const sem::Struct* ty);
void EmitStructType(TextBuffer* buffer, const type::Struct* ty);
/// Handles generating the members of a structure
/// @param buffer the text buffer that the struct members will be written to
/// @param ty the struct to generate
void EmitStructMembers(TextBuffer* buffer, const sem::Struct* ty);
void EmitStructMembers(TextBuffer* buffer, const type::Struct* ty);
/// Handles a unary op expression
/// @param out the output of the expression stream
/// @param expr the expression to emit
@ -460,7 +460,7 @@ class GeneratorImpl : public TextGenerator {
std::unordered_map<const type::Vector*, std::string> dynamic_vector_write_;
std::unordered_map<const type::Vector*, std::string> int_dot_funcs_;
std::unordered_map<BinaryOperandType, std::string> float_modulo_funcs_;
std::unordered_set<const sem::Struct*> emitted_structs_;
std::unordered_set<const type::Struct*> emitted_structs_;
bool requires_oes_sample_variables_ = false;
bool requires_default_precision_qualifier_ = false;
bool requires_f16_extension_ = false;

View File

@ -170,8 +170,8 @@ TEST_F(GlslGeneratorImplTest_Type, EmitType_StructDecl) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
gen.EmitStructType(&buf, sem_s);
auto* str = program->TypeOf(s)->As<type::Struct>();
gen.EmitStructType(&buf, str);
EXPECT_THAT(gen.Diagnostics(), testing::IsEmpty());
EXPECT_EQ(buf.String(), R"(struct S {
int a;
@ -190,9 +190,9 @@ TEST_F(GlslGeneratorImplTest_Type, EmitType_Struct) {
GeneratorImpl& gen = Build();
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
auto* str = program->TypeOf(s)->As<type::Struct>();
utils::StringStream out;
gen.EmitType(out, sem_s, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, "");
gen.EmitType(out, str, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, "");
EXPECT_THAT(gen.Diagnostics(), testing::IsEmpty());
EXPECT_EQ(out.str(), "S");
}
@ -224,8 +224,8 @@ TEST_F(GlslGeneratorImplTest_Type, EmitType_Struct_WithOffsetAttributes) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
gen.EmitStructType(&buf, sem_s);
auto* str = program->TypeOf(s)->As<type::Struct>();
gen.EmitStructType(&buf, str);
EXPECT_THAT(gen.Diagnostics(), testing::IsEmpty());
EXPECT_EQ(buf.String(), R"(struct S {
int a;

View File

@ -1094,7 +1094,7 @@ bool GeneratorImpl::EmitValueConstructor(utils::StringStream& out,
}
}
bool brackets = type->IsAnyOf<type::Array, sem::Struct>();
bool brackets = type->IsAnyOf<type::Array, type::Struct>();
// For single-value vector initializers, swizzle the scalar to the right
// vector dimension using .x
@ -1887,7 +1887,7 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(utils::StringStream& out,
return true;
}
case builtin::Function::kAtomicCompareExchangeWeak: {
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<type::Struct>())) {
return false;
}
@ -2004,7 +2004,7 @@ bool GeneratorImpl::EmitModfCall(utils::StringStream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<type::Struct>())) {
return false;
}
@ -2037,7 +2037,7 @@ bool GeneratorImpl::EmitFrexpCall(utils::StringStream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<type::Struct>())) {
return false;
}
@ -3287,7 +3287,7 @@ bool GeneratorImpl::EmitEntryPointFunction(const ast::Function* func) {
for (auto* var : func->params) {
auto* sem = builder_.Sem().Get(var);
auto* type = sem->Type();
if (TINT_UNLIKELY(!type->Is<sem::Struct>())) {
if (TINT_UNLIKELY(!type->Is<type::Struct>())) {
// ICE likely indicates that the CanonicalizeEntryPointIO transform was
// not run, or a builtin parameter was added after it was run.
TINT_ICE(Writer, diagnostics_) << "Unsupported non-struct entry point parameter";
@ -3437,7 +3437,7 @@ bool GeneratorImpl::EmitConstant(utils::StringStream& out,
return true;
},
[&](const sem::Struct* s) {
[&](const type::Struct* s) {
if (!EmitStructType(&helpers_, s)) {
return false;
}
@ -3580,7 +3580,7 @@ bool GeneratorImpl::EmitValue(utils::StringStream& out, const type::Type* type,
}
return true;
},
[&](const sem::Struct*) {
[&](const type::Struct*) {
out << "(";
TINT_DEFER(out << ")" << value);
return EmitType(out, type, builtin::AddressSpace::kUndefined,
@ -4077,7 +4077,7 @@ bool GeneratorImpl::EmitType(utils::StringStream& out,
out << "State";
return true;
},
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
out << StructName(str);
return true;
},
@ -4202,7 +4202,7 @@ bool GeneratorImpl::EmitTypeAndName(utils::StringStream& out,
return true;
}
bool GeneratorImpl::EmitStructType(TextBuffer* b, const sem::Struct* str) {
bool GeneratorImpl::EmitStructType(TextBuffer* b, const type::Struct* str) {
auto it = emitted_structs_.emplace(str);
if (!it.second) {
return true;

View File

@ -449,7 +449,7 @@ class GeneratorImpl : public TextGenerator {
/// @param buffer the text buffer that the type declaration will be written to
/// @param ty the struct to generate
/// @returns true if the struct is emitted
bool EmitStructType(TextBuffer* buffer, const sem::Struct* ty);
bool EmitStructType(TextBuffer* buffer, const type::Struct* ty);
/// Handles a unary op expression
/// @param out the output of the expression stream
/// @param expr the expression to emit
@ -568,7 +568,7 @@ class GeneratorImpl : public TextGenerator {
std::unordered_map<const type::Matrix*, std::string> dynamic_matrix_vector_write_;
std::unordered_map<const type::Matrix*, std::string> dynamic_matrix_scalar_write_;
std::unordered_map<const type::Type*, std::string> value_or_one_if_zero_;
std::unordered_set<const sem::Struct*> emitted_structs_;
std::unordered_set<const type::Struct*> emitted_structs_;
};
} // namespace tint::writer::hlsl

View File

@ -171,8 +171,8 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.Diagnostics();
auto* str = program->TypeOf(s)->As<type::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, str)) << gen.Diagnostics();
EXPECT_EQ(buf.String(), R"(struct S {
int a;
float b;
@ -203,10 +203,10 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) {
GeneratorImpl& gen = Build();
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
auto* str = program->TypeOf(s)->As<type::Struct>();
utils::StringStream out;
ASSERT_TRUE(gen.EmitType(out, sem_s, builtin::AddressSpace::kUndefined,
builtin::Access::kReadWrite, ""))
ASSERT_TRUE(
gen.EmitType(out, str, builtin::AddressSpace::kUndefined, builtin::Access::kReadWrite, ""))
<< gen.Diagnostics();
EXPECT_EQ(out.str(), "S");
}
@ -238,8 +238,8 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_WithOffsetAttributes) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.Diagnostics();
auto* str = program->TypeOf(s)->As<type::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, str)) << gen.Diagnostics();
EXPECT_EQ(buf.String(), R"(struct S {
int a;
float b;

View File

@ -363,7 +363,7 @@ bool GeneratorImpl::Generate() {
}
bool GeneratorImpl::EmitTypeDecl(const type::Type* ty) {
if (auto* str = ty->As<sem::Struct>()) {
if (auto* str = ty->As<type::Struct>()) {
if (!EmitStructType(current_buffer_, str)) {
return false;
}
@ -826,7 +826,7 @@ bool GeneratorImpl::EmitTypeInitializer(utils::StringStream& out,
terminator = "}";
return true;
},
[&](const sem::Struct*) {
[&](const type::Struct*) {
out << "{";
terminator = "}";
return true;
@ -848,10 +848,9 @@ bool GeneratorImpl::EmitTypeInitializer(utils::StringStream& out,
out << ", ";
}
if (auto* struct_ty = type->As<sem::Struct>()) {
if (auto* struct_ty = type->As<type::Struct>()) {
// Emit field designators for structures to account for padding members.
auto* member = struct_ty->Members()[i]->Declaration();
auto name = member->name->symbol.Name();
auto name = struct_ty->Members()[i]->Name().Name();
out << "." << name << "=";
}
@ -922,11 +921,11 @@ bool GeneratorImpl::EmitAtomicCall(utils::StringStream& out,
case builtin::Function::kAtomicCompareExchangeWeak: {
auto* ptr_ty = TypeOf(expr->args[0])->UnwrapRef()->As<type::Pointer>();
auto sc = ptr_ty->AddressSpace();
auto* str = builtin->ReturnType()->As<sem::Struct>();
auto* str = builtin->ReturnType()->As<type::Struct>();
auto func = utils::GetOrCreate(
atomicCompareExchangeWeak_, ACEWKeyType{{sc, str}}, [&]() -> std::string {
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<type::Struct>())) {
return "";
}
@ -937,7 +936,7 @@ bool GeneratorImpl::EmitAtomicCall(utils::StringStream& out,
{
auto f = line(&buf);
auto str_name = StructName(builtin->ReturnType()->As<sem::Struct>());
auto str_name = StructName(builtin->ReturnType()->As<type::Struct>());
f << str_name << " " << name << "(";
if (!EmitTypeAndName(f, atomic_ty, "atomic")) {
return "";
@ -1361,11 +1360,11 @@ bool GeneratorImpl::EmitModfCall(utils::StringStream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<type::Struct>())) {
return false;
}
line(b) << StructName(builtin->ReturnType()->As<sem::Struct>()) << " result;";
line(b) << StructName(builtin->ReturnType()->As<type::Struct>()) << " result;";
line(b) << "result.fract = modf(" << in << ", result.whole);";
line(b) << "return result;";
return true;
@ -1387,11 +1386,11 @@ bool GeneratorImpl::EmitFrexpCall(utils::StringStream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
if (!EmitStructType(&helpers_, builtin->ReturnType()->As<type::Struct>())) {
return false;
}
line(b) << StructName(builtin->ReturnType()->As<sem::Struct>()) << " result;";
line(b) << StructName(builtin->ReturnType()->As<type::Struct>()) << " result;";
line(b) << "result.fract = frexp(" << in << ", result.exp);";
line(b) << "return result;";
return true;
@ -1658,7 +1657,7 @@ bool GeneratorImpl::EmitZeroValue(utils::StringStream& out, const type::Type* ty
out << "{}";
return true;
},
[&](const sem::Struct*) {
[&](const type::Struct*) {
out << "{}";
return true;
},
@ -1763,7 +1762,7 @@ bool GeneratorImpl::EmitConstant(utils::StringStream& out, const constant::Value
return true;
},
[&](const sem::Struct* s) {
[&](const type::Struct* s) {
if (!EmitStructType(&helpers_, s)) {
return false;
}
@ -2636,7 +2635,7 @@ bool GeneratorImpl::EmitType(utils::StringStream& out,
out << "sampler";
return true;
},
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
// The struct type emits as just the name. The declaration would be
// emitted as part of emitting the declared types.
out << StructName(str);
@ -2791,7 +2790,7 @@ bool GeneratorImpl::EmitAddressSpace(utils::StringStream& out, builtin::AddressS
return false;
}
bool GeneratorImpl::EmitStructType(TextBuffer* b, const sem::Struct* str) {
bool GeneratorImpl::EmitStructType(TextBuffer* b, const type::Struct* str) {
auto it = emitted_structs_.emplace(str);
if (!it.second) {
return true;
@ -3186,7 +3185,7 @@ GeneratorImpl::SizeAndAlign GeneratorImpl::MslPackedTypeSizeAndAlign(const type:
return SizeAndAlign{};
},
[&](const sem::Struct* str) {
[&](const type::Struct* str) {
// TODO(crbug.com/tint/650): There's an assumption here that MSL's
// default structure size and alignment matches WGSL's. We need to
// confirm this.

View File

@ -340,7 +340,7 @@ class GeneratorImpl : public TextGenerator {
/// @param buffer the text buffer that the type declaration will be written to
/// @param str the struct to generate
/// @returns true if the struct is emitted
bool EmitStructType(TextBuffer* buffer, const sem::Struct* str);
bool EmitStructType(TextBuffer* buffer, const type::Struct* str);
/// Handles a unary op expression
/// @param out the output of the expression stream
/// @param expr the expression to emit
@ -418,7 +418,7 @@ class GeneratorImpl : public TextGenerator {
/// Name of atomicCompareExchangeWeak() helper for the given pointer storage
/// class and struct return type
using ACEWKeyType =
utils::UnorderedKeyWrapper<std::tuple<builtin::AddressSpace, const sem::Struct*>>;
utils::UnorderedKeyWrapper<std::tuple<builtin::AddressSpace, const type::Struct*>>;
std::unordered_map<ACEWKeyType, std::string> atomicCompareExchangeWeak_;
/// Unique name of the 'TINT_INVARIANT' preprocessor define.
@ -440,7 +440,7 @@ class GeneratorImpl : public TextGenerator {
std::unordered_map<const sem::Builtin*, std::string> builtins_;
std::unordered_map<const type::Type*, std::string> unary_minus_funcs_;
std::unordered_map<uint32_t, std::string> int_dot_funcs_;
std::unordered_set<const sem::Struct*> emitted_structs_;
std::unordered_set<const type::Struct*> emitted_structs_;
};
} // namespace tint::writer::msl

View File

@ -245,8 +245,8 @@ TEST_F(MslGeneratorImplTest, EmitType_StructDecl) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.Diagnostics();
auto* str = program->TypeOf(s)->As<type::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, str)) << gen.Diagnostics();
EXPECT_EQ(buf.String(), R"(struct S {
int a;
float b;
@ -292,8 +292,8 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_NonComposites) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(type)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.Diagnostics();
auto* str = program->TypeOf(type)->As<type::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, str)) << gen.Diagnostics();
// ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, ARRAY_COUNT, NAME)
// for each field of the structure s.
@ -401,8 +401,8 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_Structures) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(type)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.Diagnostics();
auto* str = program->TypeOf(type)->As<type::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, str)) << gen.Diagnostics();
// ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, ARRAY_COUNT, NAME)
// for each field of the structure s.
@ -493,8 +493,8 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(type)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.Diagnostics();
auto* str = program->TypeOf(type)->As<type::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, str)) << gen.Diagnostics();
// ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, ARRAY_COUNT, NAME)
// for each field of the structure s.
@ -577,8 +577,8 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayVec3DefaultStride) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(type)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.Diagnostics();
auto* str = program->TypeOf(type)->As<type::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, str)) << gen.Diagnostics();
// ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, ARRAY_COUNT, NAME)
// for each field of the structure s.
@ -639,8 +639,8 @@ TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(type)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.Diagnostics();
auto* str = program->TypeOf(type)->As<type::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, str)) << gen.Diagnostics();
EXPECT_EQ(buf.String(), R"(struct S {
/* 0x0000 */ int tint_pad_2;
/* 0x0004 */ tint_array<int8_t, 124> tint_pad_10;
@ -698,8 +698,8 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_WithAttribute) {
GeneratorImpl& gen = Build();
TextGenerator::TextBuffer buf;
auto* sem_s = program->TypeOf(type)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.Diagnostics();
auto* str = program->TypeOf(type)->As<type::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, str)) << gen.Diagnostics();
EXPECT_EQ(buf.String(), R"(struct S {
/* 0x0000 */ int a;
/* 0x0004 */ float b;

View File

@ -790,8 +790,8 @@ bool Builder::GenerateGlobalVariable(const ast::Variable* v) {
ops.push_back(Operand(init_id));
} else {
auto* st = type->As<type::StorageTexture>();
if (st || type->Is<sem::Struct>()) {
// type is a sem::Struct or a type::StorageTexture
if (st || type->Is<type::Struct>()) {
// type is a type::Struct or a type::StorageTexture
auto access = st ? st->access() : sem->Access();
switch (access) {
case builtin::Access::kWrite:
@ -1353,7 +1353,7 @@ uint32_t Builder::GenerateValueConstructorOrConversion(const sem::Call* call,
// If the result is not a vector then we should have validated that the
// value type is a correctly sized vector so we can just use it directly.
if (result_type == value_type || result_type->Is<type::Matrix>() ||
result_type->Is<type::Array>() || result_type->Is<sem::Struct>()) {
result_type->Is<type::Array>() || result_type->Is<type::Struct>()) {
ops.push_back(Operand(id));
continue;
}
@ -1715,7 +1715,7 @@ uint32_t Builder::GenerateConstantIfNeeded(const constant::Value* constant) {
}
return composite(count.value());
},
[&](const sem::Struct* s) { return composite(s->Members().Length()); },
[&](const type::Struct* s) { return composite(s->Members().Length()); },
[&](Default) {
error_ = "unhandled constant type: " + builder_.FriendlyName(ty);
return 0;
@ -2391,13 +2391,12 @@ uint32_t Builder::GenerateBuiltinCall(const sem::Call* call, const sem::Builtin*
params.push_back(Operand(struct_id));
auto* type = TypeOf(accessor->object)->UnwrapRef();
if (!type->Is<sem::Struct>()) {
if (!type->Is<type::Struct>()) {
error_ = "invalid type (" + type->FriendlyName() + ") for runtime array length";
return 0;
}
// Runtime array must be the last member in the structure
params.push_back(
Operand(uint32_t(type->As<sem::Struct>()->Declaration()->members.Length() - 1)));
params.push_back(Operand(uint32_t(type->As<type::Struct>()->Members().Length() - 1)));
if (!push_function_inst(spv::Op::OpArrayLength, params)) {
return 0;
@ -3702,7 +3701,7 @@ uint32_t Builder::GenerateTypeIfNeeded(const type::Type* type) {
[&](const type::Reference* ref) { //
return GenerateReferenceType(ref, result);
},
[&](const sem::Struct* str) { //
[&](const type::Struct* str) { //
return GenerateStructType(str, result);
},
[&](const type::U32*) {
@ -3914,7 +3913,7 @@ bool Builder::GenerateReferenceType(const type::Reference* ref, const Operand& r
return true;
}
bool Builder::GenerateStructType(const sem::Struct* struct_type, const Operand& result) {
bool Builder::GenerateStructType(const type::Struct* struct_type, const Operand& result) {
auto struct_id = std::get<uint32_t>(result);
if (struct_type->Name().IsValid()) {
@ -3924,9 +3923,11 @@ bool Builder::GenerateStructType(const sem::Struct* struct_type, const Operand&
OperandList ops;
ops.push_back(result);
auto* decl = struct_type->Declaration();
if (decl && ast::HasAttribute<transform::AddBlockAttribute::BlockAttribute>(decl->attributes)) {
push_annot(spv::Op::OpDecorate, {Operand(struct_id), U32Operand(SpvDecorationBlock)});
if (auto* sem_str = struct_type->As<sem::Struct>()) {
auto* decl = sem_str->Declaration();
if (ast::HasAttribute<transform::AddBlockAttribute::BlockAttribute>(decl->attributes)) {
push_annot(spv::Op::OpDecorate, {Operand(struct_id), U32Operand(SpvDecorationBlock)});
}
}
for (uint32_t i = 0; i < struct_type->Members().Length(); ++i) {
@ -3944,7 +3945,7 @@ bool Builder::GenerateStructType(const sem::Struct* struct_type, const Operand&
uint32_t Builder::GenerateStructMember(uint32_t struct_id,
uint32_t idx,
const sem::StructMember* member) {
const type::StructMember* member) {
push_debug(spv::Op::OpMemberName,
{Operand(struct_id), Operand(idx), Operand(member->Name().Name())});

View File

@ -496,7 +496,7 @@ class Builder {
/// @param struct_type the vector to generate
/// @param result the result operand
/// @returns true if the vector was successfully generated
bool GenerateStructType(const sem::Struct* struct_type, const Operand& result);
bool GenerateStructType(const type::Struct* struct_type, const Operand& result);
/// Generates a struct member
/// @param struct_id the id of the parent structure
/// @param idx the index of the member
@ -504,7 +504,7 @@ class Builder {
/// @returns the id of the struct member or 0 on error.
uint32_t GenerateStructMember(uint32_t struct_id,
uint32_t idx,
const sem::StructMember* member);
const type::StructMember* member);
/// Generates a variable declaration statement
/// @param stmt the statement to generate
/// @returns true on successfull generation

View File

@ -30,7 +30,7 @@ std::string TextGenerator::UniqueIdentifier(const std::string& prefix) {
return builder_.Symbols().New(prefix).Name();
}
std::string TextGenerator::StructName(const sem::Struct* s) {
std::string TextGenerator::StructName(const type::Struct* s) {
auto name = s->Name().Name();
if (name.size() > 1 && name[0] == '_' && name[1] == '_') {
name = utils::GetOrCreate(builtin_struct_names_, s,

View File

@ -112,7 +112,7 @@ class TextGenerator {
/// structures that start with double underscores. If the structure is a
/// builtin, then the returned name will be a unique name without the leading
/// underscores.
std::string StructName(const sem::Struct* s);
std::string StructName(const type::Struct* s);
/// @param str the string
/// @param suffix the suffix to remove
@ -221,7 +221,7 @@ class TextGenerator {
/// The primary text buffer that the generator will emit
TextBuffer main_buffer_;
/// Map of builtin structure to unique generated name
std::unordered_map<const sem::Struct*, std::string> builtin_struct_names_;
std::unordered_map<const type::Struct*, std::string> builtin_struct_names_;
};
} // namespace tint::writer