Clean up function name mangling code

Fix a few incorrect comments about mangled names, and refactor
generating mangled names from function call nodes.

BUG=angleproject:1490
TEST=angle_unittests

Change-Id: I3ee68c4c0982f1a9c28d8e87aafa19f19559bbf8
Reviewed-on: https://chromium-review.googlesource.com/465826
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/CallDAG.h b/src/compiler/translator/CallDAG.h
index 102a3dd..d29f932 100644
--- a/src/compiler/translator/CallDAG.h
+++ b/src/compiler/translator/CallDAG.h
@@ -26,7 +26,7 @@
 // can be reused by multiple analyses.
 //
 // It stores a vector of function records, with one record per function.
-// Records are accessed by index but a mangled function name can be converted
+// Records are accessed by index but a function symbol id can be converted
 // to the index of the corresponding record. The records mostly contain the
 // AST node of the function and the indices of the function's callees.
 //
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index 9abf7d3..edc50b8 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -690,9 +690,9 @@
     symbolTable.insert(COMMON_BUILTINS, depthRangeParameters);
     TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
     depthRange->setQualifier(EvqUniform);
-    // Ensure we evaluate the mangled name for depth range, so we allocate to the current scope.
-    depthRangeParameters->getType().getMangledName();
-    depthRange->getType().getMangledName();
+    // Do lazy initialization for depth range, so we allocate to the current scope.
+    depthRangeParameters->getType().realize();
+    depthRange->getType().realize();
     symbolTable.insert(COMMON_BUILTINS, depthRange);
 
     //
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index dd80396..e63848a 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -450,6 +450,21 @@
         mType.setPrecision(precision);
 }
 
+TString TIntermAggregate::getSymbolTableMangledName() const
+{
+    ASSERT(!isConstructor());
+    switch (mOp)
+    {
+        case EOpCallInternalRawFunction:
+        case EOpCallBuiltInFunction:
+        case EOpCallFunctionInAST:
+            return TFunction::GetMangledNameFromCall(mFunctionInfo.getName(), mArguments);
+        default:
+            TString opString = GetOperatorString(mOp);
+            return TFunction::GetMangledNameFromCall(opString, mArguments);
+    }
+}
+
 void TIntermBlock::appendStatement(TIntermNode *statement)
 {
     // Declaration nodes with no children can appear if all the declarators just added constants to
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index 93729d5..bef27a5 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -544,7 +544,6 @@
 
     void setFromFunction(const TFunction &function);
 
-    // The name stored here should always be mangled.
     void setNameObj(const TName &name) { mName = name; }
     const TName &getNameObj() const { return mName; }
 
@@ -629,6 +628,8 @@
     TIntermSequence *getSequence() override { return &mArguments; }
     const TIntermSequence *getSequence() const override { return &mArguments; }
 
+    TString getSymbolTableMangledName() const;
+
     void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
     bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
 
diff --git a/src/compiler/translator/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index 552979d..1819ab8 100644
--- a/src/compiler/translator/IntermTraverse.cpp
+++ b/src/compiler/translator/IntermTraverse.cpp
@@ -690,7 +690,8 @@
             TFunction *builtInFunc = nullptr;
             if (!node->isFunctionCall() && !node->isConstructor())
             {
-                builtInFunc = mSymbolTable.findBuiltInOp(node, mShaderVersion);
+                builtInFunc = static_cast<TFunction *>(
+                    mSymbolTable.findBuiltIn(node->getSymbolTableMangledName(), mShaderVersion));
             }
 
             size_t paramIndex = 0;
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index 4ec871e..a7f7e8f 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -24,6 +24,13 @@
 namespace sh
 {
 
+namespace
+{
+
+static const char kFunctionMangledNameSeparator = '(';
+
+}  // anonymous namespace
+
 int TSymbolTable::uniqueIdCounter = 0;
 
 TSymbolUniqueId::TSymbolUniqueId() : mId(TSymbolTable::nextUniqueId())
@@ -70,20 +77,22 @@
 
 const TString *TFunction::buildMangledName() const
 {
-    std::string newName = mangleName(getName()).c_str();
+    std::string newName = getName().c_str();
+    newName += kFunctionMangledNameSeparator;
 
     for (const auto &p : parameters)
     {
         newName += p.type->getMangledName().c_str();
     }
-
     return NewPoolTString(newName.c_str());
 }
 
-const TString &TFunction::GetMangledNameFromCall(const TString &unmangledFunctionName,
-                                                 TIntermSequence &arguments)
+const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
+                                                 const TIntermSequence &arguments)
 {
-    std::string newName = mangleName(unmangledFunctionName).c_str();
+    std::string newName = functionName.c_str();
+    newName += kFunctionMangledNameSeparator;
+
     for (TIntermNode *argument : arguments)
     {
         newName += argument->getAsTyped()->getType().getMangledName().c_str();
@@ -179,20 +188,6 @@
     return 0;
 }
 
-TFunction *TSymbolTable::findBuiltInOp(TIntermAggregate *callNode, int shaderVersion) const
-{
-    ASSERT(!callNode->isConstructor());
-    ASSERT(!callNode->isFunctionCall());
-    TString opString = GetOperatorString(callNode->getOp());
-    TSymbol *sym     = findBuiltIn(
-        TFunction::GetMangledNameFromCall(opString, *callNode->getSequence()), shaderVersion);
-    ASSERT(sym != nullptr && sym->isFunction());
-
-    TFunction *builtInFunc = static_cast<TFunction *>(sym);
-    ASSERT(builtInFunc->getParamCount() == callNode->getSequence()->size());
-    return builtInFunc;
-}
-
 TSymbolTable::~TSymbolTable()
 {
     while (table.size() > 0)
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index 4ab958a..c348943 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -174,8 +174,6 @@
     ~TFunction() override;
     bool isFunction() const override { return true; }
 
-    static TString mangleName(const TString &name) { return name + '('; }
-
     void addParameter(const TConstParameter &p)
     {
         parameters.push_back(p);
@@ -193,8 +191,8 @@
         return *mangledName;
     }
 
-    static const TString &GetMangledNameFromCall(const TString &unmangledFunctionName,
-                                                 TIntermSequence &arguments);
+    static const TString &GetMangledNameFromCall(const TString &functionName,
+                                                 const TIntermSequence &arguments);
 
     const TType &getReturnType() const { return *returnType; }
 
@@ -440,10 +438,6 @@
 
     TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
 
-    // Helper front-end for regular findBuiltIn that constructs the mangled function name from
-    // callNode.
-    TFunction *findBuiltInOp(TIntermAggregate *callNode, int shaderVersion) const;
-
     TSymbolTableLevel *getOuterLevel()
     {
         assert(currentLevel() >= 1);
diff --git a/src/compiler/translator/ValidateMultiviewWebGL.cpp b/src/compiler/translator/ValidateMultiviewWebGL.cpp
index 79524fc..169a32e 100644
--- a/src/compiler/translator/ValidateMultiviewWebGL.cpp
+++ b/src/compiler/translator/ValidateMultiviewWebGL.cpp
@@ -375,7 +375,8 @@
         }
         else if (!node->isConstructor())
         {
-            TFunction *builtInFunc = mSymbolTable.findBuiltInOp(node, mShaderVersion);
+            TFunction *builtInFunc = static_cast<TFunction *>(
+                mSymbolTable.findBuiltIn(node->getSymbolTableMangledName(), mShaderVersion));
             for (size_t paramIndex = 0u; paramIndex < builtInFunc->getParamCount(); ++paramIndex)
             {
                 TQualifier qualifier = builtInFunc->getParam(paramIndex).type->getQualifier();