Add constant casting support.

BUG=380353

Change-Id: I5a350ca09e2b7e7abb9fa079365adb5aad5af607
Reviewed-on: https://chromium-review.googlesource.com/203450
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Nicolas Capens <nicolascapens@chromium.org>
diff --git a/src/compiler/translator/ConstantUnion.h b/src/compiler/translator/ConstantUnion.h
index 5fdba61..5e86c64 100644
--- a/src/compiler/translator/ConstantUnion.h
+++ b/src/compiler/translator/ConstantUnion.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -18,6 +18,67 @@
         type = EbtVoid;
     }
 
+    bool cast(TBasicType newType, const ConstantUnion &constant)
+    {
+        switch (newType)
+        {
+          case EbtFloat:
+            switch (constant.type)
+            {
+              case EbtInt:   setFConst(static_cast<float>(constant.getIConst())); break;
+              case EbtUInt:  setFConst(static_cast<float>(constant.getUConst())); break;
+              case EbtBool:  setFConst(static_cast<float>(constant.getBConst())); break;
+              case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
+              default:       return false;
+            }
+            break;
+          case EbtInt:
+            switch (constant.type)
+            {
+              case EbtInt:   setIConst(static_cast<int>(constant.getIConst())); break;
+              case EbtUInt:  setIConst(static_cast<int>(constant.getUConst())); break;
+              case EbtBool:  setIConst(static_cast<int>(constant.getBConst())); break;
+              case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
+              default:       return false;
+            }
+            break;
+          case EbtUInt:
+            switch (constant.type)
+            {
+              case EbtInt:   setUConst(static_cast<unsigned int>(constant.getIConst())); break;
+              case EbtUInt:  setUConst(static_cast<unsigned int>(constant.getUConst())); break;
+              case EbtBool:  setUConst(static_cast<unsigned int>(constant.getBConst())); break;
+              case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
+              default:       return false;
+            }
+            break;
+          case EbtBool:
+            switch (constant.type)
+            {
+              case EbtInt:   setBConst(constant.getIConst() != 0);    break;
+              case EbtUInt:  setBConst(constant.getUConst() != 0);    break;
+              case EbtBool:  setBConst(constant.getBConst());         break;
+              case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
+              default:       return false;
+            }
+            break;
+          case EbtStruct:    // Struct fields don't get cast
+            switch (constant.type)
+            {
+              case EbtInt:   setIConst(constant.getIConst()); break;
+              case EbtUInt:  setUConst(constant.getUConst()); break;
+              case EbtBool:  setBConst(constant.getBConst()); break;
+              case EbtFloat: setFConst(constant.getFConst()); break;
+              default:       return false;
+            }
+            break;
+          default:
+            return false;
+        }
+
+        return true;
+    }
+
     void setIConst(int i) {iConst = i; type = EbtInt; }
     void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
     void setFConst(float f) {fConst = f; type = EbtFloat; }
diff --git a/src/compiler/translator/parseConst.cpp b/src/compiler/translator/parseConst.cpp
index 33617e5..05cf912 100644
--- a/src/compiler/translator/parseConst.cpp
+++ b/src/compiler/translator/parseConst.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -162,6 +162,7 @@
 
     ConstantUnion* leftUnionArray = unionArray;
     size_t instanceSize = type.getObjectSize();
+    TBasicType basicType = type.getBasicType();
 
     if (index >= instanceSize)
         return;
@@ -173,7 +174,7 @@
         for (size_t i=0; i < objectSize; i++) {
             if (index >= instanceSize)
                 return;
-            leftUnionArray[index] = rightUnionArray[i];
+            leftUnionArray[index].cast(basicType, rightUnionArray[i]);
 
             (index)++;
         }
@@ -186,7 +187,7 @@
                 if (i >= instanceSize)
                     return;
 
-                leftUnionArray[i] = rightUnionArray[count];
+                leftUnionArray[i].cast(basicType, rightUnionArray[count]);
 
                 (index)++;
                 
@@ -203,7 +204,7 @@
                 {
                     if (col == row)
                     {
-                        leftUnionArray[i] = rightUnionArray[0];
+                        leftUnionArray[i].cast(basicType, rightUnionArray[0]);
                     }
                     else
                     {