Fix edge case scoped structures name conflict.

Structures with names ending in "_#" such as "_0" could conflict
with the internally rewritten scoped structures. Fix this by using
a prepending rule instead of appending.

Also includes a test, and fixes a WebGL test in Firefox. (Chrome is
not affected because of the variable hashing step.)

BUG=angle:618

Change-Id: I3d441f1de268b6d7e74a0834b43e889b7bfe578c
Reviewed-on: https://chromium-review.googlesource.com/201468
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Nicolas Capens <nicolascapens@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 2d7818b..3cea64f 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -3537,7 +3537,7 @@
         return;   // Nameless structures don't have constructors
     }
 
-    if (type.getStruct() && mStructNames.find(decorate(name)) != mStructNames.end())
+    if (type.getStruct() && mStructNames.find(name) != mStructNames.end())
     {
         return;   // Already added
     }
@@ -3547,15 +3547,13 @@
     ctorType.setPrecision(EbpHigh);
     ctorType.setQualifier(EvqTemporary);
 
-    TString ctorName = type.getStruct() ? decorate(name) : name;
-
     typedef std::vector<TType> ParameterArray;
     ParameterArray ctorParameters;
 
     const TStructure* structure = type.getStruct();
     if (structure)
     {
-        mStructNames.insert(decorate(name));
+        mStructNames.insert(name);
 
         const TString &structString = structureString(*structure, false, false);
 
@@ -3596,11 +3594,11 @@
 
     if (ctorType.getStruct())
     {
-        constructor += ctorName + " " + ctorName + "_ctor(";
+        constructor += name + " " + name + "_ctor(";
     }
     else   // Built-in type
     {
-        constructor += typeString(ctorType) + " " + ctorName + "(";
+        constructor += typeString(ctorType) + " " + name + "(";
     }
 
     for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
@@ -3620,7 +3618,7 @@
 
     if (ctorType.getStruct())
     {
-        constructor += "    " + ctorName + " structure = {";
+        constructor += "    " + name + " structure = {";
     }
     else
     {
@@ -3814,10 +3812,10 @@
 
     for (unsigned int i = 0; i < mScopeBracket.size() && i < depthLimit; i++)
     {
-        string += "_" + str(mScopeBracket[i]);
+        string += str(mScopeBracket[i]) + "_";
     }
 
-    return string;
+    return "ss_" + string;
 }
 
 TString OutputHLSL::scopedStruct(const TString &typeName)
@@ -3827,14 +3825,14 @@
         return typeName;
     }
 
-    return typeName + scopeString(mScopeDepth);
+    return scopeString(mScopeDepth) + typeName;
 }
 
 TString OutputHLSL::structLookup(const TString &typeName)
 {
     for (int depth = mScopeDepth; depth >= 0; depth--)
     {
-        TString scopedName = decorate(typeName + scopeString(depth));
+        TString scopedName = scopeString(depth) + typeName;
 
         for (StructNames::iterator structName = mStructNames.begin(); structName != mStructNames.end(); structName++)
         {