resolver: Support shadowing

Add transform::Unshadow to renamed shadowed symbols. Required by a
number of other transforms.

Replace Resolver symbol resolution with dep-graph.

The dependency graph now performs full symbol resolution before the
regular resolver pass.
Make use of this instead of duplicating the effort.

Simplfies code, and actually performs variable shadowing consistently.

Fixed: tint:819
Bug: tint:1266
Change-Id: I595d1812aebe1d79d2d32e724ff90de36e74cf4b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/70523
Reviewed-by: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton
2021-11-23 20:45:51 +00:00
parent e524ee1813
commit b05e185a36
99 changed files with 2357 additions and 363 deletions

View File

@@ -18,6 +18,7 @@
#include "src/transform/simplify_pointers.h"
#include "src/transform/test_helper.h"
#include "src/transform/unshadow.h"
namespace tint {
namespace transform {
@@ -32,7 +33,7 @@ TEST_F(ArrayLengthFromUniformTest, Error_MissingTransformData) {
"error: missing transform data for "
"tint::transform::ArrayLengthFromUniform";
auto got = Run<SimplifyPointers, ArrayLengthFromUniform>(src);
auto got = Run<Unshadow, SimplifyPointers, ArrayLengthFromUniform>(src);
EXPECT_EQ(expect, str(got));
}
@@ -93,7 +94,7 @@ fn main() {
DataMap data;
data.Add<ArrayLengthFromUniform::Config>(std::move(cfg));
auto got = Run<SimplifyPointers, ArrayLengthFromUniform>(src, data);
auto got = Run<Unshadow, SimplifyPointers, ArrayLengthFromUniform>(src, data);
EXPECT_EQ(expect, str(got));
EXPECT_EQ(std::unordered_set<uint32_t>({0}),
@@ -146,7 +147,7 @@ fn main() {
DataMap data;
data.Add<ArrayLengthFromUniform::Config>(std::move(cfg));
auto got = Run<SimplifyPointers, ArrayLengthFromUniform>(src, data);
auto got = Run<Unshadow, SimplifyPointers, ArrayLengthFromUniform>(src, data);
EXPECT_EQ(expect, str(got));
EXPECT_EQ(std::unordered_set<uint32_t>({0}),
@@ -267,7 +268,7 @@ fn main() {
DataMap data;
data.Add<ArrayLengthFromUniform::Config>(std::move(cfg));
auto got = Run<SimplifyPointers, ArrayLengthFromUniform>(src, data);
auto got = Run<Unshadow, SimplifyPointers, ArrayLengthFromUniform>(src, data);
EXPECT_EQ(expect, str(got));
EXPECT_EQ(std::unordered_set<uint32_t>({0, 1, 2, 3, 4}),
@@ -382,7 +383,7 @@ fn main() {
DataMap data;
data.Add<ArrayLengthFromUniform::Config>(std::move(cfg));
auto got = Run<SimplifyPointers, ArrayLengthFromUniform>(src, data);
auto got = Run<Unshadow, SimplifyPointers, ArrayLengthFromUniform>(src, data);
EXPECT_EQ(expect, str(got));
EXPECT_EQ(std::unordered_set<uint32_t>({0, 2}),
@@ -411,7 +412,7 @@ fn main() {
DataMap data;
data.Add<ArrayLengthFromUniform::Config>(std::move(cfg));
auto got = Run<SimplifyPointers, ArrayLengthFromUniform>(src, data);
auto got = Run<Unshadow, SimplifyPointers, ArrayLengthFromUniform>(src, data);
EXPECT_EQ(src, str(got));
EXPECT_EQ(std::unordered_set<uint32_t>(),
@@ -482,7 +483,7 @@ fn main() {
DataMap data;
data.Add<ArrayLengthFromUniform::Config>(std::move(cfg));
auto got = Run<SimplifyPointers, ArrayLengthFromUniform>(src, data);
auto got = Run<Unshadow, SimplifyPointers, ArrayLengthFromUniform>(src, data);
EXPECT_EQ(expect, str(got));
EXPECT_EQ(std::unordered_set<uint32_t>({0}),

View File

@@ -25,8 +25,9 @@
#include "src/sem/statement.h"
#include "src/sem/struct.h"
#include "src/sem/variable.h"
#include "src/utils/map.h"
#include "src/transform/simplify_pointers.h"
#include "src/utils/hash.h"
#include "src/utils/map.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::CalculateArrayLength);
TINT_INSTANTIATE_TYPEINFO(
@@ -72,6 +73,9 @@ CalculateArrayLength::~CalculateArrayLength() = default;
void CalculateArrayLength::Run(CloneContext& ctx, const DataMap&, DataMap&) {
auto& sem = ctx.src->Sem();
if (!Requires<SimplifyPointers>(ctx)) {
return;
}
// get_buffer_size_intrinsic() emits the function decorated with
// BufferSizeIntrinsic that is transformed by the HLSL writer into a call to

View File

@@ -14,7 +14,9 @@
#include "src/transform/calculate_array_length.h"
#include "src/transform/simplify_pointers.h"
#include "src/transform/test_helper.h"
#include "src/transform/unshadow.h"
namespace tint {
namespace transform {
@@ -22,6 +24,18 @@ namespace {
using CalculateArrayLengthTest = TransformTest;
TEST_F(CalculateArrayLengthTest, Error_MissingCalculateArrayLength) {
auto* src = "";
auto* expect =
"error: tint::transform::CalculateArrayLength depends on "
"tint::transform::SimplifyPointers but the dependency was not run";
auto got = Run<CalculateArrayLength>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(CalculateArrayLengthTest, Basic) {
auto* src = R"(
[[block]]
@@ -59,7 +73,7 @@ fn main() {
}
)";
auto got = Run<CalculateArrayLength>(src);
auto got = Run<Unshadow, SimplifyPointers, CalculateArrayLength>(src);
EXPECT_EQ(expect, str(got));
}
@@ -105,7 +119,7 @@ fn main() {
}
)";
auto got = Run<CalculateArrayLength>(src);
auto got = Run<Unshadow, SimplifyPointers, CalculateArrayLength>(src);
EXPECT_EQ(expect, str(got));
}
@@ -149,7 +163,7 @@ fn main() {
}
)";
auto got = Run<CalculateArrayLength>(src);
auto got = Run<Unshadow, SimplifyPointers, CalculateArrayLength>(src);
EXPECT_EQ(expect, str(got));
}
@@ -206,7 +220,7 @@ fn main() {
}
)";
auto got = Run<CalculateArrayLength>(src);
auto got = Run<Unshadow, SimplifyPointers, CalculateArrayLength>(src);
EXPECT_EQ(expect, str(got));
}
@@ -274,7 +288,63 @@ fn main() {
}
)";
auto got = Run<CalculateArrayLength>(src);
auto got = Run<Unshadow, SimplifyPointers, CalculateArrayLength>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(CalculateArrayLengthTest, Shadowing) {
auto* src = R"(
[[block]]
struct SB {
x : i32;
arr : array<i32>;
};
[[group(0), binding(0)]] var<storage, read> a : SB;
[[group(0), binding(1)]] var<storage, read> b : SB;
[[stage(compute), workgroup_size(1)]]
fn main() {
let x = &a;
var a : u32 = arrayLength(&a.arr);
{
var b : u32 = arrayLength(&((*x).arr));
}
}
)";
auto* expect =
R"(
[[block]]
struct SB {
x : i32;
arr : array<i32>;
};
[[internal(intrinsic_buffer_size)]]
fn tint_symbol([[internal(disable_validation__ignore_constructible_function_parameter)]] buffer : SB, result : ptr<function, u32>)
[[group(0), binding(0)]] var<storage, read> a : SB;
[[group(0), binding(1)]] var<storage, read> b : SB;
[[stage(compute), workgroup_size(1)]]
fn main() {
var tint_symbol_1 : u32 = 0u;
tint_symbol(a, &(tint_symbol_1));
let tint_symbol_2 : u32 = ((tint_symbol_1 - 4u) / 4u);
var a_1 : u32 = tint_symbol_2;
{
var tint_symbol_3 : u32 = 0u;
tint_symbol(a, &(tint_symbol_3));
let tint_symbol_4 : u32 = ((tint_symbol_3 - 4u) / 4u);
var b_1 : u32 = tint_symbol_4;
}
}
)";
auto got = Run<Unshadow, SimplifyPointers, CalculateArrayLength>(src);
EXPECT_EQ(expect, str(got));
}

View File

@@ -23,6 +23,7 @@
#include "src/ast/disable_validation_decoration.h"
#include "src/program_builder.h"
#include "src/sem/function.h"
#include "src/transform/unshadow.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::CanonicalizeEntryPointIO);
TINT_INSTANTIATE_TYPEINFO(tint::transform::CanonicalizeEntryPointIO::Config);
@@ -550,6 +551,10 @@ struct CanonicalizeEntryPointIO::State {
void CanonicalizeEntryPointIO::Run(CloneContext& ctx,
const DataMap& inputs,
DataMap&) {
if (!Requires<Unshadow>(ctx)) {
return;
}
auto* cfg = inputs.Get<Config>();
if (cfg == nullptr) {
ctx.dst->Diagnostics().add_error(

View File

@@ -15,6 +15,7 @@
#include "src/transform/canonicalize_entry_point_io.h"
#include "src/transform/test_helper.h"
#include "src/transform/unshadow.h"
namespace tint {
namespace transform {
@@ -22,6 +23,18 @@ namespace {
using CanonicalizeEntryPointIOTest = TransformTest;
TEST_F(CanonicalizeEntryPointIOTest, Error_MissingUnshadow) {
auto* src = "";
auto* expect =
"error: tint::transform::CanonicalizeEntryPointIO depends on "
"tint::transform::Unshadow but the dependency was not run";
auto got = Run<CanonicalizeEntryPointIO>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(CanonicalizeEntryPointIOTest, Error_MissingTransformData) {
auto* src = "";
@@ -29,7 +42,7 @@ TEST_F(CanonicalizeEntryPointIOTest, Error_MissingTransformData) {
"error: missing transform data for "
"tint::transform::CanonicalizeEntryPointIO";
auto got = Run<CanonicalizeEntryPointIO>(src);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src);
EXPECT_EQ(expect, str(got));
}
@@ -52,7 +65,7 @@ fn comp_main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -87,7 +100,7 @@ fn frag_main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -123,7 +136,7 @@ fn frag_main([[builtin(position)]] coord : vec4<f32>, tint_symbol : tint_symbol_
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -161,7 +174,7 @@ fn frag_main(tint_symbol : tint_symbol_1) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -197,7 +210,7 @@ fn frag_main(tint_symbol : tint_symbol_1) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -251,7 +264,7 @@ fn frag_main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -306,7 +319,7 @@ fn frag_main([[builtin(position)]] coord : vec4<f32>, tint_symbol : tint_symbol_
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -363,7 +376,7 @@ fn frag_main(tint_symbol : tint_symbol_1) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -393,7 +406,7 @@ fn frag_main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -428,7 +441,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -463,7 +476,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -519,7 +532,7 @@ fn frag_main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -580,7 +593,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -641,7 +654,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -709,7 +722,7 @@ fn frag_main2() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -783,7 +796,7 @@ fn frag_main2(tint_symbol_2 : tint_symbol_3) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -857,7 +870,7 @@ fn frag_main2(tint_symbol_2 : tint_symbol_3) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -925,7 +938,7 @@ fn frag_main1(tint_symbol : tint_symbol_1) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1012,7 +1025,7 @@ fn frag_main(tint_symbol : tint_symbol_1) -> tint_symbol_2 {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1104,7 +1117,7 @@ fn frag_main(tint_symbol_1 : tint_symbol_2) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1235,7 +1248,7 @@ fn frag_main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1300,7 +1313,7 @@ fn main2() -> tint_symbol_1 {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1370,7 +1383,7 @@ fn frag_main(tint_symbol : tint_symbol_1) -> tint_symbol_2 {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1475,7 +1488,7 @@ fn frag_main(tint_symbol_1 : tint_symbol_2) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1505,7 +1518,7 @@ fn tint_symbol_1(tint_symbol : tint_symbol_2) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1538,7 +1551,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0x03u);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1573,7 +1586,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0x03u);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1608,7 +1621,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0x03u);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1646,7 +1659,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0x03u);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1699,7 +1712,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0x03u);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1751,7 +1764,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0x03u);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1841,7 +1854,7 @@ fn comp_main1() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0x03u);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1892,7 +1905,7 @@ fn frag_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0x03);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1926,7 +1939,7 @@ fn vert_main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv, 0xFFFFFFFF, true);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -1964,7 +1977,7 @@ fn vert_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0xFFFFFFFF, true);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -2005,7 +2018,7 @@ fn vert_main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv, 0xFFFFFFFF, true);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -2051,7 +2064,7 @@ fn vert_main() -> tint_symbol {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0xFFFFFFFF, true);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -2129,7 +2142,7 @@ fn vert_main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv, 0xFFFFFFFF, true);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -2205,7 +2218,7 @@ fn vert_main(tint_symbol : tint_symbol_1) -> tint_symbol_2 {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kMsl, 0xFFFFFFFF, true);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -2281,7 +2294,7 @@ fn vert_main(tint_symbol : tint_symbol_1) -> tint_symbol_2 {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl, 0xFFFFFFFF, true);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}
@@ -2317,7 +2330,7 @@ fn main() {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kSpirv);
auto got = Run<CanonicalizeEntryPointIO>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO>(src, data);
EXPECT_EQ(expect, str(got));
}

View File

@@ -22,6 +22,7 @@
#include "src/program_builder.h"
#include "src/transform/simplify_pointers.h"
#include "src/transform/test_helper.h"
#include "src/transform/unshadow.h"
namespace tint {
namespace transform {
@@ -34,7 +35,7 @@ TEST_F(DecomposeStridedMatrixTest, Empty) {
auto* src = R"()";
auto* expect = src;
auto got = Run<SimplifyPointers, DecomposeStridedMatrix>(src);
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(src);
EXPECT_EQ(expect, str(got));
}
@@ -109,8 +110,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}
@@ -171,8 +172,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}
@@ -234,8 +235,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}
@@ -300,8 +301,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}
@@ -362,8 +363,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}
@@ -429,8 +430,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}
@@ -491,8 +492,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}
@@ -580,8 +581,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}
@@ -637,8 +638,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}
@@ -695,8 +696,8 @@ fn f() {
}
)";
auto got =
Run<SimplifyPointers, DecomposeStridedMatrix>(Program(std::move(b)));
auto got = Run<Unshadow, SimplifyPointers, DecomposeStridedMatrix>(
Program(std::move(b)));
EXPECT_EQ(expect, str(got));
}

View File

@@ -35,13 +35,13 @@ TEST_F(FoldTrivialSingleUseLetsTest, Single) {
auto* src = R"(
fn f() {
let x = 1;
ignore(x);
_ = x;
}
)";
auto* expect = R"(
fn f() {
ignore(1);
_ = 1;
}
)";
@@ -56,13 +56,13 @@ fn f() {
let x = 1;
let y = 2;
let z = 3;
ignore(x + y + z);
_ = x + y + z;
}
)";
auto* expect = R"(
fn f() {
ignore(((1 + 2) + 3));
_ = ((1 + 2) + 3);
}
)";
@@ -77,13 +77,13 @@ fn f() {
let x = 1;
let y = x;
let z = y;
ignore(z);
_ = z;
}
)";
auto* expect = R"(
fn f() {
ignore(1);
_ = 1;
}
)";
@@ -101,7 +101,7 @@ fn function_with_posssible_side_effect() -> i32 {
fn f() {
let x = 1;
let y = function_with_posssible_side_effect();
ignore((x + y));
_ = (x + y);
}
)";
@@ -117,7 +117,7 @@ TEST_F(FoldTrivialSingleUseLetsTest, NoFold_UseInSubBlock) {
fn f() {
let x = 1;
{
ignore(x);
_ = x;
}
}
)";
@@ -133,7 +133,26 @@ TEST_F(FoldTrivialSingleUseLetsTest, NoFold_MultipleUses) {
auto* src = R"(
fn f() {
let x = 1;
ignore((x + x));
_ = (x + x);
}
)";
auto* expect = src;
auto got = Run<FoldTrivialSingleUseLets>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(FoldTrivialSingleUseLetsTest, NoFold_Shadowing) {
auto* src = R"(
fn f() {
var y = 1;
let x = y;
{
let y = false;
_ = (x + x);
}
}
)";

View File

@@ -29,6 +29,7 @@
#include "src/transform/remove_phonies.h"
#include "src/transform/simplify_pointers.h"
#include "src/transform/single_entry_point.h"
#include "src/transform/unshadow.h"
#include "src/transform/zero_init_workgroup_memory.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::Glsl);
@@ -46,6 +47,8 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) {
auto* cfg = inputs.Get<Config>();
manager.Add<Unshadow>();
// Attempt to convert `loop`s into for-loops. This is to try and massage the
// output into something that will not cause FXC to choke or misbehave.
manager.Add<FoldTrivialSingleUseLets>();

View File

@@ -18,6 +18,7 @@
#include "src/transform/canonicalize_entry_point_io.h"
#include "src/transform/test_helper.h"
#include "src/transform/unshadow.h"
namespace tint {
namespace transform {
@@ -35,7 +36,8 @@ TEST_F(NumWorkgroupsFromUniformTest, Error_MissingTransformData) {
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(
src, data);
EXPECT_EQ(expect, str(got));
}
@@ -87,7 +89,8 @@ fn main() {
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
data.Add<NumWorkgroupsFromUniform::Config>(sem::BindingPoint{0, 30u});
auto got = Run<CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(
src, data);
EXPECT_EQ(expect, str(got));
}
@@ -133,7 +136,8 @@ fn main() {
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
data.Add<NumWorkgroupsFromUniform::Config>(sem::BindingPoint{0, 30u});
auto got = Run<CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(
src, data);
EXPECT_EQ(expect, str(got));
}
@@ -190,7 +194,8 @@ fn main(tint_symbol : tint_symbol_1) {
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
data.Add<NumWorkgroupsFromUniform::Config>(sem::BindingPoint{0, 30u});
auto got = Run<CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(
src, data);
EXPECT_EQ(expect, str(got));
}
@@ -291,7 +296,8 @@ fn main3() {
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
data.Add<NumWorkgroupsFromUniform::Config>(sem::BindingPoint{0, 30u});
auto got = Run<CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(
src, data);
EXPECT_EQ(expect, str(got));
}
@@ -333,7 +339,8 @@ fn main(tint_symbol : tint_symbol_1) {
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
data.Add<NumWorkgroupsFromUniform::Config>(sem::BindingPoint{0, 30u});
auto got = Run<CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(src, data);
auto got = Run<Unshadow, CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(
src, data);
EXPECT_EQ(expect, str(got));
}

View File

@@ -24,6 +24,7 @@
#include "src/sem/function.h"
#include "src/sem/statement.h"
#include "src/sem/variable.h"
#include "src/transform/unshadow.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::SimplifyPointers);
@@ -231,6 +232,9 @@ SimplifyPointers::SimplifyPointers() = default;
SimplifyPointers::~SimplifyPointers() = default;
void SimplifyPointers::Run(CloneContext& ctx, const DataMap&, DataMap&) {
if (!Requires<Unshadow>(ctx)) {
return;
}
State(ctx).Run();
}

View File

@@ -15,16 +15,14 @@
#ifndef SRC_TRANSFORM_SIMPLIFY_POINTERS_H_
#define SRC_TRANSFORM_SIMPLIFY_POINTERS_H_
#include <string>
#include <unordered_map>
#include "src/transform/transform.h"
namespace tint {
namespace transform {
/// SimplifyPointers is a Transform that moves all usage of function-scope
/// `let` statements of a pointer type into their places of usage.
/// `let` statements of a pointer type into their places of usage, while also
/// simplifying any chains of address-of or indirections operators.
///
/// Parameters of a pointer type are not adjusted.
///

View File

@@ -14,11 +14,8 @@
#include "src/transform/simplify_pointers.h"
#include <memory>
#include <utility>
#include <vector>
#include "src/transform/test_helper.h"
#include "src/transform/unshadow.h"
namespace tint {
namespace transform {
@@ -26,11 +23,23 @@ namespace {
using SimplifyPointersTest = TransformTest;
TEST_F(SimplifyPointersTest, Error_MissingSimplifyPointers) {
auto* src = "";
auto* expect =
"error: tint::transform::SimplifyPointers depends on "
"tint::transform::Unshadow but the dependency was not run";
auto got = Run<SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(SimplifyPointersTest, EmptyModule) {
auto* src = "";
auto* expect = "";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
@@ -51,7 +60,7 @@ fn f() {
}
)";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
@@ -79,7 +88,7 @@ fn f() {
}
)";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
@@ -103,7 +112,7 @@ fn f() {
}
)";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
@@ -126,7 +135,7 @@ fn f() {
}
)";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
@@ -180,7 +189,7 @@ fn matrix() {
}
)";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
@@ -201,7 +210,7 @@ fn f() {
}
)";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
@@ -229,7 +238,7 @@ fn f() {
}
)";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
@@ -264,7 +273,7 @@ fn main() {
}
)";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
@@ -330,34 +339,42 @@ fn f() {
}
)";
auto got = Run<SimplifyPointers>(src);
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
// TODO(crbug.com/tint/819): Enable when we support inter-scope shadowing.
TEST_F(SimplifyPointersTest, DISABLED_ModificationAfterInline) {
TEST_F(SimplifyPointersTest, ShadowPointer) {
auto* src = R"(
fn x(p : ptr<function, i32>) -> i32 {
return *p;
}
var<private> a : array<i32, 2>;
fn f() {
var i : i32 = 1;
let p : ptr<function, i32> = &i;
if (true) {
var i : i32 = 2;
x(p);
[[stage(compute), workgroup_size(1)]]
fn main() {
let x = &a;
var a : i32 = (*x)[0];
{
var a : i32 = (*x)[1];
}
}
)";
auto* expect = R"(<TODO>)";
auto* expect = R"(
var<private> a : array<i32, 2>;
auto got = Run<SimplifyPointers>(src);
[[stage(compute), workgroup_size(1)]]
fn main() {
var a_1 : i32 = a[0];
{
var a_2 : i32 = a[1];
}
}
)";
auto got = Run<Unshadow, SimplifyPointers>(src);
EXPECT_EQ(expect, str(got));
}
} // namespace
} // namespace transform
} // namespace tint

99
src/transform/unshadow.cc Normal file
View File

@@ -0,0 +1,99 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/transform/unshadow.h"
#include <memory>
#include <unordered_map>
#include <utility>
#include "src/program_builder.h"
#include "src/sem/block_statement.h"
#include "src/sem/function.h"
#include "src/sem/statement.h"
#include "src/sem/variable.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::Unshadow);
namespace tint {
namespace transform {
/// The PIMPL state for the Unshadow transform
struct Unshadow::State {
/// The clone context
CloneContext& ctx;
/// Constructor
/// @param context the clone context
explicit State(CloneContext& context) : ctx(context) {}
/// Performs the transformation
void Run() {
auto& sem = ctx.src->Sem();
// Maps a variable to its new name.
std::unordered_map<const sem::Variable*, Symbol> renamed_to;
auto rename = [&](const sem::Variable* var) -> const ast::Variable* {
auto* decl = var->Declaration();
auto name = ctx.src->Symbols().NameFor(decl->symbol);
auto symbol = ctx.dst->Symbols().New(name);
renamed_to.emplace(var, symbol);
auto source = ctx.Clone(decl->source);
auto* type = ctx.Clone(decl->type);
auto* constructor = ctx.Clone(decl->constructor);
auto decorations = ctx.Clone(decl->decorations);
return ctx.dst->create<ast::Variable>(
source, symbol, decl->declared_storage_class, decl->declared_access,
type, decl->is_const, constructor, decorations);
};
ctx.ReplaceAll([&](const ast::Variable* var) -> const ast::Variable* {
if (auto* local = sem.Get<sem::LocalVariable>(var)) {
if (local->Shadows()) {
return rename(local);
}
}
if (auto* param = sem.Get<sem::Parameter>(var)) {
if (param->Shadows()) {
return rename(param);
}
}
return nullptr;
});
ctx.ReplaceAll([&](const ast::IdentifierExpression* ident)
-> const tint::ast::IdentifierExpression* {
if (auto* user = sem.Get<sem::VariableUser>(ident)) {
auto it = renamed_to.find(user->Variable());
if (it != renamed_to.end()) {
return ctx.dst->Expr(it->second);
}
}
return nullptr;
});
ctx.Clone();
}
};
Unshadow::Unshadow() = default;
Unshadow::~Unshadow() = default;
void Unshadow::Run(CloneContext& ctx, const DataMap&, DataMap&) {
State(ctx).Run();
}
} // namespace transform
} // namespace tint

48
src/transform/unshadow.h Normal file
View File

@@ -0,0 +1,48 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_TRANSFORM_UNSHADOW_H_
#define SRC_TRANSFORM_UNSHADOW_H_
#include "src/transform/transform.h"
namespace tint {
namespace transform {
/// Unshadow is a Transform that renames any variables that shadow another
/// variable.
class Unshadow : public Castable<Unshadow, Transform> {
public:
/// Constructor
Unshadow();
/// Destructor
~Unshadow() override;
protected:
struct State;
/// Runs the transform using the CloneContext built for transforming a
/// program. Run() is responsible for calling Clone() on the CloneContext.
/// @param ctx the CloneContext primed with the input program and
/// ProgramBuilder
/// @param inputs optional extra transform-specific input data
/// @param outputs optional extra transform-specific output data
void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) override;
};
} // namespace transform
} // namespace tint
#endif // SRC_TRANSFORM_UNSHADOW_H_

View File

@@ -0,0 +1,397 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/transform/unshadow.h"
#include "src/transform/test_helper.h"
namespace tint {
namespace transform {
namespace {
using UnshadowTest = TransformTest;
TEST_F(UnshadowTest, EmptyModule) {
auto* src = "";
auto* expect = "";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, Noop) {
auto* src = R"(
var<private> a : i32;
let b : i32 = 1;
fn F(c : i32) {
var d : i32;
let e : i32 = 1;
{
var f : i32;
let g : i32 = 1;
}
}
)";
auto* expect = src;
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, LocalShadowsAlias) {
auto* src = R"(
type a = i32;
fn X() {
var a = false;
}
fn Y() {
let a = true;
}
)";
auto* expect = R"(
type a = i32;
fn X() {
var a_1 = false;
}
fn Y() {
let a_2 = true;
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, LocalShadowsStruct) {
auto* src = R"(
struct a {
m : i32;
};
fn X() {
var a = true;
}
fn Y() {
let a = false;
}
)";
auto* expect = R"(
struct a {
m : i32;
};
fn X() {
var a_1 = true;
}
fn Y() {
let a_2 = false;
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, LocalShadowsFunction) {
auto* src = R"(
fn a() {
var a = true;
}
fn b() {
let b = false;
}
)";
auto* expect = R"(
fn a() {
var a_1 = true;
}
fn b() {
let b_1 = false;
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, LocalShadowsGlobalVar) {
auto* src = R"(
var<private> a : i32;
fn X() {
var a = (a == 123);
}
fn Y() {
let a = (a == 321);
}
)";
auto* expect = R"(
var<private> a : i32;
fn X() {
var a_1 = (a == 123);
}
fn Y() {
let a_2 = (a == 321);
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, LocalShadowsGlobalLet) {
auto* src = R"(
let a : i32 = 1;
fn X() {
var a = (a == 123);
}
fn Y() {
let a = (a == 321);
}
)";
auto* expect = R"(
let a : i32 = 1;
fn X() {
var a_1 = (a == 123);
}
fn Y() {
let a_2 = (a == 321);
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, LocalShadowsLocalVar) {
auto* src = R"(
fn X() {
var a : i32;
{
var a = (a == 123);
}
{
let a = (a == 321);
}
}
)";
auto* expect = R"(
fn X() {
var a : i32;
{
var a_1 = (a == 123);
}
{
let a_2 = (a == 321);
}
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, LocalShadowsLocalLet) {
auto* src = R"(
fn X() {
let a = 1;
{
var a = (a == 123);
}
{
let a = (a == 321);
}
}
)";
auto* expect = R"(
fn X() {
let a = 1;
{
var a_1 = (a == 123);
}
{
let a_2 = (a == 321);
}
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, LocalShadowsParam) {
auto* src = R"(
fn F(a : i32) {
{
var a = (a == 123);
}
{
let a = (a == 321);
}
}
)";
auto* expect = R"(
fn F(a : i32) {
{
var a_1 = (a == 123);
}
{
let a_2 = (a == 321);
}
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, ParamShadowsFunction) {
auto* src = R"(
fn a(a : i32) {
{
var a = (a == 123);
}
{
let a = (a == 321);
}
}
)";
auto* expect = R"(
fn a(a_1 : i32) {
{
var a_2 = (a_1 == 123);
}
{
let a_3 = (a_1 == 321);
}
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, ParamShadowsGlobalVar) {
auto* src = R"(
var<private> a : i32;
fn F(a : bool) {
}
)";
auto* expect = R"(
var<private> a : i32;
fn F(a_1 : bool) {
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, ParamShadowsGlobalLet) {
auto* src = R"(
let a : i32 = 1;
fn F(a : bool) {
}
)";
auto* expect = R"(
let a : i32 = 1;
fn F(a_1 : bool) {
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(UnshadowTest, ParamShadowsAlias) {
auto* src = R"(
type a = i32;
fn F(a : a) {
{
var a = (a == 123);
}
{
let a = (a == 321);
}
}
)";
auto* expect = R"(
type a = i32;
fn F(a_1 : a) {
{
var a_2 = (a_1 == 123);
}
{
let a_3 = (a_1 == 321);
}
}
)";
auto got = Run<Unshadow>(src);
EXPECT_EQ(expect, str(got));
}
} // namespace
} // namespace transform
} // namespace tint