Add basic support for array constructors

Add limited support for parsing array constructors and writing them out as
GLSL code.

Still missing from this version: HLSL output, array support in
initializer lists, arrays with implicit size.

BUG=angleproject:941

Change-Id: I7febf80923c4cd0b730399f1f49f9456cf3668e9
Reviewed-on: https://chromium-review.googlesource.com/260572
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 7ad3f81..86eeb6d 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1651,7 +1651,24 @@
         aggregateArguments->getSequence()->push_back(arguments);
     }
 
-    if (op == EOpConstructStruct)
+    if (type->isArray())
+    {
+        // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of the array.
+        TIntermSequence *args = aggregateArguments->getSequence();
+        for (size_t i = 0; i < args->size(); i++)
+        {
+            const TType &argType = (*args)[i]->getAsTyped()->getType();
+            // It has already been checked that the argument is not an array.
+            ASSERT(!argType.isArray());
+            if (!argType.sameElementType(*type))
+            {
+                error(line, "Array constructor argument has an incorrect type", "Error");
+                recover();
+                return nullptr;
+            }
+        }
+    }
+    else if (op == EOpConstructStruct)
     {
         const TFieldList &fields = type->getStruct()->fields();
         TIntermSequence *args = aggregateArguments->getSequence();
@@ -1689,7 +1706,8 @@
 
 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
 {
-    bool canBeFolded = areAllChildConst(aggrNode);
+    // TODO: Add support for folding array constructors
+    bool canBeFolded = areAllChildConst(aggrNode) && !type.isArray();
     aggrNode->setType(type);
     if (canBeFolded) {
         bool returnVal = false;