Don't use TIntermSymbol nodes for function parameters

Parameter nodes are not needed - it's simpler to just create a
TVariable object for each parameter when the TFunction is initialized.

With this change we also store only one object per each parameter type
used in built-in functions, instead of one array of TConstParameter
entries for each unique parameter sequence.

This simplifies code and reduces binary size and compiler memory use.
Compiler perf does not seem to be significantly affected.

BUG=angleproject:2267
TEST=angle_unittests

Change-Id: I2b82400dd594731074309f92a705e75135a4c82c
Reviewed-on: https://chromium-review.googlesource.com/955589
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 74c0f8d..31f1a80 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -1756,35 +1756,30 @@
 
     out << TypeString(node->getFunctionPrototype()->getType()) << " ";
 
-    TIntermSequence *parameters = node->getFunctionPrototype()->getSequence();
+    const TFunction *func = node->getFunction();
 
-    if (node->getFunction()->isMain())
+    if (func->isMain())
     {
         out << "gl_main(";
     }
     else
     {
-        out << DecorateFunctionIfNeeded(node->getFunction()) << DisambiguateFunctionName(parameters)
+        out << DecorateFunctionIfNeeded(func) << DisambiguateFunctionName(func)
             << (mOutputLod0Function ? "Lod0(" : "(");
     }
 
-    for (unsigned int i = 0; i < parameters->size(); i++)
+    size_t paramCount = func->getParamCount();
+    for (unsigned int i = 0; i < paramCount; i++)
     {
-        TIntermSymbol *symbol = (*parameters)[i]->getAsSymbolNode();
+        const TVariable *param = func->getParam(i);
+        ensureStructDefined(param->getType());
 
-        if (symbol)
+        writeParameter(param, out);
+
+        if (i < paramCount - 1)
         {
-            ensureStructDefined(symbol->getType());
-
-            writeParameter(symbol, out);
-
-            if (i < parameters->size() - 1)
-            {
-                out << ", ";
-            }
+            out << ", ";
         }
-        else
-            UNREACHABLE();
     }
 
     out << ")\n";
@@ -1871,32 +1866,29 @@
     return false;
 }
 
-bool OutputHLSL::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node)
+void OutputHLSL::visitFunctionPrototype(TIntermFunctionPrototype *node)
 {
     TInfoSinkBase &out = getInfoSink();
 
-    ASSERT(visit == PreVisit);
     size_t index = mCallDag.findIndex(node->getFunction()->uniqueId());
     // Skip the prototype if it is not implemented (and thus not used)
     if (index == CallDAG::InvalidIndex)
     {
-        return false;
+        return;
     }
 
-    TIntermSequence *arguments = node->getSequence();
+    const TFunction *func = node->getFunction();
 
-    TString name = DecorateFunctionIfNeeded(node->getFunction());
-    out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(arguments)
+    TString name = DecorateFunctionIfNeeded(func);
+    out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(func)
         << (mOutputLod0Function ? "Lod0(" : "(");
 
-    for (unsigned int i = 0; i < arguments->size(); i++)
+    size_t paramCount = func->getParamCount();
+    for (unsigned int i = 0; i < paramCount; i++)
     {
-        TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode();
-        ASSERT(symbol != nullptr);
+        writeParameter(func->getParam(i), out);
 
-        writeParameter(symbol, out);
-
-        if (i < arguments->size() - 1)
+        if (i < paramCount - 1)
         {
             out << ", ";
         }
@@ -1912,8 +1904,6 @@
         node->traverse(this);
         mOutputLod0Function = false;
     }
-
-    return false;
 }
 
 bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
@@ -2642,22 +2632,13 @@
     }
 }
 
-void OutputHLSL::writeParameter(const TIntermSymbol *symbol, TInfoSinkBase &out)
+void OutputHLSL::writeParameter(const TVariable *param, TInfoSinkBase &out)
 {
-    TQualifier qualifier = symbol->getQualifier();
-    const TType &type    = symbol->getType();
-    const TVariable &variable = symbol->variable();
-    TString nameStr;
+    const TType &type    = param->getType();
+    TQualifier qualifier = type.getQualifier();
 
-    if (variable.symbolType() ==
-        SymbolType::Empty)  // HLSL demands named arguments, also for prototypes
-    {
-        nameStr = "x" + str(mUniqueIndex++);
-    }
-    else
-    {
-        nameStr = DecorateVariableIfNeeded(variable);
-    }
+    TString nameStr = DecorateVariableIfNeeded(*param);
+    ASSERT(nameStr != "");  // HLSL demands named arguments, also for prototypes
 
     if (IsSampler(type.getBasicType()))
     {