mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-12 06:45:16 +00:00
tint: Fix Renamer transform with type short-names
Fixed: tint:1783 Change-Id: I0ffd5860405651f15961dc8fe753eeac6edc8434 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/113441 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
384e2bee88
commit
06c1af47bd
@@ -21,7 +21,10 @@
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/sem/call.h"
|
||||
#include "src/tint/sem/member_accessor_expression.h"
|
||||
#include "src/tint/sem/type_conversion.h"
|
||||
#include "src/tint/sem/type_initializer.h"
|
||||
#include "src/tint/text/unicode.h"
|
||||
#include "src/tint/type/short_name.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::Renamer);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::Renamer::Data);
|
||||
@@ -1258,27 +1261,63 @@ Transform::ApplyResult Renamer::Apply(const Program* src,
|
||||
ProgramBuilder b;
|
||||
CloneContext ctx{&b, src, /* auto_clone_symbols */ false};
|
||||
|
||||
// Swizzles, builtin calls and builtin structure members need to keep their
|
||||
// symbols preserved.
|
||||
utils::Hashset<const ast::IdentifierExpression*, 8> preserve;
|
||||
for (auto* node : src->ASTNodes().Objects()) {
|
||||
if (auto* member = node->As<ast::MemberAccessorExpression>()) {
|
||||
auto* sem = src->Sem().Get(member);
|
||||
if (sem->Is<sem::Swizzle>()) {
|
||||
preserve.Add(member->member);
|
||||
} else if (auto* str_expr = src->Sem().Get(member->structure)) {
|
||||
if (auto* ty = str_expr->Type()->UnwrapRef()->As<sem::Struct>()) {
|
||||
if (ty->Declaration() == nullptr) { // Builtin structure
|
||||
preserve.Add(member->member);
|
||||
}
|
||||
// Identifiers that need to keep their symbols preserved.
|
||||
utils::Hashset<const ast::IdentifierExpression*, 8> preserved_identifiers;
|
||||
// Type names that need to keep their symbols preserved.
|
||||
utils::Hashset<const ast::TypeName*, 8> preserved_type_names;
|
||||
|
||||
auto is_type_short_name = [&](const Symbol& symbol) {
|
||||
auto name = src->Symbols().NameFor(symbol);
|
||||
if (type::ParseShortName(name) != type::ShortName::kUndefined) {
|
||||
// Identifier *looks* like a builtin short-name, but check the using actually
|
||||
// shadowing a short-name with a type alias.
|
||||
for (auto* decl : src->AST().TypeDecls()) {
|
||||
if (decl->name == symbol) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (auto* call = node->As<ast::CallExpression>()) {
|
||||
auto* sem = src->Sem().Get(call)->UnwrapMaterialize()->As<sem::Call>();
|
||||
if (sem->Target()->Is<sem::Builtin>()) {
|
||||
preserve.Add(call->target.name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
for (auto* node : src->ASTNodes().Objects()) {
|
||||
Switch(
|
||||
node,
|
||||
[&](const ast::MemberAccessorExpression* accessor) {
|
||||
auto* sem = src->Sem().Get(accessor);
|
||||
if (sem->Is<sem::Swizzle>()) {
|
||||
preserved_identifiers.Add(accessor->member);
|
||||
} else if (auto* str_expr = src->Sem().Get(accessor->structure)) {
|
||||
if (auto* ty = str_expr->Type()->UnwrapRef()->As<sem::Struct>()) {
|
||||
if (ty->Declaration() == nullptr) { // Builtin structure
|
||||
preserved_identifiers.Add(accessor->member);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
[&](const ast::CallExpression* call) {
|
||||
if (auto* ident = call->target.name) {
|
||||
Switch(
|
||||
src->Sem().Get(call)->UnwrapMaterialize()->As<sem::Call>()->Target(),
|
||||
[&](const sem::Builtin*) { preserved_identifiers.Add(ident); },
|
||||
[&](const sem::TypeConversion*) {
|
||||
if (is_type_short_name(ident->symbol)) {
|
||||
preserved_identifiers.Add(ident);
|
||||
}
|
||||
},
|
||||
[&](const sem::TypeInitializer*) {
|
||||
if (is_type_short_name(ident->symbol)) {
|
||||
preserved_identifiers.Add(ident);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
[&](const ast::TypeName* type_name) {
|
||||
if (is_type_short_name(type_name->name)) {
|
||||
preserved_type_names.Add(type_name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Data::Remappings remappings;
|
||||
@@ -1335,7 +1374,7 @@ Transform::ApplyResult Renamer::Apply(const Program* src,
|
||||
});
|
||||
|
||||
ctx.ReplaceAll([&](const ast::IdentifierExpression* ident) -> const ast::IdentifierExpression* {
|
||||
if (preserve.Contains(ident)) {
|
||||
if (preserved_identifiers.Contains(ident)) {
|
||||
auto sym_in = ident->symbol;
|
||||
auto str = src->Symbols().NameFor(sym_in);
|
||||
auto sym_out = b.Symbols().Register(str);
|
||||
@@ -1344,6 +1383,16 @@ Transform::ApplyResult Renamer::Apply(const Program* src,
|
||||
return nullptr; // Clone ident. Uses the symbol remapping above.
|
||||
});
|
||||
|
||||
ctx.ReplaceAll([&](const ast::TypeName* type_name) -> const ast::TypeName* {
|
||||
if (preserved_type_names.Contains(type_name)) {
|
||||
auto sym_in = type_name->name;
|
||||
auto str = src->Symbols().NameFor(sym_in);
|
||||
auto sym_out = b.Symbols().Register(str);
|
||||
return ctx.dst->create<ast::TypeName>(ctx.Clone(type_name->source), sym_out);
|
||||
}
|
||||
return nullptr; // Clone ident. Uses the symbol remapping above.
|
||||
});
|
||||
|
||||
ctx.Clone(); // Must come before the std::move()
|
||||
|
||||
outputs.Add<Data>(std::move(remappings));
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "src/tint/transform/test_helper.h"
|
||||
#include "src/tint/type/short_name.h"
|
||||
|
||||
namespace tint::transform {
|
||||
namespace {
|
||||
@@ -1457,5 +1458,219 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
// "while" // WGSL reserved keyword
|
||||
kUnicodeIdentifier));
|
||||
|
||||
const char* ExpandShortName(std::string_view name) {
|
||||
if (name == "vec2f") {
|
||||
return "vec2<f32>";
|
||||
}
|
||||
if (name == "vec2h") {
|
||||
return "vec2<f16>";
|
||||
}
|
||||
if (name == "vec2i") {
|
||||
return "vec2<i32>";
|
||||
}
|
||||
if (name == "vec2u") {
|
||||
return "vec2<u32>";
|
||||
}
|
||||
if (name == "vec3f") {
|
||||
return "vec3<f32>";
|
||||
}
|
||||
if (name == "vec3h") {
|
||||
return "vec3<f16>";
|
||||
}
|
||||
if (name == "vec3i") {
|
||||
return "vec3<i32>";
|
||||
}
|
||||
if (name == "vec3u") {
|
||||
return "vec3<u32>";
|
||||
}
|
||||
if (name == "vec4f") {
|
||||
return "vec4<f32>";
|
||||
}
|
||||
if (name == "vec4h") {
|
||||
return "vec4<f16>";
|
||||
}
|
||||
if (name == "vec4i") {
|
||||
return "vec4<i32>";
|
||||
}
|
||||
if (name == "vec4u") {
|
||||
return "vec4<u32>";
|
||||
}
|
||||
ADD_FAILURE() << "unhandled type short-name: " << name;
|
||||
return "<invalid>";
|
||||
}
|
||||
|
||||
using RenamerTypeShortNamesTest = TransformTestWithParam<const char*>;
|
||||
|
||||
TEST_P(RenamerTypeShortNamesTest, PreserveTypeUsage) {
|
||||
auto expand = [&](const char* source) {
|
||||
auto out = utils::ReplaceAll(source, "$name", GetParam());
|
||||
out = utils::ReplaceAll(out, "$type", ExpandShortName(GetParam()));
|
||||
return out;
|
||||
};
|
||||
|
||||
auto src = expand(R"(
|
||||
enable f16;
|
||||
|
||||
fn x(v : $name) -> $name {
|
||||
const a : $name = $name();
|
||||
let b : $name = a;
|
||||
var c : $name = b;
|
||||
return c;
|
||||
}
|
||||
|
||||
struct y {
|
||||
a : $name,
|
||||
}
|
||||
)");
|
||||
|
||||
auto expect = expand(R"(
|
||||
enable f16;
|
||||
|
||||
fn tint_symbol(tint_symbol_1 : $name) -> $name {
|
||||
const tint_symbol_2 : $name = $name();
|
||||
let tint_symbol_3 : $name = tint_symbol_2;
|
||||
var tint_symbol_4 : $name = tint_symbol_3;
|
||||
return tint_symbol_4;
|
||||
}
|
||||
|
||||
struct tint_symbol_5 {
|
||||
tint_symbol_2 : $name,
|
||||
}
|
||||
)");
|
||||
|
||||
auto got = Run<Renamer>(src);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
TEST_P(RenamerTypeShortNamesTest, PreserveTypeInitializer) {
|
||||
auto expand = [&](const char* source) {
|
||||
auto out = utils::ReplaceAll(source, "$name", GetParam());
|
||||
out = utils::ReplaceAll(out, "$type", ExpandShortName(GetParam()));
|
||||
return out;
|
||||
};
|
||||
|
||||
auto src = expand(R"(
|
||||
enable f16;
|
||||
|
||||
@fragment
|
||||
fn f() {
|
||||
var v : $type = $name();
|
||||
}
|
||||
)");
|
||||
|
||||
auto expect = expand(R"(
|
||||
enable f16;
|
||||
|
||||
@fragment
|
||||
fn tint_symbol() {
|
||||
var tint_symbol_1 : $type = $name();
|
||||
}
|
||||
)");
|
||||
|
||||
auto got = Run<Renamer>(src);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_P(RenamerTypeShortNamesTest, PreserveTypeConversion) {
|
||||
auto expand = [&](const char* source) {
|
||||
auto out = utils::ReplaceAll(source, "$name", GetParam());
|
||||
out = utils::ReplaceAll(out, "$type", ExpandShortName(GetParam()));
|
||||
return out;
|
||||
};
|
||||
|
||||
auto src = expand(R"(
|
||||
enable f16;
|
||||
|
||||
@fragment
|
||||
fn f() {
|
||||
var v : $type = $name($type());
|
||||
}
|
||||
)");
|
||||
|
||||
auto expect = expand(R"(
|
||||
enable f16;
|
||||
|
||||
@fragment
|
||||
fn tint_symbol() {
|
||||
var tint_symbol_1 : $type = $name($type());
|
||||
}
|
||||
)");
|
||||
|
||||
auto got = Run<Renamer>(src);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_P(RenamerTypeShortNamesTest, RenameShadowedByAlias) {
|
||||
auto expand = [&](const char* source) {
|
||||
auto out = utils::ReplaceAll(source, "$name", GetParam());
|
||||
out = utils::ReplaceAll(out, "$type", ExpandShortName(GetParam()));
|
||||
return out;
|
||||
};
|
||||
|
||||
auto src = expand(R"(
|
||||
type $name = i32;
|
||||
|
||||
@fragment
|
||||
fn f() {
|
||||
var v : i32 = $name();
|
||||
}
|
||||
)");
|
||||
|
||||
auto expect = expand(R"(
|
||||
type tint_symbol = i32;
|
||||
|
||||
@fragment
|
||||
fn tint_symbol_1() {
|
||||
var tint_symbol_2 : i32 = tint_symbol();
|
||||
}
|
||||
)");
|
||||
|
||||
auto got = Run<Renamer>(src);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_P(RenamerTypeShortNamesTest, RenameShadowedByStruct) {
|
||||
auto expand = [&](const char* source) {
|
||||
auto out = utils::ReplaceAll(source, "$name", GetParam());
|
||||
out = utils::ReplaceAll(out, "$type", ExpandShortName(GetParam()));
|
||||
return out;
|
||||
};
|
||||
|
||||
auto src = expand(R"(
|
||||
struct $name {
|
||||
i : i32,
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn f() {
|
||||
var a = $name();
|
||||
var b = a.i;
|
||||
}
|
||||
)");
|
||||
|
||||
auto expect = expand(R"(
|
||||
struct tint_symbol {
|
||||
tint_symbol_1 : i32,
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn tint_symbol_2() {
|
||||
var tint_symbol_3 = tint_symbol();
|
||||
var tint_symbol_4 = tint_symbol_3.tint_symbol_1;
|
||||
}
|
||||
)");
|
||||
|
||||
auto got = Run<Renamer>(src);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(RenamerTypeShortNamesTest,
|
||||
RenamerTypeShortNamesTest,
|
||||
testing::ValuesIn(type::kShortNameStrings));
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::transform
|
||||
|
||||
Reference in New Issue
Block a user