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: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/DeferGlobalInitializers.cpp b/src/compiler/translator/DeferGlobalInitializers.cpp
index 067e6ce..5a12238 100644
--- a/src/compiler/translator/DeferGlobalInitializers.cpp
+++ b/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -111,7 +111,7 @@
if (symbolNode->getQualifier() == EvqConst)
{
// 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)
{
TIntermBinary *siblingBinary = siblingNode->getAsBinaryNode();
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index a8f6d64..f38d925 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -598,6 +598,24 @@
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 visitChildren = true;
@@ -614,21 +632,6 @@
case EOpInvariantDeclaration:
visitChildren = false;
break;
- case EOpDeclaration:
- // Variable declaration.
- if (visit == PreVisit)
- {
- mDeclaringVariables = true;
- }
- else if (visit == InVisit)
- {
- mDeclaringVariables = true;
- }
- else
- {
- mDeclaringVariables = false;
- }
- break;
case EOpFunctionCall:
{
// Function call.
diff --git a/src/compiler/translator/EmulatePrecision.h b/src/compiler/translator/EmulatePrecision.h
index f23e40b..22ae217 100644
--- a/src/compiler/translator/EmulatePrecision.h
+++ b/src/compiler/translator/EmulatePrecision.h
@@ -27,6 +27,7 @@
bool visitBinary(Visit visit, TIntermBinary *node) override;
bool visitUnary(Visit visit, TIntermUnary *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
void writeEmulationHelpers(TInfoSinkBase &sink,
const int shaderVersion,
diff --git a/src/compiler/translator/ExpandIntegerPowExpressions.cpp b/src/compiler/translator/ExpandIntegerPowExpressions.cpp
index 9409c01..c5ff7b3 100644
--- a/src/compiler/translator/ExpandIntegerPowExpressions.cpp
+++ b/src/compiler/translator/ExpandIntegerPowExpressions.cpp
@@ -116,7 +116,7 @@
TIntermTyped *lhs = sequence->at(0)->getAsTyped();
ASSERT(lhs);
- TIntermAggregate *init = createTempInitDeclaration(lhs);
+ TIntermDeclaration *init = createTempInitDeclaration(lhs);
TIntermTyped *current = createTempSymbol(lhs->getType());
insertStatementInParentBlock(init);
diff --git a/src/compiler/translator/ForLoopUnroll.cpp b/src/compiler/translator/ForLoopUnroll.cpp
index 4cc1c26..9aa86b4 100644
--- a/src/compiler/translator/ForLoopUnroll.cpp
+++ b/src/compiler/translator/ForLoopUnroll.cpp
@@ -51,7 +51,7 @@
// Check if loop index type is integer.
// This is called after ValidateLimitations pass, so the loop has the limited form specified
// 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();
if (symbol->getBasicType() == EbtInt)
node->setUnrollFlag(true);
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 0acfe40..add4946 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -222,6 +222,11 @@
return replaceChildNodeInternal(original, replacement);
}
+bool TIntermDeclaration::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)
@@ -320,12 +325,26 @@
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);
}
}
+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)
{
REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index f465a5d..fcf9999 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -32,6 +32,7 @@
class TIntermTraverser;
class TIntermAggregate;
class TIntermBlock;
+class TIntermDeclaration;
class TIntermFunctionDefinition;
class TIntermSwizzle;
class TIntermBinary;
@@ -98,6 +99,7 @@
virtual TIntermFunctionDefinition *getAsFunctionDefinition() { return nullptr; }
virtual TIntermAggregate *getAsAggregate() { return 0; }
virtual TIntermBlock *getAsBlock() { return nullptr; }
+ virtual TIntermDeclaration *getAsDeclarationNode() { return nullptr; }
virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; }
virtual TIntermBinary *getAsBinaryNode() { return 0; }
virtual TIntermUnary *getAsUnaryNode() { return 0; }
@@ -710,6 +712,28 @@
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.
class TIntermTernary : public TIntermTyped
{
@@ -858,6 +882,7 @@
}
virtual bool visitAggregate(Visit visit, TIntermAggregate *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 visitBranch(Visit visit, TIntermBranch *node) { return true; }
@@ -877,6 +902,7 @@
virtual void traverseFunctionDefinition(TIntermFunctionDefinition *node);
virtual void traverseAggregate(TIntermAggregate *node);
virtual void traverseBlock(TIntermBlock *node);
+ virtual void traverseDeclaration(TIntermDeclaration *node);
virtual void traverseLoop(TIntermLoop *node);
virtual void traverseBranch(TIntermBranch *node);
@@ -987,11 +1013,11 @@
// Helper to create a temporary symbol node.
TIntermSymbol *createTempSymbol(const TType &type);
// 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.
- TIntermAggregate *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier);
+ TIntermDeclaration *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier);
// 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.
TIntermBinary *createTempAssignment(TIntermTyped *rightNode);
// Increment temporary symbol index.
diff --git a/src/compiler/translator/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index 29f81f4..1e623d1 100644
--- a/src/compiler/translator/IntermTraverse.cpp
+++ b/src/compiler/translator/IntermTraverse.cpp
@@ -68,6 +68,11 @@
it->traverseBlock(this);
}
+void TIntermDeclaration::traverse(TIntermTraverser *it)
+{
+ it->traverseDeclaration(this);
+}
+
void TIntermAggregate::traverse(TIntermTraverser *it)
{
it->traverseAggregate(this);
@@ -155,24 +160,25 @@
return createTempSymbol(type, EvqTemporary);
}
-TIntermAggregate *TIntermTraverser::createTempDeclaration(const TType &type)
+TIntermDeclaration *TIntermTraverser::createTempDeclaration(const TType &type)
{
- TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
- tempDeclaration->getSequence()->push_back(createTempSymbol(type));
+ TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
+ tempDeclaration->appendDeclarator(createTempSymbol(type));
return tempDeclaration;
}
-TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier)
+TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer,
+ TQualifier qualifier)
{
ASSERT(initializer != nullptr);
TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier);
- TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
+ TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
TIntermBinary *tempInit = new TIntermBinary(EOpInitialize, tempSymbol, initializer);
- tempDeclaration->getSequence()->push_back(tempInit);
+ tempDeclaration->appendDeclarator(tempInit);
return tempDeclaration;
}
-TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer)
+TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer)
{
return createTempInitDeclaration(initializer, EvqTemporary);
}
@@ -490,6 +496,37 @@
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.
void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
{
diff --git a/src/compiler/translator/LoopInfo.cpp b/src/compiler/translator/LoopInfo.cpp
index d931a18..e53bd4d 100644
--- a/src/compiler/translator/LoopInfo.cpp
+++ b/src/compiler/translator/LoopInfo.cpp
@@ -93,8 +93,7 @@
// Here we assume all the operations are valid, because the loop node is
// already validated in ValidateLimitations.
- TIntermSequence *declSeq =
- node->getInit()->getAsAggregate()->getSequence();
+ TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
diff --git a/src/compiler/translator/Operator.h b/src/compiler/translator/Operator.h
index 42c5c63..f7706f8 100644
--- a/src/compiler/translator/Operator.h
+++ b/src/compiler/translator/Operator.h
@@ -16,7 +16,6 @@
EOpFunctionCall,
EOpParameters, // an aggregate listing the parameters to a function
- EOpDeclaration,
EOpInvariantDeclaration, // Specialized declarations for attributing invariance
EOpPrototype,
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 2be8e7e..8abafb8 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -916,27 +916,6 @@
out << ")";
visitChildren = false;
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:
// Invariant declaration.
ASSERT(visit == PreVisit);
@@ -1059,6 +1038,32 @@
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)
{
TInfoSinkBase &out = objSink();
@@ -1092,8 +1097,7 @@
else
{
// Need to put a one-iteration loop here to handle break.
- TIntermSequence *declSeq =
- node->getInit()->getAsAggregate()->getSequence();
+ TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
TIntermSymbol *indexSymbol =
(*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
TString name = hashVariableName(indexSymbol->getSymbol());
diff --git a/src/compiler/translator/OutputGLSLBase.h b/src/compiler/translator/OutputGLSLBase.h
index aa861c7..01dc2e8 100644
--- a/src/compiler/translator/OutputGLSLBase.h
+++ b/src/compiler/translator/OutputGLSLBase.h
@@ -52,6 +52,7 @@
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
bool visitBlock(Visit visit, TIntermBlock *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
bool visitLoop(Visit visit, TIntermLoop *node) override;
bool visitBranch(Visit visit, TIntermBranch *node) override;
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index feae684..3af0e17 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -1519,84 +1519,80 @@
return false;
}
+bool OutputHLSL::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+ if (visit == PreVisit)
+ {
+ TIntermSequence *sequence = node->getSequence();
+ TIntermTyped *variable = (*sequence)[0]->getAsTyped();
+ ASSERT(sequence->size() == 1);
+
+ if (variable &&
+ (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal ||
+ variable->getQualifier() == EvqConst))
+ {
+ ensureStructDefined(variable->getType());
+
+ if (!variable->getAsSymbolNode() ||
+ variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
+ {
+ if (!mInsideFunction)
+ {
+ out << "static ";
+ }
+
+ out << TypeString(variable->getType()) + " ";
+
+ TIntermSymbol *symbol = variable->getAsSymbolNode();
+
+ if (symbol)
+ {
+ symbol->traverse(this);
+ out << ArrayString(symbol->getType());
+ out << " = " + initializer(symbol->getType());
+ }
+ else
+ {
+ variable->traverse(this);
+ }
+ }
+ else if (variable->getAsSymbolNode() &&
+ variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration
+ {
+ // Already added to constructor map
+ }
+ else
+ UNREACHABLE();
+ }
+ else if (variable && IsVaryingOut(variable->getQualifier()))
+ {
+ for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
+ {
+ TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
+
+ if (symbol)
+ {
+ // Vertex (output) varyings which are declared but not written to should
+ // still be declared to allow successful linking
+ mReferencedVaryings[symbol->getSymbol()] = symbol;
+ }
+ else
+ {
+ (*sit)->traverse(this);
+ }
+ }
+ }
+ }
+ return false;
+}
+
bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
TInfoSinkBase &out = getInfoSink();
switch (node->getOp())
{
- case EOpDeclaration:
- if (visit == PreVisit)
- {
- TIntermSequence *sequence = node->getSequence();
- TIntermTyped *variable = (*sequence)[0]->getAsTyped();
- ASSERT(sequence->size() == 1);
-
- if (variable &&
- (variable->getQualifier() == EvqTemporary ||
- variable->getQualifier() == EvqGlobal || variable->getQualifier() == EvqConst))
- {
- ensureStructDefined(variable->getType());
-
- if (!variable->getAsSymbolNode() ||
- variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
- {
- if (!mInsideFunction)
- {
- out << "static ";
- }
-
- out << TypeString(variable->getType()) + " ";
-
- TIntermSymbol *symbol = variable->getAsSymbolNode();
-
- if (symbol)
- {
- symbol->traverse(this);
- out << ArrayString(symbol->getType());
- out << " = " + initializer(symbol->getType());
- }
- else
- {
- variable->traverse(this);
- }
- }
- else if (variable->getAsSymbolNode() &&
- variable->getAsSymbolNode()->getSymbol() ==
- "") // Type (struct) declaration
- {
- // Already added to constructor map
- }
- else
- UNREACHABLE();
- }
- else if (variable && IsVaryingOut(variable->getQualifier()))
- {
- for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end();
- sit++)
- {
- TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
-
- if (symbol)
- {
- // Vertex (output) varyings which are declared but not written to should
- // still be declared to allow successful linking
- mReferencedVaryings[symbol->getSymbol()] = symbol;
- }
- else
- {
- (*sit)->traverse(this);
- }
- }
- }
-
- return false;
- }
- else if (visit == InVisit)
- {
- out << ", ";
- }
- break;
case EOpInvariantDeclaration:
// Do not do any translation
return false;
@@ -2177,39 +2173,6 @@
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
// (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254).
bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node)
@@ -2227,7 +2190,7 @@
// Parse index name and intial value
if (node->getInit())
{
- TIntermAggregate *init = node->getInit()->getAsAggregate();
+ TIntermDeclaration *init = node->getInit()->getAsDeclarationNode();
if (init)
{
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index db78859..833f473 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -69,10 +69,10 @@
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
bool visitAggregate(Visit visit, TIntermAggregate*);
bool visitBlock(Visit visit, TIntermBlock *node);
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node);
bool visitLoop(Visit visit, TIntermLoop*);
bool visitBranch(Visit visit, TIntermBranch*);
- bool isSingleStatement(TIntermNode *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.
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index fc5ea60..2e2c27e 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1475,9 +1475,10 @@
const TString &identifier,
const TPublicType &pType,
TIntermTyped *initializer,
- TIntermNode **intermNode)
+ TIntermBinary **initNode)
{
- ASSERT(intermNode != nullptr);
+ ASSERT(initNode != nullptr);
+ ASSERT(*initNode == nullptr);
TType type = TType(pType);
TVariable *variable = nullptr;
@@ -1549,7 +1550,7 @@
if (initializer->getAsConstantUnion())
{
variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
- *intermNode = nullptr;
+ *initNode = nullptr;
return false;
}
else if (initializer->getAsSymbolNode())
@@ -1562,7 +1563,7 @@
if (constArray)
{
variable->shareConstPointer(constArray);
- *intermNode = nullptr;
+ *initNode = nullptr;
return false;
}
}
@@ -1570,8 +1571,8 @@
TIntermSymbol *intermSymbol = intermediate.addSymbol(
variable->getUniqueId(), variable->getName(), variable->getType(), line);
- *intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
- if (*intermNode == nullptr)
+ *initNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
+ if (*initNode == nullptr)
{
assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
return true;
@@ -1753,9 +1754,10 @@
return true;
}
-TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType,
- const TSourceLoc &identifierOrTypeLocation,
- const TString &identifier)
+TIntermDeclaration *TParseContext::parseSingleDeclaration(
+ TPublicType &publicType,
+ const TSourceLoc &identifierOrTypeLocation,
+ const TString &identifier)
{
TType type(publicType);
if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) &&
@@ -1791,6 +1793,9 @@
mDeferredSingleDeclarationErrorCheck = emptyDeclaration;
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierOrTypeLocation);
+
if (emptyDeclaration)
{
if (publicType.isUnsizedArray())
@@ -1811,17 +1816,23 @@
declareVariable(identifierOrTypeLocation, identifier, type, &variable);
if (variable && symbol)
+ {
symbol->setId(variable->getUniqueId());
+ }
}
- return TIntermediate::MakeAggregate(symbol, identifierOrTypeLocation);
+ // We append the symbol even if the declaration is empty, mainly because of struct declarations
+ // that may just declare a type.
+ declaration->appendDeclarator(symbol);
+
+ return declaration;
}
-TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression)
+TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression)
{
mDeferredSingleDeclarationErrorCheck = false;
@@ -1841,38 +1852,44 @@
TVariable *variable = nullptr;
declareVariable(identifierLocation, identifier, arrayType, &variable);
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierLocation);
+
TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
if (variable && symbol)
+ {
symbol->setId(variable->getUniqueId());
+ declaration->appendDeclarator(symbol);
+ }
- return TIntermediate::MakeAggregate(symbol, identifierLocation);
+ return declaration;
}
-TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer)
+TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer)
{
mDeferredSingleDeclarationErrorCheck = false;
singleDeclarationErrorCheck(publicType, identifierLocation);
- TIntermNode *intermNode = nullptr;
- if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierLocation);
+
+ TIntermBinary *initNode = nullptr;
+ if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
{
- //
- // Build intermediate representation
- //
- return intermNode ? TIntermediate::MakeAggregate(intermNode, initLocation) : nullptr;
+ if (initNode)
+ {
+ declaration->appendDeclarator(initNode);
+ }
}
- else
- {
- return nullptr;
- }
+ return declaration;
}
-TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration(
+TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
TPublicType &publicType,
const TSourceLoc &identifierLocation,
const TString &identifier,
@@ -1900,16 +1917,20 @@
// This ensures useless error messages regarding the variable's non-arrayness won't follow.
arrayType.setArraySize(size);
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierLocation);
+
// initNode will correspond to the whole of "type b[n] = initializer".
- TIntermNode *initNode = nullptr;
+ TIntermBinary *initNode = nullptr;
if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
{
- return initNode ? TIntermediate::MakeAggregate(initNode, initLocation) : nullptr;
+ if (initNode)
+ {
+ declaration->appendDeclarator(initNode);
+ }
}
- else
- {
- return nullptr;
- }
+
+ return declaration;
}
TIntermAggregate *TParseContext::parseInvariantDeclaration(
@@ -1967,10 +1988,10 @@
return aggregate;
}
-TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType,
- TIntermAggregate *aggregateDeclaration,
- const TSourceLoc &identifierLocation,
- const TString &identifier)
+void TParseContext::parseDeclarator(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ TIntermDeclaration *declarationOut)
{
// If the declaration starting this declarator list was empty (example: int,), some checks were
// not performed.
@@ -1990,17 +2011,18 @@
TIntermSymbol *symbol =
intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
if (variable && symbol)
+ {
symbol->setId(variable->getUniqueId());
-
- return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
+ declarationOut->appendDeclarator(symbol);
+ }
}
-TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType,
- TIntermAggregate *aggregateDeclaration,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &arrayLocation,
- TIntermTyped *indexExpression)
+void TParseContext::parseArrayDeclarator(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &arrayLocation,
+ TIntermTyped *indexExpression,
+ TIntermDeclaration *declarationOut)
{
// If the declaration starting this declarator list was empty (example: int,), some checks were
// not performed.
@@ -2028,18 +2050,16 @@
if (variable && symbol)
symbol->setId(variable->getUniqueId());
- return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
+ declarationOut->appendDeclarator(symbol);
}
-
- return nullptr;
}
-TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicType,
- TIntermAggregate *aggregateDeclaration,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer)
+void TParseContext::parseInitDeclarator(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut)
{
// If the declaration starting this declarator list was empty (example: int,), some checks were
// not performed.
@@ -2051,35 +2071,27 @@
checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
- TIntermNode *intermNode = nullptr;
- if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
+ TIntermBinary *initNode = nullptr;
+ if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
{
//
// build the intermediate representation
//
- if (intermNode)
+ if (initNode)
{
- return intermediate.growAggregate(aggregateDeclaration, intermNode, initLocation);
+ declarationOut->appendDeclarator(initNode);
}
- else
- {
- return aggregateDeclaration;
- }
- }
- else
- {
- return nullptr;
}
}
-TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
- TIntermAggregate *aggregateDeclaration,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer)
+void TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut)
{
// If the declaration starting this declarator list was empty (example: int,), some checks were
// not performed.
@@ -2107,21 +2119,13 @@
arrayType.setArraySize(size);
// initNode will correspond to the whole of "b[n] = initializer".
- TIntermNode *initNode = nullptr;
+ TIntermBinary *initNode = nullptr;
if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
{
if (initNode)
{
- return intermediate.growAggregate(aggregateDeclaration, initNode, initLocation);
+ declarationOut->appendDeclarator(initNode);
}
- else
- {
- return aggregateDeclaration;
- }
- }
- else
- {
- return nullptr;
}
}
@@ -2620,7 +2624,7 @@
//
// Interface/uniform blocks
//
-TIntermAggregate *TParseContext::addInterfaceBlock(
+TIntermDeclaration *TParseContext::addInterfaceBlock(
const TTypeQualifierBuilder &typeQualifierBuilder,
const TSourceLoc &nameLine,
const TString &blockName,
@@ -2782,13 +2786,14 @@
symbolName = instanceTypeDef->getName();
}
- TIntermAggregate *aggregate = TIntermediate::MakeAggregate(
- intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line),
- nameLine);
- aggregate->setOp(EOpDeclaration);
+ TIntermSymbol *blockSymbol =
+ intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line);
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->appendDeclarator(blockSymbol);
+ declaration->setLine(nameLine);
exitStructDeclaration();
- return aggregate;
+ return declaration;
}
void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier)
@@ -3903,10 +3908,10 @@
return node;
}
-TIntermTyped *TParseContext::createAssign(TOperator op,
- TIntermTyped *left,
- TIntermTyped *right,
- const TSourceLoc &loc)
+TIntermBinary *TParseContext::createAssign(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
{
if (binaryOpCommonCheck(op, left, right, loc))
{
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index df34dd3..4b1c6ae 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -202,66 +202,66 @@
const TString &identifier,
const TPublicType &pType,
TIntermTyped *initializer,
- TIntermNode **intermNode);
+ TIntermBinary **initNode);
TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
const TPublicType &typeSpecifier);
- TIntermAggregate *parseSingleDeclaration(TPublicType &publicType,
- const TSourceLoc &identifierOrTypeLocation,
- const TString &identifier);
- TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression);
- TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer);
+ TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierOrTypeLocation,
+ const TString &identifier);
+ TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression);
+ TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
// Parse a declaration like "type a[n] = initializer"
// Note that this does not apply to declarations like "type[n] a = initializer"
- TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer);
+ TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
TIntermAggregate *parseInvariantDeclaration(const TTypeQualifierBuilder &typeQualifierBuilder,
const TSourceLoc &identifierLoc,
const TString *identifier,
const TSymbol *symbol);
- TIntermAggregate *parseDeclarator(TPublicType &publicType,
- TIntermAggregate *aggregateDeclaration,
- const TSourceLoc &identifierLocation,
- const TString &identifier);
- TIntermAggregate *parseArrayDeclarator(TPublicType &publicType,
- TIntermAggregate *aggregateDeclaration,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &arrayLocation,
- TIntermTyped *indexExpression);
- TIntermAggregate *parseInitDeclarator(const TPublicType &publicType,
- TIntermAggregate *aggregateDeclaration,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer);
+ void parseDeclarator(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ TIntermDeclaration *declarationOut);
+ void parseArrayDeclarator(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &arrayLocation,
+ TIntermTyped *indexExpression,
+ TIntermDeclaration *declarationOut);
+ void parseInitDeclarator(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut);
// Parse a declarator like "a[n] = initializer"
- TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType,
- TIntermAggregate *aggregateDeclaration,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer);
+ void parseArrayInitDeclarator(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut);
void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
@@ -302,14 +302,14 @@
const TString *structName,
TFieldList *fieldList);
- TIntermAggregate *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
- const TSourceLoc &nameLine,
- const TString &blockName,
- TFieldList *fieldList,
- const TString *instanceName,
- const TSourceLoc &instanceLine,
- TIntermTyped *arrayIndex,
- const TSourceLoc &arrayIndexLine);
+ TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TSourceLoc &nameLine,
+ const TString &blockName,
+ TFieldList *fieldList,
+ const TString *instanceName,
+ const TSourceLoc &instanceLine,
+ TIntermTyped *arrayIndex,
+ const TSourceLoc &arrayIndexLine);
void parseLocalSize(const TString &qualifierType,
const TSourceLoc &qualifierTypeLine,
@@ -409,8 +409,10 @@
TIntermTyped *addBinaryMathInternal(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
- TIntermTyped *createAssign(
- TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
+ TIntermBinary *createAssign(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
// 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.
TIntermTyped *createUnaryMath(
diff --git a/src/compiler/translator/PruneEmptyDeclarations.cpp b/src/compiler/translator/PruneEmptyDeclarations.cpp
index 4763dd6..133130d 100644
--- a/src/compiler/translator/PruneEmptyDeclarations.cpp
+++ b/src/compiler/translator/PruneEmptyDeclarations.cpp
@@ -18,7 +18,7 @@
static void apply(TIntermNode *root);
private:
PruneEmptyDeclarationsTraverser();
- bool visitAggregate(Visit, TIntermAggregate *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
};
void PruneEmptyDeclarationsTraverser::apply(TIntermNode *root)
@@ -33,74 +33,71 @@
{
}
-bool PruneEmptyDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node)
+bool PruneEmptyDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
{
- if (node->getOp() == EOpDeclaration)
+ TIntermSequence *sequence = node->getSequence();
+ if (sequence->size() >= 1)
{
- TIntermSequence *sequence = node->getSequence();
- if (sequence->size() >= 1)
+ TIntermSymbol *sym = sequence->front()->getAsSymbolNode();
+ // Prune declarations without a variable name, unless it's an interface block declaration.
+ if (sym != nullptr && sym->getSymbol() == "" && !sym->isInterfaceBlock())
{
- TIntermSymbol *sym = sequence->front()->getAsSymbolNode();
- // Prune declarations without a variable name, unless it's an interface block declaration.
- if (sym != nullptr && sym->getSymbol() == "" && !sym->isInterfaceBlock())
+ if (sequence->size() > 1)
{
- if (sequence->size() > 1)
+ // Generate a replacement that will remove the empty declarator in the beginning of
+ // a declarator list. Example of a declaration that will be changed:
+ // float, a;
+ // will be changed to
+ // float a;
+ // This applies also to struct declarations.
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.push_back(
+ NodeReplaceWithMultipleEntry(node, sym, emptyReplacement));
+ }
+ else if (sym->getBasicType() != EbtStruct)
+ {
+ // Single struct declarations may just declare the struct type and no variables, so
+ // they should not be pruned. All other single empty declarations can be pruned
+ // entirely. Example of an empty declaration that will be pruned:
+ // float;
+ TIntermSequence emptyReplacement;
+ TIntermBlock *parentAsBlock = getParentNode()->getAsBlock();
+ // The declaration may be inside a block or in a loop init expression.
+ ASSERT(parentAsBlock != nullptr || getParentNode()->getAsLoopNode() != nullptr);
+ if (parentAsBlock)
{
- // Generate a replacement that will remove the empty declarator in the beginning of a declarator
- // list. Example of a declaration that will be changed:
- // float, a;
- // will be changed to
- // float a;
- // This applies also to struct declarations.
- TIntermSequence emptyReplacement;
- mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(node, sym, emptyReplacement));
+ mMultiReplacements.push_back(
+ NodeReplaceWithMultipleEntry(parentAsBlock, node, emptyReplacement));
}
- else if (sym->getBasicType() != EbtStruct)
+ else
{
- // Single struct declarations may just declare the struct type and no variables, so they should
- // not be pruned. All other single empty declarations can be pruned entirely. Example of an empty
- // declaration that will be pruned:
- // float;
- TIntermSequence emptyReplacement;
- TIntermBlock *parentAsBlock = getParentNode()->getAsBlock();
- // The declaration may be inside a block or in a loop init expression.
- ASSERT(parentAsBlock != nullptr || getParentNode()->getAsLoopNode() != nullptr);
- if (parentAsBlock)
- {
- mMultiReplacements.push_back(
- NodeReplaceWithMultipleEntry(parentAsBlock, node, emptyReplacement));
- }
- else
- {
- queueReplacement(node, nullptr, OriginalNode::IS_DROPPED);
- }
+ queueReplacement(node, nullptr, OriginalNode::IS_DROPPED);
}
- else if (sym->getType().getQualifier() != EvqGlobal &&
- sym->getType().getQualifier() != EvqTemporary)
- {
- // We've hit an empty struct declaration with a qualifier, for example like
- // this:
- // const struct a { int i; };
- // NVIDIA GL driver version 367.27 doesn't accept this kind of declarations, so
- // we convert the declaration to a regular struct declaration. This is okay,
- // since ESSL 1.00 spec section 4.1.8 says about structs that "The optional
- // qualifiers only apply to any declarators, and are not part of the type being
- // defined for name."
+ }
+ else if (sym->getType().getQualifier() != EvqGlobal &&
+ sym->getType().getQualifier() != EvqTemporary)
+ {
+ // We've hit an empty struct declaration with a qualifier, for example like
+ // this:
+ // const struct a { int i; };
+ // NVIDIA GL driver version 367.27 doesn't accept this kind of declarations, so
+ // we convert the declaration to a regular struct declaration. This is okay,
+ // since ESSL 1.00 spec section 4.1.8 says about structs that "The optional
+ // qualifiers only apply to any declarators, and are not part of the type being
+ // defined for name."
- if (mInGlobalScope)
- {
- sym->getTypePointer()->setQualifier(EvqGlobal);
- }
- else
- {
- sym->getTypePointer()->setQualifier(EvqTemporary);
- }
+ if (mInGlobalScope)
+ {
+ sym->getTypePointer()->setQualifier(EvqGlobal);
+ }
+ else
+ {
+ sym->getTypePointer()->setQualifier(EvqTemporary);
}
}
}
- return false;
}
- return true;
+ return false;
}
} // namespace
diff --git a/src/compiler/translator/RemoveDynamicIndexing.cpp b/src/compiler/translator/RemoveDynamicIndexing.cpp
index 994ae31..ad2d08a 100644
--- a/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -390,7 +390,7 @@
// Now v_expr[s0] can be safely executed several times without unintended side effects.
// Init the temp variable holding the index
- TIntermAggregate *initIndex = createTempInitDeclaration(node->getRight());
+ TIntermDeclaration *initIndex = createTempInitDeclaration(node->getRight());
insertStatementInParentBlock(initIndex);
mUsedTreeInsertion = true;
@@ -441,7 +441,7 @@
// Store the index in a temporary signed int variable.
TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight());
- TIntermAggregate *initIndex = createTempInitDeclaration(indexInitializer);
+ TIntermDeclaration *initIndex = createTempInitDeclaration(indexInitializer);
initIndex->setLine(node->getLine());
insertionsBefore.push_back(initIndex);
diff --git a/src/compiler/translator/RewriteDoWhile.cpp b/src/compiler/translator/RewriteDoWhile.cpp
index 9cc551b..7336e5c 100644
--- a/src/compiler/translator/RewriteDoWhile.cpp
+++ b/src/compiler/translator/RewriteDoWhile.cpp
@@ -67,7 +67,7 @@
TType boolType = TType(EbtBool);
// bool temp = false;
- TIntermAggregate *tempDeclaration = nullptr;
+ TIntermDeclaration *tempDeclaration = nullptr;
{
TConstantUnion *falseConstant = new TConstantUnion();
falseConstant->setBConst(false);
diff --git a/src/compiler/translator/RewriteElseBlocks.cpp b/src/compiler/translator/RewriteElseBlocks.cpp
index aafb86f..937de11 100644
--- a/src/compiler/translator/RewriteElseBlocks.cpp
+++ b/src/compiler/translator/RewriteElseBlocks.cpp
@@ -70,8 +70,7 @@
nextTemporaryIndex();
- TIntermTyped *typedCondition = ifElse->getCondition()->getAsTyped();
- TIntermAggregate *storeCondition = createTempInitDeclaration(typedCondition);
+ TIntermDeclaration *storeCondition = createTempInitDeclaration(ifElse->getCondition());
TIntermBlock *falseBlock = nullptr;
diff --git a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
index 96789bd..f12afa4 100644
--- a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
+++ b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
@@ -265,8 +265,8 @@
TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type);
TIntermBinary *init = new TIntermBinary(EOpInitialize, symbolNode, original);
- TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration);
- decl->getSequence()->push_back(init);
+ TIntermDeclaration *decl = new TIntermDeclaration();
+ decl->appendDeclarator(init);
ASSERT(mBlockStack.size() > 0);
TIntermSequence &sequence = mBlockStack.back();
diff --git a/src/compiler/translator/SeparateArrayInitialization.cpp b/src/compiler/translator/SeparateArrayInitialization.cpp
index 8cd1fa1..2c853e3 100644
--- a/src/compiler/translator/SeparateArrayInitialization.cpp
+++ b/src/compiler/translator/SeparateArrayInitialization.cpp
@@ -29,7 +29,7 @@
static void apply(TIntermNode *root);
private:
SeparateArrayInitTraverser();
- bool visitAggregate(Visit, TIntermAggregate *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
};
void SeparateArrayInitTraverser::apply(TIntermNode *root)
@@ -44,43 +44,38 @@
{
}
-bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node)
+bool SeparateArrayInitTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
{
- if (node->getOp() == EOpDeclaration)
+ TIntermSequence *sequence = node->getSequence();
+ TIntermBinary *initNode = sequence->back()->getAsBinaryNode();
+ if (initNode != nullptr && initNode->getOp() == EOpInitialize)
{
- TIntermSequence *sequence = node->getSequence();
- TIntermBinary *initNode = sequence->back()->getAsBinaryNode();
- if (initNode != nullptr && initNode->getOp() == EOpInitialize)
+ TIntermTyped *initializer = initNode->getRight();
+ if (initializer->isArray() && !sh::OutputHLSL::canWriteAsHLSLLiteral(initializer))
{
- TIntermTyped *initializer = initNode->getRight();
- if (initializer->isArray() && !sh::OutputHLSL::canWriteAsHLSLLiteral(initializer))
- {
- // We rely on that array declarations have been isolated to single declarations.
- ASSERT(sequence->size() == 1);
- TIntermTyped *symbol = initNode->getLeft();
- TIntermBlock *parentBlock = getParentNode()->getAsBlock();
- ASSERT(parentBlock != nullptr);
+ // We rely on that array declarations have been isolated to single declarations.
+ ASSERT(sequence->size() == 1);
+ TIntermTyped *symbol = initNode->getLeft();
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ ASSERT(parentBlock != nullptr);
- TIntermSequence replacements;
+ TIntermSequence replacements;
- TIntermAggregate *replacementDeclaration = new TIntermAggregate;
- replacementDeclaration->setOp(EOpDeclaration);
- replacementDeclaration->getSequence()->push_back(symbol);
- replacementDeclaration->setLine(symbol->getLine());
- replacements.push_back(replacementDeclaration);
+ TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
+ replacementDeclaration->appendDeclarator(symbol);
+ replacementDeclaration->setLine(symbol->getLine());
+ replacements.push_back(replacementDeclaration);
- TIntermBinary *replacementAssignment =
- new TIntermBinary(EOpAssign, symbol, initializer);
- replacementAssignment->setLine(symbol->getLine());
- replacements.push_back(replacementAssignment);
+ TIntermBinary *replacementAssignment =
+ new TIntermBinary(EOpAssign, symbol, initializer);
+ replacementAssignment->setLine(symbol->getLine());
+ replacements.push_back(replacementAssignment);
- mMultiReplacements.push_back(
- NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
- }
+ mMultiReplacements.push_back(
+ NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
}
- return false;
}
- return true;
+ return false;
}
} // namespace
diff --git a/src/compiler/translator/SeparateDeclarations.cpp b/src/compiler/translator/SeparateDeclarations.cpp
index cc339ea..a6aab22 100644
--- a/src/compiler/translator/SeparateDeclarations.cpp
+++ b/src/compiler/translator/SeparateDeclarations.cpp
@@ -26,7 +26,7 @@
static void apply(TIntermNode *root);
private:
SeparateDeclarationsTraverser();
- bool visitAggregate(Visit, TIntermAggregate *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
};
void SeparateDeclarationsTraverser::apply(TIntermNode *root)
@@ -41,33 +41,28 @@
{
}
-bool SeparateDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node)
+bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
{
- if (node->getOp() == EOpDeclaration)
+ TIntermSequence *sequence = node->getSequence();
+ if (sequence->size() > 1)
{
- TIntermSequence *sequence = node->getSequence();
- if (sequence->size() > 1)
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ ASSERT(parentBlock != nullptr);
+
+ TIntermSequence replacementDeclarations;
+ for (size_t ii = 0; ii < sequence->size(); ++ii)
{
- TIntermBlock *parentBlock = getParentNode()->getAsBlock();
- ASSERT(parentBlock != nullptr);
+ TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
- TIntermSequence replacementDeclarations;
- for (size_t ii = 0; ii < sequence->size(); ++ii)
- {
- TIntermAggregate *replacementDeclaration = new TIntermAggregate;
-
- replacementDeclaration->setOp(EOpDeclaration);
- replacementDeclaration->getSequence()->push_back(sequence->at(ii));
- replacementDeclaration->setLine(sequence->at(ii)->getLine());
- replacementDeclarations.push_back(replacementDeclaration);
- }
-
- mMultiReplacements.push_back(
- NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations));
+ replacementDeclaration->appendDeclarator(sequence->at(ii)->getAsTyped());
+ replacementDeclaration->setLine(sequence->at(ii)->getLine());
+ replacementDeclarations.push_back(replacementDeclaration);
}
- return false;
+
+ mMultiReplacements.push_back(
+ NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations));
}
- return true;
+ return false;
}
} // namespace
diff --git a/src/compiler/translator/UnfoldShortCircuitToIf.cpp b/src/compiler/translator/UnfoldShortCircuitToIf.cpp
index 712f59a..a221bdf 100644
--- a/src/compiler/translator/UnfoldShortCircuitToIf.cpp
+++ b/src/compiler/translator/UnfoldShortCircuitToIf.cpp
@@ -134,9 +134,7 @@
// Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
TIntermSequence insertions;
- TIntermSymbol *tempSymbol = createTempSymbol(node->getType());
- TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
- tempDeclaration->getSequence()->push_back(tempSymbol);
+ TIntermDeclaration *tempDeclaration = createTempDeclaration(node->getType());
insertions.push_back(tempDeclaration);
TIntermBlock *trueBlock = new TIntermBlock();
diff --git a/src/compiler/translator/ValidateLimitations.cpp b/src/compiler/translator/ValidateLimitations.cpp
index 5dcfe69..660436b 100644
--- a/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/compiler/translator/ValidateLimitations.cpp
@@ -213,8 +213,8 @@
// init-declaration has the form:
// type-specifier identifier = constant-expression
//
- TIntermAggregate *decl = init->getAsAggregate();
- if ((decl == NULL) || (decl->getOp() != EOpDeclaration))
+ TIntermDeclaration *decl = init->getAsDeclarationNode();
+ if (decl == nullptr)
{
error(init->getLine(), "Invalid init declaration", "for");
return -1;
diff --git a/src/compiler/translator/VariableInfo.cpp b/src/compiler/translator/VariableInfo.cpp
index 7e1e5cd..07fe12e 100644
--- a/src/compiler/translator/VariableInfo.cpp
+++ b/src/compiler/translator/VariableInfo.cpp
@@ -559,54 +559,43 @@
}
}
-bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
+bool CollectVariables::visitDeclaration(Visit, TIntermDeclaration *node)
{
- bool visitChildren = true;
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT(!sequence.empty());
- switch (node->getOp())
+ const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
+ TQualifier qualifier = typedNode.getQualifier();
+
+ if (typedNode.getBasicType() == EbtInterfaceBlock)
{
- case EOpDeclaration:
+ visitInfoList(sequence, mInterfaceBlocks);
+ return false;
+ }
+ else if (qualifier == EvqAttribute || qualifier == EvqVertexIn || qualifier == EvqFragmentOut ||
+ qualifier == EvqUniform || IsVarying(qualifier))
+ {
+ switch (qualifier)
{
- const TIntermSequence &sequence = *(node->getSequence());
- ASSERT(!sequence.empty());
-
- const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
- TQualifier qualifier = typedNode.getQualifier();
-
- if (typedNode.getBasicType() == EbtInterfaceBlock)
- {
- visitInfoList(sequence, mInterfaceBlocks);
- visitChildren = false;
- }
- else if (qualifier == EvqAttribute || qualifier == EvqVertexIn ||
- qualifier == EvqFragmentOut || qualifier == EvqUniform ||
- IsVarying(qualifier))
- {
- switch (qualifier)
- {
- case EvqAttribute:
- case EvqVertexIn:
- visitInfoList(sequence, mAttribs);
- break;
- case EvqFragmentOut:
- visitInfoList(sequence, mOutputVariables);
- break;
- case EvqUniform:
- visitInfoList(sequence, mUniforms);
- break;
- default:
- visitInfoList(sequence, mVaryings);
- break;
- }
-
- visitChildren = false;
- }
- break;
+ case EvqAttribute:
+ case EvqVertexIn:
+ visitInfoList(sequence, mAttribs);
+ break;
+ case EvqFragmentOut:
+ visitInfoList(sequence, mOutputVariables);
+ break;
+ case EvqUniform:
+ visitInfoList(sequence, mUniforms);
+ break;
+ default:
+ visitInfoList(sequence, mVaryings);
+ break;
}
- default: break;
+
+ return false;
}
- return visitChildren;
+ return true;
}
bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
diff --git a/src/compiler/translator/VariableInfo.h b/src/compiler/translator/VariableInfo.h
index f79035d..6b21156 100644
--- a/src/compiler/translator/VariableInfo.h
+++ b/src/compiler/translator/VariableInfo.h
@@ -31,7 +31,7 @@
const TExtensionBehavior &extensionBehavior);
void visitSymbol(TIntermSymbol *symbol) override;
- bool visitAggregate(Visit, TIntermAggregate *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
private:
diff --git a/src/compiler/translator/VersionGLSL.cpp b/src/compiler/translator/VersionGLSL.cpp
index 5c0c519..b967065 100644
--- a/src/compiler/translator/VersionGLSL.cpp
+++ b/src/compiler/translator/VersionGLSL.cpp
@@ -62,21 +62,22 @@
}
}
+bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ if (sequence.front()->getAsTyped()->getType().isInvariant())
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ return true;
+}
+
bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
{
bool visitChildren = true;
switch (node->getOp())
{
- case EOpDeclaration:
- {
- const TIntermSequence &sequence = *(node->getSequence());
- if (sequence.front()->getAsTyped()->getType().isInvariant())
- {
- ensureVersionIsAtLeast(GLSL_VERSION_120);
- }
- break;
- }
case EOpInvariantDeclaration:
ensureVersionIsAtLeast(GLSL_VERSION_120);
break;
diff --git a/src/compiler/translator/VersionGLSL.h b/src/compiler/translator/VersionGLSL.h
index c41069d..f03a48b 100644
--- a/src/compiler/translator/VersionGLSL.h
+++ b/src/compiler/translator/VersionGLSL.h
@@ -58,6 +58,7 @@
void visitSymbol(TIntermSymbol *) override;
bool visitAggregate(Visit, TIntermAggregate *) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
private:
void ensureVersionIsAtLeast(int version);
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index d1132c6..0aa15ec 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -77,6 +77,7 @@
TIntermTyped* intermTypedNode;
TIntermAggregate* intermAggregate;
TIntermBlock* intermBlock;
+ TIntermDeclaration* intermDeclaration;
TIntermSwitch* intermSwitch;
TIntermCase* intermCase;
};
@@ -606,10 +607,7 @@
$$ = context->addFunctionPrototypeDeclaration(*($1.function), @1);
}
| init_declarator_list SEMICOLON {
- TIntermAggregate *aggNode = $1.intermAggregate;
- if (aggNode && aggNode->getOp() == EOpNull)
- aggNode->setOp(EOpDeclaration);
- $$ = aggNode;
+ $$ = $1.intermDeclaration;
}
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) {
@@ -762,54 +760,54 @@
}
| init_declarator_list COMMA identifier {
$$ = $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 {
$$ = $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 {
ES3_OR_NEWER("[]", @3, "implicitly sized array");
$$ = $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 {
ES3_OR_NEWER("=", @7, "first-class arrays (array initializer)");
$$ = $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 {
$$ = $1;
- $$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5);
+ context->parseInitDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration);
}
;
single_declaration
: fully_specified_type {
$$.type = $1;
- $$.intermAggregate = context->parseSingleDeclaration($$.type, @1, "");
+ $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, "");
}
| fully_specified_type identifier {
$$.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 {
$$.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 {
ES3_OR_NEWER("[]", @3, "implicitly sized array");
$$.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 {
ES3_OR_NEWER("=", @6, "first-class arrays (array initializer)");
$$.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 {
$$.type = $1;
- $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
+ $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
}
;
@@ -1416,10 +1414,10 @@
context->checkIsScalarBool($1->getLine(), $1);
}
| fully_specified_type identifier EQUAL initializer {
- TIntermNode *intermNode;
+ TIntermBinary *initNode = nullptr;
context->checkIsScalarBool(@2, $1);
- if (!context->executeInitializer(@2, *$2.string, $1, $4, &intermNode))
+ if (!context->executeInitializer(@2, *$2.string, $1, $4, &initNode))
$$ = $4;
else {
$$ = 0;
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 4f7007d..aa62e48 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -306,6 +306,7 @@
TIntermTyped* intermTypedNode;
TIntermAggregate* intermAggregate;
TIntermBlock* intermBlock;
+ TIntermDeclaration* intermDeclaration;
TIntermSwitch* intermSwitch;
TIntermCase* intermCase;
};
@@ -729,35 +730,35 @@
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 240, 240, 241, 244, 254, 257, 262, 267, 272,
- 277, 283, 286, 289, 292, 295, 298, 304, 311, 322,
- 326, 334, 337, 343, 347, 354, 360, 369, 377, 383,
- 389, 398, 401, 404, 407, 417, 418, 419, 420, 428,
- 429, 432, 435, 442, 443, 446, 452, 453, 457, 464,
- 465, 468, 471, 474, 480, 481, 484, 490, 491, 498,
- 499, 506, 507, 514, 515, 521, 522, 528, 529, 535,
- 536, 542, 543, 550, 551, 552, 553, 557, 558, 559,
- 563, 567, 571, 575, 582, 585, 591, 598, 605, 608,
- 614, 623, 627, 631, 635, 639, 646, 653, 656, 663,
- 671, 691, 701, 709, 734, 738, 742, 746, 753, 760,
- 763, 767, 771, 776, 781, 788, 792, 796, 800, 805,
- 810, 817, 827, 833, 836, 842, 846, 853, 859, 863,
- 867, 870, 873, 882, 888, 896, 899, 919, 938, 945,
- 949, 953, 956, 962, 972, 975, 978, 984, 991, 994,
- 1000, 1003, 1006, 1012, 1015, 1020, 1031, 1034, 1037, 1040,
- 1043, 1046, 1050, 1054, 1058, 1062, 1066, 1070, 1074, 1078,
- 1082, 1086, 1090, 1094, 1098, 1102, 1106, 1110, 1114, 1118,
- 1122, 1126, 1130, 1133, 1136, 1139, 1142, 1145, 1148, 1151,
- 1154, 1157, 1160, 1163, 1166, 1169, 1172, 1175, 1182, 1188,
- 1191, 1194, 1197, 1200, 1203, 1206, 1209, 1212, 1215, 1218,
- 1221, 1224, 1227, 1239, 1239, 1242, 1242, 1248, 1251, 1266,
- 1269, 1276, 1280, 1286, 1292, 1304, 1308, 1312, 1313, 1319,
- 1320, 1321, 1322, 1323, 1324, 1325, 1329, 1330, 1330, 1330,
- 1339, 1340, 1344, 1344, 1345, 1345, 1350, 1353, 1362, 1367,
- 1374, 1375, 1379, 1386, 1390, 1397, 1397, 1404, 1407, 1414,
- 1418, 1431, 1431, 1436, 1436, 1442, 1442, 1450, 1453, 1459,
- 1462, 1468, 1472, 1479, 1482, 1485, 1488, 1491, 1500, 1506,
- 1512, 1515, 1521, 1521
+ 0, 241, 241, 242, 245, 255, 258, 263, 268, 273,
+ 278, 284, 287, 290, 293, 296, 299, 305, 312, 323,
+ 327, 335, 338, 344, 348, 355, 361, 370, 378, 384,
+ 390, 399, 402, 405, 408, 418, 419, 420, 421, 429,
+ 430, 433, 436, 443, 444, 447, 453, 454, 458, 465,
+ 466, 469, 472, 475, 481, 482, 485, 491, 492, 499,
+ 500, 507, 508, 515, 516, 522, 523, 529, 530, 536,
+ 537, 543, 544, 551, 552, 553, 554, 558, 559, 560,
+ 564, 568, 572, 576, 583, 586, 592, 599, 606, 609,
+ 612, 621, 625, 629, 633, 637, 644, 651, 654, 661,
+ 669, 689, 699, 707, 732, 736, 740, 744, 751, 758,
+ 761, 765, 769, 774, 779, 786, 790, 794, 798, 803,
+ 808, 815, 825, 831, 834, 840, 844, 851, 857, 861,
+ 865, 868, 871, 880, 886, 894, 897, 917, 936, 943,
+ 947, 951, 954, 960, 970, 973, 976, 982, 989, 992,
+ 998, 1001, 1004, 1010, 1013, 1018, 1029, 1032, 1035, 1038,
+ 1041, 1044, 1048, 1052, 1056, 1060, 1064, 1068, 1072, 1076,
+ 1080, 1084, 1088, 1092, 1096, 1100, 1104, 1108, 1112, 1116,
+ 1120, 1124, 1128, 1131, 1134, 1137, 1140, 1143, 1146, 1149,
+ 1152, 1155, 1158, 1161, 1164, 1167, 1170, 1173, 1180, 1186,
+ 1189, 1192, 1195, 1198, 1201, 1204, 1207, 1210, 1213, 1216,
+ 1219, 1222, 1225, 1237, 1237, 1240, 1240, 1246, 1249, 1264,
+ 1267, 1274, 1278, 1284, 1290, 1302, 1306, 1310, 1311, 1317,
+ 1318, 1319, 1320, 1321, 1322, 1323, 1327, 1328, 1328, 1328,
+ 1337, 1338, 1342, 1342, 1343, 1343, 1348, 1351, 1360, 1365,
+ 1372, 1373, 1377, 1384, 1388, 1395, 1395, 1402, 1405, 1412,
+ 1416, 1429, 1429, 1434, 1434, 1440, 1440, 1448, 1451, 1457,
+ 1460, 1466, 1470, 1477, 1480, 1483, 1486, 1489, 1498, 1504,
+ 1510, 1513, 1519, 1519
};
#endif
@@ -3143,10 +3144,7 @@
case 89:
{
- TIntermAggregate *aggNode = (yyvsp[-1].interm).intermAggregate;
- if (aggNode && aggNode->getOp() == EOpNull)
- aggNode->setOp(EOpDeclaration);
- (yyval.interm.intermNode) = aggNode;
+ (yyval.interm.intermNode) = (yyvsp[-1].interm).intermDeclaration;
}
break;
@@ -3369,7 +3367,7 @@
{
(yyval.interm) = (yyvsp[-2].interm);
- (yyval.interm).intermAggregate = context->parseDeclarator((yyval.interm).type, (yyvsp[-2].interm).intermAggregate, (yylsp[0]), *(yyvsp[0].lex).string);
+ context->parseDeclarator((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string, (yyval.interm).intermDeclaration);
}
break;
@@ -3378,7 +3376,7 @@
{
(yyval.interm) = (yyvsp[-5].interm);
- (yyval.interm).intermAggregate = context->parseArrayDeclarator((yyval.interm).type, (yyvsp[-5].interm).intermAggregate, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+ context->parseArrayDeclarator((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode), (yyval.interm).intermDeclaration);
}
break;
@@ -3388,7 +3386,7 @@
{
ES3_OR_NEWER("[]", (yylsp[-4]), "implicitly sized array");
(yyval.interm) = (yyvsp[-6].interm);
- (yyval.interm).intermAggregate = context->parseArrayInitDeclarator((yyval.interm).type, (yyvsp[-6].interm).intermAggregate, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ context->parseArrayInitDeclarator((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
}
break;
@@ -3398,7 +3396,7 @@
{
ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
(yyval.interm) = (yyvsp[-7].interm);
- (yyval.interm).intermAggregate = context->parseArrayInitDeclarator((yyval.interm).type, (yyvsp[-7].interm).intermAggregate, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ context->parseArrayInitDeclarator((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
}
break;
@@ -3407,7 +3405,7 @@
{
(yyval.interm) = (yyvsp[-4].interm);
- (yyval.interm).intermAggregate = context->parseInitDeclarator((yyval.interm).type, (yyvsp[-4].interm).intermAggregate, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ context->parseInitDeclarator((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
}
break;
@@ -3416,7 +3414,7 @@
{
(yyval.interm).type = (yyvsp[0].interm.type);
- (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), "");
+ (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), "");
}
break;
@@ -3425,7 +3423,7 @@
{
(yyval.interm).type = (yyvsp[-1].interm.type);
- (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string);
+ (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string);
}
break;
@@ -3434,7 +3432,7 @@
{
(yyval.interm).type = (yyvsp[-4].interm.type);
- (yyval.interm).intermAggregate = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+ (yyval.interm).intermDeclaration = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
}
break;
@@ -3444,7 +3442,7 @@
{
ES3_OR_NEWER("[]", (yylsp[-3]), "implicitly sized array");
(yyval.interm).type = (yyvsp[-5].interm.type);
- (yyval.interm).intermAggregate = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3454,7 +3452,7 @@
{
ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
(yyval.interm).type = (yyvsp[-6].interm.type);
- (yyval.interm).intermAggregate = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3463,7 +3461,7 @@
{
(yyval.interm).type = (yyvsp[-3].interm.type);
- (yyval.interm).intermAggregate = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).intermDeclaration = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -4672,10 +4670,10 @@
case 260:
{
- TIntermNode *intermNode;
+ TIntermBinary *initNode = nullptr;
context->checkIsScalarBool((yylsp[-2]), (yyvsp[-3].interm.type));
- if (!context->executeInitializer((yylsp[-2]), *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), (yyvsp[0].interm.intermTypedNode), &intermNode))
+ if (!context->executeInitializer((yylsp[-2]), *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), (yyvsp[0].interm.intermTypedNode), &initNode))
(yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
else {
(yyval.interm.intermTypedNode) = 0;
diff --git a/src/compiler/translator/glslang_tab.h b/src/compiler/translator/glslang_tab.h
index 09025b0..707d946 100644
--- a/src/compiler/translator/glslang_tab.h
+++ b/src/compiler/translator/glslang_tab.h
@@ -219,6 +219,7 @@
TIntermTyped* intermTypedNode;
TIntermAggregate* intermAggregate;
TIntermBlock *intermBlock;
+ TIntermDeclaration *intermDeclaration;
TIntermSwitch* intermSwitch;
TIntermCase* intermCase;
};
diff --git a/src/compiler/translator/intermOut.cpp b/src/compiler/translator/intermOut.cpp
index 352fde3..9767c9f 100644
--- a/src/compiler/translator/intermOut.cpp
+++ b/src/compiler/translator/intermOut.cpp
@@ -53,6 +53,7 @@
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *) override;
bool visitBlock(Visit visit, TIntermBlock *) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
bool visitLoop(Visit visit, TIntermLoop *) override;
bool visitBranch(Visit visit, TIntermBranch *) override;
};
@@ -467,7 +468,6 @@
case EOpOuterProduct: out << "outer product"; break;
- case EOpDeclaration: out << "Declaration: "; break;
case EOpInvariantDeclaration: out << "Invariant Declaration: "; break;
default:
@@ -493,6 +493,16 @@
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)
{
TInfoSinkBase &out = sink;