Commit dca3e796 by Olli Etuaho

Refactor unary math operator handling to clarify responsibilities

Shuffle the code around so that each part has a clear responsibility: IntermUnary::promote is responsible for setting the return type of the node, Intermediate::addUnaryMath is responsible for creating the node object, and ParseContext::createUnaryMath is responsible for validating the operand type. This removes duplicated bool type check for logical not. BUG=angleproject:952 TEST=angle_unittests, WebGL conformance tests Change-Id: I9f5a0abb6434ad2730441ea9199ec3f5382ebcda Reviewed-on: https://chromium-review.googlesource.com/262415Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 7f67b030
......@@ -328,55 +328,34 @@ bool TIntermOperator::isConstructor() const
// Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type.
//
// Returns false in nothing makes sense.
//
bool TIntermUnary::promote(TInfoSink &)
void TIntermUnary::promote()
{
switch (mOp)
{
case EOpLogicalNot:
if (mOperand->getBasicType() != EbtBool)
return false;
break;
// bit-wise not is already checked
case EOpBitwiseNot:
break;
case EOpNegative:
case EOpPositive:
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
case EOpPreDecrement:
if (mOperand->getBasicType() == EbtBool)
return false;
break;
// Operators for built-ins are already type checked against their prototype
// and some of them get the type of their return value assigned elsewhere.
// 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:
case EOpUintBitsToFloat:
case EOpPackSnorm2x16:
case EOpPackUnorm2x16:
case EOpPackHalf2x16:
case EOpUnpackSnorm2x16:
case EOpUnpackUnorm2x16:
mType.setPrecision(EbpHigh);
break;
case EOpUnpackHalf2x16:
return true;
case EOpAbs:
case EOpSign:
mType.setPrecision(EbpMedium);
break;
default:
if (mOperand->getBasicType() != EbtFloat)
return false;
setType(mOperand->getType());
}
setType(mOperand->getType());
mType.setQualifier(EvqTemporary);
return true;
}
//
......
......@@ -383,7 +383,7 @@ class TIntermUnary : public TIntermOperator
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
bool promote(TInfoSink &);
void promote();
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
......
......@@ -139,29 +139,7 @@ TIntermTyped *TIntermediate::addUnaryMath(
TIntermUnary *node = new TIntermUnary(op);
node->setLine(line);
node->setOperand(child);
if (!node->promote(mInfoSink))
return 0;
switch (op)
{
case EOpFloatBitsToInt:
case EOpFloatBitsToUint:
case EOpIntBitsToFloat:
case EOpUintBitsToFloat:
case EOpPackSnorm2x16:
case EOpPackUnorm2x16:
case EOpPackHalf2x16:
case EOpUnpackSnorm2x16:
case EOpUnpackUnorm2x16:
node->getTypePointer()->setPrecision(EbpHigh);
break;
case EOpUnpackHalf2x16:
node->getTypePointer()->setPrecision(EbpMedium);
break;
default:
break;
}
node->promote();
if (childTempConstant)
{
......
......@@ -2730,10 +2730,12 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child,
case EOpNegative:
case EOpPositive:
if (child->getBasicType() == EbtStruct ||
child->getBasicType() == EbtBool ||
child->isArray())
{
return nullptr;
}
// Operators for built-ins are already type checked against their prototype.
default:
break;
}
......
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