Make aggregate node creation more robust
Now aggregate nodes are always built with their return type, op and
arguments set. They'll determine their qualifier and precision
automatically.
This fixes setting of gotPrecisionFromChildren in a few cases.
This will also make it easier to split TIntermAggregate further into
specialized classes if that is desired.
BUG=angleproject:1490
TEST=angle_unittests
Change-Id: I1fbe0c75679c517a22d44dfc1ea160ad7a7fdfda
Reviewed-on: https://chromium-review.googlesource.com/433468
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
index 3f0952f..1c7e604 100644
--- a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
@@ -43,17 +43,17 @@
TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall,
TIntermTyped *returnValueTarget)
{
- TIntermAggregate *replacementCall = new TIntermAggregate(EOpCallFunctionInAST);
- replacementCall->setType(TType(EbtVoid));
+ TIntermSequence *replacementArguments = new TIntermSequence();
+ TIntermSequence *originalArguments = originalCall->getSequence();
+ for (auto &arg : *originalArguments)
+ {
+ replacementArguments->push_back(arg);
+ }
+ replacementArguments->push_back(returnValueTarget);
+ TIntermAggregate *replacementCall =
+ new TIntermAggregate(TType(EbtVoid), EOpCallFunctionInAST, replacementArguments);
*replacementCall->getFunctionSymbolInfo() = *originalCall->getFunctionSymbolInfo();
replacementCall->setLine(originalCall->getLine());
- TIntermSequence *replacementParameters = replacementCall->getSequence();
- TIntermSequence *originalParameters = originalCall->getSequence();
- for (auto ¶m : *originalParameters)
- {
- replacementParameters->push_back(param);
- }
- replacementParameters->push_back(returnValueTarget);
return replacementCall;
}
diff --git a/src/compiler/translator/DeferGlobalInitializers.cpp b/src/compiler/translator/DeferGlobalInitializers.cpp
index 3e2224b..7353506 100644
--- a/src/compiler/translator/DeferGlobalInitializers.cpp
+++ b/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -50,10 +50,10 @@
TIntermAggregate *CreateFunctionCallNode(const char *name, const int functionId)
{
- TIntermAggregate *functionNode = new TIntermAggregate(EOpCallFunctionInAST);
- SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
TType returnType(EbtVoid);
- functionNode->setType(returnType);
+ TIntermAggregate *functionNode =
+ new TIntermAggregate(returnType, EOpCallFunctionInAST, nullptr);
+ SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
functionNode->getFunctionSymbolInfo()->setId(functionId);
return functionNode;
}
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index 1c9dc39..b8a5c9a 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -427,13 +427,14 @@
(type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium);
}
-TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *child)
+TIntermAggregate *createInternalFunctionCallNode(const TType &type,
+ TString name,
+ TIntermSequence *arguments)
{
- TIntermAggregate *callNode = new TIntermAggregate(EOpCallInternalRawFunction);
- TName nameObj(TFunction::mangleName(name));
+ TName nameObj(TFunction::GetMangledNameFromCall(name, *arguments));
nameObj.setInternal(true);
+ TIntermAggregate *callNode = new TIntermAggregate(type, EOpCallInternalRawFunction, arguments);
callNode->getFunctionSymbolInfo()->setNameObj(nameObj);
- callNode->getSequence()->push_back(child);
return callNode;
}
@@ -444,9 +445,9 @@
roundFunctionName = "angle_frm";
else
roundFunctionName = "angle_frl";
- TIntermAggregate *callNode = createInternalFunctionCallNode(roundFunctionName, roundedChild);
- callNode->setType(roundedChild->getType());
- return callNode;
+ TIntermSequence *arguments = new TIntermSequence();
+ arguments->push_back(roundedChild);
+ return createInternalFunctionCallNode(roundedChild->getType(), roundFunctionName, arguments);
}
TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
@@ -459,9 +460,10 @@
else
strstr << "angle_compound_" << opNameStr << "_frl";
TString functionName = strstr.str().c_str();
- TIntermAggregate *callNode = createInternalFunctionCallNode(functionName, left);
- callNode->getSequence()->push_back(right);
- return callNode;
+ TIntermSequence *arguments = new TIntermSequence();
+ arguments->push_back(left);
+ arguments->push_back(right);
+ return createInternalFunctionCallNode(TType(EbtVoid), functionName, arguments);
}
bool parentUsesResult(TIntermNode *parent, TIntermNode *node)
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 6bf2aa8..276b653 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -272,12 +272,48 @@
return true;
}
+TIntermAggregate::TIntermAggregate(const TType &type, TOperator op, TIntermSequence *arguments)
+ : TIntermOperator(op), mUseEmulatedFunction(false), mGotPrecisionFromChildren(false)
+{
+ if (arguments != nullptr)
+ {
+ mArguments.swap(*arguments);
+ }
+ setTypePrecisionAndQualifier(type);
+}
+
+void TIntermAggregate::setTypePrecisionAndQualifier(const TType &type)
+{
+ setType(type);
+ mType.setQualifier(EvqTemporary);
+ if (!isFunctionCall())
+ {
+ if (isConstructor())
+ {
+ // Structs should not be precision qualified, the individual members may be.
+ // Built-in types on the other hand should be precision qualified.
+ if (mOp != EOpConstructStruct)
+ {
+ setPrecisionFromChildren();
+ }
+ }
+ else
+ {
+ setPrecisionForBuiltInOp();
+ }
+ if (areChildrenConstQualified())
+ {
+ mType.setQualifier(EvqConst);
+ }
+ }
+}
+
bool TIntermAggregate::areChildrenConstQualified()
{
- for (TIntermNode *&child : mSequence)
+ for (TIntermNode *&arg : mArguments)
{
- TIntermTyped *typed = child->getAsTyped();
- if (typed && typed->getQualifier() != EvqConst)
+ TIntermTyped *typedArg = arg->getAsTyped();
+ if (typedArg && typedArg->getQualifier() != EvqConst)
{
return false;
}
@@ -295,8 +331,8 @@
}
TPrecision precision = EbpUndefined;
- TIntermSequence::iterator childIter = mSequence.begin();
- while (childIter != mSequence.end())
+ TIntermSequence::iterator childIter = mArguments.begin();
+ while (childIter != mArguments.end())
{
TIntermTyped *typed = (*childIter)->getAsTyped();
if (typed)
@@ -321,11 +357,13 @@
switch (mOp)
{
case EOpBitfieldExtract:
- mType.setPrecision(mSequence[0]->getAsTyped()->getPrecision());
+ mType.setPrecision(mArguments[0]->getAsTyped()->getPrecision());
+ mGotPrecisionFromChildren = true;
return true;
case EOpBitfieldInsert:
- mType.setPrecision(GetHigherPrecision(mSequence[0]->getAsTyped()->getPrecision(),
- mSequence[1]->getAsTyped()->getPrecision()));
+ mType.setPrecision(GetHigherPrecision(mArguments[0]->getAsTyped()->getPrecision(),
+ mArguments[1]->getAsTyped()->getPrecision()));
+ mGotPrecisionFromChildren = true;
return true;
case EOpUaddCarry:
case EOpUsubBorrow:
@@ -342,18 +380,16 @@
ASSERT(getBasicType() != EbtBool);
ASSERT(mOp == EOpCallBuiltInFunction);
- TPrecision precision = EbpUndefined;
- TIntermSequence::iterator childIter = mSequence.begin();
- while (childIter != mSequence.end())
+ TPrecision precision = EbpUndefined;
+ for (TIntermNode *arg : mArguments)
{
- TIntermTyped *typed = (*childIter)->getAsTyped();
+ TIntermTyped *typed = arg->getAsTyped();
// ESSL spec section 8: texture functions get their precision from the sampler.
if (typed && IsSampler(typed->getBasicType()))
{
precision = typed->getPrecision();
break;
}
- ++childIter;
}
// ESSL 3.0 spec section 8: textureSize always gets highp precision.
// All other functions that take a sampler are assumed to be texture functions.
@@ -497,8 +533,7 @@
return node;
}
- TIntermAggregate *constructor = new TIntermAggregate(sh::TypeToConstructorOperator(type));
- constructor->setType(constType);
+ TIntermSequence *arguments = new TIntermSequence();
if (type.isArray())
{
@@ -508,7 +543,7 @@
size_t arraySize = type.getArraySize();
for (size_t i = 0; i < arraySize; ++i)
{
- constructor->getSequence()->push_back(CreateZero(elementType));
+ arguments->push_back(CreateZero(elementType));
}
}
else
@@ -518,11 +553,11 @@
TStructure *structure = type.getStruct();
for (const auto &field : structure->fields())
{
- constructor->getSequence()->push_back(CreateZero(*field->type()));
+ arguments->push_back(CreateZero(*field->type()));
}
}
- return constructor;
+ return new TIntermAggregate(constType, sh::TypeToConstructorOperator(type), arguments);
}
// static
@@ -553,12 +588,12 @@
mGotPrecisionFromChildren(node.mGotPrecisionFromChildren),
mFunctionInfo(node.mFunctionInfo)
{
- for (TIntermNode *child : node.mSequence)
+ for (TIntermNode *arg : node.mArguments)
{
- TIntermTyped *typedChild = child->getAsTyped();
- ASSERT(typedChild != nullptr);
- TIntermTyped *childCopy = typedChild->deepCopy();
- mSequence.push_back(childCopy);
+ TIntermTyped *typedArg = arg->getAsTyped();
+ ASSERT(typedArg != nullptr);
+ TIntermTyped *argCopy = typedArg->deepCopy();
+ mArguments.push_back(argCopy);
}
}
@@ -1308,8 +1343,7 @@
constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics);
// Nodes may be constant folded without being qualified as constant.
- TQualifier resultQualifier = areChildrenConstQualified() ? EvqConst : EvqTemporary;
- return CreateFoldedNode(constArray, this, resultQualifier);
+ return CreateFoldedNode(constArray, this, getQualifier());
}
//
@@ -2417,32 +2451,32 @@
TDiagnostics *diagnostics)
{
TOperator op = aggregate->getOp();
- TIntermSequence *sequence = aggregate->getSequence();
- unsigned int paramsCount = static_cast<unsigned int>(sequence->size());
- std::vector<const TConstantUnion *> unionArrays(paramsCount);
- std::vector<size_t> objectSizes(paramsCount);
+ TIntermSequence *arguments = aggregate->getSequence();
+ unsigned int argsCount = static_cast<unsigned int>(arguments->size());
+ std::vector<const TConstantUnion *> unionArrays(argsCount);
+ std::vector<size_t> objectSizes(argsCount);
size_t maxObjectSize = 0;
TBasicType basicType = EbtVoid;
TSourceLoc loc;
- for (unsigned int i = 0; i < paramsCount; i++)
+ for (unsigned int i = 0; i < argsCount; i++)
{
- TIntermConstantUnion *paramConstant = (*sequence)[i]->getAsConstantUnion();
- ASSERT(paramConstant != nullptr); // Should be checked already.
+ TIntermConstantUnion *argConstant = (*arguments)[i]->getAsConstantUnion();
+ ASSERT(argConstant != nullptr); // Should be checked already.
if (i == 0)
{
- basicType = paramConstant->getType().getBasicType();
- loc = paramConstant->getLine();
+ basicType = argConstant->getType().getBasicType();
+ loc = argConstant->getLine();
}
- unionArrays[i] = paramConstant->getUnionArrayPointer();
- objectSizes[i] = paramConstant->getType().getObjectSize();
+ unionArrays[i] = argConstant->getUnionArrayPointer();
+ objectSizes[i] = argConstant->getType().getObjectSize();
if (objectSizes[i] > maxObjectSize)
maxObjectSize = objectSizes[i];
}
- if (!(*sequence)[0]->getAsTyped()->isMatrix() && aggregate->getOp() != EOpOuterProduct)
+ if (!(*arguments)[0]->getAsTyped()->isMatrix() && aggregate->getOp() != EOpOuterProduct)
{
- for (unsigned int i = 0; i < paramsCount; i++)
+ for (unsigned int i = 0; i < argsCount; i++)
if (objectSizes[i] != maxObjectSize)
unionArrays[i] = Vectorize(*unionArrays[i], maxObjectSize);
}
@@ -2791,11 +2825,11 @@
case EOpMulMatrixComponentWise:
{
- ASSERT(basicType == EbtFloat && (*sequence)[0]->getAsTyped()->isMatrix() &&
- (*sequence)[1]->getAsTyped()->isMatrix());
+ ASSERT(basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() &&
+ (*arguments)[1]->getAsTyped()->isMatrix());
// Perform component-wise matrix multiplication.
resultArray = new TConstantUnion[maxObjectSize];
- int size = (*sequence)[0]->getAsTyped()->getNominalSize();
+ int size = (*arguments)[0]->getAsTyped()->getNominalSize();
angle::Matrix<float> result =
GetMatrix(unionArrays[0], size).compMult(GetMatrix(unionArrays[1], size));
SetUnionArrayFromMatrix(result, resultArray);
@@ -2805,8 +2839,8 @@
case EOpOuterProduct:
{
ASSERT(basicType == EbtFloat);
- size_t numRows = (*sequence)[0]->getAsTyped()->getType().getObjectSize();
- size_t numCols = (*sequence)[1]->getAsTyped()->getType().getObjectSize();
+ size_t numRows = (*arguments)[0]->getAsTyped()->getType().getObjectSize();
+ size_t numCols = (*arguments)[1]->getAsTyped()->getType().getObjectSize();
resultArray = new TConstantUnion[numRows * numCols];
angle::Matrix<float> result =
GetMatrix(unionArrays[0], static_cast<int>(numRows), 1)
@@ -2878,7 +2912,7 @@
{
float x = unionArrays[0][i].getFConst();
float y = unionArrays[1][i].getFConst();
- TBasicType type = (*sequence)[2]->getAsTyped()->getType().getBasicType();
+ TBasicType type = (*arguments)[2]->getAsTyped()->getType().getBasicType();
if (type == EbtFloat)
{
// Returns the linear blend of x and y, i.e., x * (1 - a) + y * a.
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index b90ef61..608aa05 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -136,15 +136,6 @@
};
//
-// This is just to help yacc.
-//
-struct TIntermFunctionCallOrMethod
-{
- TIntermAggregate *argumentsNode;
- TIntermNode *thisNode;
-};
-
-//
// Intermediate class for nodes that have a type.
//
class TIntermTyped : public TIntermNode
@@ -569,6 +560,15 @@
typedef TVector<TIntermNode *> TIntermSequence;
typedef TVector<int> TQualifierList;
+//
+// This is just to help yacc.
+//
+struct TIntermFunctionCallOrMethod
+{
+ TIntermSequence *arguments;
+ TIntermNode *thisNode;
+};
+
// Interface for node classes that have an arbitrarily sized set of children.
class TIntermAggregateBase
{
@@ -593,19 +593,12 @@
class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
{
public:
- TIntermAggregate(TOperator op)
- : TIntermOperator(op),
- mUseEmulatedFunction(false),
- mGotPrecisionFromChildren(false)
- {
- }
+ TIntermAggregate(const TType &type, TOperator op, TIntermSequence *arguments);
~TIntermAggregate() {}
// Note: only supported for nodes that can be a part of an expression.
TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }
- void setOp(TOperator op) { mOp = op; }
-
TIntermAggregate *getAsAggregate() override { return this; }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
@@ -614,29 +607,24 @@
bool hasSideEffects() const override { return true; }
TIntermTyped *fold(TDiagnostics *diagnostics);
- TIntermSequence *getSequence() override { return &mSequence; }
- const TIntermSequence *getSequence() const override { return &mSequence; }
+ TIntermSequence *getSequence() override { return &mArguments; }
+ const TIntermSequence *getSequence() const override { return &mArguments; }
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
- bool areChildrenConstQualified();
-
- void setPrecisionForBuiltInOp();
-
- void setPrecisionFromChildren();
-
- // Used for built-in functions under EOpCallBuiltInFunction.
- void setBuiltInFunctionPrecision();
-
// Returns true if changing parameter precision may affect the return value.
bool gotPrecisionFromChildren() const { return mGotPrecisionFromChildren; }
TFunctionSymbolInfo *getFunctionSymbolInfo() { return &mFunctionInfo; }
const TFunctionSymbolInfo *getFunctionSymbolInfo() const { return &mFunctionInfo; }
+ // Used for built-in functions under EOpCallBuiltInFunction. The function name in the symbol
+ // info needs to be set before calling this.
+ void setBuiltInFunctionPrecision();
+
protected:
- TIntermSequence mSequence;
+ TIntermSequence mArguments;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs. Only for calls mapped to ops other than EOpCall*.
@@ -649,6 +637,14 @@
private:
TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just private!
+ void setTypePrecisionAndQualifier(const TType &type);
+
+ bool areChildrenConstQualified();
+
+ void setPrecisionFromChildren();
+
+ void setPrecisionForBuiltInOp();
+
// Returns true if precision was set according to special rules for this built-in.
bool setPrecisionForSpecialBuiltInOp();
};
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 8904c5c..52e7669 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -552,7 +552,7 @@
// something of the type of the constructor. Also returns the type of
// the constructor.
bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
- const TIntermAggregate *argumentsNode,
+ const TIntermSequence *arguments,
TOperator op,
const TType &type)
{
@@ -585,7 +585,7 @@
bool overFull = false;
bool matrixInMatrix = false;
bool arrayArg = false;
- for (TIntermNode *arg : *argumentsNode->getSequence())
+ for (TIntermNode *arg : *arguments)
{
const TIntermTyped *argTyped = arg->getAsTyped();
size += argTyped->getType().getObjectSize();
@@ -604,7 +604,7 @@
{
// The size of an unsized constructor should already have been determined.
ASSERT(!type.isUnsizedArray());
- if (static_cast<size_t>(type.getArraySize()) != argumentsNode->getSequence()->size())
+ if (static_cast<size_t>(type.getArraySize()) != arguments->size())
{
error(line, "array constructor needs one argument per array element", "constructor");
return false;
@@ -619,7 +619,7 @@
if (matrixInMatrix && !type.isArray())
{
- if (argumentsNode->getSequence()->size() != 1)
+ if (arguments->size() != 1)
{
error(line, "constructing matrix from matrix can only take one argument",
"constructor");
@@ -634,7 +634,7 @@
}
if (op == EOpConstructStruct && !type.isArray() &&
- type.getStruct()->fields().size() != argumentsNode->getSequence()->size())
+ type.getStruct()->fields().size() != arguments->size())
{
error(line,
"Number of constructor parameters does not match the number of structure fields",
@@ -652,13 +652,13 @@
}
}
- if (argumentsNode->getSequence()->empty())
+ if (arguments->empty())
{
error(line, "constructor does not have any arguments", "constructor");
return false;
}
- for (TIntermNode *const &argNode : *argumentsNode->getSequence())
+ for (TIntermNode *const &argNode : *arguments)
{
TIntermTyped *argTyped = argNode->getAsTyped();
ASSERT(argTyped != nullptr);
@@ -683,7 +683,7 @@
{
// GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
// the array.
- for (TIntermNode *const &argNode : *argumentsNode->getSequence())
+ for (TIntermNode *const &argNode : *arguments)
{
const TType &argType = argNode->getAsTyped()->getType();
// It has already been checked that the argument is not an array.
@@ -698,11 +698,11 @@
else if (op == EOpConstructStruct)
{
const TFieldList &fields = type.getStruct()->fields();
- const TIntermSequence *args = argumentsNode->getSequence();
for (size_t i = 0; i < fields.size(); i++)
{
- if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type())
+ if (i >= arguments->size() ||
+ (*arguments)[i]->getAsTyped()->getType() != *fields[i]->type())
{
error(line, "Structure constructor arguments do not match structure fields",
"constructor");
@@ -1528,40 +1528,6 @@
}
//
-// Look up a function name in the symbol table, and make sure it is a function.
-//
-// Return the function symbol if found, otherwise 0.
-//
-const TFunction *TParseContext::findFunction(const TSourceLoc &line,
- TFunction *call,
- int inputShaderVersion,
- bool *builtIn)
-{
- // First find by unmangled name to check whether the function name has been
- // hidden by a variable name or struct typename.
- // If a function is found, check for one with a matching argument list.
- const TSymbol *symbol = symbolTable.find(call->getName(), inputShaderVersion, builtIn);
- if (symbol == 0 || symbol->isFunction())
- {
- symbol = symbolTable.find(call->getMangledName(), inputShaderVersion, builtIn);
- }
-
- if (symbol == 0)
- {
- error(line, "no matching overloaded function found", call->getName().c_str());
- return 0;
- }
-
- if (!symbol->isFunction())
- {
- error(line, "function name expected", call->getName().c_str());
- return 0;
- }
-
- return static_cast<const TFunction *>(symbol);
-}
-
-//
// Initializers show up in several places in the grammar. Have one set of
// code to handle them here.
//
@@ -2690,61 +2656,39 @@
//
// Returns a node to add to the tree regardless of if an error was generated or not.
//
-TIntermTyped *TParseContext::addConstructor(TIntermAggregate *arguments,
+TIntermTyped *TParseContext::addConstructor(TIntermSequence *arguments,
TOperator op,
TType type,
const TSourceLoc &line)
{
if (type.isUnsizedArray())
{
- if (arguments->getSequence()->empty())
+ if (arguments->empty())
{
error(line, "implicitly sized array constructor must have at least one argument", "[]");
type.setArraySize(1u);
return TIntermTyped::CreateZero(type);
}
- type.setArraySize(static_cast<unsigned int>(arguments->getSequence()->size()));
+ type.setArraySize(static_cast<unsigned int>(arguments->size()));
}
- bool constType = true;
- for (TIntermNode *arg : *arguments->getSequence())
- {
- TIntermTyped *argTyped = arg->getAsTyped();
- ASSERT(argTyped);
- if (argTyped->getQualifier() != EvqConst)
- constType = false;
- }
- if (constType)
- type.setQualifier(EvqConst);
if (!checkConstructorArguments(line, arguments, op, type))
{
return TIntermTyped::CreateZero(type);
}
- // Turn the argument list itself into a constructor
- arguments->setOp(op);
- arguments->setLine(line);
- ASSERT(arguments->isConstructor());
- // Need to set type before setPrecisionFromChildren() because bool doesn't have precision.
- arguments->setType(type);
+ TIntermAggregate *constructorNode = new TIntermAggregate(type, op, arguments);
+ constructorNode->setLine(line);
+ ASSERT(constructorNode->isConstructor());
- // Structs should not be precision qualified, the individual members may be.
- // Built-in types on the other hand should be precision qualified.
- if (op != EOpConstructStruct)
- {
- arguments->setPrecisionFromChildren();
- type.setPrecision(arguments->getPrecision());
- }
-
- arguments->setType(type);
-
- TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(arguments, mDiagnostics);
+ TIntermTyped *constConstructor =
+ intermediate.foldAggregateBuiltIn(constructorNode, mDiagnostics);
if (constConstructor)
{
return constConstructor;
}
- return arguments;
+ return constructorNode;
}
//
@@ -4320,83 +4264,102 @@
}
}
-TIntermAggregate *TParseContext::createEmptyArgumentsNode(const TSourceLoc &loc)
+TIntermSequence *TParseContext::createEmptyArgumentsList()
{
- TIntermAggregate *argumentsNode = new TIntermAggregate(EOpNull);
- argumentsNode->setLine(loc);
- return argumentsNode;
+ return new TIntermSequence();
}
TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
- TIntermAggregate *argumentsNode,
+ TIntermSequence *arguments,
TIntermNode *thisNode,
const TSourceLoc &loc)
{
- TOperator op = fnCall->getBuiltInOp();
- TIntermTyped *callNode = nullptr;
-
if (thisNode != nullptr)
{
- TConstantUnion *unionArray = new TConstantUnion[1];
- int arraySize = 0;
- TIntermTyped *typedThis = thisNode->getAsTyped();
- // It's possible for the name pointer in the TFunction to be null in case it gets parsed as
- // a constructor. But such a TFunction can't reach here, since the lexer goes into FIELDS
- // mode after a dot, which makes type identifiers to be parsed as FIELD_SELECTION instead.
- // So accessing fnCall->getName() below is safe.
- if (fnCall->getName() != "length")
- {
- error(loc, "invalid method", fnCall->getName().c_str());
- }
- else if (!argumentsNode->getSequence()->empty())
- {
- error(loc, "method takes no parameters", "length");
- }
- else if (typedThis == nullptr || !typedThis->isArray())
- {
- error(loc, "length can only be called on arrays", "length");
- }
- else
- {
- arraySize = typedThis->getArraySize();
- if (typedThis->getAsSymbolNode() == nullptr)
- {
- // This code path can be hit with expressions like these:
- // (a = b).length()
- // (func()).length()
- // (int[3](0, 1, 2)).length()
- // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid
- // expression.
- // It allows "An array name with the length method applied" in contrast to GLSL 4.4
- // spec section 5.9 which allows "An array, vector or matrix expression with the
- // length method applied".
- error(loc, "length can only be called on array names, not on array expressions",
- "length");
- }
- }
- unionArray->setIConst(arraySize);
- callNode =
- intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), loc);
+ return addMethod(fnCall, arguments, thisNode, loc);
}
- else if (op != EOpNull)
+
+ TOperator op = fnCall->getBuiltInOp();
+ if (op != EOpNull)
{
- // Then this should be a constructor.
- callNode = addConstructor(argumentsNode, op, fnCall->getReturnType(), loc);
+ return addConstructor(arguments, op, fnCall->getReturnType(), loc);
}
else
{
- //
- // Not a constructor. Find it in the symbol table.
- //
- const TFunction *fnCandidate;
- bool builtIn;
- for (TIntermNode *arg : *argumentsNode->getSequence())
+ return addNonConstructorFunctionCall(fnCall, arguments, loc);
+ }
+}
+
+TIntermTyped *TParseContext::addMethod(TFunction *fnCall,
+ TIntermSequence *arguments,
+ TIntermNode *thisNode,
+ const TSourceLoc &loc)
+{
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ int arraySize = 0;
+ TIntermTyped *typedThis = thisNode->getAsTyped();
+ // It's possible for the name pointer in the TFunction to be null in case it gets parsed as
+ // a constructor. But such a TFunction can't reach here, since the lexer goes into FIELDS
+ // mode after a dot, which makes type identifiers to be parsed as FIELD_SELECTION instead.
+ // So accessing fnCall->getName() below is safe.
+ if (fnCall->getName() != "length")
+ {
+ error(loc, "invalid method", fnCall->getName().c_str());
+ }
+ else if (!arguments->empty())
+ {
+ error(loc, "method takes no parameters", "length");
+ }
+ else if (typedThis == nullptr || !typedThis->isArray())
+ {
+ error(loc, "length can only be called on arrays", "length");
+ }
+ else
+ {
+ arraySize = typedThis->getArraySize();
+ if (typedThis->getAsSymbolNode() == nullptr)
{
- fnCall->addParameter(TConstParameter(&arg->getAsTyped()->getType()));
+ // This code path can be hit with expressions like these:
+ // (a = b).length()
+ // (func()).length()
+ // (int[3](0, 1, 2)).length()
+ // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid
+ // expression.
+ // It allows "An array name with the length method applied" in contrast to GLSL 4.4
+ // spec section 5.9 which allows "An array, vector or matrix expression with the
+ // length method applied".
+ error(loc, "length can only be called on array names, not on array expressions",
+ "length");
}
- fnCandidate = findFunction(loc, fnCall, mShaderVersion, &builtIn);
- if (fnCandidate)
+ }
+ unionArray->setIConst(arraySize);
+ return intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), loc);
+}
+
+TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunction *fnCall,
+ TIntermSequence *arguments,
+ const TSourceLoc &loc)
+{
+ // First find by unmangled name to check whether the function name has been
+ // hidden by a variable name or struct typename.
+ // If a function is found, check for one with a matching argument list.
+ bool builtIn;
+ const TSymbol *symbol = symbolTable.find(fnCall->getName(), mShaderVersion, &builtIn);
+ if (symbol != nullptr && !symbol->isFunction())
+ {
+ error(loc, "function name expected", fnCall->getName().c_str());
+ }
+ else
+ {
+ symbol = symbolTable.find(TFunction::GetMangledNameFromCall(fnCall->getName(), *arguments),
+ mShaderVersion, &builtIn);
+ if (symbol == nullptr)
{
+ error(loc, "no matching overloaded function found", fnCall->getName().c_str());
+ }
+ else
+ {
+ const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
//
// A declared function.
//
@@ -4404,51 +4367,42 @@
{
checkCanUseExtension(loc, fnCandidate->getExtension());
}
- op = fnCandidate->getBuiltInOp();
+ TOperator op = fnCandidate->getBuiltInOp();
if (builtIn && op != EOpNull)
{
// A function call mapped to a built-in operation.
if (fnCandidate->getParamCount() == 1)
{
// Treat it like a built-in unary operator.
- TIntermNode *unaryParamNode = argumentsNode->getSequence()->front();
- callNode = createUnaryMath(op, unaryParamNode->getAsTyped(), loc);
+ TIntermNode *unaryParamNode = arguments->front();
+ TIntermTyped *callNode = createUnaryMath(op, unaryParamNode->getAsTyped(), loc);
ASSERT(callNode != nullptr);
+ return callNode;
}
else
{
- ASSERT(argumentsNode->getOp() == EOpNull);
- argumentsNode->setOp(op);
- argumentsNode->setType(fnCandidate->getReturnType());
- argumentsNode->setPrecisionForBuiltInOp();
- if (argumentsNode->areChildrenConstQualified())
- {
- argumentsNode->getTypePointer()->setQualifier(EvqConst);
- }
+ TIntermAggregate *callNode =
+ new TIntermAggregate(fnCandidate->getReturnType(), op, arguments);
+ callNode->setLine(loc);
// Some built-in functions have out parameters too.
- functionCallLValueErrorCheck(fnCandidate, argumentsNode);
+ 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(argumentsNode, mDiagnostics);
+ intermediate.foldAggregateBuiltIn(callNode, mDiagnostics);
if (foldedNode)
{
- callNode = foldedNode;
+ return foldedNode;
}
- else
- {
- callNode = argumentsNode;
- }
+ return callNode;
}
}
else
{
// This is a real function call
- ASSERT(argumentsNode->getOp() == EOpNull);
- argumentsNode->setType(fnCandidate->getReturnType());
- argumentsNode->getFunctionSymbolInfo()->setFromFunction(*fnCandidate);
+ TIntermAggregate *callNode = nullptr;
// If builtIn == false, the function is user defined - could be an overloaded
// built-in as well.
@@ -4456,31 +4410,33 @@
// This needs to happen after the function info including name is set.
if (builtIn)
{
- argumentsNode->setOp(EOpCallBuiltInFunction);
- argumentsNode->setBuiltInFunctionPrecision();
-
- checkTextureOffsetConst(argumentsNode);
- checkImageMemoryAccessForBuiltinFunctions(argumentsNode);
+ callNode = new TIntermAggregate(fnCandidate->getReturnType(),
+ EOpCallBuiltInFunction, arguments);
+ // Note that name needs to be set before texture function type is determined.
+ callNode->getFunctionSymbolInfo()->setFromFunction(*fnCandidate);
+ callNode->setBuiltInFunctionPrecision();
+ checkTextureOffsetConst(callNode);
+ checkImageMemoryAccessForBuiltinFunctions(callNode);
}
else
{
- argumentsNode->setOp(EOpCallFunctionInAST);
- checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, argumentsNode);
+ callNode = new TIntermAggregate(fnCandidate->getReturnType(),
+ EOpCallFunctionInAST, arguments);
+ callNode->getFunctionSymbolInfo()->setFromFunction(*fnCandidate);
+ checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, callNode);
}
- callNode = argumentsNode;
+ functionCallLValueErrorCheck(fnCandidate, callNode);
- functionCallLValueErrorCheck(fnCandidate, argumentsNode);
+ callNode->setLine(loc);
+
+ return callNode;
}
}
- else
- {
- // error message was put out by findFunction()
- // Put on a dummy node for error recovery
- callNode = TIntermTyped::CreateZero(TType(EbtFloat, EbpMedium, EvqConst));
- }
}
- return callNode;
+
+ // Error message was already written. Put on a dummy node for error recovery.
+ return TIntermTyped::CreateZero(TType(EbtFloat, EbpMedium, EvqConst));
}
TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 8a8fbb5..c7a7f8c 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -112,7 +112,7 @@
void checkIsScalarInteger(TIntermTyped *node, const char *token);
bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
bool checkConstructorArguments(const TSourceLoc &line,
- const TIntermAggregate *argumentsNode,
+ const TIntermSequence *arguments,
TOperator op,
const TType &type);
@@ -167,10 +167,6 @@
const char *value,
bool stdgl);
- const TFunction *findFunction(const TSourceLoc &line,
- TFunction *pfnCall,
- int inputShaderVersion,
- bool *builtIn = 0);
bool executeInitializer(const TSourceLoc &line,
const TString &identifier,
const TPublicType &pType,
@@ -252,10 +248,6 @@
const TString *name,
const TSourceLoc &location);
TFunction *addConstructorFunc(const TPublicType &publicType);
- TIntermTyped *addConstructor(TIntermAggregate *arguments,
- TOperator op,
- TType type,
- const TSourceLoc &line);
TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
const TSourceLoc &location,
@@ -345,12 +337,12 @@
void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
const TIntermAggregate *functionCall);
- TIntermAggregate *createEmptyArgumentsNode(const TSourceLoc &loc);
+ TIntermSequence *createEmptyArgumentsList();
- // fnCall is only storing the built-in op, and function name or constructor type. argumentsNode
+ // fnCall is only storing the built-in op, and function name or constructor type. arguments
// has the arguments.
TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
- TIntermAggregate *argumentsNode,
+ TIntermSequence *arguments,
TIntermNode *thisNode,
const TSourceLoc &loc);
@@ -406,9 +398,19 @@
TIntermTyped *left,
TIntermTyped *right,
const TSourceLoc &loc);
- TIntermTyped *createUnaryMath(TOperator op,
- TIntermTyped *child,
- const TSourceLoc &loc);
+ TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
+
+ TIntermTyped *addMethod(TFunction *fnCall,
+ TIntermSequence *arguments,
+ TIntermNode *thisNode,
+ const TSourceLoc &loc);
+ TIntermTyped *addConstructor(TIntermSequence *arguments,
+ TOperator op,
+ TType type,
+ const TSourceLoc &line);
+ TIntermTyped *addNonConstructorFunctionCall(TFunction *fnCall,
+ TIntermSequence *arguments,
+ const TSourceLoc &loc);
// Return true if the checks pass
bool binaryOpCommonCheck(TOperator op,
diff --git a/src/compiler/translator/RemoveDynamicIndexing.cpp b/src/compiler/translator/RemoveDynamicIndexing.cpp
index fbe0264..7424f39 100644
--- a/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -113,11 +113,9 @@
if (node->getBasicType() == EbtInt)
return node;
- TIntermAggregate *convertedNode = new TIntermAggregate(EOpConstructInt);
- convertedNode->setType(TType(EbtInt));
- convertedNode->getSequence()->push_back(node);
- convertedNode->setPrecisionFromChildren();
- return convertedNode;
+ TIntermSequence *arguments = new TIntermSequence();
+ arguments->push_back(node);
+ return new TIntermAggregate(TType(EbtInt), EOpConstructInt, arguments);
}
TType GetFieldType(const TType &indexedType)
@@ -351,15 +349,16 @@
TIntermTyped *index)
{
ASSERT(node->getOp() == EOpIndexIndirect);
- TIntermAggregate *indexingCall = new TIntermAggregate(EOpCallFunctionInAST);
+ TIntermSequence *arguments = new TIntermSequence();
+ arguments->push_back(indexedNode);
+ arguments->push_back(index);
+
+ TType fieldType = GetFieldType(indexedNode->getType());
+ TIntermAggregate *indexingCall =
+ new TIntermAggregate(fieldType, EOpCallFunctionInAST, arguments);
indexingCall->setLine(node->getLine());
indexingCall->getFunctionSymbolInfo()->setNameObj(
GetIndexFunctionName(indexedNode->getType(), false));
- indexingCall->getSequence()->push_back(indexedNode);
- indexingCall->getSequence()->push_back(index);
-
- TType fieldType = GetFieldType(indexedNode->getType());
- indexingCall->setType(fieldType);
return indexingCall;
}
diff --git a/src/compiler/translator/RewriteTexelFetchOffset.cpp b/src/compiler/translator/RewriteTexelFetchOffset.cpp
index 96e7db6..b1ccf0c 100644
--- a/src/compiler/translator/RewriteTexelFetchOffset.cpp
+++ b/src/compiler/translator/RewriteTexelFetchOffset.cpp
@@ -94,14 +94,11 @@
// Create new node that represents the call of function texelFetch.
// Its argument list will be: texelFetch(sampler, Position+offset, lod).
- TIntermAggregate *texelFetchNode = new TIntermAggregate(EOpCallBuiltInFunction);
- texelFetchNode->getFunctionSymbolInfo()->setName(newName);
- texelFetchNode->getFunctionSymbolInfo()->setId(uniqueId);
- texelFetchNode->setType(node->getType());
- texelFetchNode->setLine(node->getLine());
+
+ TIntermSequence *texelFetchArguments = new TIntermSequence();
// sampler
- texelFetchNode->getSequence()->push_back(sequence->at(0));
+ texelFetchArguments->push_back(sequence->at(0));
// Position
TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped();
@@ -114,20 +111,15 @@
{
// For 2DArray samplers, Position is ivec3 and offset is ivec2;
// So offset must be converted into an ivec3 before being added to Position.
- TIntermAggregate *constructIVec3Node = new TIntermAggregate(EOpConstructIVec3);
- constructIVec3Node->setLine(texCoordNode->getLine());
- constructIVec3Node->setType(texCoordNode->getType());
+ TIntermSequence *constructOffsetIvecArguments = new TIntermSequence();
+ constructOffsetIvecArguments->push_back(sequence->at(3)->getAsTyped());
- constructIVec3Node->getSequence()->push_back(sequence->at(3)->getAsTyped());
+ TIntermTyped *zeroNode = TIntermTyped::CreateZero(TType(EbtInt));
+ constructOffsetIvecArguments->push_back(zeroNode);
- TConstantUnion *zero = new TConstantUnion();
- zero->setIConst(0);
- TType *intType = new TType(EbtInt);
-
- TIntermConstantUnion *zeroNode = new TIntermConstantUnion(zero, *intType);
- constructIVec3Node->getSequence()->push_back(zeroNode);
-
- offsetNode = constructIVec3Node;
+ offsetNode = new TIntermAggregate(texCoordNode->getType(), EOpConstructIVec3,
+ constructOffsetIvecArguments);
+ offsetNode->setLine(texCoordNode->getLine());
}
else
{
@@ -137,12 +129,18 @@
// Position+offset
TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode);
add->setLine(texCoordNode->getLine());
- texelFetchNode->getSequence()->push_back(add);
+ texelFetchArguments->push_back(add);
// lod
- texelFetchNode->getSequence()->push_back(sequence->at(2));
+ texelFetchArguments->push_back(sequence->at(2));
- ASSERT(texelFetchNode->getSequence()->size() == 3u);
+ ASSERT(texelFetchArguments->size() == 3u);
+
+ TIntermAggregate *texelFetchNode =
+ new TIntermAggregate(node->getType(), EOpCallBuiltInFunction, texelFetchArguments);
+ texelFetchNode->getFunctionSymbolInfo()->setName(newName);
+ texelFetchNode->getFunctionSymbolInfo()->setId(uniqueId);
+ texelFetchNode->setLine(node->getLine());
// Replace the old node by this new node.
queueReplacement(node, texelFetchNode, OriginalNode::IS_DROPPED);
diff --git a/src/compiler/translator/SeparateExpressionsReturningArrays.cpp b/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
index ddce9c3..6489a91 100644
--- a/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
+++ b/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
@@ -58,10 +58,9 @@
// Performs a shallow copy of a constructor/function call node.
TIntermAggregate *CopyAggregateNode(TIntermAggregate *node)
{
- TIntermAggregate *copyNode = new TIntermAggregate(node->getOp());
- TIntermSequence *copySeq = copyNode->getSequence();
+ TIntermSequence *copySeq = new TIntermSequence();
copySeq->insert(copySeq->begin(), node->getSequence()->begin(), node->getSequence()->end());
- copyNode->setType(node->getType());
+ TIntermAggregate *copyNode = new TIntermAggregate(node->getType(), node->getOp(), copySeq);
*copyNode->getFunctionSymbolInfo() = *node->getFunctionSymbolInfo();
return copyNode;
}
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index 3ba0223..b246a0f 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -67,6 +67,17 @@
return NewPoolTString(newName.c_str());
}
+const TString &TFunction::GetMangledNameFromCall(const TString &unmangledFunctionName,
+ TIntermSequence &arguments)
+{
+ std::string newName = mangleName(unmangledFunctionName).c_str();
+ for (TIntermNode *argument : arguments)
+ {
+ newName += argument->getAsTyped()->getType().getMangledName().c_str();
+ }
+ return *NewPoolTString(newName.c_str());
+}
+
//
// Symbol table levels are a map of pointers to symbols that have to be deleted.
//
@@ -160,22 +171,12 @@
ASSERT(!callNode->isConstructor());
ASSERT(!callNode->isFunctionCall());
TString opString = GetOperatorString(callNode->getOp());
- // The return type doesn't affect the mangled name of the function, which is used to look it up.
- TType dummyReturnType;
- TFunction call(&opString, &dummyReturnType, callNode->getOp());
- TIntermSequence *sequence = callNode->getSequence();
- for (auto *child : *sequence)
- {
- TType *paramType = child->getAsTyped()->getTypePointer();
- TConstParameter p(paramType);
- call.addParameter(p);
- }
-
- TSymbol *sym = findBuiltIn(call.getMangledName(), shaderVersion);
+ TSymbol *sym = findBuiltIn(
+ TFunction::GetMangledNameFromCall(opString, *callNode->getSequence()), shaderVersion);
ASSERT(sym != nullptr && sym->isFunction());
TFunction *builtInFunc = static_cast<TFunction *>(sym);
- ASSERT(builtInFunc->getParamCount() == sequence->size());
+ ASSERT(builtInFunc->getParamCount() == callNode->getSequence()->size());
return builtInFunc;
}
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index 2a4cfff..671b183 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -41,8 +41,6 @@
namespace sh
{
-class TIntermAggregate;
-
// Symbol base class. (Can build functions or variables out of these...)
class TSymbol : angle::NonCopyable
{
@@ -182,6 +180,10 @@
}
return *mangledName;
}
+
+ static const TString &GetMangledNameFromCall(const TString &unmangledFunctionName,
+ TIntermSequence &arguments);
+
const TType &getReturnType() const { return *returnType; }
TOperator getBuiltInOp() const { return op; }
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index 3d3cbc3..8674087 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -315,7 +315,7 @@
function_call
: function_call_or_method {
- $$ = context->addFunctionCallOrMethod($1.function, $1.callOrMethodPair.argumentsNode, $1.callOrMethodPair.thisNode, @1);
+ $$ = context->addFunctionCallOrMethod($1.function, $1.callOrMethodPair.arguments, $1.callOrMethodPair.thisNode, @1);
}
;
@@ -343,23 +343,23 @@
function_call_header_no_parameters
: function_call_header VOID_TYPE {
$$.function = $1;
- $$.callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode(@1);
+ $$.callOrMethodPair.arguments = context->createEmptyArgumentsList();
}
| function_call_header {
$$.function = $1;
- $$.callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode(@1);
+ $$.callOrMethodPair.arguments = context->createEmptyArgumentsList();
}
;
function_call_header_with_parameters
: function_call_header assignment_expression {
- $$.callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode(@1);
+ $$.callOrMethodPair.arguments = context->createEmptyArgumentsList();
$$.function = $1;
- $$.callOrMethodPair.argumentsNode->getSequence()->push_back($2);
+ $$.callOrMethodPair.arguments->push_back($2);
}
| function_call_header_with_parameters COMMA assignment_expression {
$$.function = $1.function;
- $$.callOrMethodPair.argumentsNode->getSequence()->push_back($3);
+ $$.callOrMethodPair.arguments->push_back($3);
}
;
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 56bbe02..b6f1a04 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -2619,7 +2619,7 @@
case 18:
{
- (yyval.interm.intermTypedNode) = context->addFunctionCallOrMethod((yyvsp[0].interm).function, (yyvsp[0].interm).callOrMethodPair.argumentsNode, (yyvsp[0].interm).callOrMethodPair.thisNode, (yylsp[0]));
+ (yyval.interm.intermTypedNode) = context->addFunctionCallOrMethod((yyvsp[0].interm).function, (yyvsp[0].interm).callOrMethodPair.arguments, (yyvsp[0].interm).callOrMethodPair.thisNode, (yylsp[0]));
}
break;
@@ -2663,7 +2663,7 @@
{
(yyval.interm).function = (yyvsp[-1].interm.function);
- (yyval.interm).callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode((yylsp[-1]));
+ (yyval.interm).callOrMethodPair.arguments = context->createEmptyArgumentsList();
}
break;
@@ -2672,7 +2672,7 @@
{
(yyval.interm).function = (yyvsp[0].interm.function);
- (yyval.interm).callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode((yylsp[0]));
+ (yyval.interm).callOrMethodPair.arguments = context->createEmptyArgumentsList();
}
break;
@@ -2680,9 +2680,9 @@
case 25:
{
- (yyval.interm).callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode((yylsp[-1]));
+ (yyval.interm).callOrMethodPair.arguments = context->createEmptyArgumentsList();
(yyval.interm).function = (yyvsp[-1].interm.function);
- (yyval.interm).callOrMethodPair.argumentsNode->getSequence()->push_back((yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).callOrMethodPair.arguments->push_back((yyvsp[0].interm.intermTypedNode));
}
break;
@@ -2691,7 +2691,7 @@
{
(yyval.interm).function = (yyvsp[-2].interm).function;
- (yyval.interm).callOrMethodPair.argumentsNode->getSequence()->push_back((yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).callOrMethodPair.arguments->push_back((yyvsp[0].interm.intermTypedNode));
}
break;