Sanitize AST nodes created by UseInterfaceBlockFields

Don't add the same node pointer to the AST more than once, and assign
the right symbol ids to symbol nodes.

BUG=angleproject:1490
TEST=angle_unittests, angle_end2end_tests

Change-Id: I3f00e9234245fe4b81a2388df3f83e13c4c24856
Reviewed-on: https://chromium-review.googlesource.com/559534
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/UseInterfaceBlockFields.cpp b/src/compiler/translator/UseInterfaceBlockFields.cpp
index aa98611..c1391d4 100644
--- a/src/compiler/translator/UseInterfaceBlockFields.cpp
+++ b/src/compiler/translator/UseInterfaceBlockFields.cpp
@@ -35,28 +35,13 @@
             name = name.substr(0, pos);
         }
     }
-    const TType *type;
-    TType basicType;
-    if (var.isStruct())
-    {
-        TVariable *structInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
-        ASSERT(structInfo);
-        const TType &structType = structInfo->getType();
-        type                    = &structType;
-    }
-    else
-    {
-        basicType = sh::GetShaderVariableBasicType(var);
-        type      = &basicType;
-    }
-    ASSERT(type);
-
-    TIntermSymbol *symbol = new TIntermSymbol(0, name, *type);
+    TIntermSymbol *symbol = ReferToGlobalSymbol(name, symbolTable);
     if (var.isArray())
     {
-        for (unsigned int i = 0; i < var.arraySize; ++i)
+        for (unsigned int i = 0u; i < var.arraySize; ++i)
         {
-            TIntermBinary *element = new TIntermBinary(EOpIndexDirect, symbol, CreateIndexNode(i));
+            TIntermBinary *element =
+                new TIntermBinary(EOpIndexDirect, symbol->deepCopy(), CreateIndexNode(i));
             sequence->insert(sequence->begin(), element);
         }
     }
@@ -66,6 +51,16 @@
     }
 }
 
+void InsertUseCode(const InterfaceBlock &block, TIntermTyped *blockNode, TIntermSequence *sequence)
+{
+    for (unsigned int i = 0; i < block.fields.size(); ++i)
+    {
+        TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
+                                                   blockNode->deepCopy(), CreateIndexNode(i));
+        sequence->insert(sequence->begin(), element);
+    }
+}
+
 void InsertUseCode(TIntermSequence *sequence,
                    const InterfaceBlockList &blocks,
                    const TSymbolTable &symbolTable)
@@ -79,37 +74,22 @@
                 AddFieldUseStatements(var, sequence, symbolTable);
             }
         }
-        else if (block.arraySize > 0)
+        else if (block.arraySize > 0u)
         {
-            TString name      = TString(block.instanceName.c_str());
-            TVariable *ubInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
-            ASSERT(ubInfo);
-            TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, ubInfo->getType());
-            for (unsigned int i = 0; i < block.arraySize; ++i)
+            TString name(block.instanceName.c_str());
+            TIntermSymbol *arraySymbol = ReferToGlobalSymbol(name, symbolTable);
+            for (unsigned int i = 0u; i < block.arraySize; ++i)
             {
-                TIntermBinary *instanceSymbol =
-                    new TIntermBinary(EOpIndexDirect, arraySymbol, CreateIndexNode(i));
-                for (unsigned int j = 0; j < block.fields.size(); ++j)
-                {
-                    TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
-                                                               instanceSymbol, CreateIndexNode(j));
-                    sequence->insert(sequence->begin(), element);
-                }
+                TIntermBinary *elementSymbol =
+                    new TIntermBinary(EOpIndexDirect, arraySymbol->deepCopy(), CreateIndexNode(i));
+                InsertUseCode(block, elementSymbol, sequence);
             }
         }
         else
         {
-            TString name      = TString(block.instanceName.c_str());
-            TVariable *ubInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
-            ASSERT(ubInfo);
-            TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, ubInfo->getType());
-            for (unsigned int i = 0; i < block.fields.size(); ++i)
-            {
-                TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
-                                                           blockSymbol, CreateIndexNode(i));
-
-                sequence->insert(sequence->begin(), element);
-            }
+            TString name(block.instanceName.c_str());
+            TIntermSymbol *blockSymbol = ReferToGlobalSymbol(name, symbolTable);
+            InsertUseCode(block, blockSymbol, sequence);
         }
     }
 }