Refine swizzle/indexing constant folding code

Fix constant folding of subscripting non-square matrices. Previously
constant folding would offset the pointer into the matrix in multiples
of the number of columns, when it should offset the pointer in
multiples of the number of rows.

Also change the MalformedShaderTest so that it only succeeds if vector
swizzle is being checked correctly. Previously compilation would fail
in the test either way because the shader code contained a call to an
undefined function.

Also refactor indexing checks and constant folding so that constant
folding is done entirely separately from out-of-range checks. Bogus
comments are removed from the constant folding functions.

BUG=angleproject:1444
TEST=angle_unittests, angle_end2end_tests

Change-Id: I7073b38f759e9b3635ee05947df4f6d8e23a39d5
Reviewed-on: https://chromium-review.googlesource.com/360112
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index c511330..6973a2c 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -253,18 +253,7 @@
                                  TOperator op,
                                  TFunction *fnCall,
                                  const TSourceLoc &line);
-    TIntermTyped *addConstVectorNode(TVectorFields &fields,
-                                     TIntermConstantUnion *node,
-                                     const TSourceLoc &line,
-                                     bool outOfRangeIndexIsError);
-    TIntermTyped *addConstMatrixNode(int index,
-                                     TIntermConstantUnion *node,
-                                     const TSourceLoc &line,
-                                     bool outOfRangeIndexIsError);
-    TIntermTyped *addConstArrayNode(int index,
-                                    TIntermConstantUnion *node,
-                                    const TSourceLoc &line,
-                                    bool outOfRangeIndexIsError);
+
     TIntermTyped *addConstStruct(
         const TString &identifier, TIntermTyped *node, const TSourceLoc& line);
     TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
@@ -342,6 +331,26 @@
     TSymbolTable &symbolTable;   // symbol table that goes with the language currently being parsed
 
   private:
+    // Returns a clamped index.
+    int checkIndexOutOfRange(bool outOfRangeIndexIsError,
+                             const TSourceLoc &location,
+                             int index,
+                             int arraySize,
+                             const char *reason,
+                             const char *token);
+
+    // Constant folding for element access. Note that the returned node does not have the correct
+    // type - it is expected to be fixed later.
+    TIntermConstantUnion *foldVectorSwizzle(TVectorFields &fields,
+                                            TIntermConstantUnion *baseNode,
+                                            const TSourceLoc &location);
+    TIntermConstantUnion *foldMatrixSubscript(int index,
+                                              TIntermConstantUnion *baseNode,
+                                              const TSourceLoc &location);
+    TIntermConstantUnion *foldArraySubscript(int index,
+                                             TIntermConstantUnion *baseNode,
+                                             const TSourceLoc &location);
+
     bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
 
     bool nonInitErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type);