Fix for loops with multiple init-variables in Metal.

This is structured differently than the GLSL fix, due to the different
semantics of array-types in Metal.

Change-Id: I27ad11539bbbb96abb0686d5686b8fcd2f5dd6d1
Bug: skia:11860
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/396916
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/codegen/SkSLMetalCodeGenerator.cpp b/src/sksl/codegen/SkSLMetalCodeGenerator.cpp
index cb6b81e..9647907 100644
--- a/src/sksl/codegen/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLMetalCodeGenerator.cpp
@@ -1876,12 +1876,26 @@
         return;
     }
 
-    this->write("for (");
+    bool closeForLoopScope = false;
     if (f.initializer() && !f.initializer()->isEmpty()) {
-        this->writeStatement(*f.initializer());
+        if (f.initializer()->is<Block>()) {
+            // Our initializer-statement could potentially contain multiple variables of differing
+            // type (e.g. `int` and `int[4]`). In Metal, there isn't a clean way to express this in
+            // the for's init-statement block, since we use `array<T, N>` type for our arrays.
+            // Instead, we synthesize a scope and declare those variables right above the for loop.
+            this->writeLine("{");
+            ++fIndentation;
+            this->writeStatement(*f.initializer());
+            this->write("for (; ");
+            closeForLoopScope = true;
+        } else {
+            this->write("for (");
+            this->writeStatement(*f.initializer());
+        }
     } else {
-        this->write("; ");
+        this->write("for (; ");
     }
+
     if (f.test()) {
         this->writeExpression(*f.test(), Precedence::kTopLevel);
     }
@@ -1891,6 +1905,12 @@
     }
     this->write(") ");
     this->writeStatement(*f.statement());
+
+    if (closeForLoopScope) {
+        --fIndentation;
+        this->writeLine("");
+        this->writeLine("}");
+    }
 }
 
 void MetalCodeGenerator::writeDoStatement(const DoStatement& d) {