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/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)
{