Refactor function call node creation
This makes function call node creation code simpler and more type
safe. It also prepares for further simplification by removing usage of
TFunction in places where the arguments node is sufficient.
BUG=angleproject:1490
TEST=angle_unittests
Change-Id: I75d9e059bb32c475487f0be24e40ac0d78012d86
Reviewed-on: https://chromium-review.googlesource.com/433217
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index 39811fe..6ae74a3 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -429,8 +429,7 @@
TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *child)
{
- TIntermAggregate *callNode = new TIntermAggregate();
- callNode->setOp(EOpFunctionCall);
+ TIntermAggregate *callNode = new TIntermAggregate(EOpFunctionCall);
TName nameObj(TFunction::mangleName(name));
nameObj.setInternal(true);
callNode->getFunctionSymbolInfo()->setNameObj(nameObj);
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index 554f7ef..d75ba6c 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -136,6 +136,15 @@
};
//
+// This is just to help yacc.
+//
+struct TIntermFunctionCallOrMethod
+{
+ TIntermAggregate *argumentsNode;
+ TIntermNode *thisNode;
+};
+
+//
// Intermediate class for nodes that have a type.
//
class TIntermTyped : public TIntermNode
@@ -579,13 +588,6 @@
class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
{
public:
- TIntermAggregate()
- : TIntermOperator(EOpNull),
- mUserDefined(false),
- mUseEmulatedFunction(false),
- mGotPrecisionFromChildren(false)
- {
- }
TIntermAggregate(TOperator op)
: TIntermOperator(op),
mUserDefined(false),
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index ca73712..084df31 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -67,97 +67,6 @@
return node;
}
-// This is the safe way to change the operator on an aggregate, as it
-// does lots of error checking and fixing. Especially for establishing
-// a function call's operation on it's set of parameters.
-//
-// Returns an aggregate node, which could be the one passed in if
-// it was already an aggregate but no operator was set.
-TIntermAggregate *TIntermediate::setAggregateOperator(TIntermNode *node,
- TOperator op,
- const TSourceLoc &line)
-{
- TIntermAggregate *aggNode;
-
- //
- // Make sure we have an aggregate. If not turn it into one.
- //
- if (node)
- {
- aggNode = node->getAsAggregate();
- if (aggNode == NULL || aggNode->getOp() != EOpNull)
- {
- //
- // Make an aggregate containing this node.
- //
- aggNode = new TIntermAggregate();
- aggNode->getSequence()->push_back(node);
- }
- }
- else
- {
- aggNode = new TIntermAggregate();
- }
-
- //
- // Set the operator.
- //
- aggNode->setOp(op);
- aggNode->setLine(line);
-
- return aggNode;
-}
-
-//
-// Safe way to combine two nodes into an aggregate. Works with null pointers,
-// a node that's not a aggregate yet, etc.
-//
-// Returns the resulting aggregate, unless 0 was passed in for
-// both existing nodes.
-//
-TIntermAggregate *TIntermediate::growAggregate(TIntermNode *left,
- TIntermNode *right,
- const TSourceLoc &line)
-{
- if (left == NULL && right == NULL)
- return NULL;
-
- TIntermAggregate *aggNode = NULL;
- if (left)
- aggNode = left->getAsAggregate();
- if (!aggNode || aggNode->getOp() != EOpNull)
- {
- aggNode = new TIntermAggregate;
- if (left)
- aggNode->getSequence()->push_back(left);
- }
-
- if (right)
- aggNode->getSequence()->push_back(right);
-
- aggNode->setLine(line);
-
- return aggNode;
-}
-
-//
-// Turn an existing node into an aggregate.
-//
-// Returns an aggregate, unless NULL was passed in for the existing node.
-//
-TIntermAggregate *TIntermediate::MakeAggregate(TIntermNode *node, const TSourceLoc &line)
-{
- if (node == nullptr)
- return nullptr;
-
- TIntermAggregate *aggNode = new TIntermAggregate;
- aggNode->getSequence()->push_back(node);
-
- aggNode->setLine(line);
-
- return aggNode;
-}
-
// If the input node is nullptr, return nullptr.
// If the input node is a block node, return it.
// If the input node is not a block node, put it inside a block node and return that.
diff --git a/src/compiler/translator/Intermediate.h b/src/compiler/translator/Intermediate.h
index 57c01d0..eb1d1d0 100644
--- a/src/compiler/translator/Intermediate.h
+++ b/src/compiler/translator/Intermediate.h
@@ -33,14 +33,7 @@
TIntermTyped *index,
const TSourceLoc &line,
TDiagnostics *diagnostics);
- TIntermTyped *addUnaryMath(TOperator op,
- TIntermTyped *child,
- const TSourceLoc &line,
- const TType *funcReturnType);
- TIntermAggregate *growAggregate(TIntermNode *left, TIntermNode *right, const TSourceLoc &);
- static TIntermAggregate *MakeAggregate(TIntermNode *node, const TSourceLoc &line);
static TIntermBlock *EnsureBlock(TIntermNode *node);
- TIntermAggregate *setAggregateOperator(TIntermNode *, TOperator, const TSourceLoc &);
TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &line);
static TIntermTyped *AddTernarySelection(TIntermTyped *cond,
TIntermTyped *trueExpression,
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 0be3339..41b58d4 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -552,8 +552,7 @@
// something of the type of the constructor. Also returns the type of
// the constructor.
bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
- TIntermNode *argumentsNode,
- const TFunction &function,
+ const TIntermAggregate *argumentsNode,
TOperator op,
const TType &type)
{
@@ -586,18 +585,18 @@
bool overFull = false;
bool matrixInMatrix = false;
bool arrayArg = false;
- for (size_t i = 0; i < function.getParamCount(); ++i)
+ for (TIntermNode *arg : *argumentsNode->getSequence())
{
- const TConstParameter ¶m = function.getParam(i);
- size += param.type->getObjectSize();
+ const TIntermTyped *argTyped = arg->getAsTyped();
+ size += argTyped->getType().getObjectSize();
- if (constructingMatrix && param.type->isMatrix())
+ if (constructingMatrix && argTyped->getType().isMatrix())
matrixInMatrix = true;
if (full)
overFull = true;
if (op != EOpConstructStruct && !type.isArray() && size >= type.getObjectSize())
full = true;
- if (param.type->isArray())
+ if (argTyped->getType().isArray())
arrayArg = true;
}
@@ -605,7 +604,7 @@
{
// The size of an unsized constructor should already have been determined.
ASSERT(!type.isUnsizedArray());
- if (static_cast<size_t>(type.getArraySize()) != function.getParamCount())
+ if (static_cast<size_t>(type.getArraySize()) != argumentsNode->getSequence()->size())
{
error(line, "array constructor needs one argument per array element", "constructor");
return false;
@@ -620,7 +619,7 @@
if (matrixInMatrix && !type.isArray())
{
- if (function.getParamCount() != 1)
+ if (argumentsNode->getSequence()->size() != 1)
{
error(line, "constructing matrix from matrix can only take one argument",
"constructor");
@@ -635,7 +634,7 @@
}
if (op == EOpConstructStruct && !type.isArray() &&
- type.getStruct()->fields().size() != function.getParamCount())
+ type.getStruct()->fields().size() != argumentsNode->getSequence()->size())
{
error(line,
"Number of constructor parameters does not match the number of structure fields",
@@ -653,14 +652,13 @@
}
}
- if (argumentsNode == nullptr)
+ if (argumentsNode->getSequence()->empty())
{
error(line, "constructor does not have any arguments", "constructor");
return false;
}
- TIntermAggregate *argumentsAgg = argumentsNode->getAsAggregate();
- for (TIntermNode *&argNode : *argumentsAgg->getSequence())
+ for (TIntermNode *const &argNode : *argumentsNode->getSequence())
{
TIntermTyped *argTyped = argNode->getAsTyped();
ASSERT(argTyped != nullptr);
@@ -685,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 *&argNode : *argumentsAgg->getSequence())
+ for (TIntermNode *const &argNode : *argumentsNode->getSequence())
{
const TType &argType = argNode->getAsTyped()->getType();
// It has already been checked that the argument is not an array.
@@ -700,7 +698,7 @@
else if (op == EOpConstructStruct)
{
const TFieldList &fields = type.getStruct()->fields();
- TIntermSequence *args = argumentsAgg->getSequence();
+ const TIntermSequence *args = argumentsNode->getSequence();
for (size_t i = 0; i < fields.size(); i++)
{
@@ -2683,9 +2681,8 @@
}
}
- TString tempString;
const TType *type = new TType(publicType);
- return new TFunction(&tempString, type, op);
+ return new TFunction(nullptr, type, op);
}
// This function is used to test for the correctness of the parameters passed to various constructor
@@ -2693,66 +2690,61 @@
//
// Returns a node to add to the tree regardless of if an error was generated or not.
//
-TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments,
+TIntermTyped *TParseContext::addConstructor(TIntermAggregate *arguments,
TOperator op,
- TFunction *fnCall,
+ TType type,
const TSourceLoc &line)
{
- TType type = fnCall->getReturnType();
if (type.isUnsizedArray())
{
- if (fnCall->getParamCount() == 0)
+ if (arguments->getSequence()->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>(fnCall->getParamCount()));
+ type.setArraySize(static_cast<unsigned int>(arguments->getSequence()->size()));
}
bool constType = true;
- for (size_t i = 0; i < fnCall->getParamCount(); ++i)
+ for (TIntermNode *arg : *arguments->getSequence())
{
- const TConstParameter ¶m = fnCall->getParam(i);
- if (param.type->getQualifier() != EvqConst)
+ TIntermTyped *argTyped = arg->getAsTyped();
+ ASSERT(argTyped);
+ if (argTyped->getQualifier() != EvqConst)
constType = false;
}
if (constType)
type.setQualifier(EvqConst);
- if (!checkConstructorArguments(line, arguments, *fnCall, op, type))
+ if (!checkConstructorArguments(line, arguments, op, type))
{
- TIntermTyped *dummyNode = intermediate.setAggregateOperator(nullptr, op, line);
- dummyNode->setType(type);
- return dummyNode;
+ return TIntermTyped::CreateZero(type);
}
- TIntermAggregate *constructor = arguments->getAsAggregate();
- ASSERT(constructor != nullptr);
-
// Turn the argument list itself into a constructor
- constructor->setOp(op);
- constructor->setLine(line);
- ASSERT(constructor->isConstructor());
+ arguments->setOp(op);
+ arguments->setLine(line);
+ ASSERT(arguments->isConstructor());
// Need to set type before setPrecisionFromChildren() because bool doesn't have precision.
- constructor->setType(type);
+ arguments->setType(type);
// 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)
{
- constructor->setPrecisionFromChildren();
- type.setPrecision(constructor->getPrecision());
+ arguments->setPrecisionFromChildren();
+ type.setPrecision(arguments->getPrecision());
}
- constructor->setType(type);
+ arguments->setType(type);
- TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor, mDiagnostics);
+ TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(arguments, mDiagnostics);
if (constConstructor)
{
return constConstructor;
}
- return constructor;
+ return arguments;
}
//
@@ -4330,13 +4322,18 @@
}
}
-TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
- TIntermNode *paramNode,
- TIntermNode *thisNode,
- const TSourceLoc &loc,
- bool *fatalError)
+TIntermAggregate *TParseContext::createEmptyArgumentsNode(const TSourceLoc &loc)
{
- *fatalError = false;
+ TIntermAggregate *argumentsNode = new TIntermAggregate(EOpNull);
+ argumentsNode->setLine(loc);
+ return argumentsNode;
+}
+
+TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
+ TIntermAggregate *argumentsNode,
+ TIntermNode *thisNode,
+ const TSourceLoc &loc)
+{
TOperator op = fnCall->getBuiltInOp();
TIntermTyped *callNode = nullptr;
@@ -4345,11 +4342,15 @@
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 (paramNode != nullptr)
+ else if (!argumentsNode->getSequence()->empty())
{
error(loc, "method takes no parameters", "length");
}
@@ -4382,7 +4383,7 @@
else if (op != EOpNull)
{
// Then this should be a constructor.
- callNode = addConstructor(paramNode, op, fnCall, loc);
+ callNode = addConstructor(argumentsNode, op, fnCall->getReturnType(), loc);
}
else
{
@@ -4391,6 +4392,10 @@
//
const TFunction *fnCandidate;
bool builtIn;
+ for (TIntermNode *arg : *argumentsNode->getSequence())
+ {
+ fnCall->addParameter(TConstParameter(&arg->getAsTyped()->getType()));
+ }
fnCandidate = findFunction(loc, fnCall, mShaderVersion, &builtIn);
if (fnCandidate)
{
@@ -4412,55 +4417,54 @@
//
// Treat it like a built-in unary operator.
//
- TIntermAggregate *paramAgg = paramNode->getAsAggregate();
- paramNode = paramAgg->getSequence()->front();
- callNode = createUnaryMath(op, paramNode->getAsTyped(), loc,
+ TIntermNode *unaryParamNode = argumentsNode->getSequence()->front();
+ callNode = createUnaryMath(op, unaryParamNode->getAsTyped(), loc,
&fnCandidate->getReturnType());
if (callNode == nullptr)
{
std::stringstream reasonStream;
- reasonStream << "wrong operand type for built in unary function: "
- << static_cast<TIntermTyped *>(paramNode)->getCompleteString();
+ reasonStream
+ << "wrong operand type for built in unary function: "
+ << static_cast<TIntermTyped *>(argumentsNode)->getCompleteString();
std::string reason = reasonStream.str();
- error(paramNode->getLine(), reason.c_str(), "Internal Error");
- *fatalError = true;
- return nullptr;
+ error(argumentsNode->getLine(), reason.c_str(), "Internal Error");
+ return TIntermTyped::CreateZero(TType(EbtFloat, EbpMedium, EvqConst));
}
}
else
{
- TIntermAggregate *aggregate =
- intermediate.setAggregateOperator(paramNode, op, loc);
- aggregate->setType(fnCandidate->getReturnType());
- aggregate->setPrecisionForBuiltInOp();
- if (aggregate->areChildrenConstQualified())
+ ASSERT(argumentsNode->getOp() == EOpNull);
+ argumentsNode->setOp(op);
+ argumentsNode->setType(fnCandidate->getReturnType());
+ argumentsNode->setPrecisionForBuiltInOp();
+ if (argumentsNode->areChildrenConstQualified())
{
- aggregate->getTypePointer()->setQualifier(EvqConst);
+ argumentsNode->getTypePointer()->setQualifier(EvqConst);
}
// Some built-in functions have out parameters too.
- functionCallLValueErrorCheck(fnCandidate, aggregate);
+ functionCallLValueErrorCheck(fnCandidate, argumentsNode);
// 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(aggregate, mDiagnostics);
+ intermediate.foldAggregateBuiltIn(argumentsNode, mDiagnostics);
if (foldedNode)
{
callNode = foldedNode;
}
else
{
- callNode = aggregate;
+ callNode = argumentsNode;
}
}
}
else
{
// This is a real function call
- TIntermAggregate *aggregate =
- intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc);
- aggregate->setType(fnCandidate->getReturnType());
+ ASSERT(argumentsNode->getOp() == EOpNull);
+ argumentsNode->setOp(EOpFunctionCall);
+ argumentsNode->setType(fnCandidate->getReturnType());
// this is how we know whether the given function is a builtIn function or a user
// defined function
@@ -4468,36 +4472,33 @@
// builtIn function also
// if builtIn == true, it's definitely a builtIn function with EOpNull
if (!builtIn)
- aggregate->setUserDefined();
- aggregate->getFunctionSymbolInfo()->setFromFunction(*fnCandidate);
+ argumentsNode->setUserDefined();
+ argumentsNode->getFunctionSymbolInfo()->setFromFunction(*fnCandidate);
// This needs to happen after the function info including name is set
if (builtIn)
{
- aggregate->setBuiltInFunctionPrecision();
+ argumentsNode->setBuiltInFunctionPrecision();
- checkTextureOffsetConst(aggregate);
+ checkTextureOffsetConst(argumentsNode);
- checkImageMemoryAccessForBuiltinFunctions(aggregate);
+ checkImageMemoryAccessForBuiltinFunctions(argumentsNode);
}
else
{
- checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, aggregate);
+ checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, argumentsNode);
}
- callNode = aggregate;
+ callNode = argumentsNode;
- functionCallLValueErrorCheck(fnCandidate, aggregate);
+ functionCallLValueErrorCheck(fnCandidate, argumentsNode);
}
}
else
{
// error message was put out by findFunction()
// Put on a dummy node for error recovery
- TConstantUnion *unionArray = new TConstantUnion[1];
- unionArray->setFConst(0.0f);
- callNode = intermediate.addConstantUnion(unionArray,
- TType(EbtFloat, EbpUndefined, EvqConst), loc);
+ callNode = TIntermTyped::CreateZero(TType(EbtFloat, EbpMedium, EvqConst));
}
}
return callNode;
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 55c5c4c..ced5802 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -112,8 +112,7 @@
void checkIsScalarInteger(TIntermTyped *node, const char *token);
bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
bool checkConstructorArguments(const TSourceLoc &line,
- TIntermNode *argumentsNode,
- const TFunction &function,
+ const TIntermAggregate *argumentsNode,
TOperator op,
const TType &type);
@@ -253,9 +252,9 @@
const TString *name,
const TSourceLoc &location);
TFunction *addConstructorFunc(const TPublicType &publicType);
- TIntermTyped *addConstructor(TIntermNode *arguments,
+ TIntermTyped *addConstructor(TIntermAggregate *arguments,
TOperator op,
- TFunction *fnCall,
+ TType type,
const TSourceLoc &line);
TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
@@ -346,11 +345,14 @@
void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
const TIntermAggregate *functionCall);
+ TIntermAggregate *createEmptyArgumentsNode(const TSourceLoc &loc);
+
+ // fnCall is only storing the built-in op, and function name or constructor type. argumentsNode
+ // has the arguments.
TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
- TIntermNode *paramNode,
+ TIntermAggregate *argumentsNode,
TIntermNode *thisNode,
- const TSourceLoc &loc,
- bool *fatalError);
+ const TSourceLoc &loc);
TIntermTyped *addTernarySelection(TIntermTyped *cond,
TIntermTyped *trueExpression,
diff --git a/src/compiler/translator/Types.h b/src/compiler/translator/Types.h
index 2d23264..676036c 100644
--- a/src/compiler/translator/Types.h
+++ b/src/compiler/translator/Types.h
@@ -484,7 +484,6 @@
private:
void invalidateMangledName() { mangled = ""; }
TString buildMangledName() const;
- size_t getStructSize() const;
TBasicType type;
TPrecision precision;
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index bbc7ba9..3d3cbc3 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -76,6 +76,7 @@
union {
TIntermNode *intermNode;
TIntermNodePair nodePair;
+ TIntermFunctionCallOrMethod callOrMethodPair;
TIntermTyped *intermTypedNode;
TIntermAggregate *intermAggregate;
TIntermBlock *intermBlock;
@@ -314,24 +315,19 @@
function_call
: function_call_or_method {
- bool fatalError = false;
- $$ = context->addFunctionCallOrMethod($1.function, $1.nodePair.node1, $1.nodePair.node2, @1, &fatalError);
- if (fatalError)
- {
- YYERROR;
- }
+ $$ = context->addFunctionCallOrMethod($1.function, $1.callOrMethodPair.argumentsNode, $1.callOrMethodPair.thisNode, @1);
}
;
function_call_or_method
: function_call_generic {
$$ = $1;
- $$.nodePair.node2 = nullptr;
+ $$.callOrMethodPair.thisNode = nullptr;
}
| postfix_expression DOT function_call_generic {
ES3_OR_NEWER("", @3, "methods");
$$ = $3;
- $$.nodePair.node2 = $1;
+ $$.callOrMethodPair.thisNode = $1;
}
;
@@ -347,26 +343,23 @@
function_call_header_no_parameters
: function_call_header VOID_TYPE {
$$.function = $1;
- $$.nodePair.node1 = nullptr;
+ $$.callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode(@1);
}
| function_call_header {
$$.function = $1;
- $$.nodePair.node1 = nullptr;
+ $$.callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode(@1);
}
;
function_call_header_with_parameters
: function_call_header assignment_expression {
- const TType *type = new TType($2->getType());
- $1->addParameter(TConstParameter(type));
+ $$.callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode(@1);
$$.function = $1;
- $$.nodePair.node1 = TIntermediate::MakeAggregate($2, @2);
+ $$.callOrMethodPair.argumentsNode->getSequence()->push_back($2);
}
| function_call_header_with_parameters COMMA assignment_expression {
- const TType *type = new TType($3->getType());
- $1.function->addParameter(TConstParameter(type));
$$.function = $1.function;
- $$.nodePair.node1 = context->intermediate.growAggregate($1.intermNode, $3, @2);
+ $$.callOrMethodPair.argumentsNode->getSequence()->push_back($3);
}
;
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 0454af4..56bbe02 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -308,6 +308,7 @@
union {
TIntermNode *intermNode;
TIntermNodePair nodePair;
+ TIntermFunctionCallOrMethod callOrMethodPair;
TIntermTyped *intermTypedNode;
TIntermAggregate *intermAggregate;
TIntermBlock *intermBlock;
@@ -737,36 +738,36 @@
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 245, 245, 246, 249, 259, 262, 267, 272, 277,
- 282, 288, 291, 294, 297, 300, 303, 309, 316, 327,
- 331, 339, 342, 348, 352, 359, 365, 374, 382, 388,
- 394, 403, 406, 409, 412, 422, 423, 424, 425, 433,
- 434, 437, 440, 447, 448, 451, 457, 458, 462, 469,
- 470, 473, 476, 479, 485, 486, 489, 495, 496, 503,
- 504, 511, 512, 519, 520, 526, 527, 533, 534, 540,
- 541, 547, 548, 555, 556, 557, 558, 562, 563, 564,
- 568, 572, 576, 580, 587, 590, 596, 603, 610, 613,
- 616, 625, 629, 633, 637, 641, 648, 655, 658, 665,
- 673, 693, 703, 711, 736, 740, 744, 748, 755, 762,
- 765, 769, 773, 778, 783, 790, 794, 798, 802, 807,
- 812, 819, 823, 829, 832, 838, 842, 849, 855, 859,
- 863, 866, 869, 878, 884, 892, 895, 915, 934, 941,
- 945, 949, 952, 955, 958, 961, 964, 972, 979, 982,
- 985, 991, 998, 1001, 1007, 1010, 1013, 1016, 1022, 1025,
- 1030, 1041, 1044, 1047, 1050, 1053, 1056, 1060, 1064, 1068,
- 1072, 1076, 1080, 1084, 1088, 1092, 1096, 1100, 1104, 1108,
- 1112, 1116, 1120, 1124, 1128, 1132, 1136, 1140, 1143, 1146,
- 1149, 1152, 1155, 1158, 1161, 1164, 1167, 1170, 1173, 1176,
- 1179, 1182, 1185, 1188, 1191, 1194, 1201, 1207, 1210, 1213,
- 1216, 1219, 1222, 1225, 1228, 1231, 1234, 1237, 1240, 1243,
- 1246, 1258, 1258, 1261, 1261, 1267, 1270, 1276, 1279, 1286,
- 1290, 1296, 1302, 1314, 1318, 1322, 1323, 1329, 1330, 1331,
- 1332, 1333, 1334, 1335, 1339, 1340, 1340, 1340, 1349, 1350,
- 1354, 1354, 1355, 1355, 1360, 1363, 1372, 1377, 1384, 1385,
- 1389, 1396, 1400, 1407, 1407, 1414, 1417, 1424, 1428, 1441,
- 1441, 1446, 1446, 1452, 1452, 1460, 1463, 1469, 1472, 1478,
- 1482, 1489, 1492, 1495, 1498, 1501, 1510, 1516, 1522, 1525,
- 1531, 1531
+ 0, 246, 246, 247, 250, 260, 263, 268, 273, 278,
+ 283, 289, 292, 295, 298, 301, 304, 310, 317, 323,
+ 327, 335, 338, 344, 348, 355, 360, 367, 375, 381,
+ 387, 396, 399, 402, 405, 415, 416, 417, 418, 426,
+ 427, 430, 433, 440, 441, 444, 450, 451, 455, 462,
+ 463, 466, 469, 472, 478, 479, 482, 488, 489, 496,
+ 497, 504, 505, 512, 513, 519, 520, 526, 527, 533,
+ 534, 540, 541, 548, 549, 550, 551, 555, 556, 557,
+ 561, 565, 569, 573, 580, 583, 589, 596, 603, 606,
+ 609, 618, 622, 626, 630, 634, 641, 648, 651, 658,
+ 666, 686, 696, 704, 729, 733, 737, 741, 748, 755,
+ 758, 762, 766, 771, 776, 783, 787, 791, 795, 800,
+ 805, 812, 816, 822, 825, 831, 835, 842, 848, 852,
+ 856, 859, 862, 871, 877, 885, 888, 908, 927, 934,
+ 938, 942, 945, 948, 951, 954, 957, 965, 972, 975,
+ 978, 984, 991, 994, 1000, 1003, 1006, 1009, 1015, 1018,
+ 1023, 1034, 1037, 1040, 1043, 1046, 1049, 1053, 1057, 1061,
+ 1065, 1069, 1073, 1077, 1081, 1085, 1089, 1093, 1097, 1101,
+ 1105, 1109, 1113, 1117, 1121, 1125, 1129, 1133, 1136, 1139,
+ 1142, 1145, 1148, 1151, 1154, 1157, 1160, 1163, 1166, 1169,
+ 1172, 1175, 1178, 1181, 1184, 1187, 1194, 1200, 1203, 1206,
+ 1209, 1212, 1215, 1218, 1221, 1224, 1227, 1230, 1233, 1236,
+ 1239, 1251, 1251, 1254, 1254, 1260, 1263, 1269, 1272, 1279,
+ 1283, 1289, 1295, 1307, 1311, 1315, 1316, 1322, 1323, 1324,
+ 1325, 1326, 1327, 1328, 1332, 1333, 1333, 1333, 1342, 1343,
+ 1347, 1347, 1348, 1348, 1353, 1356, 1365, 1370, 1377, 1378,
+ 1382, 1389, 1393, 1400, 1400, 1407, 1410, 1417, 1421, 1434,
+ 1434, 1439, 1439, 1445, 1445, 1453, 1456, 1462, 1465, 1471,
+ 1475, 1482, 1485, 1488, 1491, 1494, 1503, 1509, 1515, 1518,
+ 1524, 1524
};
#endif
@@ -2618,12 +2619,7 @@
case 18:
{
- bool fatalError = false;
- (yyval.interm.intermTypedNode) = context->addFunctionCallOrMethod((yyvsp[0].interm).function, (yyvsp[0].interm).nodePair.node1, (yyvsp[0].interm).nodePair.node2, (yylsp[0]), &fatalError);
- if (fatalError)
- {
- YYERROR;
- }
+ (yyval.interm.intermTypedNode) = context->addFunctionCallOrMethod((yyvsp[0].interm).function, (yyvsp[0].interm).callOrMethodPair.argumentsNode, (yyvsp[0].interm).callOrMethodPair.thisNode, (yylsp[0]));
}
break;
@@ -2632,7 +2628,7 @@
{
(yyval.interm) = (yyvsp[0].interm);
- (yyval.interm).nodePair.node2 = nullptr;
+ (yyval.interm).callOrMethodPair.thisNode = nullptr;
}
break;
@@ -2642,7 +2638,7 @@
{
ES3_OR_NEWER("", (yylsp[0]), "methods");
(yyval.interm) = (yyvsp[0].interm);
- (yyval.interm).nodePair.node2 = (yyvsp[-2].interm.intermTypedNode);
+ (yyval.interm).callOrMethodPair.thisNode = (yyvsp[-2].interm.intermTypedNode);
}
break;
@@ -2667,7 +2663,7 @@
{
(yyval.interm).function = (yyvsp[-1].interm.function);
- (yyval.interm).nodePair.node1 = nullptr;
+ (yyval.interm).callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode((yylsp[-1]));
}
break;
@@ -2676,7 +2672,7 @@
{
(yyval.interm).function = (yyvsp[0].interm.function);
- (yyval.interm).nodePair.node1 = nullptr;
+ (yyval.interm).callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode((yylsp[0]));
}
break;
@@ -2684,10 +2680,9 @@
case 25:
{
- const TType *type = new TType((yyvsp[0].interm.intermTypedNode)->getType());
- (yyvsp[-1].interm.function)->addParameter(TConstParameter(type));
+ (yyval.interm).callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode((yylsp[-1]));
(yyval.interm).function = (yyvsp[-1].interm.function);
- (yyval.interm).nodePair.node1 = TIntermediate::MakeAggregate((yyvsp[0].interm.intermTypedNode), (yylsp[0]));
+ (yyval.interm).callOrMethodPair.argumentsNode->getSequence()->push_back((yyvsp[0].interm.intermTypedNode));
}
break;
@@ -2695,10 +2690,8 @@
case 26:
{
- const TType *type = new TType((yyvsp[0].interm.intermTypedNode)->getType());
- (yyvsp[-2].interm).function->addParameter(TConstParameter(type));
(yyval.interm).function = (yyvsp[-2].interm).function;
- (yyval.interm).nodePair.node1 = context->intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ (yyval.interm).callOrMethodPair.argumentsNode->getSequence()->push_back((yyvsp[0].interm.intermTypedNode));
}
break;
diff --git a/src/compiler/translator/glslang_tab.h b/src/compiler/translator/glslang_tab.h
index b68cd51..fb7399c 100644
--- a/src/compiler/translator/glslang_tab.h
+++ b/src/compiler/translator/glslang_tab.h
@@ -220,6 +220,7 @@
union {
TIntermNode *intermNode;
TIntermNodePair nodePair;
+ TIntermFunctionCallOrMethod callOrMethodPair;
TIntermTyped *intermTypedNode;
TIntermAggregate *intermAggregate;
TIntermBlock *intermBlock;