Fix constructor constant folding

The previous solution for constant folding constructors was significantly
overengineered and partially incorrect. Switch to a much simpler
constructor folding function that does not use an AST traverser, but
simply iterates over the constant folded parameters of the constructor
and doesn't do any unnecessary checks. It also reuses some code for
constant folding other built-in functions.

This fixes issues with initializing constant matrices with only a single
parameter. Instead of copying the first component of the constructor
parameter all over the matrix, passing a vec4 or matrix argument now
assigns the values correctly.

BUG=angleproject:1193
TEST=angle_unittests, WebGL conformance tests

Change-Id: I50b10721ea30cb15843fba892c1b1a211f1d72e5
Reviewed-on: https://chromium-review.googlesource.com/311191
Tryjob-Request: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index fff2b8e..d537bcb 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1369,17 +1369,6 @@
     return false;
 }
 
-bool TParseContext::areAllChildrenConstantFolded(TIntermAggregate *aggrNode)
-{
-    ASSERT(aggrNode != nullptr);
-    for (TIntermNode *&node : *aggrNode->getSequence())
-    {
-        if (node->getAsConstantUnion() == nullptr)
-            return false;
-    }
-    return true;
-}
-
 TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier,
                                                  bool invariant,
                                                  TLayoutQualifier layoutQualifier,
@@ -2318,7 +2307,7 @@
         type->setPrecision(constructor->getPrecision());
     }
 
-    TIntermTyped *constConstructor = foldConstConstructor(constructor, *type);
+    TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor);
     if (constConstructor)
     {
         return constConstructor;
@@ -2327,33 +2316,6 @@
     return constructor;
 }
 
-TIntermTyped *TParseContext::foldConstConstructor(TIntermAggregate *aggrNode, const TType &type)
-{
-    // TODO: Add support for folding array constructors
-    bool canBeFolded = areAllChildrenConstantFolded(aggrNode) && !type.isArray();
-    if (canBeFolded)
-    {
-        bool returnVal             = false;
-        TConstantUnion *unionArray = new TConstantUnion[type.getObjectSize()];
-        if (aggrNode->getSequence()->size() == 1)
-        {
-            returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray,
-                                                    aggrNode->getOp(), type, true);
-        }
-        else
-        {
-            returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray,
-                                                    aggrNode->getOp(), type);
-        }
-        if (returnVal)
-            return 0;
-
-        return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
-    }
-
-    return 0;
-}
-
 //
 // This function returns the tree representation for the vector field(s) being accessed from contant
 // vector.