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
// Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type.
//
void TIntermUnary::promote()
void TIntermUnary::promote(const TType *funcReturnType)
{
switch (mOp)
{
// Some built-ins get the type of their return value assigned elsewhere.
case EOpAny:
case EOpAll:
case EOpVectorLogicalNot:
break;
case EOpFloatBitsToInt:
case EOpFloatBitsToUint:
case EOpIntBitsToFloat:
......@@ -355,6 +350,20 @@ void TIntermUnary::promote()
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);
}
......
......@@ -383,7 +383,7 @@ class TIntermUnary : public TIntermOperator
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
void promote();
void promote(const TType *funcReturnType);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
......
......@@ -127,7 +127,7 @@ TIntermTyped *TIntermediate::addIndex(
// Returns the added node.
//
TIntermTyped *TIntermediate::addUnaryMath(
TOperator op, TIntermTyped *child, const TSourceLoc &line)
TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType)
{
TIntermConstantUnion *childTempConstant = 0;
if (child->getAsConstantUnion())
......@@ -139,7 +139,7 @@ TIntermTyped *TIntermediate::addUnaryMath(
TIntermUnary *node = new TIntermUnary(op);
node->setLine(line);
node->setOperand(child);
node->promote();
node->promote(funcReturnType);
if (childTempConstant)
{
......
......@@ -35,7 +35,7 @@ class TIntermediate
TIntermTyped *addIndex(
TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &);
TIntermTyped *addUnaryMath(
TOperator op, TIntermTyped *child, const TSourceLoc &line);
TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType);
TIntermAggregate *growAggregate(
TIntermNode *left, TIntermNode *right, const TSourceLoc &);
TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &);
......
......@@ -2697,7 +2697,8 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
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)
{
......@@ -2740,12 +2741,12 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child,
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 *node = createUnaryMath(op, child, loc);
TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
if (node == nullptr)
{
unaryOpError(loc, GetOperatorString(op), child->getCompleteString());
......@@ -3094,7 +3095,7 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN
//
// 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)
{
std::stringstream extraInfoStream;
......@@ -3105,18 +3106,6 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN
*fatalError = true;
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
{
......
......@@ -191,7 +191,10 @@ struct TParseContext {
const TSourceLoc &loc);
TIntermTyped *createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
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
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