Always create TFunctions for function call nodes
This simplifies code and ensures that nodes get consistent data.
In the future function call nodes could have a pointer to the
TFunction instead of converting the same information into a different
data structure.
BUG=angleproject:2267
TEST=angle_unittests, angle_end2end_tests
Change-Id: Ic0c24bb86b44b9bcc4a5da7f6b03701081a3af5c
Reviewed-on: https://chromium-review.googlesource.com/824606
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index a2b486d..1ead5a5 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1682,7 +1682,7 @@
{
error(argument->getLine(),
"Writeonly value cannot be passed for 'in' or 'inout' parameters.",
- fnCall->getFunctionSymbolInfo()->getName().c_str());
+ fnCall->functionName());
return;
}
}
@@ -1692,7 +1692,7 @@
{
error(argument->getLine(),
"Constant value cannot be passed for 'out' or 'inout' parameters.",
- fnCall->getFunctionSymbolInfo()->getName().c_str());
+ fnCall->functionName());
return;
}
}
@@ -3442,7 +3442,7 @@
}
// Add the function as a prototype after parsing it (we do not support recursion)
- return new TFunction(&symbolTable, name, new TType(type), SymbolType::UserDefined);
+ return new TFunction(&symbolTable, name, new TType(type), SymbolType::UserDefined, false);
}
TFunction *TParseContext::addNonConstructorFunc(const TString *name, const TSourceLoc &loc)
@@ -3454,7 +3454,7 @@
// would be enough, but TFunction carries a lot of extra information in addition to that.
// Besides function calls we do have to store constructor calls in the same data structure, for
// them we need to store a TType.
- return new TFunction(&symbolTable, name, returnType, SymbolType::NotResolved);
+ return new TFunction(&symbolTable, name, returnType, SymbolType::NotResolved, false);
}
TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType)
@@ -3478,7 +3478,7 @@
type->setBasicType(EbtFloat);
}
- return new TFunction(&symbolTable, nullptr, type, SymbolType::NotResolved, EOpConstruct);
+ return new TFunction(&symbolTable, nullptr, type, SymbolType::NotResolved, true, EOpConstruct);
}
void TParseContext::checkIsNotUnsizedArray(const TSourceLoc &line,
@@ -5757,7 +5757,7 @@
{
if (thisNode != nullptr)
{
- return addMethod(fnCall, arguments, thisNode, loc);
+ return addMethod(fnCall->name(), arguments, thisNode, loc);
}
TOperator op = fnCall->getBuiltInOp();
@@ -5768,11 +5768,11 @@
else
{
ASSERT(op == EOpNull);
- return addNonConstructorFunctionCall(fnCall, arguments, loc);
+ return addNonConstructorFunctionCall(fnCall->name(), arguments, loc);
}
}
-TIntermTyped *TParseContext::addMethod(TFunction *fnCall,
+TIntermTyped *TParseContext::addMethod(const TString *name,
TIntermSequence *arguments,
TIntermNode *thisNode,
const TSourceLoc &loc)
@@ -5782,9 +5782,9 @@
// 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->name() below is safe.
- if (*fnCall->name() != "length")
+ if (*name != "length")
{
- error(loc, "invalid method", fnCall->name()->c_str());
+ error(loc, "invalid method", name->c_str());
}
else if (!arguments->empty())
{
@@ -5809,26 +5809,27 @@
return CreateZeroNode(TType(EbtInt, EbpUndefined, EvqConst));
}
-TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunction *fnCall,
+TIntermTyped *TParseContext::addNonConstructorFunctionCall(const TString *name,
TIntermSequence *arguments,
const TSourceLoc &loc)
{
+ ASSERT(name);
// 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->name(), mShaderVersion, &builtIn);
+ const TSymbol *symbol = symbolTable.find(*name, mShaderVersion, &builtIn);
if (symbol != nullptr && !symbol->isFunction())
{
- error(loc, "function name expected", fnCall->name()->c_str());
+ error(loc, "function name expected", name->c_str());
}
else
{
- symbol = symbolTable.find(TFunction::GetMangledNameFromCall(*fnCall->name(), *arguments),
+ symbol = symbolTable.find(TFunction::GetMangledNameFromCall(*name, *arguments),
mShaderVersion, &builtIn);
if (symbol == nullptr)
{
- error(loc, "no matching overloaded function found", fnCall->name()->c_str());
+ error(loc, "no matching overloaded function found", name->c_str());
}
else
{