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/262415
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 6b2eadb..910a8b8 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -328,55 +328,34 @@
// 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:
- case EOpUnpackHalf2x16:
- return true;
-
- case EOpAbs:
- case EOpSign:
+ mType.setPrecision(EbpHigh);
break;
-
+ case EOpUnpackHalf2x16:
+ mType.setPrecision(EbpMedium);
+ break;
default:
- if (mOperand->getBasicType() != EbtFloat)
- return false;
+ setType(mOperand->getType());
}
- setType(mOperand->getType());
mType.setQualifier(EvqTemporary);
-
- return true;
}
//
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index f2de2d9..75879c1 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -383,7 +383,7 @@
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
- bool promote(TInfoSink &);
+ void promote();
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index 12fb5bd..b72a2bf 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -139,29 +139,7 @@
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)
{
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 77e70a7..00dbf5e 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -2730,10 +2730,12 @@
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;
}