Refactor GLSL array length method parsing

This prepares for accepting arbitrary expressions as the "this" node
of the array length method.

BUG=angleproject:2142
TEST=angle_unittests

Change-Id: I728adb6e76d2779dedbabfaeec7d096872e0d00d
Reviewed-on: https://chromium-review.googlesource.com/633945
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 4216a71..f3a198a 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -5447,8 +5447,6 @@
                                        TIntermNode *thisNode,
                                        const TSourceLoc &loc)
 {
-    TConstantUnion *unionArray = new TConstantUnion[1];
-    int arraySize              = 0;
     TIntermTyped *typedThis    = thisNode->getAsTyped();
     // It's possible for the name pointer in the TFunction to be null in case it gets parsed as
     // a constructor. But such a TFunction can't reach here, since the lexer goes into FIELDS
@@ -5471,29 +5469,18 @@
     {
         error(loc, "missing input primitive declaration before calling length on gl_in", "length");
     }
+    else if (typedThis->hasSideEffects())
+    {
+        error(loc, "length method not supported on expressions with possible side effects",
+              "length");
+    }
     else
     {
-        arraySize = typedThis->getOutermostArraySize();
-        if (typedThis->getAsSymbolNode() == nullptr)
-        {
-            // This code path can be hit with expressions like these:
-            // (a = b).length()
-            // (func()).length()
-            // (int[3](0, 1, 2)).length()
-            // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid
-            // expression.
-            // It allows "An array name with the length method applied" in contrast to GLSL 4.4
-            // spec section 5.9 which allows "An array, vector or matrix expression with the
-            // length method applied".
-            error(loc, "length can only be called on array names, not on array expressions",
-                  "length");
-        }
+        TIntermUnary *node = new TIntermUnary(EOpArrayLength, typedThis);
+        node->setLine(loc);
+        return node->fold(mDiagnostics);
     }
-    unionArray->setIConst(arraySize);
-    TIntermConstantUnion *node =
-        new TIntermConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst));
-    node->setLine(loc);
-    return node;
+    return CreateZeroNode(TType(EbtInt, EbpUndefined, EvqConst));
 }
 
 TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunction *fnCall,