Fold user-definedness of function nodes into TOperator

Whether a function call is user-defined is not orthogonal to TOperator
associated with the call node - other ops than function calls can't be
user-defined. Because of this it makes sense to store the user-
definedness by having different TOperator enums for different types of
calls.

This patch also tags internal helper functions that have a raw
definition outside the AST with a separate TOperator enum. This way
they can be handled with logic that is easy to understand. Before this,
function calls like this left the user-defined bit unset, despite not
really being built-ins either. The EmulatePrecision traverser uses
this. This is also something that could be used to clean up built-in
emulation in the future.

BUG=angleproject:1490
TEST=angle_unittests

Change-Id: I597fcd9789d0cc22b689ef3ce5a0cc3f621d4859
Reviewed-on: https://chromium-review.googlesource.com/433443
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index 6ae74a3..1c9dc39 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -429,7 +429,7 @@
 
 TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *child)
 {
-    TIntermAggregate *callNode = new TIntermAggregate(EOpFunctionCall);
+    TIntermAggregate *callNode = new TIntermAggregate(EOpCallInternalRawFunction);
     TName nameObj(TFunction::mangleName(name));
     nameObj.setInternal(true);
     callNode->getFunctionSymbolInfo()->setNameObj(nameObj);
@@ -638,24 +638,11 @@
     switch (node->getOp())
     {
         case EOpConstructStruct:
+        case EOpCallInternalRawFunction:
+        case EOpCallFunctionInAST:
+            // User-defined function return values are not rounded. The calculations that produced
+            // the value inside the function definition should have been rounded.
             break;
-        case EOpFunctionCall:
-        {
-            // Function call.
-            if (visit == PreVisit)
-            {
-                // User-defined function return values are not rounded, this relies on that
-                // calculations producing the value were rounded.
-                TIntermNode *parent = getParentNode();
-                if (canRoundFloat(node->getType()) && !isInFunctionMap(node) &&
-                    parentUsesResult(parent, node))
-                {
-                    TIntermNode *replacement = createRoundingFunctionCallNode(node);
-                    queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD);
-                }
-            }
-            break;
-        }
         default:
             TIntermNode *parent = getParentNode();
             if (canRoundFloat(node->getType()) && visit == PreVisit &&