Assign built-in function return type in promote()

This finishes the refactoring of unary math operation handling so that
IntermUnary::promote has the complete code for setting the return type of
the node.

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

Change-Id: I19bd8d53029e24f734c9436eceb446b37e7fcf26
Reviewed-on: https://chromium-review.googlesource.com/262416
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 910a8b8..266e3c8 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -328,15 +328,10 @@
 // Make sure the type of a unary operator is appropriate for its
 // combination of operation and operand type.
 //
-void TIntermUnary::promote()
+void TIntermUnary::promote(const TType *funcReturnType)
 {
     switch (mOp)
     {
-      // Some built-ins get the type of their return value assigned elsewhere.
-      case EOpAny:
-      case EOpAll:
-      case EOpVectorLogicalNot:
-        break;
       case EOpFloatBitsToInt:
       case EOpFloatBitsToUint:
       case EOpIntBitsToFloat:
@@ -355,6 +350,20 @@
         setType(mOperand->getType());
     }
 
+    if (funcReturnType != nullptr)
+    {
+        if (funcReturnType->getBasicType() == EbtBool)
+        {
+            // Bool types should not have precision.
+            setType(*funcReturnType);
+        }
+        else
+        {
+            // Precision of the node has been set based on the operand.
+            setTypePreservePrecision(*funcReturnType);
+        }
+    }
+
     mType.setQualifier(EvqTemporary);
 }