Record precision of constant variables when needed

Add a traverser that checks precision qualifiers of folded constants and
hoists them to separate precision qualified variables if needed.

Fixes sdk/tests/conformance/glsl/bugs/constant-precision-qualifier.html

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

Change-Id: I1639595e0e49470736be93274f0af07ee732e1fe
Reviewed-on: https://chromium-review.googlesource.com/275095
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index d46c13e..aeaf7de 100644
--- a/src/compiler/translator/IntermTraverse.cpp
+++ b/src/compiler/translator/IntermTraverse.cpp
@@ -30,7 +30,7 @@
     mInsertions.push_back(insert);
 }
 
-TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type)
+TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type, TQualifier qualifier)
 {
     // Each traversal uses at most one temporary variable, so the index stays the same within a single traversal.
     TInfoSinkBase symbolNameOut;
@@ -40,10 +40,15 @@
 
     TIntermSymbol *node = new TIntermSymbol(0, symbolName, type);
     node->setInternal(true);
-    node->getTypePointer()->setQualifier(EvqTemporary);
+    node->getTypePointer()->setQualifier(qualifier);
     return node;
 }
 
+TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type)
+{
+    return createTempSymbol(type, EvqTemporary);
+}
+
 TIntermAggregate *TIntermTraverser::createTempDeclaration(const TType &type)
 {
     TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
@@ -51,10 +56,10 @@
     return tempDeclaration;
 }
 
-TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer)
+TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier)
 {
     ASSERT(initializer != nullptr);
-    TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType());
+    TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier);
     TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
     TIntermBinary *tempInit = new TIntermBinary(EOpInitialize);
     tempInit->setLeft(tempSymbol);
@@ -64,6 +69,11 @@
     return tempDeclaration;
 }
 
+TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer)
+{
+    return createTempInitDeclaration(initializer, EvqTemporary);
+}
+
 TIntermBinary *TIntermTraverser::createTempAssignment(TIntermTyped *rightNode)
 {
     ASSERT(rightNode != nullptr);