Remove simple Intermediate.h functions
Most of the functions were just simple wrappers around node
constructors. Dropping this extra redirection makes the code simpler.
The fold() functions of node types are simplified, so that if the node
can't be folded the pointer to the node itself is returned. This makes
the code in ParseContext more straightforward.
The few remaining functions in Intermediate are a bit more complex so
they should be handled separately, but they'll be removed eventually
as well.
BUG=angleproject:1490
TEST=angle_unittests
Change-Id: I85e11919d1f62358cfba9c011b841e32bc25402f
Reviewed-on: https://chromium-review.googlesource.com/563393
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index c1e8f3e..8b04ae2 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -176,21 +176,19 @@
{
}
-//
-// Look at a '.' field selector string and change it into offsets
-// for a vector.
-//
-bool TParseContext::parseVectorFields(const TString &compString,
+bool TParseContext::parseVectorFields(const TSourceLoc &line,
+ const TString &compString,
int vecSize,
- TVectorFields &fields,
- const TSourceLoc &line)
+ TVector<int> *fieldOffsets)
{
- fields.num = (int)compString.size();
- if (fields.num > 4)
+ ASSERT(fieldOffsets);
+ size_t fieldCount = compString.size();
+ if (fieldCount > 4u)
{
error(line, "illegal vector field selection", compString.c_str());
return false;
}
+ fieldOffsets->resize(fieldCount);
enum
{
@@ -199,57 +197,57 @@
estpq
} fieldSet[4];
- for (int i = 0; i < fields.num; ++i)
+ for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
{
switch (compString[i])
{
case 'x':
- fields.offsets[i] = 0;
+ (*fieldOffsets)[i] = 0;
fieldSet[i] = exyzw;
break;
case 'r':
- fields.offsets[i] = 0;
+ (*fieldOffsets)[i] = 0;
fieldSet[i] = ergba;
break;
case 's':
- fields.offsets[i] = 0;
+ (*fieldOffsets)[i] = 0;
fieldSet[i] = estpq;
break;
case 'y':
- fields.offsets[i] = 1;
+ (*fieldOffsets)[i] = 1;
fieldSet[i] = exyzw;
break;
case 'g':
- fields.offsets[i] = 1;
+ (*fieldOffsets)[i] = 1;
fieldSet[i] = ergba;
break;
case 't':
- fields.offsets[i] = 1;
+ (*fieldOffsets)[i] = 1;
fieldSet[i] = estpq;
break;
case 'z':
- fields.offsets[i] = 2;
+ (*fieldOffsets)[i] = 2;
fieldSet[i] = exyzw;
break;
case 'b':
- fields.offsets[i] = 2;
+ (*fieldOffsets)[i] = 2;
fieldSet[i] = ergba;
break;
case 'p':
- fields.offsets[i] = 2;
+ (*fieldOffsets)[i] = 2;
fieldSet[i] = estpq;
break;
case 'w':
- fields.offsets[i] = 3;
+ (*fieldOffsets)[i] = 3;
fieldSet[i] = exyzw;
break;
case 'a':
- fields.offsets[i] = 3;
+ (*fieldOffsets)[i] = 3;
fieldSet[i] = ergba;
break;
case 'q':
- fields.offsets[i] = 3;
+ (*fieldOffsets)[i] = 3;
fieldSet[i] = estpq;
break;
default:
@@ -258,9 +256,9 @@
}
}
- for (int i = 0; i < fields.num; ++i)
+ for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
{
- if (fields.offsets[i] >= vecSize)
+ if ((*fieldOffsets)[i] >= vecSize)
{
error(line, "vector field selection out of range", compString.c_str());
return false;
@@ -1682,8 +1680,10 @@
}
else
{
- return intermediate.addSymbol(variable->getUniqueId(), variable->getName(),
- variable->getType(), location);
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(variable->getUniqueId(), variable->getName(), variable->getType());
+ symbolNode->setLine(location);
+ return symbolNode;
}
}
@@ -1800,8 +1800,9 @@
}
}
- TIntermSymbol *intermSymbol = intermediate.addSymbol(
- variable->getUniqueId(), variable->getName(), variable->getType(), line);
+ TIntermSymbol *intermSymbol =
+ new TIntermSymbol(variable->getUniqueId(), variable->getName(), variable->getType());
+ intermSymbol->setLine(line);
*initNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
if (*initNode == nullptr)
{
@@ -2188,7 +2189,7 @@
// But if the empty declaration is declaring a struct type, the symbol node will store that.
if (type.getBasicType() == EbtStruct)
{
- symbol = intermediate.addSymbol(0, "", type, identifierOrTypeLocation);
+ symbol = new TIntermSymbol(0, "", type);
}
else if (IsAtomicCounter(publicType.getBasicType()))
{
@@ -2213,8 +2214,7 @@
if (variable)
{
- symbol = intermediate.addSymbol(variable->getUniqueId(), identifier, type,
- identifierOrTypeLocation);
+ symbol = new TIntermSymbol(variable->getUniqueId(), identifier, type);
}
}
@@ -2222,6 +2222,7 @@
declaration->setLine(identifierOrTypeLocation);
if (symbol)
{
+ symbol->setLine(identifierOrTypeLocation);
declaration->appendDeclarator(symbol);
}
return declaration;
@@ -2263,10 +2264,10 @@
TIntermDeclaration *declaration = new TIntermDeclaration();
declaration->setLine(identifierLocation);
- TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
- if (variable && symbol)
+ if (variable)
{
- symbol->setId(variable->getUniqueId());
+ TIntermSymbol *symbol = new TIntermSymbol(variable->getUniqueId(), identifier, arrayType);
+ symbol->setLine(identifierLocation);
declaration->appendDeclarator(symbol);
}
@@ -2394,8 +2395,8 @@
symbolTable.addInvariantVarying(std::string(identifier->c_str()));
- TIntermSymbol *intermSymbol =
- intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc);
+ TIntermSymbol *intermSymbol = new TIntermSymbol(variable->getUniqueId(), *identifier, type);
+ intermSymbol->setLine(identifierLoc);
return new TIntermInvariantDeclaration(intermSymbol, identifierLoc);
}
@@ -2426,10 +2427,10 @@
}
declareVariable(identifierLocation, identifier, type, &variable);
- TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, type, identifierLocation);
- if (variable && symbol)
+ if (variable)
{
- symbol->setId(variable->getUniqueId());
+ TIntermSymbol *symbol = new TIntermSymbol(variable->getUniqueId(), identifier, type);
+ symbol->setLine(identifierLocation);
declarationOut->appendDeclarator(symbol);
}
}
@@ -2468,9 +2469,9 @@
TVariable *variable = nullptr;
declareVariable(identifierLocation, identifier, arrayType, &variable);
- TIntermSymbol *symbol =
- intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
- if (variable && symbol)
+ TIntermSymbol *symbol = new TIntermSymbol(0, identifier, arrayType);
+ symbol->setLine(identifierLocation);
+ if (variable)
symbol->setId(variable->getUniqueId());
declarationOut->appendDeclarator(symbol);
@@ -2744,6 +2745,8 @@
{
const TConstParameter ¶m = function.getParam(i);
+ TIntermSymbol *symbol = nullptr;
+
// If the parameter has no name, it's not an error, just don't add it to symbol table (could
// be used for unused args).
if (param.name != nullptr)
@@ -2751,20 +2754,27 @@
TVariable *variable = new TVariable(param.name, *param.type);
// Insert the parameter in the symbol table.
- if (insertParametersToSymbolTable && !symbolTable.declare(variable))
+ if (insertParametersToSymbolTable)
{
- error(location, "redefinition", variable->getName().c_str());
- prototype->appendParameter(intermediate.addSymbol(0, "", *param.type, location));
- continue;
+ if (symbolTable.declare(variable))
+ {
+ symbol = new TIntermSymbol(variable->getUniqueId(), variable->getName(),
+ variable->getType());
+ }
+ else
+ {
+ error(location, "redefinition", variable->getName().c_str());
+ }
}
- TIntermSymbol *symbol = intermediate.addSymbol(
- variable->getUniqueId(), variable->getName(), variable->getType(), location);
- prototype->appendParameter(symbol);
}
- else
+ if (!symbol)
{
- prototype->appendParameter(intermediate.addSymbol(0, "", *param.type, location));
+ // The parameter had no name or declaring the symbol failed - either way, add a nameless
+ // symbol.
+ symbol = new TIntermSymbol(0, "", *param.type);
}
+ symbol->setLine(location);
+ prototype->appendParameter(symbol);
}
return prototype;
}
@@ -3075,13 +3085,11 @@
TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, arguments);
constructorNode->setLine(line);
- TIntermTyped *constConstructor =
- intermediate.foldAggregateBuiltIn(constructorNode, mDiagnostics);
- if (constConstructor)
+ // TODO(oetuaho@nvidia.com): Add support for folding array constructors.
+ if (!constructorNode->isArray())
{
- return constConstructor;
+ return constructorNode->fold(mDiagnostics);
}
-
return constructorNode;
}
@@ -3259,8 +3267,8 @@
symbolName = instanceTypeDef->getName();
}
- TIntermSymbol *blockSymbol =
- intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line);
+ TIntermSymbol *blockSymbol = new TIntermSymbol(symbolId, symbolName, interfaceBlockType);
+ blockSymbol->setLine(typeQualifier.line);
TIntermDeclaration *declaration = new TIntermDeclaration();
declaration->appendDeclarator(blockSymbol);
declaration->setLine(nameLine);
@@ -3427,13 +3435,16 @@
indexConstantUnion->replaceConstantUnion(safeConstantUnion);
}
- return intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location,
- mDiagnostics);
+ TIntermBinary *node = new TIntermBinary(EOpIndexDirect, baseExpression, indexExpression);
+ node->setLine(location);
+ return node->fold(mDiagnostics);
}
else
{
- return intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location,
- mDiagnostics);
+ TIntermBinary *node = new TIntermBinary(EOpIndexIndirect, baseExpression, indexExpression);
+ node->setLine(location);
+ // Indirect indexing can never be constant folded.
+ return node;
}
}
@@ -3474,15 +3485,17 @@
if (baseExpression->isVector())
{
- TVectorFields fields;
- if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields,
- fieldLocation))
+ TVector<int> fieldOffsets;
+ if (!parseVectorFields(fieldLocation, fieldString, baseExpression->getNominalSize(),
+ &fieldOffsets))
{
- fields.num = 1;
- fields.offsets[0] = 0;
+ fieldOffsets.resize(1);
+ fieldOffsets[0] = 0;
}
+ TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldOffsets);
+ node->setLine(dotLocation);
- return TIntermediate::AddSwizzle(baseExpression, fields, dotLocation);
+ return node->fold();
}
else if (baseExpression->getBasicType() == EbtStruct)
{
@@ -3508,8 +3521,10 @@
{
TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
index->setLine(fieldLocation);
- return intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index,
- dotLocation, mDiagnostics);
+ TIntermBinary *node =
+ new TIntermBinary(EOpIndexDirectStruct, baseExpression, index);
+ node->setLine(dotLocation);
+ return node->fold(mDiagnostics);
}
else
{
@@ -3542,8 +3557,11 @@
{
TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
index->setLine(fieldLocation);
- return intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index,
- dotLocation, mDiagnostics);
+ TIntermBinary *node =
+ new TIntermBinary(EOpIndexDirectInterfaceBlock, baseExpression, index);
+ node->setLine(dotLocation);
+ // Indexing interface blocks can never be constant folded.
+ return node;
}
else
{
@@ -4065,12 +4083,8 @@
}
}
- TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc);
- if (node == nullptr)
- {
- error(loc, "erroneous switch statement", "switch");
- return nullptr;
- }
+ TIntermSwitch *node = new TIntermSwitch(init, statementList);
+ node->setLine(loc);
return node;
}
@@ -4099,12 +4113,8 @@
{
error(condition->getLine(), "case label must be constant", "case");
}
- TIntermCase *node = intermediate.addCase(condition, loc);
- if (node == nullptr)
- {
- error(loc, "erroneous case statement", "case");
- return nullptr;
- }
+ TIntermCase *node = new TIntermCase(condition);
+ node->setLine(loc);
return node;
}
@@ -4115,12 +4125,8 @@
error(loc, "default labels need to be inside switch statements", "default");
return nullptr;
}
- TIntermCase *node = intermediate.addCase(nullptr, loc);
- if (node == nullptr)
- {
- error(loc, "erroneous default statement", "default");
- return nullptr;
- }
+ TIntermCase *node = new TIntermCase(nullptr);
+ node->setLine(loc);
return node;
}
@@ -4169,11 +4175,7 @@
TIntermUnary *node = new TIntermUnary(op, child);
node->setLine(loc);
- TIntermTyped *foldedNode = node->fold(mDiagnostics);
- if (foldedNode)
- return foldedNode;
-
- return node;
+ return node->fold(mDiagnostics);
}
TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
@@ -4529,11 +4531,7 @@
node->setLine(loc);
// See if we can fold constants.
- TIntermTyped *foldedNode = node->fold(mDiagnostics);
- if (foldedNode)
- return foldedNode;
-
- return node;
+ return node->fold(mDiagnostics);
}
TIntermTyped *TParseContext::addBinaryMath(TOperator op,
@@ -4623,7 +4621,10 @@
",");
}
- return TIntermediate::AddComma(left, right, loc, mShaderVersion);
+ TIntermBinary *commaNode = new TIntermBinary(EOpComma, left, right);
+ TQualifier resultQualifier = TIntermBinary::GetCommaQualifier(mShaderVersion, left, right);
+ commaNode->getTypePointer()->setQualifier(resultQualifier);
+ return commaNode->fold(mDiagnostics);
}
TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
@@ -4948,15 +4949,16 @@
// Some built-in functions have out parameters too.
functionCallLValueErrorCheck(fnCandidate, callNode);
- // See if we can constant fold a built-in. Note that this may be possible even
- // if it is not const-qualified.
- TIntermTyped *foldedNode =
- intermediate.foldAggregateBuiltIn(callNode, mDiagnostics);
- if (foldedNode)
+ if (TIntermAggregate::CanFoldAggregateBuiltInOp(callNode->getOp()))
{
- return foldedNode;
+ // See if we can constant fold a built-in. Note that this may be possible
+ // even if it is not const-qualified.
+ return callNode->fold(mDiagnostics);
}
- return callNode;
+ else
+ {
+ return callNode;
+ }
}
}
else
@@ -5002,8 +5004,12 @@
if (trueExpression->getType() != falseExpression->getType())
{
- binaryOpError(loc, "?:", trueExpression->getCompleteString(),
- falseExpression->getCompleteString());
+ std::stringstream reasonStream;
+ reasonStream << "mismatching ternary operator operand types '"
+ << trueExpression->getCompleteString() << " and '"
+ << falseExpression->getCompleteString() << "'";
+ std::string reason = reasonStream.str();
+ error(loc, reason.c_str(), "?:");
return falseExpression;
}
if (IsOpaqueType(trueExpression->getBasicType()))
@@ -5042,7 +5048,12 @@
return falseExpression;
}
- return TIntermediate::AddTernarySelection(cond, trueExpression, falseExpression, loc);
+ // Note that the node resulting from here can be a constant union without being qualified as
+ // constant.
+ TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
+ node->setLine(loc);
+
+ return node->fold();
}
//