Commit 13389b66 by Olli Etuaho Committed by Commit Bot

Split TIntermDeclaration from TIntermAggregate

The new class TIntermDeclaration is now used for struct, interface block and variable declarations. TIntermDeclaration nodes do not have a type - rather the type is stored in each child node. The types may differ in case the declaration is a series of array declarators with mismatching sizes. TIntermAggregate is still used for function calls, function prototypes, function parameter lists and invariant declarations. BUG=angleproject:1490 TEST=angle_unittests Change-Id: I0457188f354481470855f61ac1c878fc2579b1d1 Reviewed-on: https://chromium-review.googlesource.com/400023 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 3feb3ff5
...@@ -111,7 +111,7 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n ...@@ -111,7 +111,7 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n
if (symbolNode->getQualifier() == EvqConst) if (symbolNode->getQualifier() == EvqConst)
{ {
// All of the siblings in the same declaration need to have consistent qualifiers. // All of the siblings in the same declaration need to have consistent qualifiers.
auto *siblings = getParentNode()->getAsAggregate()->getSequence(); auto *siblings = getParentNode()->getAsDeclarationNode()->getSequence();
for (TIntermNode *siblingNode : *siblings) for (TIntermNode *siblingNode : *siblings)
{ {
TIntermBinary *siblingBinary = siblingNode->getAsBinaryNode(); TIntermBinary *siblingBinary = siblingNode->getAsBinaryNode();
......
...@@ -598,6 +598,24 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node) ...@@ -598,6 +598,24 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
return visitChildren; return visitChildren;
} }
bool EmulatePrecision::visitDeclaration(Visit visit, TIntermDeclaration *node)
{
// Variable or interface block declaration.
if (visit == PreVisit)
{
mDeclaringVariables = true;
}
else if (visit == InVisit)
{
mDeclaringVariables = true;
}
else
{
mDeclaringVariables = false;
}
return true;
}
bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node) bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
bool visitChildren = true; bool visitChildren = true;
...@@ -614,21 +632,6 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -614,21 +632,6 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpInvariantDeclaration: case EOpInvariantDeclaration:
visitChildren = false; visitChildren = false;
break; break;
case EOpDeclaration:
// Variable declaration.
if (visit == PreVisit)
{
mDeclaringVariables = true;
}
else if (visit == InVisit)
{
mDeclaringVariables = true;
}
else
{
mDeclaringVariables = false;
}
break;
case EOpFunctionCall: case EOpFunctionCall:
{ {
// Function call. // Function call.
......
...@@ -27,6 +27,7 @@ class EmulatePrecision : public TLValueTrackingTraverser ...@@ -27,6 +27,7 @@ class EmulatePrecision : public TLValueTrackingTraverser
bool visitBinary(Visit visit, TIntermBinary *node) override; bool visitBinary(Visit visit, TIntermBinary *node) override;
bool visitUnary(Visit visit, TIntermUnary *node) override; bool visitUnary(Visit visit, TIntermUnary *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override;
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
void writeEmulationHelpers(TInfoSinkBase &sink, void writeEmulationHelpers(TInfoSinkBase &sink,
const int shaderVersion, const int shaderVersion,
......
...@@ -116,7 +116,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -116,7 +116,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
TIntermTyped *lhs = sequence->at(0)->getAsTyped(); TIntermTyped *lhs = sequence->at(0)->getAsTyped();
ASSERT(lhs); ASSERT(lhs);
TIntermAggregate *init = createTempInitDeclaration(lhs); TIntermDeclaration *init = createTempInitDeclaration(lhs);
TIntermTyped *current = createTempSymbol(lhs->getType()); TIntermTyped *current = createTempSymbol(lhs->getType());
insertStatementInParentBlock(init); insertStatementInParentBlock(init);
......
...@@ -51,7 +51,7 @@ bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node) ...@@ -51,7 +51,7 @@ bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node)
// Check if loop index type is integer. // Check if loop index type is integer.
// This is called after ValidateLimitations pass, so the loop has the limited form specified // This is called after ValidateLimitations pass, so the loop has the limited form specified
// in ESSL 1.00 appendix A. // in ESSL 1.00 appendix A.
TIntermSequence *declSeq = node->getInit()->getAsAggregate()->getSequence(); TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
if (symbol->getBasicType() == EbtInt) if (symbol->getBasicType() == EbtInt)
node->setUnrollFlag(true); node->setUnrollFlag(true);
......
...@@ -222,6 +222,11 @@ bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacem ...@@ -222,6 +222,11 @@ bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacem
return replaceChildNodeInternal(original, replacement); return replaceChildNodeInternal(original, replacement);
} }
bool TIntermDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
return replaceChildNodeInternal(original, replacement);
}
bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement) bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement)
{ {
for (size_t ii = 0; ii < getSequence()->size(); ++ii) for (size_t ii = 0; ii < getSequence()->size(); ++ii)
...@@ -320,12 +325,26 @@ void TIntermAggregate::setBuiltInFunctionPrecision() ...@@ -320,12 +325,26 @@ void TIntermAggregate::setBuiltInFunctionPrecision()
void TIntermBlock::appendStatement(TIntermNode *statement) void TIntermBlock::appendStatement(TIntermNode *statement)
{ {
if (statement != nullptr) // Declaration nodes with no children can appear if all the declarators just added constants to
// the symbol table instead of generating code. They're no-ops so they aren't added to blocks.
if (statement != nullptr && (statement->getAsDeclarationNode() == nullptr ||
!statement->getAsDeclarationNode()->getSequence()->empty()))
{ {
mStatements.push_back(statement); mStatements.push_back(statement);
} }
} }
void TIntermDeclaration::appendDeclarator(TIntermTyped *declarator)
{
ASSERT(declarator != nullptr);
ASSERT(declarator->getAsSymbolNode() != nullptr ||
(declarator->getAsBinaryNode() != nullptr &&
declarator->getAsBinaryNode()->getOp() == EOpInitialize));
ASSERT(mDeclarators.empty() ||
declarator->getType().sameElementType(mDeclarators.back()->getAsTyped()->getType()));
mDeclarators.push_back(declarator);
}
bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement) bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{ {
REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement); REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
......
...@@ -32,6 +32,7 @@ class TDiagnostics; ...@@ -32,6 +32,7 @@ class TDiagnostics;
class TIntermTraverser; class TIntermTraverser;
class TIntermAggregate; class TIntermAggregate;
class TIntermBlock; class TIntermBlock;
class TIntermDeclaration;
class TIntermFunctionDefinition; class TIntermFunctionDefinition;
class TIntermSwizzle; class TIntermSwizzle;
class TIntermBinary; class TIntermBinary;
...@@ -98,6 +99,7 @@ class TIntermNode : angle::NonCopyable ...@@ -98,6 +99,7 @@ class TIntermNode : angle::NonCopyable
virtual TIntermFunctionDefinition *getAsFunctionDefinition() { return nullptr; } virtual TIntermFunctionDefinition *getAsFunctionDefinition() { return nullptr; }
virtual TIntermAggregate *getAsAggregate() { return 0; } virtual TIntermAggregate *getAsAggregate() { return 0; }
virtual TIntermBlock *getAsBlock() { return nullptr; } virtual TIntermBlock *getAsBlock() { return nullptr; }
virtual TIntermDeclaration *getAsDeclarationNode() { return nullptr; }
virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; } virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; }
virtual TIntermBinary *getAsBinaryNode() { return 0; } virtual TIntermBinary *getAsBinaryNode() { return 0; }
virtual TIntermUnary *getAsUnaryNode() { return 0; } virtual TIntermUnary *getAsUnaryNode() { return 0; }
...@@ -710,6 +712,28 @@ class TIntermBlock : public TIntermNode, public TIntermAggregateBase ...@@ -710,6 +712,28 @@ class TIntermBlock : public TIntermNode, public TIntermAggregateBase
TIntermSequence mStatements; TIntermSequence mStatements;
}; };
// Struct, interface block or variable declaration. Can contain multiple variable declarators.
class TIntermDeclaration : public TIntermNode, public TIntermAggregateBase
{
public:
TIntermDeclaration() : TIntermNode() {}
~TIntermDeclaration() {}
TIntermDeclaration *getAsDeclarationNode() override { return this; }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
// Only intended for initially building the declaration.
// The declarator node should be either TIntermSymbol or TIntermBinary with op set to
// EOpInitialize.
void appendDeclarator(TIntermTyped *declarator);
TIntermSequence *getSequence() override { return &mDeclarators; }
const TIntermSequence *getSequence() const override { return &mDeclarators; }
protected:
TIntermSequence mDeclarators;
};
// For ternary operators like a ? b : c. // For ternary operators like a ? b : c.
class TIntermTernary : public TIntermTyped class TIntermTernary : public TIntermTyped
{ {
...@@ -858,6 +882,7 @@ class TIntermTraverser : angle::NonCopyable ...@@ -858,6 +882,7 @@ class TIntermTraverser : angle::NonCopyable
} }
virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; } virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; }
virtual bool visitBlock(Visit visit, TIntermBlock *node) { return true; } virtual bool visitBlock(Visit visit, TIntermBlock *node) { return true; }
virtual bool visitDeclaration(Visit visit, TIntermDeclaration *node) { return true; }
virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; } virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; }
virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; } virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; }
...@@ -877,6 +902,7 @@ class TIntermTraverser : angle::NonCopyable ...@@ -877,6 +902,7 @@ class TIntermTraverser : angle::NonCopyable
virtual void traverseFunctionDefinition(TIntermFunctionDefinition *node); virtual void traverseFunctionDefinition(TIntermFunctionDefinition *node);
virtual void traverseAggregate(TIntermAggregate *node); virtual void traverseAggregate(TIntermAggregate *node);
virtual void traverseBlock(TIntermBlock *node); virtual void traverseBlock(TIntermBlock *node);
virtual void traverseDeclaration(TIntermDeclaration *node);
virtual void traverseLoop(TIntermLoop *node); virtual void traverseLoop(TIntermLoop *node);
virtual void traverseBranch(TIntermBranch *node); virtual void traverseBranch(TIntermBranch *node);
...@@ -987,11 +1013,11 @@ class TIntermTraverser : angle::NonCopyable ...@@ -987,11 +1013,11 @@ class TIntermTraverser : angle::NonCopyable
// Helper to create a temporary symbol node. // Helper to create a temporary symbol node.
TIntermSymbol *createTempSymbol(const TType &type); TIntermSymbol *createTempSymbol(const TType &type);
// Create a node that declares but doesn't initialize a temporary symbol. // Create a node that declares but doesn't initialize a temporary symbol.
TIntermAggregate *createTempDeclaration(const TType &type); TIntermDeclaration *createTempDeclaration(const TType &type);
// Create a node that initializes the current temporary symbol with initializer having the given qualifier. // Create a node that initializes the current temporary symbol with initializer having the given qualifier.
TIntermAggregate *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier); TIntermDeclaration *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier);
// Create a node that initializes the current temporary symbol with initializer. // Create a node that initializes the current temporary symbol with initializer.
TIntermAggregate *createTempInitDeclaration(TIntermTyped *initializer); TIntermDeclaration *createTempInitDeclaration(TIntermTyped *initializer);
// Create a node that assigns rightNode to the current temporary symbol. // Create a node that assigns rightNode to the current temporary symbol.
TIntermBinary *createTempAssignment(TIntermTyped *rightNode); TIntermBinary *createTempAssignment(TIntermTyped *rightNode);
// Increment temporary symbol index. // Increment temporary symbol index.
......
...@@ -68,6 +68,11 @@ void TIntermBlock::traverse(TIntermTraverser *it) ...@@ -68,6 +68,11 @@ void TIntermBlock::traverse(TIntermTraverser *it)
it->traverseBlock(this); it->traverseBlock(this);
} }
void TIntermDeclaration::traverse(TIntermTraverser *it)
{
it->traverseDeclaration(this);
}
void TIntermAggregate::traverse(TIntermTraverser *it) void TIntermAggregate::traverse(TIntermTraverser *it)
{ {
it->traverseAggregate(this); it->traverseAggregate(this);
...@@ -155,24 +160,25 @@ TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type) ...@@ -155,24 +160,25 @@ TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type)
return createTempSymbol(type, EvqTemporary); return createTempSymbol(type, EvqTemporary);
} }
TIntermAggregate *TIntermTraverser::createTempDeclaration(const TType &type) TIntermDeclaration *TIntermTraverser::createTempDeclaration(const TType &type)
{ {
TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
tempDeclaration->getSequence()->push_back(createTempSymbol(type)); tempDeclaration->appendDeclarator(createTempSymbol(type));
return tempDeclaration; return tempDeclaration;
} }
TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier) TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer,
TQualifier qualifier)
{ {
ASSERT(initializer != nullptr); ASSERT(initializer != nullptr);
TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier); TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier);
TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
TIntermBinary *tempInit = new TIntermBinary(EOpInitialize, tempSymbol, initializer); TIntermBinary *tempInit = new TIntermBinary(EOpInitialize, tempSymbol, initializer);
tempDeclaration->getSequence()->push_back(tempInit); tempDeclaration->appendDeclarator(tempInit);
return tempDeclaration; return tempDeclaration;
} }
TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer) TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer)
{ {
return createTempInitDeclaration(initializer, EvqTemporary); return createTempInitDeclaration(initializer, EvqTemporary);
} }
...@@ -490,6 +496,37 @@ void TIntermTraverser::traverseBlock(TIntermBlock *node) ...@@ -490,6 +496,37 @@ void TIntermTraverser::traverseBlock(TIntermBlock *node)
visitBlock(PostVisit, node); visitBlock(PostVisit, node);
} }
// Traverse a declaration node.
void TIntermTraverser::traverseDeclaration(TIntermDeclaration *node)
{
bool visit = true;
TIntermSequence *sequence = node->getSequence();
if (preVisit)
visit = visitDeclaration(PreVisit, node);
if (visit)
{
incrementDepth(node);
for (auto *child : *sequence)
{
child->traverse(this);
if (visit && inVisit)
{
if (child != sequence->back())
visit = visitDeclaration(InVisit, node);
}
}
decrementDepth();
}
if (visit && postVisit)
visitDeclaration(PostVisit, node);
}
// Traverse an aggregate node. Same comments in binary node apply here. // Traverse an aggregate node. Same comments in binary node apply here.
void TIntermTraverser::traverseAggregate(TIntermAggregate *node) void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
{ {
......
...@@ -93,8 +93,7 @@ void TLoopIndexInfo::fillInfo(TIntermLoop *node) ...@@ -93,8 +93,7 @@ void TLoopIndexInfo::fillInfo(TIntermLoop *node)
// Here we assume all the operations are valid, because the loop node is // Here we assume all the operations are valid, because the loop node is
// already validated in ValidateLimitations. // already validated in ValidateLimitations.
TIntermSequence *declSeq = TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
node->getInit()->getAsAggregate()->getSequence();
TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode(); TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode(); TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
......
...@@ -16,7 +16,6 @@ enum TOperator ...@@ -16,7 +16,6 @@ enum TOperator
EOpFunctionCall, EOpFunctionCall,
EOpParameters, // an aggregate listing the parameters to a function EOpParameters, // an aggregate listing the parameters to a function
EOpDeclaration,
EOpInvariantDeclaration, // Specialized declarations for attributing invariance EOpInvariantDeclaration, // Specialized declarations for attributing invariance
EOpPrototype, EOpPrototype,
......
...@@ -916,27 +916,6 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -916,27 +916,6 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
out << ")"; out << ")";
visitChildren = false; visitChildren = false;
break; break;
case EOpDeclaration:
// Variable declaration.
if (visit == PreVisit)
{
const TIntermSequence &sequence = *(node->getSequence());
const TIntermTyped *variable = sequence.front()->getAsTyped();
writeLayoutQualifier(variable->getType());
writeVariableType(variable->getType());
out << " ";
mDeclaringVariables = true;
}
else if (visit == InVisit)
{
out << ", ";
mDeclaringVariables = true;
}
else
{
mDeclaringVariables = false;
}
break;
case EOpInvariantDeclaration: case EOpInvariantDeclaration:
// Invariant declaration. // Invariant declaration.
ASSERT(visit == PreVisit); ASSERT(visit == PreVisit);
...@@ -1059,6 +1038,32 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1059,6 +1038,32 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
return visitChildren; return visitChildren;
} }
bool TOutputGLSLBase::visitDeclaration(Visit visit, TIntermDeclaration *node)
{
TInfoSinkBase &out = objSink();
// Variable declaration.
if (visit == PreVisit)
{
const TIntermSequence &sequence = *(node->getSequence());
const TIntermTyped *variable = sequence.front()->getAsTyped();
writeLayoutQualifier(variable->getType());
writeVariableType(variable->getType());
out << " ";
mDeclaringVariables = true;
}
else if (visit == InVisit)
{
out << ", ";
mDeclaringVariables = true;
}
else
{
mDeclaringVariables = false;
}
return true;
}
bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
{ {
TInfoSinkBase &out = objSink(); TInfoSinkBase &out = objSink();
...@@ -1092,8 +1097,7 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) ...@@ -1092,8 +1097,7 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
else else
{ {
// Need to put a one-iteration loop here to handle break. // Need to put a one-iteration loop here to handle break.
TIntermSequence *declSeq = TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
node->getInit()->getAsAggregate()->getSequence();
TIntermSymbol *indexSymbol = TIntermSymbol *indexSymbol =
(*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
TString name = hashVariableName(indexSymbol->getSymbol()); TString name = hashVariableName(indexSymbol->getSymbol());
......
...@@ -52,6 +52,7 @@ class TOutputGLSLBase : public TIntermTraverser ...@@ -52,6 +52,7 @@ class TOutputGLSLBase : public TIntermTraverser
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override;
bool visitBlock(Visit visit, TIntermBlock *node) override; bool visitBlock(Visit visit, TIntermBlock *node) override;
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
bool visitLoop(Visit visit, TIntermLoop *node) override; bool visitLoop(Visit visit, TIntermLoop *node) override;
bool visitBranch(Visit visit, TIntermBranch *node) override; bool visitBranch(Visit visit, TIntermBranch *node) override;
......
...@@ -1519,13 +1519,9 @@ bool OutputHLSL::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition ...@@ -1519,13 +1519,9 @@ bool OutputHLSL::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition
return false; return false;
} }
bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) bool OutputHLSL::visitDeclaration(Visit visit, TIntermDeclaration *node)
{ {
TInfoSinkBase &out = getInfoSink(); TInfoSinkBase &out = getInfoSink();
switch (node->getOp())
{
case EOpDeclaration:
if (visit == PreVisit) if (visit == PreVisit)
{ {
TIntermSequence *sequence = node->getSequence(); TIntermSequence *sequence = node->getSequence();
...@@ -1533,8 +1529,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1533,8 +1529,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
ASSERT(sequence->size() == 1); ASSERT(sequence->size() == 1);
if (variable && if (variable &&
(variable->getQualifier() == EvqTemporary || (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal ||
variable->getQualifier() == EvqGlobal || variable->getQualifier() == EvqConst)) variable->getQualifier() == EvqConst))
{ {
ensureStructDefined(variable->getType()); ensureStructDefined(variable->getType());
...@@ -1562,8 +1558,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1562,8 +1558,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
} }
} }
else if (variable->getAsSymbolNode() && else if (variable->getAsSymbolNode() &&
variable->getAsSymbolNode()->getSymbol() == variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration
"") // Type (struct) declaration
{ {
// Already added to constructor map // Already added to constructor map
} }
...@@ -1572,8 +1567,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1572,8 +1567,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
} }
else if (variable && IsVaryingOut(variable->getQualifier())) else if (variable && IsVaryingOut(variable->getQualifier()))
{ {
for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
sit++)
{ {
TIntermSymbol *symbol = (*sit)->getAsSymbolNode(); TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
...@@ -1589,14 +1583,16 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1589,14 +1583,16 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
} }
} }
} }
return false;
} }
else if (visit == InVisit) return false;
}
bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
TInfoSinkBase &out = getInfoSink();
switch (node->getOp())
{ {
out << ", ";
}
break;
case EOpInvariantDeclaration: case EOpInvariantDeclaration:
// Do not do any translation // Do not do any translation
return false; return false;
...@@ -2177,39 +2173,6 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) ...@@ -2177,39 +2173,6 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
return true; return true;
} }
bool OutputHLSL::isSingleStatement(TIntermNode *node)
{
if (node->getAsBlock())
{
return false;
}
TIntermAggregate *aggregate = node->getAsAggregate();
if (aggregate)
{
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.
return false;
}
else
{
for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++)
{
if (!isSingleStatement(*sit))
{
return false;
}
}
return true;
}
}
return true;
}
// Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them // Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them
// (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254). // (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254).
bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node)
...@@ -2227,7 +2190,7 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) ...@@ -2227,7 +2190,7 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node)
// Parse index name and intial value // Parse index name and intial value
if (node->getInit()) if (node->getInit())
{ {
TIntermAggregate *init = node->getInit()->getAsAggregate(); TIntermDeclaration *init = node->getInit()->getAsDeclarationNode();
if (init) if (init)
{ {
......
...@@ -69,10 +69,10 @@ class OutputHLSL : public TIntermTraverser ...@@ -69,10 +69,10 @@ class OutputHLSL : public TIntermTraverser
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
bool visitAggregate(Visit visit, TIntermAggregate*); bool visitAggregate(Visit visit, TIntermAggregate*);
bool visitBlock(Visit visit, TIntermBlock *node); bool visitBlock(Visit visit, TIntermBlock *node);
bool visitDeclaration(Visit visit, TIntermDeclaration *node);
bool visitLoop(Visit visit, TIntermLoop*); bool visitLoop(Visit visit, TIntermLoop*);
bool visitBranch(Visit visit, TIntermBranch*); bool visitBranch(Visit visit, TIntermBranch*);
bool isSingleStatement(TIntermNode *node);
bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node); bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node);
// Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString. // Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString.
......
...@@ -202,20 +202,20 @@ class TParseContext : angle::NonCopyable ...@@ -202,20 +202,20 @@ class TParseContext : angle::NonCopyable
const TString &identifier, const TString &identifier,
const TPublicType &pType, const TPublicType &pType,
TIntermTyped *initializer, TIntermTyped *initializer,
TIntermNode **intermNode); TIntermBinary **initNode);
TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder, TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
const TPublicType &typeSpecifier); const TPublicType &typeSpecifier);
TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
const TSourceLoc &identifierOrTypeLocation, const TSourceLoc &identifierOrTypeLocation,
const TString &identifier); const TString &identifier);
TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType, TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &publicType,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &indexLocation, const TSourceLoc &indexLocation,
TIntermTyped *indexExpression); TIntermTyped *indexExpression);
TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType, TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &initLocation, const TSourceLoc &initLocation,
...@@ -223,7 +223,7 @@ class TParseContext : angle::NonCopyable ...@@ -223,7 +223,7 @@ class TParseContext : angle::NonCopyable
// Parse a declaration like "type a[n] = initializer" // Parse a declaration like "type a[n] = initializer"
// Note that this does not apply to declarations like "type[n] a = initializer" // Note that this does not apply to declarations like "type[n] a = initializer"
TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType, TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &publicType,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &indexLocation, const TSourceLoc &indexLocation,
...@@ -236,32 +236,32 @@ class TParseContext : angle::NonCopyable ...@@ -236,32 +236,32 @@ class TParseContext : angle::NonCopyable
const TString *identifier, const TString *identifier,
const TSymbol *symbol); const TSymbol *symbol);
TIntermAggregate *parseDeclarator(TPublicType &publicType, void parseDeclarator(TPublicType &publicType,
TIntermAggregate *aggregateDeclaration,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier); const TString &identifier,
TIntermAggregate *parseArrayDeclarator(TPublicType &publicType, TIntermDeclaration *declarationOut);
TIntermAggregate *aggregateDeclaration, void parseArrayDeclarator(TPublicType &publicType,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &arrayLocation, const TSourceLoc &arrayLocation,
TIntermTyped *indexExpression); TIntermTyped *indexExpression,
TIntermAggregate *parseInitDeclarator(const TPublicType &publicType, TIntermDeclaration *declarationOut);
TIntermAggregate *aggregateDeclaration, void parseInitDeclarator(const TPublicType &publicType,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &initLocation, const TSourceLoc &initLocation,
TIntermTyped *initializer); TIntermTyped *initializer,
TIntermDeclaration *declarationOut);
// Parse a declarator like "a[n] = initializer" // Parse a declarator like "a[n] = initializer"
TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType, void parseArrayInitDeclarator(const TPublicType &publicType,
TIntermAggregate *aggregateDeclaration,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &indexLocation, const TSourceLoc &indexLocation,
TIntermTyped *indexExpression, TIntermTyped *indexExpression,
const TSourceLoc &initLocation, const TSourceLoc &initLocation,
TIntermTyped *initializer); TIntermTyped *initializer,
TIntermDeclaration *declarationOut);
void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder); void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &parsedFunction, TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
...@@ -302,7 +302,7 @@ class TParseContext : angle::NonCopyable ...@@ -302,7 +302,7 @@ class TParseContext : angle::NonCopyable
const TString *structName, const TString *structName,
TFieldList *fieldList); TFieldList *fieldList);
TIntermAggregate *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder, TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
const TSourceLoc &nameLine, const TSourceLoc &nameLine,
const TString &blockName, const TString &blockName,
TFieldList *fieldList, TFieldList *fieldList,
...@@ -409,8 +409,10 @@ class TParseContext : angle::NonCopyable ...@@ -409,8 +409,10 @@ class TParseContext : angle::NonCopyable
TIntermTyped *addBinaryMathInternal( TIntermTyped *addBinaryMathInternal(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
TIntermTyped *createAssign( TIntermBinary *createAssign(TOperator op,
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); TIntermTyped *left,
TIntermTyped *right,
const TSourceLoc &loc);
// The funcReturnType parameter is expected to be non-null when the operation is a built-in function. // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
// It is expected to be null for other unary operators. // It is expected to be null for other unary operators.
TIntermTyped *createUnaryMath( TIntermTyped *createUnaryMath(
......
...@@ -18,7 +18,7 @@ class PruneEmptyDeclarationsTraverser : private TIntermTraverser ...@@ -18,7 +18,7 @@ class PruneEmptyDeclarationsTraverser : private TIntermTraverser
static void apply(TIntermNode *root); static void apply(TIntermNode *root);
private: private:
PruneEmptyDeclarationsTraverser(); PruneEmptyDeclarationsTraverser();
bool visitAggregate(Visit, TIntermAggregate *node) override; bool visitDeclaration(Visit, TIntermDeclaration *node) override;
}; };
void PruneEmptyDeclarationsTraverser::apply(TIntermNode *root) void PruneEmptyDeclarationsTraverser::apply(TIntermNode *root)
...@@ -33,10 +33,8 @@ PruneEmptyDeclarationsTraverser::PruneEmptyDeclarationsTraverser() ...@@ -33,10 +33,8 @@ PruneEmptyDeclarationsTraverser::PruneEmptyDeclarationsTraverser()
{ {
} }
bool PruneEmptyDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node) bool PruneEmptyDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
{ {
if (node->getOp() == EOpDeclaration)
{
TIntermSequence *sequence = node->getSequence(); TIntermSequence *sequence = node->getSequence();
if (sequence->size() >= 1) if (sequence->size() >= 1)
{ {
...@@ -46,20 +44,21 @@ bool PruneEmptyDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *no ...@@ -46,20 +44,21 @@ bool PruneEmptyDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *no
{ {
if (sequence->size() > 1) if (sequence->size() > 1)
{ {
// Generate a replacement that will remove the empty declarator in the beginning of a declarator // Generate a replacement that will remove the empty declarator in the beginning of
// list. Example of a declaration that will be changed: // a declarator list. Example of a declaration that will be changed:
// float, a; // float, a;
// will be changed to // will be changed to
// float a; // float a;
// This applies also to struct declarations. // This applies also to struct declarations.
TIntermSequence emptyReplacement; TIntermSequence emptyReplacement;
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(node, sym, emptyReplacement)); mMultiReplacements.push_back(
NodeReplaceWithMultipleEntry(node, sym, emptyReplacement));
} }
else if (sym->getBasicType() != EbtStruct) else if (sym->getBasicType() != EbtStruct)
{ {
// Single struct declarations may just declare the struct type and no variables, so they should // Single struct declarations may just declare the struct type and no variables, so
// not be pruned. All other single empty declarations can be pruned entirely. Example of an empty // they should not be pruned. All other single empty declarations can be pruned
// declaration that will be pruned: // entirely. Example of an empty declaration that will be pruned:
// float; // float;
TIntermSequence emptyReplacement; TIntermSequence emptyReplacement;
TIntermBlock *parentAsBlock = getParentNode()->getAsBlock(); TIntermBlock *parentAsBlock = getParentNode()->getAsBlock();
...@@ -99,8 +98,6 @@ bool PruneEmptyDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *no ...@@ -99,8 +98,6 @@ bool PruneEmptyDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *no
} }
} }
return false; return false;
}
return true;
} }
} // namespace } // namespace
......
...@@ -390,7 +390,7 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod ...@@ -390,7 +390,7 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
// Now v_expr[s0] can be safely executed several times without unintended side effects. // Now v_expr[s0] can be safely executed several times without unintended side effects.
// Init the temp variable holding the index // Init the temp variable holding the index
TIntermAggregate *initIndex = createTempInitDeclaration(node->getRight()); TIntermDeclaration *initIndex = createTempInitDeclaration(node->getRight());
insertStatementInParentBlock(initIndex); insertStatementInParentBlock(initIndex);
mUsedTreeInsertion = true; mUsedTreeInsertion = true;
...@@ -441,7 +441,7 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod ...@@ -441,7 +441,7 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
// Store the index in a temporary signed int variable. // Store the index in a temporary signed int variable.
TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight()); TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight());
TIntermAggregate *initIndex = createTempInitDeclaration(indexInitializer); TIntermDeclaration *initIndex = createTempInitDeclaration(indexInitializer);
initIndex->setLine(node->getLine()); initIndex->setLine(node->getLine());
insertionsBefore.push_back(initIndex); insertionsBefore.push_back(initIndex);
......
...@@ -67,7 +67,7 @@ class DoWhileRewriter : public TIntermTraverser ...@@ -67,7 +67,7 @@ class DoWhileRewriter : public TIntermTraverser
TType boolType = TType(EbtBool); TType boolType = TType(EbtBool);
// bool temp = false; // bool temp = false;
TIntermAggregate *tempDeclaration = nullptr; TIntermDeclaration *tempDeclaration = nullptr;
{ {
TConstantUnion *falseConstant = new TConstantUnion(); TConstantUnion *falseConstant = new TConstantUnion();
falseConstant->setBConst(false); falseConstant->setBConst(false);
......
...@@ -70,8 +70,7 @@ TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse) ...@@ -70,8 +70,7 @@ TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse)
nextTemporaryIndex(); nextTemporaryIndex();
TIntermTyped *typedCondition = ifElse->getCondition()->getAsTyped(); TIntermDeclaration *storeCondition = createTempInitDeclaration(ifElse->getCondition());
TIntermAggregate *storeCondition = createTempInitDeclaration(typedCondition);
TIntermBlock *falseBlock = nullptr; TIntermBlock *falseBlock = nullptr;
......
...@@ -265,8 +265,8 @@ TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *orig ...@@ -265,8 +265,8 @@ TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *orig
TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type); TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type);
TIntermBinary *init = new TIntermBinary(EOpInitialize, symbolNode, original); TIntermBinary *init = new TIntermBinary(EOpInitialize, symbolNode, original);
TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration); TIntermDeclaration *decl = new TIntermDeclaration();
decl->getSequence()->push_back(init); decl->appendDeclarator(init);
ASSERT(mBlockStack.size() > 0); ASSERT(mBlockStack.size() > 0);
TIntermSequence &sequence = mBlockStack.back(); TIntermSequence &sequence = mBlockStack.back();
......
...@@ -29,7 +29,7 @@ class SeparateArrayInitTraverser : private TIntermTraverser ...@@ -29,7 +29,7 @@ class SeparateArrayInitTraverser : private TIntermTraverser
static void apply(TIntermNode *root); static void apply(TIntermNode *root);
private: private:
SeparateArrayInitTraverser(); SeparateArrayInitTraverser();
bool visitAggregate(Visit, TIntermAggregate *node) override; bool visitDeclaration(Visit, TIntermDeclaration *node) override;
}; };
void SeparateArrayInitTraverser::apply(TIntermNode *root) void SeparateArrayInitTraverser::apply(TIntermNode *root)
...@@ -44,10 +44,8 @@ SeparateArrayInitTraverser::SeparateArrayInitTraverser() ...@@ -44,10 +44,8 @@ SeparateArrayInitTraverser::SeparateArrayInitTraverser()
{ {
} }
bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node) bool SeparateArrayInitTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
{ {
if (node->getOp() == EOpDeclaration)
{
TIntermSequence *sequence = node->getSequence(); TIntermSequence *sequence = node->getSequence();
TIntermBinary *initNode = sequence->back()->getAsBinaryNode(); TIntermBinary *initNode = sequence->back()->getAsBinaryNode();
if (initNode != nullptr && initNode->getOp() == EOpInitialize) if (initNode != nullptr && initNode->getOp() == EOpInitialize)
...@@ -63,9 +61,8 @@ bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node) ...@@ -63,9 +61,8 @@ bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node)
TIntermSequence replacements; TIntermSequence replacements;
TIntermAggregate *replacementDeclaration = new TIntermAggregate; TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
replacementDeclaration->setOp(EOpDeclaration); replacementDeclaration->appendDeclarator(symbol);
replacementDeclaration->getSequence()->push_back(symbol);
replacementDeclaration->setLine(symbol->getLine()); replacementDeclaration->setLine(symbol->getLine());
replacements.push_back(replacementDeclaration); replacements.push_back(replacementDeclaration);
...@@ -79,8 +76,6 @@ bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node) ...@@ -79,8 +76,6 @@ bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node)
} }
} }
return false; return false;
}
return true;
} }
} // namespace } // namespace
......
...@@ -26,7 +26,7 @@ class SeparateDeclarationsTraverser : private TIntermTraverser ...@@ -26,7 +26,7 @@ class SeparateDeclarationsTraverser : private TIntermTraverser
static void apply(TIntermNode *root); static void apply(TIntermNode *root);
private: private:
SeparateDeclarationsTraverser(); SeparateDeclarationsTraverser();
bool visitAggregate(Visit, TIntermAggregate *node) override; bool visitDeclaration(Visit, TIntermDeclaration *node) override;
}; };
void SeparateDeclarationsTraverser::apply(TIntermNode *root) void SeparateDeclarationsTraverser::apply(TIntermNode *root)
...@@ -41,10 +41,8 @@ SeparateDeclarationsTraverser::SeparateDeclarationsTraverser() ...@@ -41,10 +41,8 @@ SeparateDeclarationsTraverser::SeparateDeclarationsTraverser()
{ {
} }
bool SeparateDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node) bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
{ {
if (node->getOp() == EOpDeclaration)
{
TIntermSequence *sequence = node->getSequence(); TIntermSequence *sequence = node->getSequence();
if (sequence->size() > 1) if (sequence->size() > 1)
{ {
...@@ -54,10 +52,9 @@ bool SeparateDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node ...@@ -54,10 +52,9 @@ bool SeparateDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node
TIntermSequence replacementDeclarations; TIntermSequence replacementDeclarations;
for (size_t ii = 0; ii < sequence->size(); ++ii) for (size_t ii = 0; ii < sequence->size(); ++ii)
{ {
TIntermAggregate *replacementDeclaration = new TIntermAggregate; TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
replacementDeclaration->setOp(EOpDeclaration); replacementDeclaration->appendDeclarator(sequence->at(ii)->getAsTyped());
replacementDeclaration->getSequence()->push_back(sequence->at(ii));
replacementDeclaration->setLine(sequence->at(ii)->getLine()); replacementDeclaration->setLine(sequence->at(ii)->getLine());
replacementDeclarations.push_back(replacementDeclaration); replacementDeclarations.push_back(replacementDeclaration);
} }
...@@ -66,8 +63,6 @@ bool SeparateDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node ...@@ -66,8 +63,6 @@ bool SeparateDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node
NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations)); NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations));
} }
return false; return false;
}
return true;
} }
} // namespace } // namespace
......
...@@ -134,9 +134,7 @@ bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node ...@@ -134,9 +134,7 @@ bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node
// Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;" // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
TIntermSequence insertions; TIntermSequence insertions;
TIntermSymbol *tempSymbol = createTempSymbol(node->getType()); TIntermDeclaration *tempDeclaration = createTempDeclaration(node->getType());
TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
tempDeclaration->getSequence()->push_back(tempSymbol);
insertions.push_back(tempDeclaration); insertions.push_back(tempDeclaration);
TIntermBlock *trueBlock = new TIntermBlock(); TIntermBlock *trueBlock = new TIntermBlock();
......
...@@ -213,8 +213,8 @@ int ValidateLimitations::validateForLoopInit(TIntermLoop *node) ...@@ -213,8 +213,8 @@ int ValidateLimitations::validateForLoopInit(TIntermLoop *node)
// init-declaration has the form: // init-declaration has the form:
// type-specifier identifier = constant-expression // type-specifier identifier = constant-expression
// //
TIntermAggregate *decl = init->getAsAggregate(); TIntermDeclaration *decl = init->getAsDeclarationNode();
if ((decl == NULL) || (decl->getOp() != EOpDeclaration)) if (decl == nullptr)
{ {
error(init->getLine(), "Invalid init declaration", "for"); error(init->getLine(), "Invalid init declaration", "for");
return -1; return -1;
......
...@@ -559,14 +559,8 @@ void CollectVariables::visitInfoList(const TIntermSequence &sequence, ...@@ -559,14 +559,8 @@ void CollectVariables::visitInfoList(const TIntermSequence &sequence,
} }
} }
bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node) bool CollectVariables::visitDeclaration(Visit, TIntermDeclaration *node)
{ {
bool visitChildren = true;
switch (node->getOp())
{
case EOpDeclaration:
{
const TIntermSequence &sequence = *(node->getSequence()); const TIntermSequence &sequence = *(node->getSequence());
ASSERT(!sequence.empty()); ASSERT(!sequence.empty());
...@@ -576,11 +570,10 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node) ...@@ -576,11 +570,10 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
if (typedNode.getBasicType() == EbtInterfaceBlock) if (typedNode.getBasicType() == EbtInterfaceBlock)
{ {
visitInfoList(sequence, mInterfaceBlocks); visitInfoList(sequence, mInterfaceBlocks);
visitChildren = false; return false;
} }
else if (qualifier == EvqAttribute || qualifier == EvqVertexIn || else if (qualifier == EvqAttribute || qualifier == EvqVertexIn || qualifier == EvqFragmentOut ||
qualifier == EvqFragmentOut || qualifier == EvqUniform || qualifier == EvqUniform || IsVarying(qualifier))
IsVarying(qualifier))
{ {
switch (qualifier) switch (qualifier)
{ {
...@@ -599,14 +592,10 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node) ...@@ -599,14 +592,10 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
break; break;
} }
visitChildren = false; return false;
}
break;
}
default: break;
} }
return visitChildren; return true;
} }
bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode) bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
......
...@@ -31,7 +31,7 @@ class CollectVariables : public TIntermTraverser ...@@ -31,7 +31,7 @@ class CollectVariables : public TIntermTraverser
const TExtensionBehavior &extensionBehavior); const TExtensionBehavior &extensionBehavior);
void visitSymbol(TIntermSymbol *symbol) override; void visitSymbol(TIntermSymbol *symbol) override;
bool visitAggregate(Visit, TIntermAggregate *node) override; bool visitDeclaration(Visit, TIntermDeclaration *node) override;
bool visitBinary(Visit visit, TIntermBinary *binaryNode) override; bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
private: private:
......
...@@ -62,21 +62,22 @@ void TVersionGLSL::visitSymbol(TIntermSymbol *node) ...@@ -62,21 +62,22 @@ void TVersionGLSL::visitSymbol(TIntermSymbol *node)
} }
} }
bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
{ {
bool visitChildren = true;
switch (node->getOp())
{
case EOpDeclaration:
{
const TIntermSequence &sequence = *(node->getSequence()); const TIntermSequence &sequence = *(node->getSequence());
if (sequence.front()->getAsTyped()->getType().isInvariant()) if (sequence.front()->getAsTyped()->getType().isInvariant())
{ {
ensureVersionIsAtLeast(GLSL_VERSION_120); ensureVersionIsAtLeast(GLSL_VERSION_120);
} }
break; return true;
} }
bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
{
bool visitChildren = true;
switch (node->getOp())
{
case EOpInvariantDeclaration: case EOpInvariantDeclaration:
ensureVersionIsAtLeast(GLSL_VERSION_120); ensureVersionIsAtLeast(GLSL_VERSION_120);
break; break;
......
...@@ -58,6 +58,7 @@ class TVersionGLSL : public TIntermTraverser ...@@ -58,6 +58,7 @@ class TVersionGLSL : public TIntermTraverser
void visitSymbol(TIntermSymbol *) override; void visitSymbol(TIntermSymbol *) override;
bool visitAggregate(Visit, TIntermAggregate *) override; bool visitAggregate(Visit, TIntermAggregate *) override;
bool visitDeclaration(Visit, TIntermDeclaration *node) override;
private: private:
void ensureVersionIsAtLeast(int version); void ensureVersionIsAtLeast(int version);
......
...@@ -77,6 +77,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). ...@@ -77,6 +77,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TIntermTyped* intermTypedNode; TIntermTyped* intermTypedNode;
TIntermAggregate* intermAggregate; TIntermAggregate* intermAggregate;
TIntermBlock* intermBlock; TIntermBlock* intermBlock;
TIntermDeclaration* intermDeclaration;
TIntermSwitch* intermSwitch; TIntermSwitch* intermSwitch;
TIntermCase* intermCase; TIntermCase* intermCase;
}; };
...@@ -606,10 +607,7 @@ declaration ...@@ -606,10 +607,7 @@ declaration
$$ = context->addFunctionPrototypeDeclaration(*($1.function), @1); $$ = context->addFunctionPrototypeDeclaration(*($1.function), @1);
} }
| init_declarator_list SEMICOLON { | init_declarator_list SEMICOLON {
TIntermAggregate *aggNode = $1.intermAggregate; $$ = $1.intermDeclaration;
if (aggNode && aggNode->getOp() == EOpNull)
aggNode->setOp(EOpDeclaration);
$$ = aggNode;
} }
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) { if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) {
...@@ -762,54 +760,54 @@ init_declarator_list ...@@ -762,54 +760,54 @@ init_declarator_list
} }
| init_declarator_list COMMA identifier { | init_declarator_list COMMA identifier {
$$ = $1; $$ = $1;
$$.intermAggregate = context->parseDeclarator($$.type, $1.intermAggregate, @3, *$3.string); context->parseDeclarator($$.type, @3, *$3.string, $$.intermDeclaration);
} }
| init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$ = $1; $$ = $1;
$$.intermAggregate = context->parseArrayDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); context->parseArrayDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration);
} }
| init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
ES3_OR_NEWER("[]", @3, "implicitly sized array"); ES3_OR_NEWER("[]", @3, "implicitly sized array");
$$ = $1; $$ = $1;
$$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, nullptr, @6, $7); context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, nullptr, @6, $7, $$.intermDeclaration);
} }
| init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
ES3_OR_NEWER("=", @7, "first-class arrays (array initializer)"); ES3_OR_NEWER("=", @7, "first-class arrays (array initializer)");
$$ = $1; $$ = $1;
$$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5, @7, $8); context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, $5, @7, $8, $$.intermDeclaration);
} }
| init_declarator_list COMMA identifier EQUAL initializer { | init_declarator_list COMMA identifier EQUAL initializer {
$$ = $1; $$ = $1;
$$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); context->parseInitDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration);
} }
; ;
single_declaration single_declaration
: fully_specified_type { : fully_specified_type {
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->parseSingleDeclaration($$.type, @1, ""); $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, "");
} }
| fully_specified_type identifier { | fully_specified_type identifier {
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string); $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, *$2.string);
} }
| fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4); $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4);
} }
| fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
ES3_OR_NEWER("[]", @3, "implicitly sized array"); ES3_OR_NEWER("[]", @3, "implicitly sized array");
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6); $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6);
} }
| fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
ES3_OR_NEWER("=", @6, "first-class arrays (array initializer)"); ES3_OR_NEWER("=", @6, "first-class arrays (array initializer)");
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7); $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7);
} }
| fully_specified_type identifier EQUAL initializer { | fully_specified_type identifier EQUAL initializer {
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
} }
; ;
...@@ -1416,10 +1414,10 @@ condition ...@@ -1416,10 +1414,10 @@ condition
context->checkIsScalarBool($1->getLine(), $1); context->checkIsScalarBool($1->getLine(), $1);
} }
| fully_specified_type identifier EQUAL initializer { | fully_specified_type identifier EQUAL initializer {
TIntermNode *intermNode; TIntermBinary *initNode = nullptr;
context->checkIsScalarBool(@2, $1); context->checkIsScalarBool(@2, $1);
if (!context->executeInitializer(@2, *$2.string, $1, $4, &intermNode)) if (!context->executeInitializer(@2, *$2.string, $1, $4, &initNode))
$$ = $4; $$ = $4;
else { else {
$$ = 0; $$ = 0;
......
...@@ -219,6 +219,7 @@ union YYSTYPE ...@@ -219,6 +219,7 @@ union YYSTYPE
TIntermTyped* intermTypedNode; TIntermTyped* intermTypedNode;
TIntermAggregate* intermAggregate; TIntermAggregate* intermAggregate;
TIntermBlock *intermBlock; TIntermBlock *intermBlock;
TIntermDeclaration *intermDeclaration;
TIntermSwitch* intermSwitch; TIntermSwitch* intermSwitch;
TIntermCase* intermCase; TIntermCase* intermCase;
}; };
......
...@@ -53,6 +53,7 @@ class TOutputTraverser : public TIntermTraverser ...@@ -53,6 +53,7 @@ class TOutputTraverser : public TIntermTraverser
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *) override; bool visitAggregate(Visit visit, TIntermAggregate *) override;
bool visitBlock(Visit visit, TIntermBlock *) override; bool visitBlock(Visit visit, TIntermBlock *) override;
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
bool visitLoop(Visit visit, TIntermLoop *) override; bool visitLoop(Visit visit, TIntermLoop *) override;
bool visitBranch(Visit visit, TIntermBranch *) override; bool visitBranch(Visit visit, TIntermBranch *) override;
}; };
...@@ -467,7 +468,6 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -467,7 +468,6 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpOuterProduct: out << "outer product"; break; case EOpOuterProduct: out << "outer product"; break;
case EOpDeclaration: out << "Declaration: "; break;
case EOpInvariantDeclaration: out << "Invariant Declaration: "; break; case EOpInvariantDeclaration: out << "Invariant Declaration: "; break;
default: default:
...@@ -493,6 +493,16 @@ bool TOutputTraverser::visitBlock(Visit visit, TIntermBlock *node) ...@@ -493,6 +493,16 @@ bool TOutputTraverser::visitBlock(Visit visit, TIntermBlock *node)
return true; return true;
} }
bool TOutputTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
{
TInfoSinkBase &out = sink;
OutputTreeText(out, node, mDepth);
out << "Declaration\n";
return true;
}
bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node) bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node)
{ {
TInfoSinkBase &out = sink; TInfoSinkBase &out = sink;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment