Commit f6c694bc by Olli Etuaho

Assign built-in function return type in promote()

This finishes the refactoring of unary math operation handling so that IntermUnary::promote has the complete code for setting the return type of the node. BUG=angleproject:952 TEST=angle_unittests, WebGL conformance tests Change-Id: I19bd8d53029e24f734c9436eceb446b37e7fcf26 Reviewed-on: https://chromium-review.googlesource.com/262416Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent dca3e796
...@@ -328,15 +328,10 @@ bool TIntermOperator::isConstructor() const ...@@ -328,15 +328,10 @@ bool TIntermOperator::isConstructor() const
// Make sure the type of a unary operator is appropriate for its // Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type. // combination of operation and operand type.
// //
void TIntermUnary::promote() void TIntermUnary::promote(const TType *funcReturnType)
{ {
switch (mOp) switch (mOp)
{ {
// Some built-ins get the type of their return value assigned elsewhere.
case EOpAny:
case EOpAll:
case EOpVectorLogicalNot:
break;
case EOpFloatBitsToInt: case EOpFloatBitsToInt:
case EOpFloatBitsToUint: case EOpFloatBitsToUint:
case EOpIntBitsToFloat: case EOpIntBitsToFloat:
...@@ -355,6 +350,20 @@ void TIntermUnary::promote() ...@@ -355,6 +350,20 @@ void TIntermUnary::promote()
setType(mOperand->getType()); setType(mOperand->getType());
} }
if (funcReturnType != nullptr)
{
if (funcReturnType->getBasicType() == EbtBool)
{
// Bool types should not have precision.
setType(*funcReturnType);
}
else
{
// Precision of the node has been set based on the operand.
setTypePreservePrecision(*funcReturnType);
}
}
mType.setQualifier(EvqTemporary); mType.setQualifier(EvqTemporary);
} }
......
...@@ -383,7 +383,7 @@ class TIntermUnary : public TIntermOperator ...@@ -383,7 +383,7 @@ class TIntermUnary : public TIntermOperator
void setOperand(TIntermTyped *operand) { mOperand = operand; } void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; } TIntermTyped *getOperand() { return mOperand; }
void promote(); void promote(const TType *funcReturnType);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; } void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; } bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
......
...@@ -127,7 +127,7 @@ TIntermTyped *TIntermediate::addIndex( ...@@ -127,7 +127,7 @@ TIntermTyped *TIntermediate::addIndex(
// Returns the added node. // Returns the added node.
// //
TIntermTyped *TIntermediate::addUnaryMath( TIntermTyped *TIntermediate::addUnaryMath(
TOperator op, TIntermTyped *child, const TSourceLoc &line) TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType)
{ {
TIntermConstantUnion *childTempConstant = 0; TIntermConstantUnion *childTempConstant = 0;
if (child->getAsConstantUnion()) if (child->getAsConstantUnion())
...@@ -139,7 +139,7 @@ TIntermTyped *TIntermediate::addUnaryMath( ...@@ -139,7 +139,7 @@ TIntermTyped *TIntermediate::addUnaryMath(
TIntermUnary *node = new TIntermUnary(op); TIntermUnary *node = new TIntermUnary(op);
node->setLine(line); node->setLine(line);
node->setOperand(child); node->setOperand(child);
node->promote(); node->promote(funcReturnType);
if (childTempConstant) if (childTempConstant)
{ {
......
...@@ -35,7 +35,7 @@ class TIntermediate ...@@ -35,7 +35,7 @@ class TIntermediate
TIntermTyped *addIndex( TIntermTyped *addIndex(
TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &); TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &);
TIntermTyped *addUnaryMath( TIntermTyped *addUnaryMath(
TOperator op, TIntermTyped *child, const TSourceLoc &line); TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType);
TIntermAggregate *growAggregate( TIntermAggregate *growAggregate(
TIntermNode *left, TIntermNode *right, const TSourceLoc &); TIntermNode *left, TIntermNode *right, const TSourceLoc &);
TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &); TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &);
......
...@@ -2697,7 +2697,8 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc) ...@@ -2697,7 +2697,8 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
return node; return node;
} }
TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc) TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc,
const TType *funcReturnType)
{ {
if (child == nullptr) if (child == nullptr)
{ {
...@@ -2740,12 +2741,12 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, ...@@ -2740,12 +2741,12 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child,
break; break;
} }
return intermediate.addUnaryMath(op, child, loc); return intermediate.addUnaryMath(op, child, loc, funcReturnType);
} }
TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc) TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
{ {
TIntermTyped *node = createUnaryMath(op, child, loc); TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
if (node == nullptr) if (node == nullptr)
{ {
unaryOpError(loc, GetOperatorString(op), child->getCompleteString()); unaryOpError(loc, GetOperatorString(op), child->getCompleteString());
...@@ -3094,7 +3095,7 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN ...@@ -3094,7 +3095,7 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN
// //
// Treat it like a built-in unary operator. // Treat it like a built-in unary operator.
// //
callNode = createUnaryMath(op, node->getAsTyped(), loc); callNode = createUnaryMath(op, node->getAsTyped(), loc, &fnCandidate->getReturnType());
if (callNode == nullptr) if (callNode == nullptr)
{ {
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
...@@ -3105,18 +3106,6 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN ...@@ -3105,18 +3106,6 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN
*fatalError = true; *fatalError = true;
return nullptr; return nullptr;
} }
const TType& returnType = fnCandidate->getReturnType();
if (returnType.getBasicType() == EbtBool)
{
// Bool types should not have precision, so we'll override any precision
// that might have been set by createUnaryMath.
callNode->setType(returnType);
}
else
{
// createUnaryMath has set the precision of the node based on the operand.
callNode->setTypePreservePrecision(returnType);
}
} }
else else
{ {
......
...@@ -191,7 +191,10 @@ struct TParseContext { ...@@ -191,7 +191,10 @@ struct TParseContext {
const TSourceLoc &loc); const TSourceLoc &loc);
TIntermTyped *createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, TIntermTyped *createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc); const TSourceLoc &loc);
TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc); // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
// It is expected to be null for other unary operators.
TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc,
const TType *funcReturnType);
// Return true if the checks pass // Return true if the checks pass
bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right,
......
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