writer/msl: Begin migration to ast::Types
The MSL writer doesn't really care much for ast::Types, so most of the work here is repointing the logic to fetch the resolved, semantic type. Bug: tint:724 Change-Id: I017b83c9f661cc01cbde377991aab184c1733348 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49529 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
44539d85b2
commit
f34cb1fe70
|
@ -886,10 +886,12 @@ bool GeneratorImpl::EmitContinue(ast::ContinueStatement*) {
|
|||
}
|
||||
|
||||
bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
|
||||
if (expr->type()->IsAnyOf<sem::ArrayType, sem::StructType>()) {
|
||||
auto* type = TypeOf(expr);
|
||||
|
||||
if (type->IsAnyOf<sem::ArrayType, sem::StructType>()) {
|
||||
out_ << "{";
|
||||
} else {
|
||||
if (!EmitType(expr->type(), "")) {
|
||||
if (!EmitType(type, "")) {
|
||||
return false;
|
||||
}
|
||||
out_ << "(";
|
||||
|
@ -898,7 +900,7 @@ bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
|
|||
// If the type constructor is empty then we need to construct with the zero
|
||||
// value for all components.
|
||||
if (expr->values().empty()) {
|
||||
if (!EmitZeroValue(expr->type())) {
|
||||
if (!EmitZeroValue(type)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -915,7 +917,7 @@ bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
|
|||
}
|
||||
}
|
||||
|
||||
if (expr->type()->IsAnyOf<sem::ArrayType, sem::StructType>()) {
|
||||
if (type->IsAnyOf<sem::ArrayType, sem::StructType>()) {
|
||||
out_ << "}";
|
||||
} else {
|
||||
out_ << ")";
|
||||
|
@ -923,7 +925,10 @@ bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitZeroValue(sem::Type* type) {
|
||||
bool GeneratorImpl::EmitZeroValue(typ::Type type) {
|
||||
if (!type.sem) {
|
||||
type.sem = program_->Sem().Get(type.ast);
|
||||
}
|
||||
if (type->Is<sem::Bool>()) {
|
||||
out_ << "false";
|
||||
} else if (type->Is<sem::F32>()) {
|
||||
|
@ -1891,7 +1896,11 @@ bool GeneratorImpl::EmitSwitch(ast::SwitchStatement* stmt) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitType(sem::Type* type, const std::string& name) {
|
||||
bool GeneratorImpl::EmitType(typ::Type type, const std::string& name) {
|
||||
if (!type.sem) {
|
||||
type.sem = program_->Sem().Get(type.ast);
|
||||
}
|
||||
|
||||
std::string access_str = "";
|
||||
if (auto* ac = type->As<sem::AccessControl>()) {
|
||||
if (ac->access_control() == ast::AccessControl::kReadOnly) {
|
||||
|
@ -2025,7 +2034,11 @@ bool GeneratorImpl::EmitType(sem::Type* type, const std::string& name) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitPackedType(sem::Type* type, const std::string& name) {
|
||||
bool GeneratorImpl::EmitPackedType(typ::Type type, const std::string& name) {
|
||||
if (!type.sem) {
|
||||
type.sem = program_->Sem().Get(type.ast);
|
||||
}
|
||||
|
||||
if (auto* alias = type->As<sem::Alias>()) {
|
||||
return EmitPackedType(alias->type(), name);
|
||||
}
|
||||
|
@ -2077,16 +2090,11 @@ bool GeneratorImpl::EmitStructType(const sem::StructType* str) {
|
|||
|
||||
increment_indent();
|
||||
uint32_t msl_offset = 0;
|
||||
for (auto* mem : str->impl()->members()) {
|
||||
for (auto* mem : sem_str->Members()) {
|
||||
make_indent();
|
||||
|
||||
auto* sem_mem = program_->Sem().Get(mem);
|
||||
if (!sem_mem) {
|
||||
TINT_ICE(diagnostics_) << "struct member missing semantic info";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto wgsl_offset = sem_mem->Offset();
|
||||
auto name = program_->Symbols().NameFor(mem->Declaration()->symbol());
|
||||
auto wgsl_offset = mem->Offset();
|
||||
|
||||
if (is_host_shareable) {
|
||||
if (wgsl_offset < msl_offset) {
|
||||
|
@ -2107,25 +2115,24 @@ bool GeneratorImpl::EmitStructType(const sem::StructType* str) {
|
|||
|
||||
add_byte_offset_comment(msl_offset);
|
||||
|
||||
if (!EmitPackedType(mem->type(),
|
||||
program_->Symbols().NameFor(mem->symbol()))) {
|
||||
if (!EmitPackedType(mem->Type(), name)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!EmitType(mem->type(), program_->Symbols().NameFor(mem->symbol()))) {
|
||||
if (!EmitType(mem->Type(), name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto* ty = mem->type()->UnwrapAliasIfNeeded();
|
||||
auto* ty = mem->Type()->UnwrapAliasIfNeeded();
|
||||
|
||||
// Array member name will be output with the type
|
||||
if (!ty->Is<sem::ArrayType>()) {
|
||||
out_ << " " << program_->Symbols().NameFor(mem->symbol());
|
||||
out_ << " " << name;
|
||||
}
|
||||
|
||||
// Emit decorations
|
||||
for (auto* deco : mem->decorations()) {
|
||||
for (auto* deco : mem->Declaration()->decorations()) {
|
||||
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
|
||||
auto attr = builtin_to_attribute(builtin->value());
|
||||
if (attr.empty()) {
|
||||
|
@ -2163,9 +2170,9 @@ bool GeneratorImpl::EmitStructType(const sem::StructType* str) {
|
|||
// Calculate new MSL offset
|
||||
auto size_align = MslPackedTypeSizeAndAlign(ty);
|
||||
if (msl_offset % size_align.align) {
|
||||
TINT_ICE(diagnostics_) << "Misaligned MSL structure member "
|
||||
<< ty->FriendlyName(program_->Symbols()) << " "
|
||||
<< program_->Symbols().NameFor(mem->symbol());
|
||||
TINT_ICE(diagnostics_)
|
||||
<< "Misaligned MSL structure member "
|
||||
<< ty->FriendlyName(program_->Symbols()) << " " << name;
|
||||
return false;
|
||||
}
|
||||
msl_offset += size_align.size;
|
||||
|
|
|
@ -195,14 +195,14 @@ class GeneratorImpl : public TextGenerator {
|
|||
/// @param type the type to generate
|
||||
/// @param name the name of the variable, only used for array emission
|
||||
/// @returns true if the type is emitted
|
||||
bool EmitType(sem::Type* type, const std::string& name);
|
||||
bool EmitType(typ::Type type, const std::string& name);
|
||||
/// Handles generating an MSL-packed storage type.
|
||||
/// If the type does not have a packed form, the standard non-packed form is
|
||||
/// emitted.
|
||||
/// @param type the type to generate
|
||||
/// @param name the name of the variable, only used for array emission
|
||||
/// @returns true if the type is emitted
|
||||
bool EmitPackedType(sem::Type* type, const std::string& name);
|
||||
bool EmitPackedType(typ::Type type, const std::string& name);
|
||||
/// Handles generating a struct declaration
|
||||
/// @param str the struct to generate
|
||||
/// @returns true if the struct is emitted
|
||||
|
@ -227,7 +227,7 @@ class GeneratorImpl : public TextGenerator {
|
|||
/// Emits the zero value for the given type
|
||||
/// @param type the type to emit the value for
|
||||
/// @returns true if the zero value was successfully emitted.
|
||||
bool EmitZeroValue(sem::Type* type);
|
||||
bool EmitZeroValue(typ::Type type);
|
||||
|
||||
/// Determines if the function needs the input struct passed to it.
|
||||
/// @param func the function to check
|
||||
|
@ -273,6 +273,12 @@ class GeneratorImpl : public TextGenerator {
|
|||
return program_->TypeOf(expr);
|
||||
}
|
||||
|
||||
/// @returns the resolved type of the ast::Type `type`
|
||||
/// @param type the type
|
||||
const sem::Type* TypeOf(ast::Type* type) const {
|
||||
return program_->TypeOf(type);
|
||||
}
|
||||
|
||||
// A pair of byte size and alignment `uint32_t`s.
|
||||
struct SizeAndAlign {
|
||||
uint32_t size;
|
||||
|
|
|
@ -31,13 +31,15 @@ using MslBinaryTest = TestParamHelper<BinaryData>;
|
|||
TEST_P(MslBinaryTest, Emit) {
|
||||
auto params = GetParam();
|
||||
|
||||
auto* type = ((params.op == ast::BinaryOp::kLogicalAnd) ||
|
||||
(params.op == ast::BinaryOp::kLogicalOr))
|
||||
? static_cast<sem::Type*>(ty.bool_())
|
||||
: static_cast<sem::Type*>(ty.u32());
|
||||
auto type = [&]() {
|
||||
return ((params.op == ast::BinaryOp::kLogicalAnd) ||
|
||||
(params.op == ast::BinaryOp::kLogicalOr))
|
||||
? static_cast<typ::Type>(ty.bool_())
|
||||
: static_cast<typ::Type>(ty.u32());
|
||||
};
|
||||
|
||||
auto* left = Var("left", type, ast::StorageClass::kFunction);
|
||||
auto* right = Var("right", type, ast::StorageClass::kFunction);
|
||||
auto* left = Var("left", type(), ast::StorageClass::kFunction);
|
||||
auto* right = Var("right", type(), ast::StorageClass::kFunction);
|
||||
|
||||
auto* expr =
|
||||
create<ast::BinaryExpression>(params.op, Expr("left"), Expr("right"));
|
||||
|
|
|
@ -602,7 +602,7 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) {
|
|||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, EmitType_U32) {
|
||||
auto u32 = ty.u32();
|
||||
auto* u32 = create<sem::U32>();
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
|
@ -715,11 +715,12 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
"texturecube_array<float, access::sample>"}));
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Emit_TypeMultisampledTexture) {
|
||||
sem::MultisampledTexture s(ast::TextureDimension::k2d, ty.u32());
|
||||
auto* u32 = create<sem::U32>();
|
||||
auto* ms = create<sem::MultisampledTexture>(ast::TextureDimension::k2d, u32);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
|
||||
ASSERT_TRUE(gen.EmitType(ms, "")) << gen.error();
|
||||
EXPECT_EQ(gen.result(), "texture2d_ms<uint, access::sample>");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue