Propagate constness.

Change-Id: I38ccac08347592356e0225b6eb90517e20394909
Reviewed-on: https://swiftshader-review.googlesource.com/5079
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp
index d8efe5d..821ea9c 100644
--- a/src/OpenGL/compiler/ParseHelper.cpp
+++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -482,7 +482,6 @@
     //
 
     int size = 0;
-    bool constType = true;
     bool full = false;
     bool overFull = false;
     bool matrixInMatrix = false;
@@ -497,15 +496,10 @@
             overFull = true;
         if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
             full = true;
-        if (param.type->getQualifier() != EvqConstExpr)
-            constType = false;
         if (param.type->isArray())
             arrayArg = true;
     }
 
-    if (constType)
-        type->setQualifier(EvqConstExpr);
-
     if(type->isArray()) {
         if(type->getArraySize() == 0) {
             type->setArraySize(function.getParamCount());
@@ -3536,7 +3530,6 @@
 			recover();
 			callNode = intermediate.setAggregateOperator(nullptr, op, loc);
 		}
-		callNode->setType(type);
 	}
 	else
 	{
@@ -3608,7 +3601,6 @@
 
 				functionCallLValueErrorCheck(fnCandidate, aggregate);
 			}
-			callNode->setType(fnCandidate->getReturnType());
 		}
 		else
 		{
diff --git a/src/OpenGL/compiler/intermediate.h b/src/OpenGL/compiler/intermediate.h
index 337fe36..9e97c25 100644
--- a/src/OpenGL/compiler/intermediate.h
+++ b/src/OpenGL/compiler/intermediate.h
@@ -297,7 +297,7 @@
     TIntermTyped(const TType& t) : type(t)  { }
     virtual TIntermTyped* getAsTyped() { return this; }
 
-    void setType(const TType& t) { type = t; }
+    virtual void setType(const TType& t) { type = t; }
     const TType& getType() const { return type; }
     TType* getTypePointer() { return &type; }
 
@@ -469,6 +469,16 @@
     virtual TIntermBinary* getAsBinaryNode() { return this; }
     virtual void traverse(TIntermTraverser*);
 
+	void setType(const TType &t) override
+	{
+		type = t;
+
+		if(left->getQualifier() == EvqConstExpr && right->getQualifier() == EvqConstExpr)
+		{
+			type.setQualifier(EvqConstExpr);
+		}
+	}
+
     void setLeft(TIntermTyped* n) { left = n; }
     void setRight(TIntermTyped* n) { right = n; }
     TIntermTyped* getLeft() const { return left; }
@@ -488,6 +498,16 @@
     TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
     TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
 
+	void setType(const TType &t) override
+	{
+		type = t;
+
+		if(operand->getQualifier() == EvqConstExpr)
+		{
+			type.setQualifier(EvqConstExpr);
+		}
+	}
+
     virtual void traverse(TIntermTraverser*);
     virtual TIntermUnary* getAsUnaryNode() { return this; }
 
@@ -516,6 +536,24 @@
 
     TIntermSequence& getSequence() { return sequence; }
 
+	void setType(const TType &t) override
+	{
+		type = t;
+
+		if(op != EOpFunctionCall)
+		{
+			for(TIntermNode *node : sequence)
+			{
+				if(!node->getAsTyped() || node->getAsTyped()->getQualifier() != EvqConstExpr)
+				{
+					return;
+				}
+			}
+
+			type.setQualifier(EvqConstExpr);
+		}
+	}
+
     void setName(const TString& n) { name = n; }
     const TString& getName() const { return name; }