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/RewriteElseBlocks.cpp b/src/compiler/translator/RewriteElseBlocks.cpp
index 13d71c7..c9427e2 100644
--- a/src/compiler/translator/RewriteElseBlocks.cpp
+++ b/src/compiler/translator/RewriteElseBlocks.cpp
@@ -26,6 +26,7 @@
protected:
bool visitAggregate(Visit visit, TIntermAggregate *aggregate) override;
+ bool visitBlock(Visit visit, TIntermBlock *block) override;
private:
const TType *mFunctionType;
@@ -40,31 +41,29 @@
bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node)
{
- switch (node->getOp())
+ if (node->getOp() == EOpFunction)
{
- case EOpSequence:
- if (visit == PostVisit)
+ // Store the current function context (see comment below)
+ mFunctionType = ((visit == PreVisit) ? &node->getType() : nullptr);
+ }
+ return true;
+}
+
+bool ElseBlockRewriter::visitBlock(Visit visit, TIntermBlock *node)
+{
+ if (visit == PostVisit)
+ {
+ for (size_t statementIndex = 0; statementIndex != node->getSequence()->size();
+ statementIndex++)
{
- for (size_t statementIndex = 0; statementIndex != node->getSequence()->size(); statementIndex++)
+ TIntermNode *statement = (*node->getSequence())[statementIndex];
+ TIntermIfElse *ifElse = statement->getAsIfElseNode();
+ if (ifElse && ifElse->getFalseBlock() != nullptr)
{
- TIntermNode *statement = (*node->getSequence())[statementIndex];
- TIntermIfElse *ifElse = statement->getAsIfElseNode();
- if (ifElse && ifElse->getFalseBlock() != nullptr)
- {
- (*node->getSequence())[statementIndex] = rewriteIfElse(ifElse);
- }
+ (*node->getSequence())[statementIndex] = rewriteIfElse(ifElse);
}
}
- break;
-
- case EOpFunction:
- // Store the current function context (see comment below)
- mFunctionType = ((visit == PreVisit) ? &node->getType() : NULL);
- break;
-
- default: break;
}
-
return true;
}
@@ -77,13 +76,13 @@
TIntermTyped *typedCondition = ifElse->getCondition()->getAsTyped();
TIntermAggregate *storeCondition = createTempInitDeclaration(typedCondition);
- TIntermAggregate *falseBlock = nullptr;
+ TIntermBlock *falseBlock = nullptr;
TType boolType(EbtBool, EbpUndefined, EvqTemporary);
if (ifElse->getFalseBlock())
{
- TIntermAggregate *negatedElse = nullptr;
+ TIntermBlock *negatedElse = nullptr;
// crbug.com/346463
// D3D generates error messages claiming a function has no return value, when rewriting
// an if-else clause that returns something non-void in a function. By appending dummy
@@ -94,7 +93,7 @@
mFunctionType->getBasicString();
TString rawText = "return (" + typeString + ")0";
TIntermRaw *returnNode = new TIntermRaw(*mFunctionType, rawText);
- negatedElse = new TIntermAggregate(EOpSequence);
+ negatedElse = new TIntermBlock();
negatedElse->getSequence()->push_back(returnNode);
}
@@ -102,14 +101,14 @@
TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot, conditionSymbolElse);
TIntermIfElse *falseIfElse =
new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse);
- falseBlock = TIntermediate::EnsureSequence(falseIfElse);
+ falseBlock = TIntermediate::EnsureBlock(falseIfElse);
}
TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType);
TIntermIfElse *newIfElse =
new TIntermIfElse(conditionSymbolSel, ifElse->getTrueBlock(), falseBlock);
- TIntermAggregate *block = new TIntermAggregate(EOpSequence);
+ TIntermBlock *block = new TIntermBlock();
block->getSequence()->push_back(storeCondition);
block->getSequence()->push_back(newIfElse);