Move most of addBinaryMath from Intermediate to ParseContext
Some type checks for binary math will be different based on the shading
language version, which is easily accessible in ParseContext. Because of
this and also for architectural simplicity it makes more sense to have
the checks in ParseContext.
BUG=angle:941
TEST=angle_unittests, WebGL conformance tests
Change-Id: I92a499f47e1cbc6a7b6391ce0fa04284803e7140
Reviewed-on: https://chromium-review.googlesource.com/260570
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index b8398e7..5e0edfd 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -45,60 +45,6 @@
TIntermTyped *TIntermediate::addBinaryMath(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line)
{
- switch (op)
- {
- case EOpEqual:
- case EOpNotEqual:
- if (left->isArray())
- return NULL;
- break;
- case EOpLessThan:
- case EOpGreaterThan:
- case EOpLessThanEqual:
- case EOpGreaterThanEqual:
- if (left->isMatrix() || left->isArray() || left->isVector() ||
- left->getBasicType() == EbtStruct)
- {
- return NULL;
- }
- break;
- case EOpLogicalOr:
- case EOpLogicalXor:
- case EOpLogicalAnd:
- if (left->getBasicType() != EbtBool ||
- left->isMatrix() || left->isArray() || left->isVector())
- {
- return NULL;
- }
- break;
- case EOpAdd:
- case EOpSub:
- case EOpDiv:
- case EOpMul:
- if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
- {
- return NULL;
- }
- break;
- case EOpIMod:
- // Note that this is only for the % operator, not for mod()
- if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
- {
- return NULL;
- }
- break;
- // Note that for bitwise ops, type checking is done in promote() to
- // share code between ops and compound assignment
- default:
- break;
- }
-
- // This check is duplicated between here and node->promote() as an optimization.
- if (left->getBasicType() != right->getBasicType() && op != EOpBitShiftLeft && op != EOpBitShiftRight)
- {
- return NULL;
- }
-
//
// Need a new node holding things together then. Make
// one and promote it to the right type.
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index eb45b27..bf4d105 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -2716,10 +2716,70 @@
return addUnaryMath(op, child, loc);
}
+TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ switch (op)
+ {
+ case EOpEqual:
+ case EOpNotEqual:
+ if (left->isArray())
+ return nullptr;
+ break;
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ if (left->isMatrix() || left->isArray() || left->isVector() ||
+ left->getBasicType() == EbtStruct)
+ {
+ return nullptr;
+ }
+ break;
+ case EOpLogicalOr:
+ case EOpLogicalXor:
+ case EOpLogicalAnd:
+ if (left->getBasicType() != EbtBool ||
+ left->isMatrix() || left->isArray() || left->isVector())
+ {
+ return nullptr;
+ }
+ break;
+ case EOpAdd:
+ case EOpSub:
+ case EOpDiv:
+ case EOpMul:
+ if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
+ {
+ return nullptr;
+ }
+ break;
+ case EOpIMod:
+ // Note that this is only for the % operator, not for mod()
+ if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
+ {
+ return nullptr;
+ }
+ break;
+ // Note that for bitwise ops, type checking is done in promote() to
+ // share code between ops and compound assignment
+ default:
+ break;
+ }
+
+ // This check is duplicated between here and node->promote() as an optimization.
+ if (left->getBasicType() != right->getBasicType() && op != EOpBitShiftLeft && op != EOpBitShiftRight)
+ {
+ return nullptr;
+ }
+
+ return intermediate.addBinaryMath(op, left, right, loc);
+}
+
TIntermTyped *TParseContext::addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc)
{
- TIntermTyped *node = intermediate.addBinaryMath(op, left, right, loc);
+ TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
if (node == 0)
{
binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString());
@@ -2732,7 +2792,7 @@
TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc)
{
- TIntermTyped *node = intermediate.addBinaryMath(op, left, right, loc);
+ TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
if (node == 0)
{
binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString());
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 20f3b36..0e62e39 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -183,6 +183,10 @@
TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *node,
const TSourceLoc &loc, bool *fatalError);
+
+ private:
+ TIntermTyped *addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &loc);
};
int PaParseStrings(size_t count, const char* const string[], const int length[],