Redesign HLSL scoped structures to a unique ID.

A unique ID gives a more flexible renaming scheme than our
current method of using nested scope identifiers. The reduced
complexity allows for fewer points of breakage and fixes an
outstanding bug with scoped structures (with added test).

BUG=angle:618

Change-Id: I6551248bb9fa2d185ab67248721f898dd50151f0
Reviewed-on: https://chromium-review.googlesource.com/202183
Reviewed-by: Nicolas Capens <nicolascapens@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 3cea64f..ea0045f 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -136,8 +136,6 @@
 
     mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
 
-    mScopeDepth = 0;
-
     mUniqueIndex = 0;
 
     mContainsLoopDiscontinuity = false;
@@ -2257,17 +2255,6 @@
             {
                 outputLineDirective(node->getLine().first_line);
                 out << "{\n";
-
-                mScopeDepth++;
-
-                if (mScopeBracket.size() < mScopeDepth)
-                {
-                    mScopeBracket.push_back(0);   // New scope level
-                }
-                else
-                {
-                    mScopeBracket[mScopeDepth - 1]++;   // New scope at existing level
-                }
             }
 
             for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++)
@@ -2283,8 +2270,6 @@
             {
                 outputLineDirective(node->getLine().last_line);
                 out << "}\n";
-
-                mScopeDepth--;
             }
 
             return false;
@@ -2299,7 +2284,7 @@
             {
                 if (variable->getType().getStruct())
                 {
-                    addConstructor(variable->getType(), scopedStruct(variable->getType().getStruct()->name()), NULL);
+                    addConstructor(variable->getType(), structNameString(*variable->getType().getStruct()), NULL);
                 }
 
                 if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "")   // Variable declaration
@@ -2426,7 +2411,7 @@
                 {
                     if (symbol->getType().getStruct())
                     {
-                        addConstructor(symbol->getType(), scopedStruct(symbol->getType().getStruct()->name()), NULL);
+                        addConstructor(symbol->getType(), structNameString(*symbol->getType().getStruct()), NULL);
                     }
 
                     out << argumentString(symbol);
@@ -2694,8 +2679,11 @@
         outputTriplet(visit, "mat4(", ", ", ")");
         break;
       case EOpConstructStruct:
-        addConstructor(node->getType(), scopedStruct(node->getType().getStruct()->name()), &node->getSequence());
-        outputTriplet(visit, structLookup(node->getType().getStruct()->name()) + "_ctor(", ", ", ")");
+        {
+            const TString &structName = structNameString(*node->getType().getStruct());
+            addConstructor(node->getType(), structName, &node->getSequence());
+            outputTriplet(visit, structName + "_ctor(", ", ", ")");
+        }
         break;
       case EOpLessThan:         outputTriplet(visit, "(", " < ", ")");                 break;
       case EOpGreaterThan:      outputTriplet(visit, "(", " > ", ")");                 break;
@@ -3320,7 +3308,7 @@
         const TString& typeName = structure->name();
         if (typeName != "")
         {
-            return structLookup(typeName);
+            return structNameString(*type.getStruct());
         }
         else   // Nameless structure, define in place
         {
@@ -3527,7 +3515,7 @@
         prefix += "rm";
     }
 
-    return prefix + structLookup(structure.name());
+    return prefix + structNameString(structure);
 }
 
 void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
@@ -3752,7 +3740,7 @@
     const TStructure* structure = type.getStruct();
     if (structure)
     {
-        out << structLookup(structure->name()) + "_ctor(";
+        out << structNameString(*structure) + "_ctor(";
         
         const TFieldList& fields = structure->fields();
 
@@ -3806,46 +3794,14 @@
     return constUnion;
 }
 
-TString OutputHLSL::scopeString(unsigned int depthLimit)
+TString OutputHLSL::structNameString(const TStructure &structure)
 {
-    TString string;
-
-    for (unsigned int i = 0; i < mScopeBracket.size() && i < depthLimit; i++)
+    if (structure.name().empty())
     {
-        string += str(mScopeBracket[i]) + "_";
+        return "";
     }
 
-    return "ss_" + string;
-}
-
-TString OutputHLSL::scopedStruct(const TString &typeName)
-{
-    if (typeName == "")
-    {
-        return typeName;
-    }
-
-    return scopeString(mScopeDepth) + typeName;
-}
-
-TString OutputHLSL::structLookup(const TString &typeName)
-{
-    for (int depth = mScopeDepth; depth >= 0; depth--)
-    {
-        TString scopedName = scopeString(depth) + typeName;
-
-        for (StructNames::iterator structName = mStructNames.begin(); structName != mStructNames.end(); structName++)
-        {
-            if (*structName == scopedName)
-            {
-                return scopedName;
-            }
-        }
-    }
-
-    UNREACHABLE();   // Should have found a matching constructor
-
-    return typeName;
+    return "ss_" + str(structure.uniqueId()) + structure.name();
 }
 
 TString OutputHLSL::decorate(const TString &string)