Split TIntermBlock from TIntermAggregate

The new TIntermBlock node class replaces TIntermAggregate nodes with
the EOpSequence op. It represents the root node of the tree which is
a list of declarations and function definitions, and any code blocks
that can be denoted by curly braces. These include function and loop
bodies, and if-else branches.

This change enables a bunch of more compile-time type checking, and
makes the AST code easier to understand and less error-prone.

The PostProcess step that used to be done to ensure that the root node
is TIntermAggregate is removed in favor of making sure that the root
node is a TIntermBlock in the glslang.y parsing code.

Intermediate output formatting is improved to print the EOpNull error
in a clearer way.

After this patch, TIntermAggregate is still used for function
definitions, function prototypes, function parameter lists, function
calls, variable and invariant declarations and the comma (sequence)
operator.

BUG=angleproject:1490
TEST=angle_unittests, angle_end2end_tests

Change-Id: I04044affff979a11577bc1fe75d747e538b799c8
Reviewed-on: https://chromium-review.googlesource.com/393726
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/RemoveDynamicIndexing.cpp b/src/compiler/translator/RemoveDynamicIndexing.cpp
index 4ac3e9f..3da4bcc 100644
--- a/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -217,7 +217,7 @@
     }
     indexingFunction->getSequence()->push_back(paramsNode);
 
-    TIntermAggregate *statementList = new TIntermAggregate(EOpSequence);
+    TIntermBlock *statementList = new TIntermBlock();
     for (int i = 0; i < numCases; ++i)
     {
         TIntermCase *caseNode = new TIntermCase(CreateIntConstantNode(i));
@@ -247,7 +247,7 @@
 
     TIntermSwitch *switchNode = new TIntermSwitch(CreateIndexSymbol(), statementList);
 
-    TIntermAggregate *bodyNode = new TIntermAggregate(EOpSequence);
+    TIntermBlock *bodyNode = new TIntermBlock();
     bodyNode->getSequence()->push_back(switchNode);
 
     TIntermBinary *cond =
@@ -256,8 +256,8 @@
 
     // Two blocks: one accesses (either reads or writes) the first element and returns,
     // the other accesses the last element.
-    TIntermAggregate *useFirstBlock = new TIntermAggregate(EOpSequence);
-    TIntermAggregate *useLastBlock = new TIntermAggregate(EOpSequence);
+    TIntermBlock *useFirstBlock = new TIntermBlock();
+    TIntermBlock *useLastBlock  = new TIntermBlock();
     TIntermBinary *indexFirstNode =
         CreateIndexDirectBaseSymbolNode(type, fieldType, 0, baseQualifier);
     TIntermBinary *indexLastNode =
@@ -327,8 +327,8 @@
 
 void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root)
 {
-    TIntermAggregate *rootAgg = root->getAsAggregate();
-    ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence);
+    TIntermBlock *rootBlock = root->getAsBlock();
+    ASSERT(rootBlock != nullptr);
     TIntermSequence insertions;
     for (TType type : mIndexedVecAndMatrixTypes)
     {
@@ -338,7 +338,7 @@
     {
         insertions.push_back(GetIndexFunctionDefinition(type, true));
     }
-    mInsertions.push_back(NodeInsertMultipleEntry(rootAgg, 0, insertions, TIntermSequence()));
+    mInsertions.push_back(NodeInsertMultipleEntry(rootBlock, 0, insertions, TIntermSequence()));
 }
 
 // Create a call to dyn_index_*() based on an indirect indexing op node