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; }