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/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index 89a9a52..e094414 100644
--- a/src/compiler/translator/IntermTraverse.cpp
+++ b/src/compiler/translator/IntermTraverse.cpp
@@ -58,6 +58,11 @@
it->traverseCase(this);
}
+void TIntermBlock::traverse(TIntermTraverser *it)
+{
+ it->traverseBlock(this);
+}
+
void TIntermAggregate::traverse(TIntermTraverser *it)
{
it->traverseAggregate(this);
@@ -88,7 +93,7 @@
{
}
-void TIntermTraverser::pushParentBlock(TIntermAggregate *node)
+void TIntermTraverser::pushParentBlock(TIntermBlock *node)
{
mParentBlockStack.push_back(ParentBlock(node, 0));
}
@@ -418,9 +423,42 @@
visitUnary(PostVisit, node);
}
-//
+// Traverse a block node.
+void TIntermTraverser::traverseBlock(TIntermBlock *node)
+{
+ bool visit = true;
+
+ TIntermSequence *sequence = node->getSequence();
+
+ if (preVisit)
+ visit = visitBlock(PreVisit, node);
+
+ if (visit)
+ {
+ incrementDepth(node);
+ pushParentBlock(node);
+
+ for (auto *child : *sequence)
+ {
+ child->traverse(this);
+ if (visit && inVisit)
+ {
+ if (child != sequence->back())
+ visit = visitBlock(InVisit, node);
+ }
+
+ incrementParentBlockPos();
+ }
+
+ popParentBlock();
+ decrementDepth();
+ }
+
+ if (visit && postVisit)
+ visitBlock(PostVisit, node);
+}
+
// Traverse an aggregate node. Same comments in binary node apply here.
-//
void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
{
bool visit = true;
@@ -434,9 +472,7 @@
{
incrementDepth(node);
- if (node->getOp() == EOpSequence)
- pushParentBlock(node);
- else if (node->getOp() == EOpFunction)
+ if (node->getOp() == EOpFunction)
mInGlobalScope = false;
for (auto *child : *sequence)
@@ -447,14 +483,9 @@
if (child != sequence->back())
visit = visitAggregate(InVisit, node);
}
-
- if (node->getOp() == EOpSequence)
- incrementParentBlockPos();
}
- if (node->getOp() == EOpSequence)
- popParentBlock();
- else if (node->getOp() == EOpFunction)
+ if (node->getOp() == EOpFunction)
mInGlobalScope = true;
decrementDepth();
@@ -529,9 +560,7 @@
}
else
{
- if (node->getOp() == EOpSequence)
- pushParentBlock(node);
- else if (node->getOp() == EOpFunction)
+ if (node->getOp() == EOpFunction)
mInGlobalScope = false;
// Find the built-in function corresponding to this op so that we can determine the
@@ -575,17 +604,12 @@
visit = visitAggregate(InVisit, node);
}
- if (node->getOp() == EOpSequence)
- incrementParentBlockPos();
-
++paramIndex;
}
setInFunctionCallOutParameter(false);
- if (node->getOp() == EOpSequence)
- popParentBlock();
- else if (node->getOp() == EOpFunction)
+ if (node->getOp() == EOpFunction)
mInGlobalScope = true;
}