Commit af6fc1b4 by Olli Etuaho Committed by Commit Bot

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/433468Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent ccab69d6
...@@ -43,17 +43,17 @@ TIntermSymbol *CreateReturnValueOutSymbol(const TType &type) ...@@ -43,17 +43,17 @@ TIntermSymbol *CreateReturnValueOutSymbol(const TType &type)
TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall, TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall,
TIntermTyped *returnValueTarget) TIntermTyped *returnValueTarget)
{ {
TIntermAggregate *replacementCall = new TIntermAggregate(EOpCallFunctionInAST); TIntermSequence *replacementArguments = new TIntermSequence();
replacementCall->setType(TType(EbtVoid)); TIntermSequence *originalArguments = originalCall->getSequence();
*replacementCall->getFunctionSymbolInfo() = *originalCall->getFunctionSymbolInfo(); for (auto &arg : *originalArguments)
replacementCall->setLine(originalCall->getLine());
TIntermSequence *replacementParameters = replacementCall->getSequence();
TIntermSequence *originalParameters = originalCall->getSequence();
for (auto &param : *originalParameters)
{ {
replacementParameters->push_back(param); replacementArguments->push_back(arg);
} }
replacementParameters->push_back(returnValueTarget); replacementArguments->push_back(returnValueTarget);
TIntermAggregate *replacementCall =
new TIntermAggregate(TType(EbtVoid), EOpCallFunctionInAST, replacementArguments);
*replacementCall->getFunctionSymbolInfo() = *originalCall->getFunctionSymbolInfo();
replacementCall->setLine(originalCall->getLine());
return replacementCall; return replacementCall;
} }
......
...@@ -50,10 +50,10 @@ TIntermFunctionDefinition *CreateFunctionDefinitionNode(const char *name, ...@@ -50,10 +50,10 @@ TIntermFunctionDefinition *CreateFunctionDefinitionNode(const char *name,
TIntermAggregate *CreateFunctionCallNode(const char *name, const int functionId) TIntermAggregate *CreateFunctionCallNode(const char *name, const int functionId)
{ {
TIntermAggregate *functionNode = new TIntermAggregate(EOpCallFunctionInAST);
SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
TType returnType(EbtVoid); TType returnType(EbtVoid);
functionNode->setType(returnType); TIntermAggregate *functionNode =
new TIntermAggregate(returnType, EOpCallFunctionInAST, nullptr);
SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
functionNode->getFunctionSymbolInfo()->setId(functionId); functionNode->getFunctionSymbolInfo()->setId(functionId);
return functionNode; return functionNode;
} }
......
...@@ -427,13 +427,14 @@ bool canRoundFloat(const TType &type) ...@@ -427,13 +427,14 @@ bool canRoundFloat(const TType &type)
(type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium); (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::GetMangledNameFromCall(name, *arguments));
TName nameObj(TFunction::mangleName(name));
nameObj.setInternal(true); nameObj.setInternal(true);
TIntermAggregate *callNode = new TIntermAggregate(type, EOpCallInternalRawFunction, arguments);
callNode->getFunctionSymbolInfo()->setNameObj(nameObj); callNode->getFunctionSymbolInfo()->setNameObj(nameObj);
callNode->getSequence()->push_back(child);
return callNode; return callNode;
} }
...@@ -444,9 +445,9 @@ TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild) ...@@ -444,9 +445,9 @@ TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild)
roundFunctionName = "angle_frm"; roundFunctionName = "angle_frm";
else else
roundFunctionName = "angle_frl"; roundFunctionName = "angle_frl";
TIntermAggregate *callNode = createInternalFunctionCallNode(roundFunctionName, roundedChild); TIntermSequence *arguments = new TIntermSequence();
callNode->setType(roundedChild->getType()); arguments->push_back(roundedChild);
return callNode; return createInternalFunctionCallNode(roundedChild->getType(), roundFunctionName, arguments);
} }
TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left, TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
...@@ -459,9 +460,10 @@ TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left, ...@@ -459,9 +460,10 @@ TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
else else
strstr << "angle_compound_" << opNameStr << "_frl"; strstr << "angle_compound_" << opNameStr << "_frl";
TString functionName = strstr.str().c_str(); TString functionName = strstr.str().c_str();
TIntermAggregate *callNode = createInternalFunctionCallNode(functionName, left); TIntermSequence *arguments = new TIntermSequence();
callNode->getSequence()->push_back(right); arguments->push_back(left);
return callNode; arguments->push_back(right);
return createInternalFunctionCallNode(TType(EbtVoid), functionName, arguments);
} }
bool parentUsesResult(TIntermNode *parent, TIntermNode *node) bool parentUsesResult(TIntermNode *parent, TIntermNode *node)
......
...@@ -136,15 +136,6 @@ struct TIntermNodePair ...@@ -136,15 +136,6 @@ struct TIntermNodePair
}; };
// //
// This is just to help yacc.
//
struct TIntermFunctionCallOrMethod
{
TIntermAggregate *argumentsNode;
TIntermNode *thisNode;
};
//
// Intermediate class for nodes that have a type. // Intermediate class for nodes that have a type.
// //
class TIntermTyped : public TIntermNode class TIntermTyped : public TIntermNode
...@@ -569,6 +560,15 @@ class TFunctionSymbolInfo ...@@ -569,6 +560,15 @@ class TFunctionSymbolInfo
typedef TVector<TIntermNode *> TIntermSequence; typedef TVector<TIntermNode *> TIntermSequence;
typedef TVector<int> TQualifierList; 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. // Interface for node classes that have an arbitrarily sized set of children.
class TIntermAggregateBase class TIntermAggregateBase
{ {
...@@ -593,19 +593,12 @@ class TIntermAggregateBase ...@@ -593,19 +593,12 @@ class TIntermAggregateBase
class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
{ {
public: public:
TIntermAggregate(TOperator op) TIntermAggregate(const TType &type, TOperator op, TIntermSequence *arguments);
: TIntermOperator(op),
mUseEmulatedFunction(false),
mGotPrecisionFromChildren(false)
{
}
~TIntermAggregate() {} ~TIntermAggregate() {}
// Note: only supported for nodes that can be a part of an expression. // Note: only supported for nodes that can be a part of an expression.
TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); } TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }
void setOp(TOperator op) { mOp = op; }
TIntermAggregate *getAsAggregate() override { return this; } TIntermAggregate *getAsAggregate() override { return this; }
void traverse(TIntermTraverser *it) override; void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
...@@ -614,29 +607,24 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase ...@@ -614,29 +607,24 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
bool hasSideEffects() const override { return true; } bool hasSideEffects() const override { return true; }
TIntermTyped *fold(TDiagnostics *diagnostics); TIntermTyped *fold(TDiagnostics *diagnostics);
TIntermSequence *getSequence() override { return &mSequence; } TIntermSequence *getSequence() override { return &mArguments; }
const TIntermSequence *getSequence() const override { return &mSequence; } const TIntermSequence *getSequence() const override { return &mArguments; }
void setUseEmulatedFunction() { mUseEmulatedFunction = true; } void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; } 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. // Returns true if changing parameter precision may affect the return value.
bool gotPrecisionFromChildren() const { return mGotPrecisionFromChildren; } bool gotPrecisionFromChildren() const { return mGotPrecisionFromChildren; }
TFunctionSymbolInfo *getFunctionSymbolInfo() { return &mFunctionInfo; } TFunctionSymbolInfo *getFunctionSymbolInfo() { return &mFunctionInfo; }
const TFunctionSymbolInfo *getFunctionSymbolInfo() const { 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: protected:
TIntermSequence mSequence; TIntermSequence mArguments;
// If set to true, replace the built-in function call with an emulated one // 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*. // to work around driver bugs. Only for calls mapped to ops other than EOpCall*.
...@@ -649,6 +637,14 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase ...@@ -649,6 +637,14 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
private: private:
TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just 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. // Returns true if precision was set according to special rules for this built-in.
bool setPrecisionForSpecialBuiltInOp(); bool setPrecisionForSpecialBuiltInOp();
}; };
......
...@@ -112,7 +112,7 @@ class TParseContext : angle::NonCopyable ...@@ -112,7 +112,7 @@ class TParseContext : angle::NonCopyable
void checkIsScalarInteger(TIntermTyped *node, const char *token); void checkIsScalarInteger(TIntermTyped *node, const char *token);
bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token); bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
bool checkConstructorArguments(const TSourceLoc &line, bool checkConstructorArguments(const TSourceLoc &line,
const TIntermAggregate *argumentsNode, const TIntermSequence *arguments,
TOperator op, TOperator op,
const TType &type); const TType &type);
...@@ -167,10 +167,6 @@ class TParseContext : angle::NonCopyable ...@@ -167,10 +167,6 @@ class TParseContext : angle::NonCopyable
const char *value, const char *value,
bool stdgl); bool stdgl);
const TFunction *findFunction(const TSourceLoc &line,
TFunction *pfnCall,
int inputShaderVersion,
bool *builtIn = 0);
bool executeInitializer(const TSourceLoc &line, bool executeInitializer(const TSourceLoc &line,
const TString &identifier, const TString &identifier,
const TPublicType &pType, const TPublicType &pType,
...@@ -252,10 +248,6 @@ class TParseContext : angle::NonCopyable ...@@ -252,10 +248,6 @@ class TParseContext : angle::NonCopyable
const TString *name, const TString *name,
const TSourceLoc &location); const TSourceLoc &location);
TFunction *addConstructorFunc(const TPublicType &publicType); TFunction *addConstructorFunc(const TPublicType &publicType);
TIntermTyped *addConstructor(TIntermAggregate *arguments,
TOperator op,
TType type,
const TSourceLoc &line);
TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
const TSourceLoc &location, const TSourceLoc &location,
...@@ -345,12 +337,12 @@ class TParseContext : angle::NonCopyable ...@@ -345,12 +337,12 @@ class TParseContext : angle::NonCopyable
void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall); void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition, void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
const TIntermAggregate *functionCall); 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. // has the arguments.
TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
TIntermAggregate *argumentsNode, TIntermSequence *arguments,
TIntermNode *thisNode, TIntermNode *thisNode,
const TSourceLoc &loc); const TSourceLoc &loc);
...@@ -406,9 +398,19 @@ class TParseContext : angle::NonCopyable ...@@ -406,9 +398,19 @@ class TParseContext : angle::NonCopyable
TIntermTyped *left, TIntermTyped *left,
TIntermTyped *right, TIntermTyped *right,
const TSourceLoc &loc); const TSourceLoc &loc);
TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
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 // Return true if the checks pass
bool binaryOpCommonCheck(TOperator op, bool binaryOpCommonCheck(TOperator op,
......
...@@ -113,11 +113,9 @@ TIntermTyped *EnsureSignedInt(TIntermTyped *node) ...@@ -113,11 +113,9 @@ TIntermTyped *EnsureSignedInt(TIntermTyped *node)
if (node->getBasicType() == EbtInt) if (node->getBasicType() == EbtInt)
return node; return node;
TIntermAggregate *convertedNode = new TIntermAggregate(EOpConstructInt); TIntermSequence *arguments = new TIntermSequence();
convertedNode->setType(TType(EbtInt)); arguments->push_back(node);
convertedNode->getSequence()->push_back(node); return new TIntermAggregate(TType(EbtInt), EOpConstructInt, arguments);
convertedNode->setPrecisionFromChildren();
return convertedNode;
} }
TType GetFieldType(const TType &indexedType) TType GetFieldType(const TType &indexedType)
...@@ -351,15 +349,16 @@ TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node, ...@@ -351,15 +349,16 @@ TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node,
TIntermTyped *index) TIntermTyped *index)
{ {
ASSERT(node->getOp() == EOpIndexIndirect); 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->setLine(node->getLine());
indexingCall->getFunctionSymbolInfo()->setNameObj( indexingCall->getFunctionSymbolInfo()->setNameObj(
GetIndexFunctionName(indexedNode->getType(), false)); GetIndexFunctionName(indexedNode->getType(), false));
indexingCall->getSequence()->push_back(indexedNode);
indexingCall->getSequence()->push_back(index);
TType fieldType = GetFieldType(indexedNode->getType());
indexingCall->setType(fieldType);
return indexingCall; return indexingCall;
} }
......
...@@ -94,14 +94,11 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -94,14 +94,11 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
// Create new node that represents the call of function texelFetch. // Create new node that represents the call of function texelFetch.
// Its argument list will be: texelFetch(sampler, Position+offset, lod). // Its argument list will be: texelFetch(sampler, Position+offset, lod).
TIntermAggregate *texelFetchNode = new TIntermAggregate(EOpCallBuiltInFunction);
texelFetchNode->getFunctionSymbolInfo()->setName(newName); TIntermSequence *texelFetchArguments = new TIntermSequence();
texelFetchNode->getFunctionSymbolInfo()->setId(uniqueId);
texelFetchNode->setType(node->getType());
texelFetchNode->setLine(node->getLine());
// sampler // sampler
texelFetchNode->getSequence()->push_back(sequence->at(0)); texelFetchArguments->push_back(sequence->at(0));
// Position // Position
TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped(); TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped();
...@@ -114,20 +111,15 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -114,20 +111,15 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
// For 2DArray samplers, Position is ivec3 and offset is ivec2; // For 2DArray samplers, Position is ivec3 and offset is ivec2;
// So offset must be converted into an ivec3 before being added to Position. // So offset must be converted into an ivec3 before being added to Position.
TIntermAggregate *constructIVec3Node = new TIntermAggregate(EOpConstructIVec3); TIntermSequence *constructOffsetIvecArguments = new TIntermSequence();
constructIVec3Node->setLine(texCoordNode->getLine()); constructOffsetIvecArguments->push_back(sequence->at(3)->getAsTyped());
constructIVec3Node->setType(texCoordNode->getType());
constructIVec3Node->getSequence()->push_back(sequence->at(3)->getAsTyped());
TConstantUnion *zero = new TConstantUnion(); TIntermTyped *zeroNode = TIntermTyped::CreateZero(TType(EbtInt));
zero->setIConst(0); constructOffsetIvecArguments->push_back(zeroNode);
TType *intType = new TType(EbtInt);
TIntermConstantUnion *zeroNode = new TIntermConstantUnion(zero, *intType); offsetNode = new TIntermAggregate(texCoordNode->getType(), EOpConstructIVec3,
constructIVec3Node->getSequence()->push_back(zeroNode); constructOffsetIvecArguments);
offsetNode->setLine(texCoordNode->getLine());
offsetNode = constructIVec3Node;
} }
else else
{ {
...@@ -137,12 +129,18 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -137,12 +129,18 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
// Position+offset // Position+offset
TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode); TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode);
add->setLine(texCoordNode->getLine()); add->setLine(texCoordNode->getLine());
texelFetchNode->getSequence()->push_back(add); texelFetchArguments->push_back(add);
// lod // lod
texelFetchNode->getSequence()->push_back(sequence->at(2)); texelFetchArguments->push_back(sequence->at(2));
ASSERT(texelFetchArguments->size() == 3u);
ASSERT(texelFetchNode->getSequence()->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. // Replace the old node by this new node.
queueReplacement(node, texelFetchNode, OriginalNode::IS_DROPPED); queueReplacement(node, texelFetchNode, OriginalNode::IS_DROPPED);
......
...@@ -58,10 +58,9 @@ TIntermBinary *CopyAssignmentNode(TIntermBinary *node) ...@@ -58,10 +58,9 @@ TIntermBinary *CopyAssignmentNode(TIntermBinary *node)
// Performs a shallow copy of a constructor/function call node. // Performs a shallow copy of a constructor/function call node.
TIntermAggregate *CopyAggregateNode(TIntermAggregate *node) TIntermAggregate *CopyAggregateNode(TIntermAggregate *node)
{ {
TIntermAggregate *copyNode = new TIntermAggregate(node->getOp()); TIntermSequence *copySeq = new TIntermSequence();
TIntermSequence *copySeq = copyNode->getSequence();
copySeq->insert(copySeq->begin(), node->getSequence()->begin(), node->getSequence()->end()); 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(); *copyNode->getFunctionSymbolInfo() = *node->getFunctionSymbolInfo();
return copyNode; return copyNode;
} }
......
...@@ -67,6 +67,17 @@ const TString *TFunction::buildMangledName() const ...@@ -67,6 +67,17 @@ const TString *TFunction::buildMangledName() const
return NewPoolTString(newName.c_str()); 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. // Symbol table levels are a map of pointers to symbols that have to be deleted.
// //
...@@ -160,22 +171,12 @@ TFunction *TSymbolTable::findBuiltInOp(TIntermAggregate *callNode, int shaderVer ...@@ -160,22 +171,12 @@ TFunction *TSymbolTable::findBuiltInOp(TIntermAggregate *callNode, int shaderVer
ASSERT(!callNode->isConstructor()); ASSERT(!callNode->isConstructor());
ASSERT(!callNode->isFunctionCall()); ASSERT(!callNode->isFunctionCall());
TString opString = GetOperatorString(callNode->getOp()); TString opString = GetOperatorString(callNode->getOp());
// The return type doesn't affect the mangled name of the function, which is used to look it up. TSymbol *sym = findBuiltIn(
TType dummyReturnType; TFunction::GetMangledNameFromCall(opString, *callNode->getSequence()), shaderVersion);
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);
ASSERT(sym != nullptr && sym->isFunction()); ASSERT(sym != nullptr && sym->isFunction());
TFunction *builtInFunc = static_cast<TFunction *>(sym); TFunction *builtInFunc = static_cast<TFunction *>(sym);
ASSERT(builtInFunc->getParamCount() == sequence->size()); ASSERT(builtInFunc->getParamCount() == callNode->getSequence()->size());
return builtInFunc; return builtInFunc;
} }
......
...@@ -41,8 +41,6 @@ ...@@ -41,8 +41,6 @@
namespace sh namespace sh
{ {
class TIntermAggregate;
// Symbol base class. (Can build functions or variables out of these...) // Symbol base class. (Can build functions or variables out of these...)
class TSymbol : angle::NonCopyable class TSymbol : angle::NonCopyable
{ {
...@@ -182,6 +180,10 @@ class TFunction : public TSymbol ...@@ -182,6 +180,10 @@ class TFunction : public TSymbol
} }
return *mangledName; return *mangledName;
} }
static const TString &GetMangledNameFromCall(const TString &unmangledFunctionName,
TIntermSequence &arguments);
const TType &getReturnType() const { return *returnType; } const TType &getReturnType() const { return *returnType; }
TOperator getBuiltInOp() const { return op; } TOperator getBuiltInOp() const { return op; }
......
...@@ -315,7 +315,7 @@ integer_expression ...@@ -315,7 +315,7 @@ integer_expression
function_call function_call
: function_call_or_method { : 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_generic ...@@ -343,23 +343,23 @@ function_call_generic
function_call_header_no_parameters function_call_header_no_parameters
: function_call_header VOID_TYPE { : function_call_header VOID_TYPE {
$$.function = $1; $$.function = $1;
$$.callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode(@1); $$.callOrMethodPair.arguments = context->createEmptyArgumentsList();
} }
| function_call_header { | function_call_header {
$$.function = $1; $$.function = $1;
$$.callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode(@1); $$.callOrMethodPair.arguments = context->createEmptyArgumentsList();
} }
; ;
function_call_header_with_parameters function_call_header_with_parameters
: function_call_header assignment_expression { : function_call_header assignment_expression {
$$.callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode(@1); $$.callOrMethodPair.arguments = context->createEmptyArgumentsList();
$$.function = $1; $$.function = $1;
$$.callOrMethodPair.argumentsNode->getSequence()->push_back($2); $$.callOrMethodPair.arguments->push_back($2);
} }
| function_call_header_with_parameters COMMA assignment_expression { | function_call_header_with_parameters COMMA assignment_expression {
$$.function = $1.function; $$.function = $1.function;
$$.callOrMethodPair.argumentsNode->getSequence()->push_back($3); $$.callOrMethodPair.arguments->push_back($3);
} }
; ;
......
...@@ -2619,7 +2619,7 @@ yyreduce: ...@@ -2619,7 +2619,7 @@ yyreduce:
case 18: 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; break;
...@@ -2663,7 +2663,7 @@ yyreduce: ...@@ -2663,7 +2663,7 @@ yyreduce:
{ {
(yyval.interm).function = (yyvsp[-1].interm.function); (yyval.interm).function = (yyvsp[-1].interm.function);
(yyval.interm).callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode((yylsp[-1])); (yyval.interm).callOrMethodPair.arguments = context->createEmptyArgumentsList();
} }
break; break;
...@@ -2672,7 +2672,7 @@ yyreduce: ...@@ -2672,7 +2672,7 @@ yyreduce:
{ {
(yyval.interm).function = (yyvsp[0].interm.function); (yyval.interm).function = (yyvsp[0].interm.function);
(yyval.interm).callOrMethodPair.argumentsNode = context->createEmptyArgumentsNode((yylsp[0])); (yyval.interm).callOrMethodPair.arguments = context->createEmptyArgumentsList();
} }
break; break;
...@@ -2680,9 +2680,9 @@ yyreduce: ...@@ -2680,9 +2680,9 @@ yyreduce:
case 25: 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).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; break;
...@@ -2691,7 +2691,7 @@ yyreduce: ...@@ -2691,7 +2691,7 @@ yyreduce:
{ {
(yyval.interm).function = (yyvsp[-2].interm).function; (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; break;
......
...@@ -184,14 +184,14 @@ TEST_F(IntermNodeTest, DeepCopyUnaryNode) ...@@ -184,14 +184,14 @@ TEST_F(IntermNodeTest, DeepCopyUnaryNode)
// original. Child nodes also need to be copies with the same attributes as the original children. // original. Child nodes also need to be copies with the same attributes as the original children.
TEST_F(IntermNodeTest, DeepCopyAggregateNode) TEST_F(IntermNodeTest, DeepCopyAggregateNode)
{ {
TType type(EbtFloat, EbpHigh); TIntermSequence *originalSeq = new TIntermSequence();
TIntermAggregate *original = new TIntermAggregate(EOpMix);
original->setLine(getTestSourceLoc());
TIntermSequence *originalSeq = original->getSequence();
originalSeq->push_back(createTestSymbol()); originalSeq->push_back(createTestSymbol());
originalSeq->push_back(createTestSymbol()); originalSeq->push_back(createTestSymbol());
originalSeq->push_back(createTestSymbol()); originalSeq->push_back(createTestSymbol());
TIntermAggregate *original =
new TIntermAggregate(originalSeq->at(0)->getAsTyped()->getType(), EOpMix, originalSeq);
original->setLine(getTestSourceLoc());
TIntermTyped *copyTyped = original->deepCopy(); TIntermTyped *copyTyped = original->deepCopy();
TIntermAggregate *copy = copyTyped->getAsAggregate(); TIntermAggregate *copy = copyTyped->getAsAggregate();
ASSERT_NE(nullptr, copy); ASSERT_NE(nullptr, copy);
...@@ -203,7 +203,7 @@ TEST_F(IntermNodeTest, DeepCopyAggregateNode) ...@@ -203,7 +203,7 @@ TEST_F(IntermNodeTest, DeepCopyAggregateNode)
TIntermSequence::size_type i = 0; TIntermSequence::size_type i = 0;
for (auto *copyChild : *copy->getSequence()) for (auto *copyChild : *copy->getSequence())
{ {
TIntermNode *originalChild = originalSeq->at(i); TIntermNode *originalChild = original->getSequence()->at(i);
checkSymbolCopy(originalChild, copyChild); checkSymbolCopy(originalChild, copyChild);
++i; ++i;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment