Return ImmutableString from ArrayString()

This makes the compiler a few kilobytes smaller, and prepares getting
rid of TString altogether.

BUG=angleproject:2267
TEST=angle_unittests

Change-Id: I93a003fe27b99bef72f872fa1066e2e108f934c5
Reviewed-on: https://chromium-review.googlesource.com/1107713
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/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 3245887..5995a15 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -393,7 +393,7 @@
 
             if (structType->isArray())
             {
-                mappedStructs += ArrayString(*mappedStruct.field->type());
+                mappedStructs += ArrayString(*mappedStruct.field->type()).data();
             }
 
             mappedStructs += " =\n";
@@ -404,33 +404,37 @@
     return mappedStructs;
 }
 
-void OutputHLSL::header(TInfoSinkBase &out,
-                        const std::vector<MappedStruct> &std140Structs,
-                        const BuiltInFunctionEmulator *builtInFunctionEmulator) const
+void OutputHLSL::writeReferencedAttributes(TInfoSinkBase &out) const
 {
-    TString varyings;
-    TString attributes;
-    TString mappedStructs = generateStructMapping(std140Structs);
+    for (const auto &attribute : mReferencedAttributes)
+    {
+        const TType &type           = attribute.second->getType();
+        const ImmutableString &name = attribute.second->name();
 
+        out << "static " << TypeString(type) << " " << Decorate(name) << ArrayString(type) << " = "
+            << zeroInitializer(type) << ";\n";
+    }
+}
+
+void OutputHLSL::writeReferencedVaryings(TInfoSinkBase &out) const
+{
     for (const auto &varying : mReferencedVaryings)
     {
         const TType &type           = varying.second->getType();
         const ImmutableString &name = varying.second->name();
 
         // Program linking depends on this exact format
-        varyings += TString("static ") + InterpolationString(type.getQualifier()) + " " +
-                    TypeString(type) + " " + Decorate(name) + ArrayString(type) + " = " +
-                    zeroInitializer(type) + ";\n";
+        out << "static " << InterpolationString(type.getQualifier()) << " " << TypeString(type)
+            << " " << Decorate(name) << ArrayString(type) << " = " << zeroInitializer(type)
+            << ";\n";
     }
+}
 
-    for (const auto &attribute : mReferencedAttributes)
-    {
-        const TType &type           = attribute.second->getType();
-        const ImmutableString &name = attribute.second->name();
-
-        attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) +
-                      " = " + zeroInitializer(type) + ";\n";
-    }
+void OutputHLSL::header(TInfoSinkBase &out,
+                        const std::vector<MappedStruct> &std140Structs,
+                        const BuiltInFunctionEmulator *builtInFunctionEmulator) const
+{
+    TString mappedStructs = generateStructMapping(std140Structs);
 
     out << mStructureHLSL->structsHeader();
 
@@ -491,7 +495,7 @@
             IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers);
 
         out << "// Varyings\n";
-        out << varyings;
+        writeReferencedVaryings(out);
         out << "\n";
 
         if (mShaderVersion >= 300)
@@ -644,7 +648,7 @@
     else if (mShaderType == GL_VERTEX_SHADER)
     {
         out << "// Attributes\n";
-        out << attributes;
+        writeReferencedAttributes(out);
         out << "\n"
                "static float4 gl_Position = float4(0, 0, 0, 0);\n";
 
@@ -665,7 +669,7 @@
 
         out << "\n"
                "// Varyings\n";
-        out << varyings;
+        writeReferencedVaryings(out);
         out << "\n";
 
         if (mUsesDepthRange)