Implement support of unary operator "+" in translator.
BUG=angle:779
TEST=conformance/glsl/misc/struct-unary-operators.html
Change-Id: Ia827e07dcfc8ad3bbbc078e54336815be9027945
Reviewed-on: https://chromium-review.googlesource.com/222720
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Tested-by: Zhenyao Mo <zmo@chromium.org>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index b155545..bf8649c 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -336,6 +336,7 @@
return false;
break;
case EOpNegative:
+ case EOpPositive:
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
@@ -1068,6 +1069,27 @@
}
break;
+ case EOpPositive:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ tempConstArray[i].setFConst(unionArray[i].getFConst());
+ break;
+ case EbtInt:
+ tempConstArray[i].setIConst(unionArray[i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setUConst(static_cast<unsigned int>(
+ static_cast<int>(unionArray[i].getUConst())));
+ break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return NULL;
+ }
+ break;
+
case EOpLogicalNot:
// this code is written for possible future use,
// will not get executed currently
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index ec440da..0f2fec5 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -45,6 +45,7 @@
//
EOpNegative,
+ EOpPositive,
EOpLogicalNot,
EOpVectorLogicalNot,
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index ef4f833..e558683 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -198,6 +198,7 @@
case EOpPostDecrement:
case EOpPreDecrement:
case EOpNegative:
+ case EOpPositive:
if (child->getType().getBasicType() == EbtStruct ||
child->getType().isArray())
{
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 6d07ccc..d03abb8 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -395,6 +395,7 @@
switch (node->getOp())
{
case EOpNegative: preString = "(-"; break;
+ case EOpPositive: preString = "(+"; break;
case EOpVectorLogicalNot: preString = "not("; break;
case EOpLogicalNot: preString = "(!"; break;
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index cc758e1..bded1fa 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -1747,6 +1747,7 @@
switch (node->getOp())
{
case EOpNegative: outputTriplet(visit, "(-", "", ")"); break;
+ case EOpPositive: outputTriplet(visit, "(+", "", ")"); break;
case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break;
diff --git a/src/compiler/translator/ValidateLimitations.cpp b/src/compiler/translator/ValidateLimitations.cpp
index c1a7b75..896e1cd 100644
--- a/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/compiler/translator/ValidateLimitations.cpp
@@ -94,6 +94,7 @@
case EOpLogicalXor: return "^^";
case EOpLogicalAnd: return "&&";
case EOpNegative: return "-";
+ case EOpPositive: return "+";
case EOpVectorLogicalNot: return "not";
case EOpLogicalNot: return "!";
case EOpPostIncrement: return "++";
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index 5c945ad..f8c4115 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -500,6 +500,7 @@
const char* errorOp = "";
switch($1.op) {
case EOpNegative: errorOp = "-"; break;
+ case EOpPositive: errorOp = "+"; break;
case EOpLogicalNot: errorOp = "!"; break;
default: break;
}
@@ -514,7 +515,7 @@
// Grammar Note: No traditional style type casts.
unary_operator
- : PLUS { $$.op = EOpNull; }
+ : PLUS { $$.op = EOpPositive; }
| DASH { $$.op = EOpNegative; }
| BANG { $$.op = EOpLogicalNot; }
;
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 6d483b1..567ba43 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -2919,6 +2919,7 @@
const char* errorOp = "";
switch((yyvsp[(1) - (2)].interm).op) {
case EOpNegative: errorOp = "-"; break;
+ case EOpPositive: errorOp = "+"; break;
case EOpLogicalNot: errorOp = "!"; break;
default: break;
}
@@ -2933,7 +2934,7 @@
case 34:
- { (yyval.interm).op = EOpNull; }
+ { (yyval.interm).op = EOpPositive; }
break;
case 35:
diff --git a/src/compiler/translator/intermOut.cpp b/src/compiler/translator/intermOut.cpp
index 56340c6..03ce5be 100644
--- a/src/compiler/translator/intermOut.cpp
+++ b/src/compiler/translator/intermOut.cpp
@@ -221,6 +221,7 @@
switch (node->getOp())
{
case EOpNegative: out << "Negate value"; break;
+ case EOpPositive: out << "Positive sign"; break;
case EOpVectorLogicalNot:
case EOpLogicalNot: out << "Negate conditional"; break;