Store symbol names as a ImmutableString

This will enable compile-time initialization of built-in symbols as
well as reducing copying strings.

Most of the code that deals with names is changed to use
ImmutableString where it makes sense to avoid conversions.

The lexer/parser now allocate const char pointers into pool memory
instead of allocating TStrings. These are then converted to
ImmutableString upon entering TParseContext.

BUG=angleproject:2267
TEST=angle_unittests, angle_end2end_tests

Change-Id: I244d6271ea1ecf7150d4f89dfa388a7745a1150c
Reviewed-on: https://chromium-review.googlesource.com/881561
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index da3ff5a..d3acfbd 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -16,6 +16,11 @@
 namespace
 {
 
+constexpr const ImmutableString kParamXName("x");
+constexpr const ImmutableString kParamYName("y");
+constexpr const ImmutableString kAngleFrmString("angle_frm");
+constexpr const ImmutableString kAngleFrlString("angle_frl");
+
 class RoundingHelperWriter : angle::NonCopyable
 {
   public:
@@ -473,10 +478,7 @@
 }  // namespace anonymous
 
 EmulatePrecision::EmulatePrecision(TSymbolTable *symbolTable)
-    : TLValueTrackingTraverser(true, true, true, symbolTable),
-      mDeclaringVariables(false),
-      mParamXName(NewPoolTString("x")),
-      mParamYName(NewPoolTString("y"))
+    : TLValueTrackingTraverser(true, true, true, symbolTable), mDeclaringVariables(false)
 {
 }
 
@@ -709,13 +711,13 @@
     }
 }
 
-const TFunction *EmulatePrecision::getInternalFunction(TString *functionName,
+const TFunction *EmulatePrecision::getInternalFunction(const ImmutableString &functionName,
                                                        const TType &returnType,
                                                        TIntermSequence *arguments,
                                                        const TVector<TConstParameter> &parameters,
                                                        bool knownToNotHaveSideEffects)
 {
-    TString mangledName = TFunctionLookup::GetMangledName(*functionName, *arguments);
+    ImmutableString mangledName = TFunctionLookup::GetMangledName(functionName.data(), *arguments);
     if (mInternalFunctions.find(mangledName) == mInternalFunctions.end())
     {
         TFunction *func = new TFunction(mSymbolTable, functionName, new TType(returnType),
@@ -732,12 +734,9 @@
 
 TIntermAggregate *EmulatePrecision::createRoundingFunctionCallNode(TIntermTyped *roundedChild)
 {
-    const char *roundFunctionName;
-    if (roundedChild->getPrecision() == EbpMedium)
-        roundFunctionName = "angle_frm";
-    else
-        roundFunctionName = "angle_frl";
-    TString *functionName      = NewPoolTString(roundFunctionName);
+    const ImmutableString *roundFunctionName = &kAngleFrmString;
+    if (roundedChild->getPrecision() == EbpLow)
+        roundFunctionName = &kAngleFrlString;
     TIntermSequence *arguments = new TIntermSequence();
     arguments->push_back(roundedChild);
 
@@ -745,10 +744,11 @@
     TType *paramType = new TType(roundedChild->getType());
     paramType->setPrecision(EbpHigh);
     paramType->setQualifier(EvqIn);
-    parameters.push_back(TConstParameter(mParamXName, static_cast<const TType *>(paramType)));
+    parameters.push_back(TConstParameter(kParamXName, static_cast<const TType *>(paramType)));
 
     return TIntermAggregate::CreateRawFunctionCall(
-        *getInternalFunction(functionName, roundedChild->getType(), arguments, parameters, true),
+        *getInternalFunction(*roundFunctionName, roundedChild->getType(), arguments, parameters,
+                             true),
         arguments);
 }
 
@@ -761,7 +761,7 @@
         strstr << "angle_compound_" << opNameStr << "_frm";
     else
         strstr << "angle_compound_" << opNameStr << "_frl";
-    TString *functionName      = NewPoolTString(strstr.str().c_str());
+    ImmutableString functionName = ImmutableString(strstr.str());
     TIntermSequence *arguments = new TIntermSequence();
     arguments->push_back(left);
     arguments->push_back(right);
@@ -770,11 +770,11 @@
     TType *leftParamType = new TType(left->getType());
     leftParamType->setPrecision(EbpHigh);
     leftParamType->setQualifier(EvqOut);
-    parameters.push_back(TConstParameter(mParamXName, static_cast<const TType *>(leftParamType)));
+    parameters.push_back(TConstParameter(kParamXName, static_cast<const TType *>(leftParamType)));
     TType *rightParamType = new TType(right->getType());
     rightParamType->setPrecision(EbpHigh);
     rightParamType->setQualifier(EvqIn);
-    parameters.push_back(TConstParameter(mParamYName, static_cast<const TType *>(rightParamType)));
+    parameters.push_back(TConstParameter(kParamYName, static_cast<const TType *>(rightParamType)));
 
     return TIntermAggregate::CreateRawFunctionCall(
         *getInternalFunction(functionName, left->getType(), arguments, parameters, false),