transform: Pass CloneContext by reference

Some methods passed by pointer, others by reference. Standarize to pass-by-reference.

Also remove CloneWithStatementsAtStart().
CloneContext::InsertFront() is a better replacement.

Change-Id: Ibbf7caaa7a1b42c2d0a0cddaa3d6e76ca0e12a17
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/58062
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/transform/binding_remapper.cc b/src/transform/binding_remapper.cc
index 0b034e1..ce6a812 100644
--- a/src/transform/binding_remapper.cc
+++ b/src/transform/binding_remapper.cc
@@ -114,7 +114,7 @@
       if (ac_it != remappings->access_controls.end()) {
         ast::Access ac = ac_it->second;
         auto* ty = ctx.src->Sem().Get(var)->Type()->UnwrapRef();
-        ast::Type* inner_ty = CreateASTTypeFor(&ctx, ty);
+        ast::Type* inner_ty = CreateASTTypeFor(ctx, ty);
         auto* new_var = ctx.dst->create<ast::Variable>(
             ctx.Clone(var->source()), ctx.Clone(var->symbol()),
             var->declared_storage_class(), ac, inner_ty, var->is_const(),
diff --git a/src/transform/canonicalize_entry_point_io.cc b/src/transform/canonicalize_entry_point_io.cc
index bd30b0d..921ae6b 100644
--- a/src/transform/canonicalize_entry_point_io.cc
+++ b/src/transform/canonicalize_entry_point_io.cc
@@ -83,7 +83,7 @@
       ast::StructMemberList new_struct_members;
       for (auto* member : struct_ty->members()) {
         ast::DecorationList new_decorations = RemoveDecorations(
-            &ctx, member->decorations(), [](const ast::Decoration* deco) {
+            ctx, member->decorations(), [](const ast::Decoration* deco) {
               return deco->IsAnyOf<
                   ast::BuiltinDecoration, ast::InterpolateDecoration,
                   ast::InvariantDecoration, ast::LocationDecoration>();
@@ -154,7 +154,7 @@
             }
 
             ast::DecorationList new_decorations = RemoveDecorations(
-                &ctx, member->Declaration()->decorations(),
+                ctx, member->Declaration()->decorations(),
                 [](const ast::Decoration* deco) {
                   return !deco->IsAnyOf<
                       ast::BuiltinDecoration, ast::InterpolateDecoration,
@@ -166,7 +166,7 @@
                     member->Declaration()->decorations())) {
               // If this struct member is a builtin and we are emitting those as
               // parameters, then move it to the parameter list.
-              auto* member_ty = CreateASTTypeFor(&ctx, member->Type());
+              auto* member_ty = CreateASTTypeFor(ctx, member->Type());
               auto new_param_name = ctx.dst->Sym();
               new_parameters.push_back(
                   ctx.dst->Param(new_param_name, member_ty, new_decorations));
@@ -244,7 +244,7 @@
           }
 
           ast::DecorationList new_decorations = RemoveDecorations(
-              &ctx, member->Declaration()->decorations(),
+              ctx, member->Declaration()->decorations(),
               [](const ast::Decoration* deco) {
                 return !deco->IsAnyOf<
                     ast::BuiltinDecoration, ast::InterpolateDecoration,
@@ -306,7 +306,7 @@
             // Create a const to hold the return value expression to avoid
             // re-evaluating it multiple times.
             auto temp = ctx.dst->Sym();
-            auto* ty = CreateASTTypeFor(&ctx, ret_type);
+            auto* ty = CreateASTTypeFor(ctx, ret_type);
             auto* temp_var =
                 ctx.dst->Decl(ctx.dst->Const(temp, ty, new_ret_value()));
             ctx.InsertBefore(ret_sem->Block()->Declaration()->statements(), ret,
diff --git a/src/transform/decompose_memory_access.cc b/src/transform/decompose_memory_access.cc
index a43c4c0..06251de 100644
--- a/src/transform/decompose_memory_access.cc
+++ b/src/transform/decompose_memory_access.cc
@@ -452,7 +452,7 @@
     auto storage_class = var_user->Variable()->StorageClass();
     return utils::GetOrCreate(
         load_funcs, LoadStoreKey{storage_class, buf_ty, el_ty}, [&] {
-          auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
+          auto* buf_ast_ty = CreateASTTypeFor(ctx, buf_ty);
           auto* disable_validation =
               ctx.dst->ASTNodes().Create<ast::DisableValidationDecoration>(
                   ctx.dst->ID(), ast::DisabledValidation::
@@ -472,7 +472,7 @@
           ast::Function* func = nullptr;
           if (auto* intrinsic =
                   IntrinsicLoadFor(ctx.dst, storage_class, el_ty)) {
-            auto* el_ast_ty = CreateASTTypeFor(&ctx, el_ty);
+            auto* el_ast_ty = CreateASTTypeFor(ctx, el_ty);
             func = ctx.dst->create<ast::Function>(
                 ctx.dst->Sym(), params, el_ast_ty, nullptr,
                 ast::DecorationList{
@@ -508,12 +508,12 @@
                 values.emplace_back(ctx.dst->Call(load, "buffer", offset));
               }
             }
-            auto* el_ast_ty = CreateASTTypeFor(&ctx, el_ty);
+            auto* el_ast_ty = CreateASTTypeFor(ctx, el_ty);
             func = ctx.dst->create<ast::Function>(
                 ctx.dst->Sym(), params, el_ast_ty,
                 ctx.dst->Block(ctx.dst->Return(
                     ctx.dst->create<ast::TypeConstructorExpression>(
-                        CreateASTTypeFor(&ctx, el_ty), values))),
+                        CreateASTTypeFor(ctx, el_ty), values))),
                 ast::DecorationList{}, ast::DecorationList{});
           }
           ctx.dst->AST().AddFunction(func);
@@ -537,8 +537,8 @@
     auto storage_class = var_user->Variable()->StorageClass();
     return utils::GetOrCreate(
         store_funcs, LoadStoreKey{storage_class, buf_ty, el_ty}, [&] {
-          auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
-          auto* el_ast_ty = CreateASTTypeFor(&ctx, el_ty);
+          auto* buf_ast_ty = CreateASTTypeFor(ctx, buf_ty);
+          auto* el_ast_ty = CreateASTTypeFor(ctx, el_ty);
           auto* disable_validation =
               ctx.dst->ASTNodes().Create<ast::DisableValidationDecoration>(
                   ctx.dst->ID(), ast::DisabledValidation::
@@ -629,7 +629,7 @@
                     const sem::VariableUser* var_user) {
     auto op = intrinsic->Type();
     return utils::GetOrCreate(atomic_funcs, AtomicKey{buf_ty, el_ty, op}, [&] {
-      auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
+      auto* buf_ast_ty = CreateASTTypeFor(ctx, buf_ty);
       auto* disable_validation =
           ctx.dst->ASTNodes().Create<ast::DisableValidationDecoration>(
               ctx.dst->ID(),
@@ -650,7 +650,7 @@
       // Other parameters are copied as-is:
       for (size_t i = 1; i < intrinsic->Parameters().size(); i++) {
         auto& param = intrinsic->Parameters()[i];
-        auto* ty = CreateASTTypeFor(&ctx, param.type);
+        auto* ty = CreateASTTypeFor(ctx, param.type);
         params.emplace_back(ctx.dst->Param("param_" + std::to_string(i), ty));
       }
 
@@ -661,7 +661,7 @@
             << " and type " << el_ty->type_name();
       }
 
-      auto* ret_ty = CreateASTTypeFor(&ctx, intrinsic->ReturnType());
+      auto* ret_ty = CreateASTTypeFor(ctx, intrinsic->ReturnType());
       auto* func = ctx.dst->create<ast::Function>(
           ctx.dst->Sym(), params, ret_ty, nullptr,
           ast::DecorationList{
diff --git a/src/transform/fold_constants.cc b/src/transform/fold_constants.cc
index 6d7760a..3c72d18 100644
--- a/src/transform/fold_constants.cc
+++ b/src/transform/fold_constants.cc
@@ -76,7 +76,7 @@
             i, [&](auto&& s) { ctors.emplace_back(ctx.dst->Expr(s)); });
       }
 
-      auto* el_ty = CreateASTTypeFor(&ctx, vec->type());
+      auto* el_ty = CreateASTTypeFor(ctx, vec->type());
       return ctx.dst->vec(el_ty, vec_size, ctors);
     }
 
diff --git a/src/transform/msl.cc b/src/transform/msl.cc
index c387b27..38e60f4 100644
--- a/src/transform/msl.cc
+++ b/src/transform/msl.cc
@@ -196,7 +196,7 @@
       // This is the symbol for the variable that replaces the module-scope var.
       auto new_var_symbol = ctx.dst->Sym();
 
-      auto* store_type = CreateASTTypeFor(&ctx, var->Type()->UnwrapRef());
+      auto* store_type = CreateASTTypeFor(ctx, var->Type()->UnwrapRef());
 
       if (is_entry_point) {
         if (store_type->is_handle()) {
diff --git a/src/transform/pad_array_elements.cc b/src/transform/pad_array_elements.cc
index a6e3351..63bcd3a 100644
--- a/src/transform/pad_array_elements.cc
+++ b/src/transform/pad_array_elements.cc
@@ -67,7 +67,7 @@
     // If the element wasn't a padded array, just create the typical AST type
     // for it
     if (el_ty == nullptr) {
-      el_ty = create_ast_type_for(&ctx, array->ElemType());
+      el_ty = create_ast_type_for(ctx, array->ElemType());
     }
 
     // Structure() will create and append the ast::Struct to the
diff --git a/src/transform/robustness.cc b/src/transform/robustness.cc
index 5a71cf6..436f0a4 100644
--- a/src/transform/robustness.cc
+++ b/src/transform/robustness.cc
@@ -167,9 +167,9 @@
           level_arg
               ? b.Call("textureDimensions", ctx.Clone(texture_arg), level_arg())
               : b.Call("textureDimensions", ctx.Clone(texture_arg));
-      auto* zero = b.Construct(CreateASTTypeFor(&ctx, coords_ty));
+      auto* zero = b.Construct(CreateASTTypeFor(ctx, coords_ty));
       auto* max = ctx.dst->Sub(
-          texture_dims, b.Construct(CreateASTTypeFor(&ctx, coords_ty), 1));
+          texture_dims, b.Construct(CreateASTTypeFor(ctx, coords_ty), 1));
       auto* clamped_coords = b.Call("clamp", ctx.Clone(coords_arg), zero, max);
       ctx.Replace(coords_arg, clamped_coords);
     }
diff --git a/src/transform/spirv.cc b/src/transform/spirv.cc
index 84cd1f8..0ce47c6 100644
--- a/src/transform/spirv.cc
+++ b/src/transform/spirv.cc
@@ -148,7 +148,7 @@
       ast::StructMemberList new_struct_members;
       for (auto* member : struct_ty->members()) {
         ast::DecorationList new_decorations = RemoveDecorations(
-            &ctx, member->decorations(), [](const ast::Decoration* deco) {
+            ctx, member->decorations(), [](const ast::Decoration* deco) {
               return deco->IsAnyOf<
                   ast::BuiltinDecoration, ast::InterpolateDecoration,
                   ast::InvariantDecoration, ast::LocationDecoration>();
@@ -289,13 +289,11 @@
 
   // Assign 1.0 to the global at the start of all vertex shader entry points.
   ctx.ReplaceAll([&ctx, pointsize](ast::Function* func) -> ast::Function* {
-    if (func->pipeline_stage() != ast::PipelineStage::kVertex) {
-      return nullptr;
+    if (func->pipeline_stage() == ast::PipelineStage::kVertex) {
+      ctx.InsertFront(func->body()->statements(),
+                      ctx.dst->Assign(pointsize, 1.0f));
     }
-    return CloneWithStatementsAtStart(&ctx, func,
-                                      {
-                                          ctx.dst->Assign(pointsize, 1.0f),
-                                      });
+    return nullptr;
   });
 }
 
@@ -319,7 +317,7 @@
   if (!ty->Is<sem::Struct>()) {
     // Base case: create a global variable and return.
     ast::DecorationList new_decorations =
-        RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) {
+        RemoveDecorations(ctx, decorations, [](const ast::Decoration* deco) {
           return !deco->IsAnyOf<
               ast::BuiltinDecoration, ast::InterpolateDecoration,
               ast::InvariantDecoration, ast::LocationDecoration>();
@@ -385,7 +383,7 @@
   if (!ty->Is<sem::Struct>()) {
     // Create a global variable.
     ast::DecorationList new_decorations =
-        RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) {
+        RemoveDecorations(ctx, decorations, [](const ast::Decoration* deco) {
           return !deco->IsAnyOf<
               ast::BuiltinDecoration, ast::InterpolateDecoration,
               ast::InvariantDecoration, ast::LocationDecoration>();
diff --git a/src/transform/transform.cc b/src/transform/transform.cc
index a6b46bd..8342d1f 100644
--- a/src/transform/transform.cc
+++ b/src/transform/transform.cc
@@ -71,101 +71,80 @@
   return true;
 }
 
-ast::Function* Transform::CloneWithStatementsAtStart(
-    CloneContext* ctx,
-    ast::Function* in,
-    ast::StatementList statements) {
-  for (auto* s : *in->body()) {
-    statements.emplace_back(ctx->Clone(s));
-  }
-  // Clone arguments outside of create() call to have deterministic ordering
-  auto source = ctx->Clone(in->source());
-  auto symbol = ctx->Clone(in->symbol());
-  auto params = ctx->Clone(in->params());
-  auto* return_type = ctx->Clone(in->return_type());
-  auto* body = ctx->dst->create<ast::BlockStatement>(
-      ctx->Clone(in->body()->source()), statements);
-  auto decos = ctx->Clone(in->decorations());
-  auto ret_decos = ctx->Clone(in->return_type_decorations());
-  return ctx->dst->create<ast::Function>(source, symbol, params, return_type,
-                                         body, decos, ret_decos);
-}
-
 ast::DecorationList Transform::RemoveDecorations(
-    CloneContext* ctx,
+    CloneContext& ctx,
     const ast::DecorationList& in,
     std::function<bool(const ast::Decoration*)> should_remove) {
   ast::DecorationList new_decorations;
   for (auto* deco : in) {
     if (!should_remove(deco)) {
-      new_decorations.push_back(ctx->Clone(deco));
+      new_decorations.push_back(ctx.Clone(deco));
     }
   }
   return new_decorations;
 }
 
-ast::Type* Transform::CreateASTTypeFor(CloneContext* ctx, const sem::Type* ty) {
+ast::Type* Transform::CreateASTTypeFor(CloneContext& ctx, const sem::Type* ty) {
   if (ty->Is<sem::Void>()) {
-    return ctx->dst->create<ast::Void>();
+    return ctx.dst->create<ast::Void>();
   }
   if (ty->Is<sem::I32>()) {
-    return ctx->dst->create<ast::I32>();
+    return ctx.dst->create<ast::I32>();
   }
   if (ty->Is<sem::U32>()) {
-    return ctx->dst->create<ast::U32>();
+    return ctx.dst->create<ast::U32>();
   }
   if (ty->Is<sem::F32>()) {
-    return ctx->dst->create<ast::F32>();
+    return ctx.dst->create<ast::F32>();
   }
   if (ty->Is<sem::Bool>()) {
-    return ctx->dst->create<ast::Bool>();
+    return ctx.dst->create<ast::Bool>();
   }
   if (auto* m = ty->As<sem::Matrix>()) {
     auto* el = CreateASTTypeFor(ctx, m->type());
-    return ctx->dst->create<ast::Matrix>(el, m->rows(), m->columns());
+    return ctx.dst->create<ast::Matrix>(el, m->rows(), m->columns());
   }
   if (auto* v = ty->As<sem::Vector>()) {
     auto* el = CreateASTTypeFor(ctx, v->type());
-    return ctx->dst->create<ast::Vector>(el, v->size());
+    return ctx.dst->create<ast::Vector>(el, v->size());
   }
   if (auto* a = ty->As<sem::Array>()) {
     auto* el = CreateASTTypeFor(ctx, a->ElemType());
     ast::DecorationList decos;
     if (!a->IsStrideImplicit()) {
-      decos.emplace_back(ctx->dst->create<ast::StrideDecoration>(a->Stride()));
+      decos.emplace_back(ctx.dst->create<ast::StrideDecoration>(a->Stride()));
     }
-    return ctx->dst->create<ast::Array>(el, a->Count(), std::move(decos));
+    return ctx.dst->create<ast::Array>(el, a->Count(), std::move(decos));
   }
   if (auto* s = ty->As<sem::Struct>()) {
-    return ctx->dst->create<ast::TypeName>(
-        ctx->Clone(s->Declaration()->name()));
+    return ctx.dst->create<ast::TypeName>(ctx.Clone(s->Declaration()->name()));
   }
   if (auto* s = ty->As<sem::Reference>()) {
     return CreateASTTypeFor(ctx, s->StoreType());
   }
   if (auto* a = ty->As<sem::Atomic>()) {
-    return ctx->dst->create<ast::Atomic>(CreateASTTypeFor(ctx, a->Type()));
+    return ctx.dst->create<ast::Atomic>(CreateASTTypeFor(ctx, a->Type()));
   }
   if (auto* t = ty->As<sem::DepthTexture>()) {
-    return ctx->dst->create<ast::DepthTexture>(t->dim());
+    return ctx.dst->create<ast::DepthTexture>(t->dim());
   }
   if (auto* t = ty->As<sem::MultisampledTexture>()) {
-    return ctx->dst->create<ast::MultisampledTexture>(
+    return ctx.dst->create<ast::MultisampledTexture>(
         t->dim(), CreateASTTypeFor(ctx, t->type()));
   }
   if (auto* t = ty->As<sem::SampledTexture>()) {
-    return ctx->dst->create<ast::SampledTexture>(
+    return ctx.dst->create<ast::SampledTexture>(
         t->dim(), CreateASTTypeFor(ctx, t->type()));
   }
   if (auto* t = ty->As<sem::StorageTexture>()) {
-    return ctx->dst->create<ast::StorageTexture>(
+    return ctx.dst->create<ast::StorageTexture>(
         t->dim(), t->image_format(), CreateASTTypeFor(ctx, t->type()),
         t->access());
   }
   if (auto* s = ty->As<sem::Sampler>()) {
-    return ctx->dst->create<ast::Sampler>(s->kind());
+    return ctx.dst->create<ast::Sampler>(s->kind());
   }
-  TINT_UNREACHABLE(Transform, ctx->dst->Diagnostics())
+  TINT_UNREACHABLE(Transform, ctx.dst->Diagnostics())
       << "Unhandled type: " << ty->TypeInfo().name;
   return nullptr;
 }
diff --git a/src/transform/transform.h b/src/transform/transform.h
index b589ab5..08bf945 100644
--- a/src/transform/transform.h
+++ b/src/transform/transform.h
@@ -185,24 +185,13 @@
   bool Requires(CloneContext& ctx,
                 std::initializer_list<const ::tint::TypeInfo*> deps);
 
-  /// Clones the function `in` adding `statements` to the beginning of the
-  /// cloned function body.
-  /// @param ctx the clone context
-  /// @param in the function to clone
-  /// @param statements the statements to prepend to `in`'s body
-  /// @return the cloned function
-  static ast::Function* CloneWithStatementsAtStart(
-      CloneContext* ctx,
-      ast::Function* in,
-      ast::StatementList statements);
-
   /// Clones the decoration list `in`, removing decorations based on a filter.
   /// @param ctx the clone context
   /// @param in the decorations to clone
   /// @param should_remove the function to select which decorations to remove
   /// @return the cloned decorations
   static ast::DecorationList RemoveDecorations(
-      CloneContext* ctx,
+      CloneContext& ctx,
       const ast::DecorationList& in,
       std::function<bool(const ast::Decoration*)> should_remove);
 
@@ -212,7 +201,7 @@
   /// @param ty the semantic type to reconstruct
   /// @returns a ast::Type that when resolved, will produce the semantic type
   /// `ty`.
-  static ast::Type* CreateASTTypeFor(CloneContext* ctx, const sem::Type* ty);
+  static ast::Type* CreateASTTypeFor(CloneContext& ctx, const sem::Type* ty);
 };
 
 }  // namespace transform
diff --git a/src/transform/transform_test.cc b/src/transform/transform_test.cc
index bfe4278..887c410 100644
--- a/src/transform/transform_test.cc
+++ b/src/transform/transform_test.cc
@@ -32,7 +32,7 @@
     auto* sem_type = create_sem_type(sem_type_builder);
     Program program(std::move(sem_type_builder));
     CloneContext ctx(&ast_type_builder, &program, false);
-    return CreateASTTypeFor(&ctx, sem_type);
+    return CreateASTTypeFor(ctx, sem_type);
   }
 
   ProgramBuilder ast_type_builder;
diff --git a/src/transform/wrap_arrays_in_structs.cc b/src/transform/wrap_arrays_in_structs.cc
index d7c7396..c16503c 100644
--- a/src/transform/wrap_arrays_in_structs.cc
+++ b/src/transform/wrap_arrays_in_structs.cc
@@ -121,7 +121,7 @@
     // If the element wasn't an array, just create the typical AST type for it
     if (!el_type) {
       el_type = [=](CloneContext& c) {
-        return CreateASTTypeFor(&c, array->ElemType());
+        return CreateASTTypeFor(c, array->ElemType());
       };
     }
 
diff --git a/src/transform/zero_init_workgroup_memory.cc b/src/transform/zero_init_workgroup_memory.cc
index 600a02f..bc820fa 100644
--- a/src/transform/zero_init_workgroup_memory.cc
+++ b/src/transform/zero_init_workgroup_memory.cc
@@ -46,7 +46,7 @@
             const std::function<ast::Expression*()>& get_expr) {
     if (CanZero(ty)) {
       auto* var = get_expr();
-      auto* zero_init = ctx.dst->Construct(CreateASTTypeFor(&ctx, ty));
+      auto* zero_init = ctx.dst->Construct(CreateASTTypeFor(ctx, ty));
       stmts.emplace_back(
           ctx.dst->create<ast::AssignmentStatement>(var, zero_init));
       return;
@@ -54,7 +54,7 @@
 
     if (auto* atomic = ty->As<sem::Atomic>()) {
       auto* zero_init =
-          ctx.dst->Construct(CreateASTTypeFor(&ctx, atomic->Type()));
+          ctx.dst->Construct(CreateASTTypeFor(ctx, atomic->Type()));
       auto* store = ctx.dst->Call("atomicStore", ctx.dst->AddressOf(get_expr()),
                                   zero_init);
       stmts.emplace_back(ctx.dst->create<ast::CallStatement>(store));