Simplify various logic around multi-dimensional arrays.

SkSL::Type now asserts if you try to create a multi-dimensional array;
various looping/recursing constructs that no longer need to loop or
recurse were updated.

Change-Id: I191b4a032ddc6e7759cebc8b41c536cfaaf1b626
Bug: skia:11026
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/340759
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 42344c8..bd6644a 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -84,21 +84,6 @@
 
 // Returns the name of the type with array dimensions, e.g. `float[2][4]`.
 String GLSLCodeGenerator::getTypeName(const Type& type) {
-    String result = this->getBaseTypeName(type);
-
-    for (const Type* t = &type; t->isArray(); t = &t->componentType()) {
-        if (t->columns() == Type::kUnsizedArray) {
-            result += "[]";
-        } else {
-            result.appendf("[%d]", t->columns());
-        }
-    }
-
-    return result;
-}
-
-// Returns the name of the type without array dimensions, e.g. `float[2][4]` returns `float`.
-String GLSLCodeGenerator::getBaseTypeName(const Type& type) const {
     switch (type.typeKind()) {
         case Type::TypeKind::kVector: {
             const Type& component = type.componentType();
@@ -138,7 +123,10 @@
             return result;
         }
         case Type::TypeKind::kArray: {
-            return this->getBaseTypeName(type.componentType());
+            String baseTypeName = this->getTypeName(type.componentType());
+            return (type.columns() == Type::kUnsizedArray)
+                           ? String::printf("%s[]", baseTypeName.c_str())
+                           : String::printf("%s[%d]", baseTypeName.c_str(), type.columns());
         }
         case Type::TypeKind::kScalar: {
             if (type == *fContext.fHalf_Type) {
@@ -1059,7 +1047,7 @@
         this->writeModifiers(param->modifiers(), false);
         std::vector<int> sizes;
         const Type* type = &param->type();
-        while (type->isArray()) {
+        if (type->isArray()) {
             sizes.push_back(type->columns());
             type = &type->componentType();
         }
@@ -1204,7 +1192,7 @@
     this->writeLine(intf.typeName() + " {");
     fIndentation++;
     const Type* structType = &intf.variable().type();
-    while (structType->isArray()) {
+    if (structType->isArray()) {
         structType = &structType->componentType();
     }
     for (const auto& f : structType->fields()) {
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
index 846c460..07c1078 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -101,8 +101,6 @@
 
     virtual String getTypeName(const Type& type);
 
-    String getBaseTypeName(const Type& type) const;
-
     bool writeStructDefinition(const Type& type);
 
     void writeType(const Type& type);
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 500e918..69d40e8 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -1246,7 +1246,7 @@
     this->write("struct ");
     this->writeLine(intf.typeName() + " {");
     const Type* structType = &intf.variable().type();
-    while (structType->isArray()) {
+    if (structType->isArray()) {
         structType = &structType->componentType();
     }
     fWrittenStructs.push_back(structType);
diff --git a/src/sksl/ir/SkSLInterfaceBlock.h b/src/sksl/ir/SkSLInterfaceBlock.h
index 65c13bcc..4222b4c 100644
--- a/src/sksl/ir/SkSLInterfaceBlock.h
+++ b/src/sksl/ir/SkSLInterfaceBlock.h
@@ -72,7 +72,7 @@
     String description() const override {
         String result = this->variable().modifiers().description() + this->typeName() + " {\n";
         const Type* structType = &this->variable().type();
-        while (structType->isArray()) {
+        if (structType->isArray()) {
             structType = &structType->componentType();
         }
         for (const auto& f : structType->fields()) {
diff --git a/src/sksl/ir/SkSLSymbolTable.cpp b/src/sksl/ir/SkSLSymbolTable.cpp
index efb7f73..120f82e 100644
--- a/src/sksl/ir/SkSLSymbolTable.cpp
+++ b/src/sksl/ir/SkSLSymbolTable.cpp
@@ -123,8 +123,6 @@
 
 const Type* SymbolTable::addArrayDimension(const Type* type, int arraySize) {
     if (arraySize != 0) {
-        // SkSL doesn't support multi-dimensional arrays.
-        SkASSERT(!type->isArray());
         String baseName = type->name();
         String arrayName = (arraySize != Type::kUnsizedArray)
                                    ? String::printf("%s[%d]", baseName.c_str(), arraySize)
diff --git a/src/sksl/ir/SkSLType.h b/src/sksl/ir/SkSLType.h
index 29f3c4c..cb967b4 100644
--- a/src/sksl/ir/SkSLType.h
+++ b/src/sksl/ir/SkSLType.h
@@ -189,7 +189,14 @@
     , fColumns(columns)
     , fRows(1)
     , fDimensions(SpvDim1D) {
-        SkASSERT(this->columns() > 0 || (this->isArray() && this->columns() == kUnsizedArray));
+        if (this->isArray()) {
+            // Allow either explicitly-sized or unsized arrays.
+            SkASSERT(this->columns() > 0 || this->columns() == kUnsizedArray);
+            // Disallow multi-dimensional arrays.
+            SkASSERT(!this->componentType().isArray());
+        } else {
+            SkASSERT(this->columns() > 0);
+        }
         fName = StringFragment(fNameString.c_str(), fNameString.length());
     }