Split TIntermDeclaration from TIntermAggregate

The new class TIntermDeclaration is now used for struct, interface
block and variable declarations. TIntermDeclaration nodes do not have
a type - rather the type is stored in each child node. The types may
differ in case the declaration is a series of array declarators with
mismatching sizes.

TIntermAggregate is still used for function calls, function
prototypes, function parameter lists and invariant declarations.

BUG=angleproject:1490
TEST=angle_unittests

Change-Id: I0457188f354481470855f61ac1c878fc2579b1d1
Reviewed-on: https://chromium-review.googlesource.com/400023
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/SeparateArrayInitialization.cpp b/src/compiler/translator/SeparateArrayInitialization.cpp
index 8cd1fa1..2c853e3 100644
--- a/src/compiler/translator/SeparateArrayInitialization.cpp
+++ b/src/compiler/translator/SeparateArrayInitialization.cpp
@@ -29,7 +29,7 @@
     static void apply(TIntermNode *root);
   private:
     SeparateArrayInitTraverser();
-    bool visitAggregate(Visit, TIntermAggregate *node) override;
+    bool visitDeclaration(Visit, TIntermDeclaration *node) override;
 };
 
 void SeparateArrayInitTraverser::apply(TIntermNode *root)
@@ -44,43 +44,38 @@
 {
 }
 
-bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node)
+bool SeparateArrayInitTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
 {
-    if (node->getOp() == EOpDeclaration)
+    TIntermSequence *sequence = node->getSequence();
+    TIntermBinary *initNode   = sequence->back()->getAsBinaryNode();
+    if (initNode != nullptr && initNode->getOp() == EOpInitialize)
     {
-        TIntermSequence *sequence = node->getSequence();
-        TIntermBinary *initNode = sequence->back()->getAsBinaryNode();
-        if (initNode != nullptr && initNode->getOp() == EOpInitialize)
+        TIntermTyped *initializer = initNode->getRight();
+        if (initializer->isArray() && !sh::OutputHLSL::canWriteAsHLSLLiteral(initializer))
         {
-            TIntermTyped *initializer = initNode->getRight();
-            if (initializer->isArray() && !sh::OutputHLSL::canWriteAsHLSLLiteral(initializer))
-            {
-                // We rely on that array declarations have been isolated to single declarations.
-                ASSERT(sequence->size() == 1);
-                TIntermTyped *symbol = initNode->getLeft();
-                TIntermBlock *parentBlock = getParentNode()->getAsBlock();
-                ASSERT(parentBlock != nullptr);
+            // We rely on that array declarations have been isolated to single declarations.
+            ASSERT(sequence->size() == 1);
+            TIntermTyped *symbol      = initNode->getLeft();
+            TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+            ASSERT(parentBlock != nullptr);
 
-                TIntermSequence replacements;
+            TIntermSequence replacements;
 
-                TIntermAggregate *replacementDeclaration = new TIntermAggregate;
-                replacementDeclaration->setOp(EOpDeclaration);
-                replacementDeclaration->getSequence()->push_back(symbol);
-                replacementDeclaration->setLine(symbol->getLine());
-                replacements.push_back(replacementDeclaration);
+            TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
+            replacementDeclaration->appendDeclarator(symbol);
+            replacementDeclaration->setLine(symbol->getLine());
+            replacements.push_back(replacementDeclaration);
 
-                TIntermBinary *replacementAssignment =
-                    new TIntermBinary(EOpAssign, symbol, initializer);
-                replacementAssignment->setLine(symbol->getLine());
-                replacements.push_back(replacementAssignment);
+            TIntermBinary *replacementAssignment =
+                new TIntermBinary(EOpAssign, symbol, initializer);
+            replacementAssignment->setLine(symbol->getLine());
+            replacements.push_back(replacementAssignment);
 
-                mMultiReplacements.push_back(
-                    NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
-            }
+            mMultiReplacements.push_back(
+                NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
         }
-        return false;
     }
-    return true;
+    return false;
 }
 
 } // namespace