Support arrays of arrays in the API

The ShaderVariable class that is used as an interface between the
compiler and the rest of the code gets arrays of arrays support.

Array of array variables are passed from the compiler just like any
other variables. However, when stored in Program state each innermost
array constitutes a separate variable. This is done to make the
implementation match the GLES specification for program interface
query APIs.

This will be tested more fully once support for parsing arrays of
arrays lands in the compiler.

TEST=angle_end2end_tests, angle_unittests
BUG=angleproject:2125

Change-Id: I0f7159000f039be92a87a52b3b68cd9a215a21cb
Reviewed-on: https://chromium-review.googlesource.com/684742
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/CollectVariables.cpp b/src/compiler/translator/CollectVariables.cpp
index 0e92f9d..1fa86bb 100644
--- a/src/compiler/translator/CollectVariables.cpp
+++ b/src/compiler/translator/CollectVariables.cpp
@@ -262,8 +262,7 @@
     info->name       = name;
     info->mappedName = name;
     info->type       = GLVariableType(type);
-    ASSERT(!type.isArrayOfArrays());
-    info->arraySize = type.isArray() ? type.getOutermostArraySize() : 0;
+    info->arraySizes.assign(type.getArraySizes().begin(), type.getArraySizes().end());
     info->precision = GLVariablePrecision(type);
 }
 
@@ -485,7 +484,8 @@
                     setBuiltInInfoFromSymbolTable("gl_FragData", &info);
                     if (!IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
                     {
-                        info.arraySize = 1;
+                        ASSERT(info.arraySizes.size() == 1u);
+                        info.arraySizes.back() = 1u;
                     }
                     info.staticUse = true;
                     mOutputVariables->push_back(info);
@@ -581,10 +581,7 @@
     variableOut->name       = name.getString().c_str();
     variableOut->mappedName = getMappedName(name);
 
-    // TODO(oetuaho@nvidia.com): Uniforms can be arrays of arrays, so this assert will need to be
-    // removed.
-    ASSERT(!type.isArrayOfArrays());
-    variableOut->arraySize = type.isArray() ? type.getOutermostArraySize() : 0;
+    variableOut->arraySizes.assign(type.getArraySizes().begin(), type.getArraySizes().end());
 }
 
 Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
@@ -677,7 +674,6 @@
         setCommonVariableProperties(fieldType, TName(field->name()), &fieldVariable);
         fieldVariable.isRowMajorLayout =
             (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
-        fieldVariable.isUnsizedArray = fieldType.isUnsizedArray();
         interfaceBlock->fields.push_back(fieldVariable);
     }
 }