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/AddDefaultReturnStatements.cpp b/src/compiler/translator/AddDefaultReturnStatements.cpp
index 25493a5..7261641 100644
--- a/src/compiler/translator/AddDefaultReturnStatements.cpp
+++ b/src/compiler/translator/AddDefaultReturnStatements.cpp
@@ -39,7 +39,7 @@
return false;
}
- TIntermAggregate *bodyNode = node->getSequence()->back()->getAsAggregate();
+ TIntermBlock *bodyNode = node->getSequence()->back()->getAsBlock();
ASSERT(bodyNode);
TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
@@ -58,7 +58,7 @@
TIntermBranch *branch =
new TIntermBranch(EOpReturn, TIntermTyped::CreateZero(returnType));
- TIntermAggregate *bodyNode = node->getSequence()->back()->getAsAggregate();
+ TIntermBlock *bodyNode = node->getSequence()->back()->getAsBlock();
bodyNode->getSequence()->push_back(branch);
return false;
diff --git a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
index 562d53d..7d223a5 100644
--- a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
@@ -136,15 +136,16 @@
// Cases 2 to 4 are already converted to simpler cases by SeparateExpressionsReturningArrays, so we
// only need to worry about the case where a function call returning an array forms an expression by
// itself.
- TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
- if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence)
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ if (parentBlock)
{
nextTemporaryIndex();
TIntermSequence replacements;
replacements.push_back(createTempDeclaration(node->getType()));
TIntermSymbol *returnSymbol = createTempSymbol(node->getType());
replacements.push_back(CreateReplacementCall(node, returnSymbol));
- mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements));
+ mMultiReplacements.push_back(
+ NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
}
return false;
}
@@ -179,7 +180,8 @@
replacementBranch->setLine(node->getLine());
replacements.push_back(replacementBranch);
- mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsAggregate(), node, replacements));
+ mMultiReplacements.push_back(
+ NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, replacements));
}
return false;
}
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 547c09b..2ac8528 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -232,16 +232,16 @@
return true;
}
-TIntermNode *TCompiler::compileTreeForTesting(const char *const shaderStrings[],
- size_t numStrings,
- ShCompileOptions compileOptions)
+TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[],
+ size_t numStrings,
+ ShCompileOptions compileOptions)
{
return compileTreeImpl(shaderStrings, numStrings, compileOptions);
}
-TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
- size_t numStrings,
- const ShCompileOptions compileOptions)
+TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions compileOptions)
{
clearResults();
@@ -282,7 +282,7 @@
success = false;
}
- TIntermNode *root = nullptr;
+ TIntermBlock *root = nullptr;
if (success)
{
@@ -293,7 +293,6 @@
mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
root = parseContext.getTreeRoot();
- root = TIntermediate::PostProcess(root);
// Highp might have been auto-enabled based on shader version
fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
@@ -473,7 +472,7 @@
}
TScopedPoolAllocator scopedAlloc(&allocator);
- TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
+ TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
if (root)
{
@@ -787,13 +786,10 @@
const std::vector<FunctionMetadata> *mMetadatas;
};
-bool TCompiler::pruneUnusedFunctions(TIntermNode *root)
+bool TCompiler::pruneUnusedFunctions(TIntermBlock *root)
{
- TIntermAggregate *rootNode = root->getAsAggregate();
- ASSERT(rootNode != nullptr);
-
UnusedPredicate isUnused(&mCallDag, &functionMetadata);
- TIntermSequence *sequence = rootNode->getSequence();
+ TIntermSequence *sequence = root->getSequence();
if (!sequence->empty())
{
diff --git a/src/compiler/translator/Compiler.h b/src/compiler/translator/Compiler.h
index ace1abb..be314ac 100644
--- a/src/compiler/translator/Compiler.h
+++ b/src/compiler/translator/Compiler.h
@@ -72,10 +72,10 @@
// compileTreeForTesting should be used only when tests require access to
// the AST. Users of this function need to manually manage the global pool
- // allocator. Returns NULL whenever there are compilation errors.
- TIntermNode *compileTreeForTesting(const char *const shaderStrings[],
- size_t numStrings,
- ShCompileOptions compileOptions);
+ // allocator. Returns nullptr whenever there are compilation errors.
+ TIntermBlock *compileTreeForTesting(const char *const shaderStrings[],
+ size_t numStrings,
+ ShCompileOptions compileOptions);
bool compile(const char *const shaderStrings[],
size_t numStrings,
@@ -181,11 +181,11 @@
// Removes unused function declarations and prototypes from the AST
class UnusedPredicate;
- bool pruneUnusedFunctions(TIntermNode *root);
+ bool pruneUnusedFunctions(TIntermBlock *root);
- TIntermNode *compileTreeImpl(const char *const shaderStrings[],
- size_t numStrings,
- const ShCompileOptions compileOptions);
+ TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions compileOptions);
sh::GLenum shaderType;
ShShaderSpec shaderSpec;
diff --git a/src/compiler/translator/DeferGlobalInitializers.cpp b/src/compiler/translator/DeferGlobalInitializers.cpp
index 285aa18..598eac0 100644
--- a/src/compiler/translator/DeferGlobalInitializers.cpp
+++ b/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -39,7 +39,7 @@
}
TIntermAggregate *CreateFunctionDefinitionNode(const char *name,
- TIntermAggregate *functionBody,
+ TIntermBlock *functionBody,
const int functionId)
{
TIntermAggregate *functionNode = new TIntermAggregate(EOpFunction);
@@ -73,7 +73,7 @@
bool visitBinary(Visit visit, TIntermBinary *node) override;
- void insertInitFunction(TIntermNode *root);
+ void insertInitFunction(TIntermBlock *root);
private:
TIntermSequence mDeferredInitializers;
@@ -134,25 +134,23 @@
return false;
}
-void DeferGlobalInitializersTraverser::insertInitFunction(TIntermNode *root)
+void DeferGlobalInitializersTraverser::insertInitFunction(TIntermBlock *root)
{
if (mDeferredInitializers.empty())
{
return;
}
const int initFunctionId = TSymbolTable::nextUniqueId();
- TIntermAggregate *rootAgg = root->getAsAggregate();
- ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence);
const char *functionName = "initializeDeferredGlobals";
// Add function prototype to the beginning of the shader
TIntermAggregate *functionPrototypeNode =
CreateFunctionPrototypeNode(functionName, initFunctionId);
- rootAgg->getSequence()->insert(rootAgg->getSequence()->begin(), functionPrototypeNode);
+ root->getSequence()->insert(root->getSequence()->begin(), functionPrototypeNode);
// Add function definition to the end of the shader
- TIntermAggregate *functionBodyNode = new TIntermAggregate(EOpSequence);
+ TIntermBlock *functionBodyNode = new TIntermBlock();
TIntermSequence *functionBody = functionBodyNode->getSequence();
for (const auto &deferredInit : mDeferredInitializers)
{
@@ -160,10 +158,10 @@
}
TIntermAggregate *functionDefinition =
CreateFunctionDefinitionNode(functionName, functionBodyNode, initFunctionId);
- rootAgg->getSequence()->push_back(functionDefinition);
+ root->getSequence()->push_back(functionDefinition);
// Insert call into main function
- for (TIntermNode *node : *rootAgg->getSequence())
+ for (TIntermNode *node : *root->getSequence())
{
TIntermAggregate *nodeAgg = node->getAsAggregate();
if (nodeAgg != nullptr && nodeAgg->getOp() == EOpFunction &&
@@ -172,18 +170,18 @@
TIntermAggregate *functionCallNode =
CreateFunctionCallNode(functionName, initFunctionId);
- TIntermNode *mainBody = nodeAgg->getSequence()->back();
- TIntermAggregate *mainBodyAgg = mainBody->getAsAggregate();
- ASSERT(mainBodyAgg != nullptr && mainBodyAgg->getOp() == EOpSequence);
- mainBodyAgg->getSequence()->insert(mainBodyAgg->getSequence()->begin(),
- functionCallNode);
+ TIntermNode *mainBody = nodeAgg->getSequence()->back();
+ TIntermBlock *mainBodyBlock = mainBody->getAsBlock();
+ ASSERT(mainBodyBlock != nullptr);
+ mainBodyBlock->getSequence()->insert(mainBodyBlock->getSequence()->begin(),
+ functionCallNode);
}
}
}
} // namespace
-void DeferGlobalInitializers(TIntermNode *root)
+void DeferGlobalInitializers(TIntermBlock *root)
{
DeferGlobalInitializersTraverser traverser;
root->traverse(&traverser);
diff --git a/src/compiler/translator/DeferGlobalInitializers.h b/src/compiler/translator/DeferGlobalInitializers.h
index 14f2553..85e55d9 100644
--- a/src/compiler/translator/DeferGlobalInitializers.h
+++ b/src/compiler/translator/DeferGlobalInitializers.h
@@ -13,8 +13,8 @@
#ifndef COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
-class TIntermNode;
+class TIntermBlock;
-void DeferGlobalInitializers(TIntermNode *root);
+void DeferGlobalInitializers(TIntermBlock *root);
#endif // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
diff --git a/src/compiler/translator/EmulateGLFragColorBroadcast.cpp b/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
index 431a326..2e2a19e 100644
--- a/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
+++ b/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
@@ -85,7 +85,7 @@
{
TIntermSequence *sequence = node->getSequence();
ASSERT(sequence->size() == 2);
- TIntermAggregate *body = (*sequence)[1]->getAsAggregate();
+ TIntermBlock *body = (*sequence)[1]->getAsBlock();
ASSERT(body);
mMainSequence = body->getSequence();
}
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index a3025f0..cc80717 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -467,14 +467,15 @@
return false;
}
- TIntermAggregate *aggParent = parent->getAsAggregate();
- // If the parent's op is EOpSequence, the result is not assigned anywhere,
+ TIntermBlock *blockParent = parent->getAsBlock();
+ // If the parent is a block, the result is not assigned anywhere,
// so rounding it is not needed. In particular, this can avoid a lot of
// unnecessary rounding of unused return values of assignment.
- if (aggParent && aggParent->getOp() == EOpSequence)
+ if (blockParent)
{
return false;
}
+ TIntermAggregate *aggParent = parent->getAsAggregate();
if (aggParent && aggParent->getOp() == EOpComma && (aggParent->getSequence()->back() != node))
{
return false;
@@ -602,7 +603,6 @@
bool visitChildren = true;
switch (node->getOp())
{
- case EOpSequence:
case EOpConstructStruct:
case EOpFunction:
break;
diff --git a/src/compiler/translator/InitializeVariables.cpp b/src/compiler/translator/InitializeVariables.cpp
index 235f498..d44f2fa 100644
--- a/src/compiler/translator/InitializeVariables.cpp
+++ b/src/compiler/translator/InitializeVariables.cpp
@@ -45,8 +45,6 @@
bool visitChildren = !mCodeInserted;
switch (node->getOp())
{
- case EOpSequence:
- break;
case EOpFunction:
{
// Function definition.
@@ -55,7 +53,7 @@
{
TIntermSequence *sequence = node->getSequence();
ASSERT(sequence->size() == 2);
- TIntermAggregate *body = (*sequence)[1]->getAsAggregate();
+ TIntermBlock *body = (*sequence)[1]->getAsBlock();
ASSERT(body);
insertInitCode(body->getSequence());
mCodeInserted = true;
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 09bc972..4f09fac 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -170,7 +170,7 @@
REPLACE_IF_IS(mInit, TIntermNode, original, replacement);
REPLACE_IF_IS(mCond, TIntermTyped, original, replacement);
REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement);
- REPLACE_IF_IS(mBody, TIntermAggregate, original, replacement);
+ REPLACE_IF_IS(mBody, TIntermBlock, original, replacement);
return false;
}
@@ -207,35 +207,47 @@
bool TIntermAggregate::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
- for (size_t ii = 0; ii < mSequence.size(); ++ii)
+ return replaceChildNodeInternal(original, replacement);
+}
+
+bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ return replaceChildNodeInternal(original, replacement);
+}
+
+bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement)
+{
+ for (size_t ii = 0; ii < getSequence()->size(); ++ii)
{
- REPLACE_IF_IS(mSequence[ii], TIntermNode, original, replacement);
+ REPLACE_IF_IS((*getSequence())[ii], TIntermNode, original, replacement);
}
return false;
}
-bool TIntermAggregate::replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements)
+bool TIntermAggregateBase::replaceChildNodeWithMultiple(TIntermNode *original,
+ const TIntermSequence &replacements)
{
- for (auto it = mSequence.begin(); it < mSequence.end(); ++it)
+ for (auto it = getSequence()->begin(); it < getSequence()->end(); ++it)
{
if (*it == original)
{
- it = mSequence.erase(it);
- mSequence.insert(it, replacements.begin(), replacements.end());
+ it = getSequence()->erase(it);
+ getSequence()->insert(it, replacements.begin(), replacements.end());
return true;
}
}
return false;
}
-bool TIntermAggregate::insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions)
+bool TIntermAggregateBase::insertChildNodes(TIntermSequence::size_type position,
+ const TIntermSequence &insertions)
{
- if (position > mSequence.size())
+ if (position > getSequence()->size())
{
return false;
}
- auto it = mSequence.begin() + position;
- mSequence.insert(it, insertions.begin(), insertions.end());
+ auto it = getSequence()->begin() + position;
+ getSequence()->insert(it, insertions.begin(), insertions.end());
return true;
}
@@ -299,6 +311,14 @@
mType.setPrecision(precision);
}
+void TIntermBlock::appendStatement(TIntermNode *statement)
+{
+ if (statement != nullptr)
+ {
+ mStatements.push_back(statement);
+ }
+}
+
bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
@@ -310,8 +330,8 @@
bool TIntermIfElse::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
- REPLACE_IF_IS(mTrueBlock, TIntermAggregate, original, replacement);
- REPLACE_IF_IS(mFalseBlock, TIntermAggregate, original, replacement);
+ REPLACE_IF_IS(mTrueBlock, TIntermBlock, original, replacement);
+ REPLACE_IF_IS(mFalseBlock, TIntermBlock, original, replacement);
return false;
}
@@ -319,7 +339,7 @@
TIntermNode *original, TIntermNode *replacement)
{
REPLACE_IF_IS(mInit, TIntermTyped, original, replacement);
- REPLACE_IF_IS(mStatementList, TIntermAggregate, original, replacement);
+ REPLACE_IF_IS(mStatementList, TIntermBlock, original, replacement);
return false;
}
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index f261e76..0a04941 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -31,6 +31,7 @@
class TIntermTraverser;
class TIntermAggregate;
+class TIntermBlock;
class TIntermSwizzle;
class TIntermBinary;
class TIntermUnary;
@@ -93,6 +94,7 @@
virtual TIntermTyped *getAsTyped() { return 0; }
virtual TIntermConstantUnion *getAsConstantUnion() { return 0; }
virtual TIntermAggregate *getAsAggregate() { return 0; }
+ virtual TIntermBlock *getAsBlock() { return nullptr; }
virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; }
virtual TIntermBinary *getAsBinaryNode() { return 0; }
virtual TIntermUnary *getAsUnaryNode() { return 0; }
@@ -189,7 +191,7 @@
TIntermNode *init,
TIntermTyped *cond,
TIntermTyped *expr,
- TIntermAggregate *body)
+ TIntermBlock *body)
: mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body), mUnrollFlag(false)
{
}
@@ -202,11 +204,11 @@
TIntermNode *getInit() { return mInit; }
TIntermTyped *getCondition() { return mCond; }
TIntermTyped *getExpression() { return mExpr; }
- TIntermAggregate *getBody() { return mBody; }
+ TIntermBlock *getBody() { return mBody; }
void setCondition(TIntermTyped *condition) { mCond = condition; }
void setExpression(TIntermTyped *expression) { mExpr = expression; }
- void setBody(TIntermAggregate *body) { mBody = body; }
+ void setBody(TIntermBlock *body) { mBody = body; }
void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
bool getUnrollFlag() const { return mUnrollFlag; }
@@ -216,7 +218,7 @@
TIntermNode *mInit; // for-loop initialization
TIntermTyped *mCond; // loop exit condition
TIntermTyped *mExpr; // for-loop expression
- TIntermAggregate *mBody; // loop body
+ TIntermBlock *mBody; // loop body
bool mUnrollFlag; // Whether the loop should be unrolled or not.
};
@@ -525,10 +527,26 @@
typedef TVector<TIntermNode *> TIntermSequence;
typedef TVector<int> TQualifierList;
+// Interface for node classes that have an arbitrarily sized set of children.
+class TIntermAggregateBase
+{
+ public:
+ virtual TIntermSequence *getSequence() = 0;
+ virtual const TIntermSequence *getSequence() const = 0;
+
+ bool replaceChildNodeWithMultiple(TIntermNode *original, const TIntermSequence &replacements);
+ bool insertChildNodes(TIntermSequence::size_type position, const TIntermSequence &insertions);
+
+ protected:
+ TIntermAggregateBase() {}
+
+ bool replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement);
+};
+
//
// Nodes that operate on an arbitrary sized set of children.
//
-class TIntermAggregate : public TIntermOperator
+class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
{
public:
TIntermAggregate()
@@ -557,8 +575,7 @@
TIntermAggregate *getAsAggregate() override { return this; }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
- bool replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements);
- bool insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions);
+
// Conservatively assume function calls and other aggregate operators have side-effects
bool hasSideEffects() const override { return true; }
TIntermTyped *fold(TDiagnostics *diagnostics);
@@ -604,6 +621,28 @@
TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just private!
};
+// A list of statements. Either the root node which contains declarations and function definitions,
+// or a block that can be marked with curly braces {}.
+class TIntermBlock : public TIntermNode, public TIntermAggregateBase
+{
+ public:
+ TIntermBlock() : TIntermNode() {}
+ ~TIntermBlock() {}
+
+ TIntermBlock *getAsBlock() override { return this; }
+ void traverse(TIntermTraverser *it) override;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ // Only intended for initially building the block.
+ void appendStatement(TIntermNode *statement);
+
+ TIntermSequence *getSequence() override { return &mStatements; }
+ const TIntermSequence *getSequence() const override { return &mStatements; }
+
+ protected:
+ TIntermSequence mStatements;
+};
+
// For ternary operators like a ? b : c.
class TIntermTernary : public TIntermTyped
{
@@ -641,7 +680,7 @@
class TIntermIfElse : public TIntermNode
{
public:
- TIntermIfElse(TIntermTyped *cond, TIntermAggregate *trueB, TIntermAggregate *falseB)
+ TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB)
: TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB)
{
}
@@ -650,14 +689,14 @@
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
TIntermTyped *getCondition() const { return mCondition; }
- TIntermAggregate *getTrueBlock() const { return mTrueBlock; }
- TIntermAggregate *getFalseBlock() const { return mFalseBlock; }
+ TIntermBlock *getTrueBlock() const { return mTrueBlock; }
+ TIntermBlock *getFalseBlock() const { return mFalseBlock; }
TIntermIfElse *getAsIfElseNode() override { return this; }
protected:
TIntermTyped *mCondition;
- TIntermAggregate *mTrueBlock;
- TIntermAggregate *mFalseBlock;
+ TIntermBlock *mTrueBlock;
+ TIntermBlock *mFalseBlock;
};
//
@@ -666,10 +705,8 @@
class TIntermSwitch : public TIntermNode
{
public:
- TIntermSwitch(TIntermTyped *init, TIntermAggregate *statementList)
- : TIntermNode(),
- mInit(init),
- mStatementList(statementList)
+ TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList)
+ : TIntermNode(), mInit(init), mStatementList(statementList)
{
}
@@ -680,12 +717,12 @@
TIntermSwitch *getAsSwitchNode() override { return this; }
TIntermTyped *getInit() { return mInit; }
- TIntermAggregate *getStatementList() { return mStatementList; }
- void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; }
+ TIntermBlock *getStatementList() { return mStatementList; }
+ void setStatementList(TIntermBlock *statementList) { mStatementList = statementList; }
protected:
TIntermTyped *mInit;
- TIntermAggregate *mStatementList;
+ TIntermBlock *mStatementList;
};
//
@@ -749,6 +786,7 @@
virtual bool visitSwitch(Visit visit, TIntermSwitch *node) { return true; }
virtual bool visitCase(Visit visit, TIntermCase *node) { return true; }
virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; }
+ virtual bool visitBlock(Visit visit, TIntermBlock *node) { return true; }
virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; }
virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; }
@@ -766,6 +804,7 @@
virtual void traverseSwitch(TIntermSwitch *node);
virtual void traverseCase(TIntermCase *node);
virtual void traverseAggregate(TIntermAggregate *node);
+ virtual void traverseBlock(TIntermBlock *node);
virtual void traverseLoop(TIntermLoop *node);
virtual void traverseBranch(TIntermBranch *node);
@@ -812,7 +851,7 @@
return nullptr;
}
- void pushParentBlock(TIntermAggregate *node);
+ void pushParentBlock(TIntermBlock *node);
void incrementParentBlockPos();
void popParentBlock();
@@ -824,14 +863,14 @@
// To replace a single node with multiple nodes on the parent aggregate node
struct NodeReplaceWithMultipleEntry
{
- NodeReplaceWithMultipleEntry(TIntermAggregate *_parent, TIntermNode *_original, TIntermSequence _replacements)
- : parent(_parent),
- original(_original),
- replacements(_replacements)
+ NodeReplaceWithMultipleEntry(TIntermAggregateBase *_parent,
+ TIntermNode *_original,
+ TIntermSequence _replacements)
+ : parent(_parent), original(_original), replacements(_replacements)
{
}
- TIntermAggregate *parent;
+ TIntermAggregateBase *parent;
TIntermNode *original;
TIntermSequence replacements;
};
@@ -839,7 +878,7 @@
// To insert multiple nodes on the parent aggregate node
struct NodeInsertMultipleEntry
{
- NodeInsertMultipleEntry(TIntermAggregate *_parent,
+ NodeInsertMultipleEntry(TIntermBlock *_parent,
TIntermSequence::size_type _position,
TIntermSequence _insertionsBefore,
TIntermSequence _insertionsAfter)
@@ -850,7 +889,7 @@
{
}
- TIntermAggregate *parent;
+ TIntermBlock *parent;
TIntermSequence::size_type position;
TIntermSequence insertionsBefore;
TIntermSequence insertionsAfter;
@@ -942,13 +981,12 @@
struct ParentBlock
{
- ParentBlock(TIntermAggregate *nodeIn, TIntermSequence::size_type posIn)
- : node(nodeIn),
- pos(posIn)
+ ParentBlock(TIntermBlock *nodeIn, TIntermSequence::size_type posIn)
+ : node(nodeIn), pos(posIn)
{
}
- TIntermAggregate *node;
+ TIntermBlock *node;
TIntermSequence::size_type pos;
};
@@ -1052,6 +1090,7 @@
bool visitTernary(Visit, TIntermTernary *) override { return depthCheck(); }
bool visitIfElse(Visit, TIntermIfElse *) override { return depthCheck(); }
bool visitAggregate(Visit, TIntermAggregate *) override { return depthCheck(); }
+ bool visitBlock(Visit, TIntermBlock *) override { return depthCheck(); }
bool visitLoop(Visit, TIntermLoop *) override { return depthCheck(); }
bool visitBranch(Visit, TIntermBranch *) override { return depthCheck(); }
diff --git a/src/compiler/translator/IntermNodePatternMatcher.cpp b/src/compiler/translator/IntermNodePatternMatcher.cpp
index 6307563..4177b05 100644
--- a/src/compiler/translator/IntermNodePatternMatcher.cpp
+++ b/src/compiler/translator/IntermNodePatternMatcher.cpp
@@ -12,17 +12,6 @@
#include "compiler/translator/IntermNode.h"
-namespace
-{
-
-bool IsNodeBlock(TIntermNode *node)
-{
- ASSERT(node != nullptr);
- return (node->getAsAggregate() && node->getAsAggregate()->getOp() == EOpSequence);
-}
-
-} // anonymous namespace
-
IntermNodePatternMatcher::IntermNodePatternMatcher(const unsigned int mask) : mMask(mask)
{
}
@@ -39,7 +28,7 @@
if ((mMask & kExpressionReturningArray) != 0)
{
if (node->isArray() && node->getOp() == EOpAssign && parentNode != nullptr &&
- !IsNodeBlock(parentNode))
+ !parentNode->getAsBlock())
{
return true;
}
@@ -96,7 +85,7 @@
if (node->getType().isArray() && !parentIsAssignment &&
(node->isConstructor() || node->getOp() == EOpFunctionCall) &&
- !IsNodeBlock(parentNode))
+ !parentNode->getAsBlock())
{
return true;
}
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;
}
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index 57d53bf..bb75d9a 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -62,16 +62,12 @@
return node;
}
-//
// This is the safe way to change the operator on an aggregate, as it
// does lots of error checking and fixing. Especially for establishing
-// a function call's operation on it's set of parameters. Sequences
-// of instructions are also aggregates, but they just direnctly set
-// their operator to EOpSequence.
+// a function call's operation on it's set of parameters.
//
// Returns an aggregate node, which could be the one passed in if
// it was already an aggregate but no operator was set.
-//
TIntermAggregate *TIntermediate::setAggregateOperator(
TIntermNode *node, TOperator op, const TSourceLoc &line)
{
@@ -156,19 +152,20 @@
}
// If the input node is nullptr, return nullptr.
-// If the input node is a sequence (block) node, return it.
-// If the input node is not a sequence node, put it inside a sequence node and return that.
-TIntermAggregate *TIntermediate::EnsureSequence(TIntermNode *node)
+// If the input node is a block node, return it.
+// If the input node is not a block node, put it inside a block node and return that.
+TIntermBlock *TIntermediate::EnsureBlock(TIntermNode *node)
{
if (node == nullptr)
return nullptr;
- TIntermAggregate *aggNode = node->getAsAggregate();
- if (aggNode != nullptr && aggNode->getOp() == EOpSequence)
- return aggNode;
+ TIntermBlock *blockNode = node->getAsBlock();
+ if (blockNode != nullptr)
+ return blockNode;
- aggNode = MakeAggregate(node, node->getLine());
- aggNode->setOp(EOpSequence);
- return aggNode;
+ blockNode = new TIntermBlock();
+ blockNode->setLine(node->getLine());
+ blockNode->getSequence()->push_back(node);
+ return blockNode;
}
// For "if" test nodes. There are three children; a condition,
@@ -186,20 +183,16 @@
{
if (cond->getAsConstantUnion()->getBConst(0) == true)
{
- return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence,
- nodePair.node1->getLine())
- : nullptr;
+ return EnsureBlock(nodePair.node1);
}
else
{
- return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence,
- nodePair.node2->getLine())
- : nullptr;
+ return EnsureBlock(nodePair.node2);
}
}
TIntermIfElse *node =
- new TIntermIfElse(cond, EnsureSequence(nodePair.node1), EnsureSequence(nodePair.node2));
+ new TIntermIfElse(cond, EnsureBlock(nodePair.node1), EnsureBlock(nodePair.node2));
node->setLine(line);
return node;
@@ -269,8 +262,9 @@
return node;
}
-TIntermSwitch *TIntermediate::addSwitch(
- TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line)
+TIntermSwitch *TIntermediate::addSwitch(TIntermTyped *init,
+ TIntermBlock *statementList,
+ const TSourceLoc &line)
{
TIntermSwitch *node = new TIntermSwitch(init, statementList);
node->setLine(line);
@@ -331,7 +325,7 @@
TLoopType type, TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr,
TIntermNode *body, const TSourceLoc &line)
{
- TIntermNode *node = new TIntermLoop(type, init, cond, expr, EnsureSequence(body));
+ TIntermNode *node = new TIntermLoop(type, init, cond, expr, EnsureBlock(body));
node->setLine(line);
return node;
@@ -355,33 +349,6 @@
return node;
}
-//
-// This is to be executed once the final root is put on top by the parsing
-// process.
-//
-TIntermAggregate *TIntermediate::PostProcess(TIntermNode *root)
-{
- if (root == nullptr)
- return nullptr;
-
- //
- // Finish off the top level sequence, if any
- //
- TIntermAggregate *aggRoot = root->getAsAggregate();
- if (aggRoot != nullptr && aggRoot->getOp() == EOpNull)
- {
- aggRoot->setOp(EOpSequence);
- }
- else if (aggRoot == nullptr || aggRoot->getOp() != EOpSequence)
- {
- aggRoot = new TIntermAggregate(EOpSequence);
- aggRoot->setLine(root->getLine());
- aggRoot->getSequence()->push_back(root);
- }
-
- return aggRoot;
-}
-
TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate,
TDiagnostics *diagnostics)
{
diff --git a/src/compiler/translator/Intermediate.h b/src/compiler/translator/Intermediate.h
index c4a21d8..f5878bd 100644
--- a/src/compiler/translator/Intermediate.h
+++ b/src/compiler/translator/Intermediate.h
@@ -36,15 +36,16 @@
TIntermAggregate *growAggregate(
TIntermNode *left, TIntermNode *right, const TSourceLoc &);
static TIntermAggregate *MakeAggregate(TIntermNode *node, const TSourceLoc &line);
- static TIntermAggregate *EnsureSequence(TIntermNode *node);
+ static TIntermBlock *EnsureBlock(TIntermNode *node);
TIntermAggregate *setAggregateOperator(TIntermNode *, TOperator, const TSourceLoc &);
TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &line);
static TIntermTyped *AddTernarySelection(TIntermTyped *cond,
TIntermTyped *trueExpression,
TIntermTyped *falseExpression,
const TSourceLoc &line);
- TIntermSwitch *addSwitch(
- TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line);
+ TIntermSwitch *addSwitch(TIntermTyped *init,
+ TIntermBlock *statementList,
+ const TSourceLoc &line);
TIntermCase *addCase(
TIntermTyped *condition, const TSourceLoc &line);
TIntermTyped *addComma(TIntermTyped *left,
@@ -61,7 +62,6 @@
static TIntermTyped *AddSwizzle(TIntermTyped *baseExpression,
const TVectorFields &fields,
const TSourceLoc &dotLocation);
- static TIntermAggregate *PostProcess(TIntermNode *root);
static void outputTree(TIntermNode *, TInfoSinkBase &);
diff --git a/src/compiler/translator/Operator.h b/src/compiler/translator/Operator.h
index 4793721..2080666 100644
--- a/src/compiler/translator/Operator.h
+++ b/src/compiler/translator/Operator.h
@@ -13,7 +13,6 @@
enum TOperator
{
EOpNull, // if in a node, should only mean a node is still being built
- EOpSequence, // denotes a list of statements, or parameters, etc.
EOpFunctionCall,
EOpFunction, // For function definition
EOpParameters, // an aggregate listing the parameters to a function
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 32db9de..ecd47fa 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -24,8 +24,11 @@
{
if (const TIntermAggregate *aggregate = node->getAsAggregate())
{
- return (aggregate->getOp() != EOpFunction) &&
- (aggregate->getOp() != EOpSequence);
+ return (aggregate->getOp() != EOpFunction);
+ }
+ else if (node->getAsBlock())
+ {
+ return false;
}
else if (node->getAsIfElseNode())
{
@@ -753,6 +756,36 @@
}
}
+bool TOutputGLSLBase::visitBlock(Visit visit, TIntermBlock *node)
+{
+ TInfoSinkBase &out = objSink();
+ // Scope the blocks except when at the global scope.
+ if (mDepth > 0)
+ {
+ out << "{\n";
+ }
+
+ incrementDepth(node);
+ for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
+ iter != node->getSequence()->end(); ++iter)
+ {
+ TIntermNode *curNode = *iter;
+ ASSERT(curNode != nullptr);
+ curNode->traverse(this);
+
+ if (isSingleStatement(curNode))
+ out << ";\n";
+ }
+ decrementDepth();
+
+ // Scope the blocks except when at the global scope.
+ if (mDepth > 0)
+ {
+ out << "}\n";
+ }
+ return false;
+}
+
bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
{
bool visitChildren = true;
@@ -760,33 +793,6 @@
bool useEmulatedFunction = (visit == PreVisit && node->getUseEmulatedFunction());
switch (node->getOp())
{
- case EOpSequence:
- // Scope the sequences except when at the global scope.
- if (mDepth > 0)
- {
- out << "{\n";
- }
-
- incrementDepth(node);
- for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
- iter != node->getSequence()->end(); ++iter)
- {
- TIntermNode *curNode = *iter;
- ASSERT(curNode != NULL);
- curNode->traverse(this);
-
- if (isSingleStatement(curNode))
- out << ";\n";
- }
- decrementDepth();
-
- // Scope the sequences except when at the global scope.
- if (mDepth > 0)
- {
- out << "}\n";
- }
- visitChildren = false;
- break;
case EOpPrototype:
// Function declaration.
ASSERT(visit == PreVisit);
@@ -830,7 +836,7 @@
params->traverse(this);
// Traverse function body.
- TIntermAggregate *body = sequence[1]->getAsAggregate();
+ TIntermBlock *body = sequence[1]->getAsBlock();
visitCodeBlock(body);
decrementDepth();
@@ -1106,7 +1112,7 @@
return true;
}
-void TOutputGLSLBase::visitCodeBlock(TIntermNode *node)
+void TOutputGLSLBase::visitCodeBlock(TIntermBlock *node)
{
TInfoSinkBase &out = objSink();
if (node != NULL)
diff --git a/src/compiler/translator/OutputGLSLBase.h b/src/compiler/translator/OutputGLSLBase.h
index f8df0cd..b95952f 100644
--- a/src/compiler/translator/OutputGLSLBase.h
+++ b/src/compiler/translator/OutputGLSLBase.h
@@ -50,10 +50,11 @@
bool visitSwitch(Visit visit, TIntermSwitch *node) override;
bool visitCase(Visit visit, TIntermCase *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
bool visitLoop(Visit visit, TIntermLoop *node) override;
bool visitBranch(Visit visit, TIntermBranch *node) override;
- void visitCodeBlock(TIntermNode *node);
+ void visitCodeBlock(TIntermBlock *node);
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 47c3894..f3f59e3 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -31,11 +31,6 @@
namespace
{
-bool IsSequence(TIntermNode *node)
-{
- return node->getAsAggregate() != nullptr && node->getAsAggregate()->getOp() == EOpSequence;
-}
-
void WriteSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion)
{
ASSERT(constUnion != nullptr);
@@ -1418,44 +1413,48 @@
}
}
+bool OutputHLSL::visitBlock(Visit visit, TIntermBlock *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ if (mInsideFunction)
+ {
+ outputLineDirective(out, node->getLine().first_line);
+ out << "{\n";
+ }
+
+ for (TIntermSequence::iterator sit = node->getSequence()->begin();
+ sit != node->getSequence()->end(); sit++)
+ {
+ outputLineDirective(out, (*sit)->getLine().first_line);
+
+ (*sit)->traverse(this);
+
+ // Don't output ; after case labels, they're terminated by :
+ // This is needed especially since outputting a ; after a case statement would turn empty
+ // case statements into non-empty case statements, disallowing fall-through from them.
+ // Also no need to output ; after if statements or sequences. This is done just for
+ // code clarity.
+ if ((*sit)->getAsCaseNode() == nullptr && (*sit)->getAsIfElseNode() == nullptr &&
+ (*sit)->getAsBlock() == nullptr)
+ out << ";\n";
+ }
+
+ if (mInsideFunction)
+ {
+ outputLineDirective(out, node->getLine().last_line);
+ out << "}\n";
+ }
+
+ return false;
+}
+
bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
TInfoSinkBase &out = getInfoSink();
switch (node->getOp())
{
- case EOpSequence:
- {
- if (mInsideFunction)
- {
- outputLineDirective(out, node->getLine().first_line);
- out << "{\n";
- }
-
- for (TIntermSequence::iterator sit = node->getSequence()->begin(); sit != node->getSequence()->end(); sit++)
- {
- outputLineDirective(out, (*sit)->getLine().first_line);
-
- (*sit)->traverse(this);
-
- // Don't output ; after case labels, they're terminated by :
- // This is needed especially since outputting a ; after a case statement would turn empty
- // case statements into non-empty case statements, disallowing fall-through from them.
- // Also no need to output ; after if statements or sequences. This is done just for
- // code clarity.
- if ((*sit)->getAsCaseNode() == nullptr && (*sit)->getAsIfElseNode() == nullptr &&
- !IsSequence(*sit))
- out << ";\n";
- }
-
- if (mInsideFunction)
- {
- outputLineDirective(out, node->getLine().last_line);
- out << "}\n";
- }
-
- return false;
- }
case EOpDeclaration:
if (visit == PreVisit)
{
@@ -1629,7 +1628,7 @@
ASSERT(sequence->size() == 2);
TIntermNode *body = (*sequence)[1];
// The function body node will output braces.
- ASSERT(IsSequence(body));
+ ASSERT(body->getAsBlock() != nullptr);
body->traverse(this);
mInsideFunction = false;
@@ -1928,8 +1927,6 @@
if (node->getTrueBlock())
{
// The trueBlock child node will output braces.
- ASSERT(IsSequence(node->getTrueBlock()));
-
node->getTrueBlock()->traverse(this);
// Detect true discard
@@ -1951,8 +1948,6 @@
outputLineDirective(out, node->getFalseBlock()->getLine().first_line);
// The falseBlock child node will output braces.
- ASSERT(IsSequence(node->getFalseBlock()));
-
node->getFalseBlock()->traverse(this);
outputLineDirective(out, node->getFalseBlock()->getLine().first_line);
@@ -2092,7 +2087,6 @@
if (node->getBody())
{
// The loop body node will output braces.
- ASSERT(IsSequence(node->getBody()));
node->getBody()->traverse(this);
}
else
@@ -2182,15 +2176,15 @@
bool OutputHLSL::isSingleStatement(TIntermNode *node)
{
- TIntermAggregate *aggregate = node->getAsAggregate();
+ if (node->getAsBlock())
+ {
+ return false;
+ }
+ TIntermAggregate *aggregate = node->getAsAggregate();
if (aggregate)
{
- if (aggregate->getOp() == EOpSequence)
- {
- return false;
- }
- else if (aggregate->getOp() == EOpDeclaration)
+ if (aggregate->getOp() == EOpDeclaration)
{
// Declaring multiple comma-separated variables must be considered multiple statements
// because each individual declaration has side effects which are visible in the next.
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index ab4f9b3..b76062e 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -67,6 +67,7 @@
bool visitSwitch(Visit visit, TIntermSwitch *);
bool visitCase(Visit visit, TIntermCase *);
bool visitAggregate(Visit visit, TIntermAggregate*);
+ bool visitBlock(Visit visit, TIntermBlock *node);
bool visitLoop(Visit visit, TIntermLoop*);
bool visitBranch(Visit visit, TIntermBranch*);
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 99d6968..36a2d84 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -2060,7 +2060,7 @@
TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function,
TIntermAggregate *functionPrototype,
- TIntermAggregate *functionBody,
+ TIntermBlock *functionBody,
const TSourceLoc &location)
{
// Check that non-void functions have at least one return statement.
@@ -2077,7 +2077,7 @@
if (functionBody == nullptr)
{
- functionBody = new TIntermAggregate(EOpSequence);
+ functionBody = new TIntermBlock();
functionBody->setLine(location);
}
functionNode->getSequence()->push_back(functionBody);
@@ -3085,7 +3085,7 @@
}
TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
- TIntermAggregate *statementList,
+ TIntermBlock *statementList,
const TSourceLoc &loc)
{
TBasicType switchType = init->getBasicType();
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index c2c4bf2..aeb901c 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -94,8 +94,8 @@
const char *token,
const char *extraInfo = "");
- TIntermNode *getTreeRoot() const { return mTreeRoot; }
- void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; }
+ TIntermBlock *getTreeRoot() const { return mTreeRoot; }
+ void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; }
bool getFragmentPrecisionHigh() const
{
@@ -268,7 +268,7 @@
const TSourceLoc &location);
TIntermAggregate *addFunctionDefinition(const TFunction &function,
TIntermAggregate *functionPrototype,
- TIntermAggregate *functionBody,
+ TIntermBlock *functionBody,
const TSourceLoc &location);
void parseFunctionPrototype(const TSourceLoc &location,
TFunction *function,
@@ -335,7 +335,9 @@
void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
- TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc);
+ TIntermSwitch *addSwitch(TIntermTyped *init,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc);
TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
TIntermCase *addDefault(const TSourceLoc &loc);
@@ -410,7 +412,7 @@
ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
ShCompileOptions mCompileOptions; // Options passed to TCompiler
int mShaderVersion;
- TIntermNode *mTreeRoot; // root of parse tree being created
+ TIntermBlock *mTreeRoot; // root of parse tree being created
int mLoopNestingLevel; // 0 if outside all loops
int mStructNestingLevel; // incremented while parsing a struct declaration
int mSwitchNestingLevel; // 0 if outside all switch statements
diff --git a/src/compiler/translator/PruneEmptyDeclarations.cpp b/src/compiler/translator/PruneEmptyDeclarations.cpp
index 8cbeb7d..695aa58 100644
--- a/src/compiler/translator/PruneEmptyDeclarations.cpp
+++ b/src/compiler/translator/PruneEmptyDeclarations.cpp
@@ -62,9 +62,10 @@
// declaration that will be pruned:
// float;
TIntermSequence emptyReplacement;
- TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
- ASSERT(parentAgg != nullptr);
- mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, emptyReplacement));
+ TIntermBlock *parentAsBlock = getParentNode()->getAsBlock();
+ ASSERT(parentAsBlock != nullptr);
+ mMultiReplacements.push_back(
+ NodeReplaceWithMultipleEntry(parentAsBlock, node, emptyReplacement));
}
else if (sym->getType().getQualifier() != EvqGlobal &&
sym->getType().getQualifier() != EvqTemporary)
diff --git a/src/compiler/translator/RecordConstantPrecision.cpp b/src/compiler/translator/RecordConstantPrecision.cpp
index facf424..6eca229 100644
--- a/src/compiler/translator/RecordConstantPrecision.cpp
+++ b/src/compiler/translator/RecordConstantPrecision.cpp
@@ -45,7 +45,7 @@
bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TIntermTyped *operand)
{
- if (getParentNode()->getAsCaseNode())
+ if (getParentNode()->getAsCaseNode() || getParentNode()->getAsBlock())
{
return false;
}
diff --git a/src/compiler/translator/RegenerateStructNames.cpp b/src/compiler/translator/RegenerateStructNames.cpp
index 5e0db2a..1a7d8aa 100644
--- a/src/compiler/translator/RegenerateStructNames.cpp
+++ b/src/compiler/translator/RegenerateStructNames.cpp
@@ -58,25 +58,14 @@
userType->setName(tmp);
}
-bool RegenerateStructNames::visitAggregate(Visit, TIntermAggregate *aggregate)
+bool RegenerateStructNames::visitBlock(Visit, TIntermBlock *block)
{
- ASSERT(aggregate);
- switch (aggregate->getOp())
+ ++mScopeDepth;
+ TIntermSequence &sequence = *(block->getSequence());
+ for (TIntermNode *node : sequence)
{
- case EOpSequence:
- ++mScopeDepth;
- {
- TIntermSequence &sequence = *(aggregate->getSequence());
- for (size_t ii = 0; ii < sequence.size(); ++ii)
- {
- TIntermNode *node = sequence[ii];
- ASSERT(node != NULL);
- node->traverse(this);
- }
- }
- --mScopeDepth;
- return false;
- default:
- return true;
+ node->traverse(this);
}
+ --mScopeDepth;
+ return false;
}
diff --git a/src/compiler/translator/RegenerateStructNames.h b/src/compiler/translator/RegenerateStructNames.h
index 3b98e5d..a910135 100644
--- a/src/compiler/translator/RegenerateStructNames.h
+++ b/src/compiler/translator/RegenerateStructNames.h
@@ -24,7 +24,7 @@
protected:
void visitSymbol(TIntermSymbol *) override;
- bool visitAggregate(Visit, TIntermAggregate *) override;
+ bool visitBlock(Visit, TIntermBlock *block) override;
private:
const TSymbolTable &mSymbolTable;
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
diff --git a/src/compiler/translator/RemoveSwitchFallThrough.cpp b/src/compiler/translator/RemoveSwitchFallThrough.cpp
index 521cbeb..df8ce1e 100644
--- a/src/compiler/translator/RemoveSwitchFallThrough.cpp
+++ b/src/compiler/translator/RemoveSwitchFallThrough.cpp
@@ -6,7 +6,7 @@
#include "compiler/translator/RemoveSwitchFallThrough.h"
-TIntermAggregate *RemoveSwitchFallThrough::removeFallThrough(TIntermAggregate *statementList)
+TIntermBlock *RemoveSwitchFallThrough::removeFallThrough(TIntermBlock *statementList)
{
RemoveSwitchFallThrough rm(statementList);
ASSERT(statementList);
@@ -22,14 +22,13 @@
return rm.mStatementListOut;
}
-RemoveSwitchFallThrough::RemoveSwitchFallThrough(TIntermAggregate *statementList)
+RemoveSwitchFallThrough::RemoveSwitchFallThrough(TIntermBlock *statementList)
: TIntermTraverser(true, false, false),
mStatementList(statementList),
mLastStatementWasBreak(false),
mPreviousCase(nullptr)
{
- mStatementListOut = new TIntermAggregate();
- mStatementListOut->setOp(EOpSequence);
+ mStatementListOut = new TIntermBlock();
}
void RemoveSwitchFallThrough::visitSymbol(TIntermSymbol *node)
@@ -130,8 +129,7 @@
bool RemoveSwitchFallThrough::visitCase(Visit, TIntermCase *node)
{
handlePreviousCase();
- mPreviousCase = new TIntermAggregate();
- mPreviousCase->setOp(EOpSequence);
+ mPreviousCase = new TIntermBlock();
mPreviousCase->getSequence()->push_back(node);
// Don't traverse the condition of the case statement
return false;
@@ -139,6 +137,13 @@
bool RemoveSwitchFallThrough::visitAggregate(Visit, TIntermAggregate *node)
{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThrough::visitBlock(Visit, TIntermBlock *node)
+{
if (node != mStatementList)
{
mPreviousCase->getSequence()->push_back(node);
diff --git a/src/compiler/translator/RemoveSwitchFallThrough.h b/src/compiler/translator/RemoveSwitchFallThrough.h
index fc73da7..171c51b 100644
--- a/src/compiler/translator/RemoveSwitchFallThrough.h
+++ b/src/compiler/translator/RemoveSwitchFallThrough.h
@@ -14,10 +14,10 @@
public:
// When given a statementList from a switch AST node, return an updated
// statementList that has fall-through removed.
- static TIntermAggregate *removeFallThrough(TIntermAggregate *statementList);
+ static TIntermBlock *removeFallThrough(TIntermBlock *statementList);
private:
- RemoveSwitchFallThrough(TIntermAggregate *statementList);
+ RemoveSwitchFallThrough(TIntermBlock *statementList);
void visitSymbol(TIntermSymbol *node) override;
void visitConstantUnion(TIntermConstantUnion *node) override;
@@ -28,17 +28,18 @@
bool visitSwitch(Visit, TIntermSwitch *node) override;
bool visitCase(Visit, TIntermCase *node) override;
bool visitAggregate(Visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit, TIntermBlock *node) override;
bool visitLoop(Visit, TIntermLoop *node) override;
bool visitBranch(Visit, TIntermBranch *node) override;
void outputSequence(TIntermSequence *sequence, size_t startIndex);
void handlePreviousCase();
- TIntermAggregate *mStatementList;
- TIntermAggregate *mStatementListOut;
+ TIntermBlock *mStatementList;
+ TIntermBlock *mStatementListOut;
bool mLastStatementWasBreak;
- TIntermAggregate *mPreviousCase;
- std::vector<TIntermAggregate *> mCasesSharingBreak;
+ TIntermBlock *mPreviousCase;
+ std::vector<TIntermBlock *> mCasesSharingBreak;
};
#endif // COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_
diff --git a/src/compiler/translator/RewriteDoWhile.cpp b/src/compiler/translator/RewriteDoWhile.cpp
index 3a62de2..9cc551b 100644
--- a/src/compiler/translator/RewriteDoWhile.cpp
+++ b/src/compiler/translator/RewriteDoWhile.cpp
@@ -43,15 +43,11 @@
public:
DoWhileRewriter() : TIntermTraverser(true, false, false) {}
- bool visitAggregate(Visit, TIntermAggregate *node) override
+ bool visitBlock(Visit, TIntermBlock *node) override
{
- // A well-formed AST can only have do-while in EOpSequence which represent lists of
- // statements. By doing a prefix traversal we are able to replace the do-while in the
- // sequence directly as the content of the do-while will be traversed later.
- if (node->getOp() != EOpSequence)
- {
- return true;
- }
+ // A well-formed AST can only have do-while inside TIntermBlock. By doing a prefix traversal
+ // we are able to replace the do-while in the sequence directly as the content of the
+ // do-while will be traversed later.
TIntermSequence *statements = node->getSequence();
@@ -99,7 +95,7 @@
{
TIntermBranch *breakStatement = new TIntermBranch(EOpBreak, nullptr);
- TIntermAggregate *breakBlock = new TIntermAggregate(EOpSequence);
+ TIntermBlock *breakBlock = new TIntermBlock();
breakBlock->getSequence()->push_back(breakStatement);
TIntermUnary *negatedCondition =
@@ -107,7 +103,7 @@
TIntermIfElse *innerIf = new TIntermIfElse(negatedCondition, breakBlock, nullptr);
- TIntermAggregate *innerIfBlock = new TIntermAggregate(EOpSequence);
+ TIntermBlock *innerIfBlock = new TIntermBlock();
innerIfBlock->getSequence()->push_back(innerIf);
breakIf = new TIntermIfElse(createTempSymbol(boolType), innerIfBlock, nullptr);
@@ -121,14 +117,10 @@
trueConstant->setBConst(true);
TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, boolType);
- TIntermAggregate *body = nullptr;
- if (loop->getBody() != nullptr)
+ TIntermBlock *body = loop->getBody();
+ if (body == nullptr)
{
- body = loop->getBody()->getAsAggregate();
- }
- else
- {
- body = new TIntermAggregate(EOpSequence);
+ body = new TIntermBlock();
}
auto sequence = body->getSequence();
sequence->insert(sequence->begin(), assignTrue);
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);
diff --git a/src/compiler/translator/RewriteTexelFetchOffset.cpp b/src/compiler/translator/RewriteTexelFetchOffset.cpp
index bcd0bb5..bf89dda 100644
--- a/src/compiler/translator/RewriteTexelFetchOffset.cpp
+++ b/src/compiler/translator/RewriteTexelFetchOffset.cpp
@@ -96,21 +96,20 @@
int uniqueId = texelFetchSymbol->getUniqueId();
// Create new node that represents the call of function texelFetch.
+ // Its argument list will be: texelFetch(sampler, Position+offset, lod).
TIntermAggregate *texelFetchNode = new TIntermAggregate(EOpFunctionCall);
texelFetchNode->setName(newName);
texelFetchNode->setFunctionId(uniqueId);
texelFetchNode->setType(node->getType());
texelFetchNode->setLine(node->getLine());
- // Create argument List of texelFetch(sampler, Position+offset, lod).
- TIntermSequence newsequence;
-
// sampler
- newsequence.push_back(sequence->at(0));
+ texelFetchNode->getSequence()->push_back(sequence->at(0));
// Position
TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped();
ASSERT(texCoordNode);
+
// offset
TIntermTyped *offsetNode = nullptr;
ASSERT(sequence->at(3)->getAsTyped());
@@ -122,16 +121,14 @@
constructIVec3Node->setLine(texCoordNode->getLine());
constructIVec3Node->setType(texCoordNode->getType());
- TIntermSequence ivec3Sequence;
- ivec3Sequence.push_back(sequence->at(3)->getAsTyped());
+ constructIVec3Node->getSequence()->push_back(sequence->at(3)->getAsTyped());
TConstantUnion *zero = new TConstantUnion();
zero->setIConst(0);
TType *intType = new TType(EbtInt);
TIntermConstantUnion *zeroNode = new TIntermConstantUnion(zero, *intType);
- ivec3Sequence.push_back(zeroNode);
- constructIVec3Node->insertChildNodes(0, ivec3Sequence);
+ constructIVec3Node->getSequence()->push_back(zeroNode);
offsetNode = constructIVec3Node;
}
@@ -143,11 +140,12 @@
// Position+offset
TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode);
add->setLine(texCoordNode->getLine());
- newsequence.push_back(add);
+ texelFetchNode->getSequence()->push_back(add);
// lod
- newsequence.push_back(sequence->at(2));
- texelFetchNode->insertChildNodes(0, newsequence);
+ texelFetchNode->getSequence()->push_back(sequence->at(2));
+
+ ASSERT(texelFetchNode->getSequence()->size() == 3u);
// Replace the old node by this new node.
queueReplacement(node, texelFetchNode, OriginalNode::IS_DROPPED);
diff --git a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
index cb69059..96789bd 100644
--- a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
+++ b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
@@ -60,25 +60,6 @@
{
switch (node->getOp())
{
- case EOpSequence:
- mSequenceStack.push_back(TIntermSequence());
- {
- for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
- iter != node->getSequence()->end(); ++iter)
- {
- TIntermNode *child = *iter;
- ASSERT(child != NULL);
- child->traverse(this);
- mSequenceStack.back().push_back(child);
- }
- }
- if (mSequenceStack.back().size() > node->getSequence()->size())
- {
- node->getSequence()->clear();
- *(node->getSequence()) = mSequenceStack.back();
- }
- mSequenceStack.pop_back();
- return false;
case EOpConstructVec2:
case EOpConstructVec3:
case EOpConstructVec4:
@@ -110,6 +91,26 @@
return true;
}
+bool ScalarizeVecAndMatConstructorArgs::visitBlock(Visit visit, TIntermBlock *node)
+{
+ mBlockStack.push_back(TIntermSequence());
+ {
+ for (TIntermNode *child : *node->getSequence())
+ {
+ ASSERT(child != nullptr);
+ child->traverse(this);
+ mBlockStack.back().push_back(child);
+ }
+ }
+ if (mBlockStack.back().size() > node->getSequence()->size())
+ {
+ node->getSequence()->clear();
+ *(node->getSequence()) = mBlockStack.back();
+ }
+ mBlockStack.pop_back();
+ return false;
+}
+
void ScalarizeVecAndMatConstructorArgs::scalarizeArgs(
TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix)
{
@@ -267,8 +268,8 @@
TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration);
decl->getSequence()->push_back(init);
- ASSERT(mSequenceStack.size() > 0);
- TIntermSequence &sequence = mSequenceStack.back();
+ ASSERT(mBlockStack.size() > 0);
+ TIntermSequence &sequence = mBlockStack.back();
sequence.push_back(decl);
return tempVarName;
diff --git a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
index d7553be..eac6125 100644
--- a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
+++ b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
@@ -21,6 +21,7 @@
protected:
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
private:
void scalarizeArgs(TIntermAggregate *aggregate,
@@ -38,7 +39,7 @@
// Return the temporary variable name.
TString createTempVariable(TIntermTyped *original);
- std::vector<TIntermSequence> mSequenceStack;
+ std::vector<TIntermSequence> mBlockStack;
int mTempVarCount;
sh::GLenum mShaderType;
diff --git a/src/compiler/translator/SeparateArrayInitialization.cpp b/src/compiler/translator/SeparateArrayInitialization.cpp
index e166eac..8cd1fa1 100644
--- a/src/compiler/translator/SeparateArrayInitialization.cpp
+++ b/src/compiler/translator/SeparateArrayInitialization.cpp
@@ -58,8 +58,8 @@
// We rely on that array declarations have been isolated to single declarations.
ASSERT(sequence->size() == 1);
TIntermTyped *symbol = initNode->getLeft();
- TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
- ASSERT(parentAgg != nullptr);
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ ASSERT(parentBlock != nullptr);
TIntermSequence replacements;
@@ -74,7 +74,8 @@
replacementAssignment->setLine(symbol->getLine());
replacements.push_back(replacementAssignment);
- mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements));
+ mMultiReplacements.push_back(
+ NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
}
}
return false;
diff --git a/src/compiler/translator/SeparateDeclarations.cpp b/src/compiler/translator/SeparateDeclarations.cpp
index d33747f..cc339ea 100644
--- a/src/compiler/translator/SeparateDeclarations.cpp
+++ b/src/compiler/translator/SeparateDeclarations.cpp
@@ -48,8 +48,8 @@
TIntermSequence *sequence = node->getSequence();
if (sequence->size() > 1)
{
- TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
- ASSERT(parentAgg != nullptr);
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ ASSERT(parentBlock != nullptr);
TIntermSequence replacementDeclarations;
for (size_t ii = 0; ii < sequence->size(); ++ii)
@@ -62,7 +62,8 @@
replacementDeclarations.push_back(replacementDeclaration);
}
- mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacementDeclarations));
+ mMultiReplacements.push_back(
+ NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations));
}
return false;
}
diff --git a/src/compiler/translator/SimplifyLoopConditions.cpp b/src/compiler/translator/SimplifyLoopConditions.cpp
index da8da48..071b8b8 100644
--- a/src/compiler/translator/SimplifyLoopConditions.cpp
+++ b/src/compiler/translator/SimplifyLoopConditions.cpp
@@ -94,7 +94,7 @@
// If we're outside a loop condition, we only need to traverse nodes that may contain loops.
if (!mInsideLoopConditionOrExpression)
- return (node->getOp() == EOpSequence || node->getOp() == EOpFunction);
+ return (node->getOp() == EOpFunction);
mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode());
return !mFoundLoopToChange;
@@ -145,10 +145,9 @@
tempInitSeq.push_back(createTempInitDeclaration(node->getCondition()->deepCopy()));
insertStatementsInParentBlock(tempInitSeq);
- TIntermAggregate *newBody = new TIntermAggregate(EOpSequence);
+ TIntermBlock *newBody = new TIntermBlock();
if (node->getBody())
{
- ASSERT(node->getBody()->getOp() == EOpSequence);
newBody->getSequence()->push_back(node->getBody());
}
newBody->getSequence()->push_back(
@@ -176,10 +175,9 @@
tempInitSeq.push_back(createTempInitDeclaration(CreateBoolConstantNode(true)));
insertStatementsInParentBlock(tempInitSeq);
- TIntermAggregate *newBody = new TIntermAggregate(EOpSequence);
+ TIntermBlock *newBody = new TIntermBlock();
if (node->getBody())
{
- ASSERT(node->getBody()->getOp() == EOpSequence);
newBody->getSequence()->push_back(node->getBody());
}
newBody->getSequence()->push_back(
@@ -202,7 +200,7 @@
// bool s0 = expr;
// while (s0) { { body; } exprB; s0 = expr; }
// }
- TIntermAggregate *loopScope = new TIntermAggregate(EOpSequence);
+ TIntermBlock *loopScope = new TIntermBlock();
if (node->getInit())
{
loopScope->getSequence()->push_back(node->getInit());
@@ -210,7 +208,7 @@
loopScope->getSequence()->push_back(
createTempInitDeclaration(node->getCondition()->deepCopy()));
- TIntermAggregate *whileLoopBody = new TIntermAggregate(EOpSequence);
+ TIntermBlock *whileLoopBody = new TIntermBlock();
if (node->getBody())
{
whileLoopBody->getSequence()->push_back(node->getBody());
@@ -242,8 +240,8 @@
// for (init; expr; ) { { body; } exprB; }
TIntermTyped *loopExpression = node->getExpression();
node->setExpression(nullptr);
- TIntermAggregate *oldBody = node->getBody();
- node->setBody(new TIntermAggregate(EOpSequence));
+ TIntermBlock *oldBody = node->getBody();
+ node->setBody(new TIntermBlock());
if (oldBody != nullptr)
{
node->getBody()->getSequence()->push_back(oldBody);
diff --git a/src/compiler/translator/UnfoldShortCircuitToIf.cpp b/src/compiler/translator/UnfoldShortCircuitToIf.cpp
index f6e9a2e..712f59a 100644
--- a/src/compiler/translator/UnfoldShortCircuitToIf.cpp
+++ b/src/compiler/translator/UnfoldShortCircuitToIf.cpp
@@ -75,7 +75,7 @@
ASSERT(node->getLeft()->getType() == boolType);
insertions.push_back(createTempInitDeclaration(node->getLeft()));
- TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence);
+ TIntermBlock *assignRightBlock = new TIntermBlock();
ASSERT(node->getRight()->getType() == boolType);
assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight()));
@@ -99,7 +99,7 @@
ASSERT(node->getLeft()->getType() == boolType);
insertions.push_back(createTempInitDeclaration(node->getLeft()));
- TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence);
+ TIntermBlock *assignRightBlock = new TIntermBlock();
ASSERT(node->getRight()->getType() == boolType);
assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight()));
@@ -139,11 +139,11 @@
tempDeclaration->getSequence()->push_back(tempSymbol);
insertions.push_back(tempDeclaration);
- TIntermAggregate *trueBlock = new TIntermAggregate(EOpSequence);
+ TIntermBlock *trueBlock = new TIntermBlock();
TIntermBinary *trueAssignment = createTempAssignment(node->getTrueExpression());
trueBlock->getSequence()->push_back(trueAssignment);
- TIntermAggregate *falseBlock = new TIntermAggregate(EOpSequence);
+ TIntermBlock *falseBlock = new TIntermBlock();
TIntermBinary *falseAssignment = createTempAssignment(node->getFalseExpression());
falseBlock->getSequence()->push_back(falseAssignment);
diff --git a/src/compiler/translator/ValidateSwitch.cpp b/src/compiler/translator/ValidateSwitch.cpp
index 1ebdffd..8fbd832 100644
--- a/src/compiler/translator/ValidateSwitch.cpp
+++ b/src/compiler/translator/ValidateSwitch.cpp
@@ -8,8 +8,10 @@
#include "compiler/translator/ParseContext.h"
-bool ValidateSwitch::validate(TBasicType switchType, TParseContext *context,
- TIntermAggregate *statementList, const TSourceLoc &loc)
+bool ValidateSwitch::validate(TBasicType switchType,
+ TParseContext *context,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc)
{
ValidateSwitch validate(switchType, context);
ASSERT(statementList);
diff --git a/src/compiler/translator/ValidateSwitch.h b/src/compiler/translator/ValidateSwitch.h
index fb6a614..9c6dee2 100644
--- a/src/compiler/translator/ValidateSwitch.h
+++ b/src/compiler/translator/ValidateSwitch.h
@@ -16,8 +16,10 @@
public:
// Check for errors and output messages any remaining errors on the context.
// Returns true if there are no errors.
- static bool validate(TBasicType switchType, TParseContext *context,
- TIntermAggregate *statementList, const TSourceLoc &loc);
+ static bool validate(TBasicType switchType,
+ TParseContext *context,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc);
void visitSymbol(TIntermSymbol *) override;
void visitConstantUnion(TIntermConstantUnion *) override;
diff --git a/src/compiler/translator/VersionGLSL.cpp b/src/compiler/translator/VersionGLSL.cpp
index c8718da..5c0c519 100644
--- a/src/compiler/translator/VersionGLSL.cpp
+++ b/src/compiler/translator/VersionGLSL.cpp
@@ -68,10 +68,6 @@
switch (node->getOp())
{
- case EOpSequence:
- // We need to visit sequence children to get to global or inner scope.
- visitChildren = true;
- break;
case EOpDeclaration:
{
const TIntermSequence &sequence = *(node->getSequence());
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index ef2dcaa..b11c7d5 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -76,6 +76,7 @@
TIntermNodePair nodePair;
TIntermTyped* intermTypedNode;
TIntermAggregate* intermAggregate;
+ TIntermBlock* intermBlock;
TIntermSwitch* intermSwitch;
TIntermCase* intermCase;
};
@@ -195,9 +196,9 @@
%type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
%type <interm.intermTypedNode> function_call initializer condition conditionopt
-%type <interm.intermNode> translation_unit function_definition
-%type <interm.intermNode> statement simple_statement
-%type <interm.intermAggregate> statement_list compound_statement compound_statement_no_new_scope
+%type <interm.intermBlock> translation_unit
+%type <interm.intermNode> function_definition statement simple_statement
+%type <interm.intermBlock> statement_list compound_statement compound_statement_no_new_scope
%type <interm.intermNode> declaration_statement selection_statement expression_statement
%type <interm.intermNode> declaration external_declaration
%type <interm.intermNode> for_init_statement
@@ -1286,7 +1287,6 @@
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
| LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
if ($3 != 0) {
- $3->setOp(EOpSequence);
$3->setLine(@$);
}
$$ = $3;
@@ -1310,7 +1310,6 @@
}
| LEFT_BRACE statement_list RIGHT_BRACE {
if ($2) {
- $2->setOp(EOpSequence);
$2->setLine(@$);
}
$$ = $2;
@@ -1319,10 +1318,13 @@
statement_list
: statement {
- $$ = TIntermediate::MakeAggregate($1, @$);
+ $$ = new TIntermBlock();
+ $$->setLine(@$);
+ $$->appendStatement($1);
}
| statement_list statement {
- $$ = context->intermediate.growAggregate($1, $2, @$);
+ $$ = $1;
+ $$->appendStatement($2);
}
;
@@ -1454,12 +1456,13 @@
translation_unit
: external_declaration {
- $$ = $1;
+ $$ = new TIntermBlock();
+ $$->setLine(@$);
+ $$->appendStatement($1);
context->setTreeRoot($$);
}
| translation_unit external_declaration {
- $$ = context->intermediate.growAggregate($1, $2, @$);
- context->setTreeRoot($$);
+ $$->appendStatement($2);
}
;
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 2d3f170..c0512e2 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -291,6 +291,7 @@
TIntermNodePair nodePair;
TIntermTyped* intermTypedNode;
TIntermAggregate* intermAggregate;
+ TIntermBlock* intermBlock;
TIntermSwitch* intermSwitch;
TIntermCase* intermCase;
};
@@ -713,33 +714,33 @@
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 236, 236, 237, 240, 250, 253, 258, 263, 268,
- 273, 279, 282, 285, 288, 291, 294, 300, 307, 318,
- 322, 330, 333, 339, 343, 350, 356, 365, 373, 379,
- 385, 394, 397, 400, 403, 413, 414, 415, 416, 424,
- 425, 428, 431, 438, 439, 442, 448, 449, 453, 460,
- 461, 464, 467, 470, 476, 477, 480, 486, 487, 494,
- 495, 502, 503, 510, 511, 517, 518, 524, 525, 531,
- 532, 538, 539, 546, 547, 548, 549, 553, 554, 555,
- 559, 563, 567, 571, 578, 581, 587, 594, 601, 604,
- 610, 619, 623, 627, 631, 635, 642, 649, 652, 659,
- 667, 687, 697, 705, 730, 734, 738, 742, 749, 756,
- 759, 763, 767, 772, 777, 784, 788, 792, 796, 801,
- 806, 813, 823, 829, 832, 838, 842, 849, 855, 862,
- 866, 869, 872, 881, 887, 895, 898, 918, 937, 944,
- 948, 955, 965, 968, 971, 977, 984, 987, 993, 996,
- 999, 1005, 1008, 1013, 1024, 1027, 1030, 1033, 1036, 1039,
- 1043, 1047, 1051, 1055, 1059, 1063, 1067, 1071, 1075, 1079,
- 1083, 1087, 1091, 1095, 1099, 1103, 1107, 1111, 1115, 1119,
- 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150,
- 1153, 1156, 1159, 1162, 1165, 1168, 1175, 1181, 1184, 1196,
- 1196, 1199, 1199, 1205, 1208, 1223, 1226, 1233, 1237, 1243,
- 1249, 1261, 1265, 1269, 1270, 1276, 1277, 1278, 1279, 1280,
- 1281, 1282, 1286, 1287, 1287, 1287, 1297, 1298, 1302, 1302,
- 1303, 1303, 1308, 1311, 1321, 1324, 1330, 1331, 1335, 1342,
- 1346, 1353, 1353, 1360, 1363, 1370, 1374, 1387, 1387, 1392,
- 1392, 1398, 1398, 1406, 1409, 1415, 1418, 1424, 1428, 1435,
- 1438, 1441, 1444, 1447, 1456, 1460, 1467, 1470, 1476, 1476
+ 0, 237, 237, 238, 241, 251, 254, 259, 264, 269,
+ 274, 280, 283, 286, 289, 292, 295, 301, 308, 319,
+ 323, 331, 334, 340, 344, 351, 357, 366, 374, 380,
+ 386, 395, 398, 401, 404, 414, 415, 416, 417, 425,
+ 426, 429, 432, 439, 440, 443, 449, 450, 454, 461,
+ 462, 465, 468, 471, 477, 478, 481, 487, 488, 495,
+ 496, 503, 504, 511, 512, 518, 519, 525, 526, 532,
+ 533, 539, 540, 547, 548, 549, 550, 554, 555, 556,
+ 560, 564, 568, 572, 579, 582, 588, 595, 602, 605,
+ 611, 620, 624, 628, 632, 636, 643, 650, 653, 660,
+ 668, 688, 698, 706, 731, 735, 739, 743, 750, 757,
+ 760, 764, 768, 773, 778, 785, 789, 793, 797, 802,
+ 807, 814, 824, 830, 833, 839, 843, 850, 856, 863,
+ 867, 870, 873, 882, 888, 896, 899, 919, 938, 945,
+ 949, 956, 966, 969, 972, 978, 985, 988, 994, 997,
+ 1000, 1006, 1009, 1014, 1025, 1028, 1031, 1034, 1037, 1040,
+ 1044, 1048, 1052, 1056, 1060, 1064, 1068, 1072, 1076, 1080,
+ 1084, 1088, 1092, 1096, 1100, 1104, 1108, 1112, 1116, 1120,
+ 1124, 1127, 1130, 1133, 1136, 1139, 1142, 1145, 1148, 1151,
+ 1154, 1157, 1160, 1163, 1166, 1169, 1176, 1182, 1185, 1197,
+ 1197, 1200, 1200, 1206, 1209, 1224, 1227, 1234, 1238, 1244,
+ 1250, 1262, 1266, 1270, 1271, 1277, 1278, 1279, 1280, 1281,
+ 1282, 1283, 1287, 1288, 1288, 1288, 1297, 1298, 1302, 1302,
+ 1303, 1303, 1308, 1311, 1320, 1325, 1332, 1333, 1337, 1344,
+ 1348, 1355, 1355, 1362, 1365, 1372, 1376, 1389, 1389, 1394,
+ 1394, 1400, 1400, 1408, 1411, 1417, 1420, 1426, 1430, 1437,
+ 1440, 1443, 1446, 1449, 1458, 1464, 1470, 1473, 1479, 1479
};
#endif
@@ -4230,7 +4231,7 @@
case 213:
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
break;
@@ -4284,7 +4285,7 @@
case 222:
- { (yyval.interm.intermAggregate) = 0; }
+ { (yyval.interm.intermBlock) = 0; }
break;
@@ -4303,18 +4304,17 @@
case 225:
{
- if ((yyvsp[-2].interm.intermAggregate) != 0) {
- (yyvsp[-2].interm.intermAggregate)->setOp(EOpSequence);
- (yyvsp[-2].interm.intermAggregate)->setLine((yyloc));
+ if ((yyvsp[-2].interm.intermBlock) != 0) {
+ (yyvsp[-2].interm.intermBlock)->setLine((yyloc));
}
- (yyval.interm.intermAggregate) = (yyvsp[-2].interm.intermAggregate);
+ (yyval.interm.intermBlock) = (yyvsp[-2].interm.intermBlock);
}
break;
case 226:
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
break;
@@ -4332,7 +4332,7 @@
case 229:
- { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
+ { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
break;
@@ -4351,7 +4351,7 @@
case 232:
{
- (yyval.interm.intermAggregate) = 0;
+ (yyval.interm.intermBlock) = 0;
}
break;
@@ -4359,11 +4359,10 @@
case 233:
{
- if ((yyvsp[-1].interm.intermAggregate)) {
- (yyvsp[-1].interm.intermAggregate)->setOp(EOpSequence);
- (yyvsp[-1].interm.intermAggregate)->setLine((yyloc));
+ if ((yyvsp[-1].interm.intermBlock)) {
+ (yyvsp[-1].interm.intermBlock)->setLine((yyloc));
}
- (yyval.interm.intermAggregate) = (yyvsp[-1].interm.intermAggregate);
+ (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
}
break;
@@ -4371,7 +4370,9 @@
case 234:
{
- (yyval.interm.intermAggregate) = TIntermediate::MakeAggregate((yyvsp[0].interm.intermNode), (yyloc));
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ (yyval.interm.intermBlock)->setLine((yyloc));
+ (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
}
break;
@@ -4379,7 +4380,8 @@
case 235:
{
- (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[-1].interm.intermAggregate), (yyvsp[0].interm.intermNode), (yyloc));
+ (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
+ (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
}
break;
@@ -4432,7 +4434,7 @@
case 242:
{
- (yyval.interm.intermSwitch) = context->addSwitch((yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermAggregate), (yylsp[-5]));
+ (yyval.interm.intermSwitch) = context->addSwitch((yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermBlock), (yylsp[-5]));
context->decrSwitchNestingLevel();
}
@@ -4621,8 +4623,10 @@
case 264:
{
- (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
- context->setTreeRoot((yyval.interm.intermNode));
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ (yyval.interm.intermBlock)->setLine((yyloc));
+ (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+ context->setTreeRoot((yyval.interm.intermBlock));
}
break;
@@ -4630,8 +4634,7 @@
case 265:
{
- (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode), (yyloc));
- context->setTreeRoot((yyval.interm.intermNode));
+ (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
}
break;
@@ -4663,7 +4666,7 @@
case 269:
{
- (yyval.interm.intermNode) = context->addFunctionDefinition(*((yyvsp[-2].interm).function), (yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermAggregate), (yylsp[-2]));
+ (yyval.interm.intermNode) = context->addFunctionDefinition(*((yyvsp[-2].interm).function), (yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermBlock), (yylsp[-2]));
}
break;
diff --git a/src/compiler/translator/intermOut.cpp b/src/compiler/translator/intermOut.cpp
index aed53d4..e3f9a55 100644
--- a/src/compiler/translator/intermOut.cpp
+++ b/src/compiler/translator/intermOut.cpp
@@ -48,6 +48,7 @@
bool visitTernary(Visit visit, TIntermTernary *node) override;
bool visitIfElse(Visit visit, TIntermIfElse *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *) override;
+ bool visitBlock(Visit visit, TIntermBlock *) override;
bool visitLoop(Visit visit, TIntermLoop *) override;
bool visitBranch(Visit visit, TIntermBranch *) override;
// TODO: Add missing visit functions
@@ -374,18 +375,18 @@
{
TInfoSinkBase &out = sink;
+ OutputTreeText(out, node, mDepth);
+
if (node->getOp() == EOpNull)
{
out.prefix(EPrefixError);
- out << "node is still EOpNull!";
+ out << "node is still EOpNull!\n";
return true;
}
- OutputTreeText(out, node, mDepth);
switch (node->getOp())
{
- case EOpSequence: out << "Sequence\n"; return true;
case EOpComma: out << "Comma\n"; return true;
case EOpFunction: OutputFunction(out, "Function Definition", node); break;
case EOpFunctionCall: OutputFunction(out, "Function Call", node); break;
@@ -457,7 +458,7 @@
out << "Bad aggregation op";
}
- if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
+ if (node->getOp() != EOpParameters)
out << " (" << node->getCompleteString() << ")";
out << "\n";
@@ -465,6 +466,16 @@
return true;
}
+bool TOutputTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+ TInfoSinkBase &out = sink;
+
+ OutputTreeText(out, node, mDepth);
+ out << "Code block\n";
+
+ return true;
+}
+
bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node)
{
TInfoSinkBase &out = sink;