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