Change grammar to support features from es31

The grammar has been changed so that ES31 grammar is followed more
closely. The ES31 grammar is not fully supported, only functionality
related to qualifier enumeration is added.

The ParseContext is changed so that type qualifiers can be now joined
together (i.e. like layout qualifiers). This will allow enumeration of
multiple storage qualifiers (i.e. uniform readonly coherent) which is
essential for support of ES31 features.

Some of the error checks had to be moved closer to the root of the
parse tree since some of the information about the expression might be
missing.

Unfortunately, as there is no explicit ordering imposed by the
grammar, additional checks for proper order of qualifiers had to be
added. I also included unit tests which test against malformed
shaders.

BUG=angleproject:1442

TEST=angle_end2end_tests
TEST=angle_unittests
TEST=dEQP-GLES3.functional.shaders.*precision*
TEST=dEQP-GLES3.functional.shaders.*function*
TEST=dEQP-GLES2.functional.shaders.*

Change-Id: Ib3653a1ed1bfced099a6b2cbf35a7cd480c9100d
Reviewed-on: https://chromium-review.googlesource.com/362940
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/util.cpp b/src/compiler/translator/util.cpp
index bd3e484..9b59ccc 100644
--- a/src/compiler/translator/util.cpp
+++ b/src/compiler/translator/util.cpp
@@ -537,4 +537,52 @@
 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
 
+// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
+bool CanBeInvariantESSL1(TQualifier qualifier)
+{
+    return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
+           IsBuiltinOutputVariable(qualifier) ||
+           (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
 }
+
+// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
+// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
+bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
+{
+    return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
+           IsBuiltinOutputVariable(qualifier);
+}
+
+bool IsBuiltinOutputVariable(TQualifier qualifier)
+{
+    switch (qualifier)
+    {
+        case EvqPosition:
+        case EvqPointSize:
+        case EvqFragDepth:
+        case EvqFragDepthEXT:
+        case EvqFragColor:
+        case EvqSecondaryFragColorEXT:
+        case EvqFragData:
+        case EvqSecondaryFragDataEXT:
+            return true;
+        default:
+            break;
+    }
+    return false;
+}
+
+bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
+{
+    switch (qualifier)
+    {
+        case EvqFragCoord:
+        case EvqPointCoord:
+        case EvqFrontFacing:
+            return true;
+        default:
+            break;
+    }
+    return false;
+}
+}  // namespace sh