Add CloneContext::Replace()
Instructs the clone context to replace a single object instance with a given replacement.
Will be used to fix brokenness in transforms.
Bug: tint:390
Change-Id: I17bf1cdf7549f697281ca7c286bdb5771e5a6f1a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38553
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/clone_context.h b/src/clone_context.h
index fc391b0..7d82532 100644
--- a/src/clone_context.h
+++ b/src/clone_context.h
@@ -154,6 +154,19 @@
return *this;
}
+ /// Replace replaces all occurrences of `what` in #src with `with` in #dst
+ /// when calling Clone().
+ /// @param what a pointer to the object in #src that will be replaced with
+ /// `with`
+ /// @param with a pointer to the replacement object that will be used when
+ /// cloning into #dst
+ /// @returns this CloneContext so calls can be chained
+ template <typename T>
+ CloneContext& Replace(T* what, T* with) {
+ cloned_.emplace(what, with);
+ return *this;
+ }
+
/// Clone performs the clone of the entire program #src to #dst.
void Clone();
diff --git a/src/clone_context_test.cc b/src/clone_context_test.cc
index 5762cf3..ff6a781 100644
--- a/src/clone_context_test.cc
+++ b/src/clone_context_test.cc
@@ -87,7 +87,7 @@
EXPECT_EQ(cloned_root->c, cloned_root->b); // Aliased
}
-TEST(CloneContext, CloneWithReplacements) {
+TEST(CloneContext, CloneWithReplaceAll) {
Program original;
auto* original_root = original.create<Cloneable>();
original_root->a = original.create<Cloneable>();
@@ -160,6 +160,30 @@
EXPECT_FALSE(cloned_root->b->b->Is<Replacement>());
}
+TEST(CloneContext, CloneWithReplace) {
+ Program original;
+ auto* original_root = original.create<Cloneable>();
+ original_root->a = original.create<Cloneable>();
+ original_root->b = original.create<Cloneable>();
+ original_root->c = original.create<Cloneable>();
+
+ // root
+ // ╭──────────────────┼──────────────────╮
+ // (a) (b) (c)
+ // Replaced
+
+ Program cloned;
+ auto* replacement = cloned.create<Cloneable>();
+
+ auto* cloned_root = CloneContext(&cloned, &original)
+ .Replace(original_root->b, replacement)
+ .Clone(original_root);
+
+ EXPECT_NE(cloned_root->a, replacement);
+ EXPECT_EQ(cloned_root->b, replacement);
+ EXPECT_NE(cloned_root->c, replacement);
+}
+
} // namespace
TINT_INSTANTIATE_CLASS_ID(Cloneable);