[ir][msl] Emit function parameters

Add support for the ir function parameters both in their usage and in
the function definition.

Bug: tint:1967
Change-Id: I6ca876d286216cd008f619d65fe17ac1ef1a8449
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/162310
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index cbb92ed..936ca99 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -48,6 +48,7 @@
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/multi_in_block.h"
 #include "src/tint/lang/core/ir/return.h"
+#include "src/tint/lang/core/ir/store.h"
 #include "src/tint/lang/core/ir/unreachable.h"
 #include "src/tint/lang/core/ir/user_call.h"
 #include "src/tint/lang/core/ir/validator.h"
@@ -225,9 +226,22 @@
             // TODO(dsinclair): Handle return type attributes
 
             EmitType(out, func->ReturnType());
-            out << " " << ir_.NameOf(func).Name() << "() {";
+            out << " " << ir_.NameOf(func).Name() << "(";
 
-            // TODO(dsinclair): Emit Function parameters
+            size_t i = 0;
+            for (auto* param : func->Params()) {
+                if (i > 0) {
+                    out << ", ";
+                }
+                ++i;
+
+                // TODO(dsinclair): Handle parameter attributes
+                EmitType(out, param->Type());
+                out << " ";
+                EmitFunctionParam(out, param);
+            }
+
+            out << ") {";
         }
         {
             ScopedIndent si(current_buffer_);
@@ -255,6 +269,7 @@
                 [&](core::ir::Unreachable*) { EmitUnreachable(); },  //
                 [&](core::ir::Var* v) { EmitVar(v); },               //
                 [&](core::ir::Discard*) { EmitDiscard(); },          //
+                [&](core::ir::Store* s) { EmitStore(s); },           //
 
                 [&](core::ir::Bitcast*) { MaybeEmitInstruction(inst); },    //
                 [&](core::ir::Binary*) { MaybeEmitInstruction(inst); },     //
@@ -262,7 +277,7 @@
                 [&](core::ir::Load*) { MaybeEmitInstruction(inst); },       //
                 [&](core::ir::Construct*) { MaybeEmitInstruction(inst); },  //
                 [&](core::ir::Access*) { MaybeEmitInstruction(inst); },     //
-                [&](core::ir::UserCall* c) {
+                [&](core::ir::UserCall* c) {                                //
                     if (c->Result()->Type()->Is<core::type::Void>()) {
                         auto out = Line();
                         EmitValue(out, c->Result());
@@ -311,7 +326,8 @@
                     [&](const core::ir::Access* a) { EmitAccess(out, a); },        //
                     [&](const core::ir::UserCall* c) { EmitUserCall(out, c); },    //
                     TINT_ICE_ON_NO_MATCH);
-            },  //
+            },                                                                     //
+            [&](const core::ir::FunctionParam* p) { EmitFunctionParam(out, p); },  //
             TINT_ICE_ON_NO_MATCH);
     }
 
@@ -496,6 +512,16 @@
     /// Emit a discard instruction
     void EmitDiscard() { Line() << "discard_fragment();"; }
 
+    /// Emit a store
+    void EmitStore(core::ir::Store* s) {
+        auto out = Line();
+
+        EmitValue(out, s->To());
+        out << " = ";
+        EmitValue(out, s->From());
+        out << ";";
+    }
+
     /// Emit a bitcast instruction
     void EmitBitcast(StringStream& out, const core::ir::Bitcast* b) {
         out << "as_type<";
@@ -546,6 +572,11 @@
         out << ")";
     }
 
+    /// Emit a function parameter
+    void EmitFunctionParam(StringStream& out, const core::ir::FunctionParam* p) {
+        out << ir_.NameOf(p).Name();
+    }
+
     /// Emit a constructor
     void EmitConstruct(StringStream& out, const core::ir::Construct* c) {
         Switch(
diff --git a/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.ir.msl b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.ir.msl
index 2454f50..636891c 100644
--- a/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.ir.msl
+++ b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.ir.msl
@@ -1,27 +1,12 @@
-SKIP: FAILED
-
 #include <metal_stdlib>
 using namespace metal;
 
-float b() {
+float b(int i) {
   return 2.29999995231628417969f;
 }
-int c() {
+int c(uint u) {
   return 1;
 }
 void a() {
   float a = b(c(2u));
 }
-program_source:11:15: error: no matching function for call to 'c'
-  float a = b(c(2u));
-              ^
-program_source:7:5: note: candidate function not viable: requires 0 arguments, but 1 was provided
-int c() {
-    ^
-program_source:11:13: error: no matching function for call to 'b'
-  float a = b(c(2u));
-            ^
-program_source:4:7: note: candidate function not viable: requires 0 arguments, but 1 was provided
-float b() {
-      ^
-
diff --git a/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.ir.msl
index 03d2607..a965f5e 100644
--- a/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.ir.msl
+++ b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.ir.msl
@@ -1,9 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:315 internal compiler error: Switch() matched no cases. Type: tint::core::ir::FunctionParam
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void c(int x, int y, int z) {
+  int a = (((1 + x) + y) + z);
+  a = (a + 2);
+}
+void b() {
+  c(1, 2, 3);
+  c(4, 5, 6);
+}
diff --git a/test/tint/expressions/user_call/multi_param_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.ir.msl
index 03d2607..5f6e07f 100644
--- a/test/tint/expressions/user_call/multi_param_return.wgsl.expected.ir.msl
+++ b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.ir.msl
@@ -1,9 +1,12 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:315 internal compiler error: Switch() matched no cases. Type: tint::core::ir::FunctionParam
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+int c(int x, int y, int z) {
+  int a = (((1 + x) + y) + z);
+  a = (a + 2);
+  return a;
+}
+void b() {
+  int b = c(2, 3, 4);
+  b = (b + c(3, 4, 5));
+}
diff --git a/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.ir.msl
index 1e88c74..c15e394 100644
--- a/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.ir.msl
+++ b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.ir.msl
@@ -1,9 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:274 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Store
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void c() {
+  int a = 1;
+  a = (a + 2);
+}
+void b() {
+  c();
+  c();
+}
diff --git a/test/tint/expressions/user_call/no_params_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/no_params_return.wgsl.expected.ir.msl
index 1e88c74..1ff2217 100644
--- a/test/tint/expressions/user_call/no_params_return.wgsl.expected.ir.msl
+++ b/test/tint/expressions/user_call/no_params_return.wgsl.expected.ir.msl
@@ -1,9 +1,12 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:274 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Store
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+int c() {
+  int a = 1;
+  a = (a + 2);
+  return a;
+}
+void b() {
+  int b = c();
+  b = (b + c());
+}
diff --git a/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.ir.msl
index 03d2607..448e012 100644
--- a/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.ir.msl
+++ b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.ir.msl
@@ -1,9 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:315 internal compiler error: Switch() matched no cases. Type: tint::core::ir::FunctionParam
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void c(int z) {
+  int a = (1 + z);
+  a = (a + 2);
+}
+void b() {
+  c(2);
+  c(3);
+}
diff --git a/test/tint/expressions/user_call/one_param_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/one_param_return.wgsl.expected.ir.msl
index 03d2607..4633fa0 100644
--- a/test/tint/expressions/user_call/one_param_return.wgsl.expected.ir.msl
+++ b/test/tint/expressions/user_call/one_param_return.wgsl.expected.ir.msl
@@ -1,9 +1,12 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:315 internal compiler error: Switch() matched no cases. Type: tint::core::ir::FunctionParam
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+int c(int z) {
+  int a = (1 + z);
+  a = (a + 2);
+  return a;
+}
+void b() {
+  int b = c(2);
+  b = (b + c(3));
+}