Home | History | Annotate | Download | only in translator
      1 //
      2 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 #ifndef _CONSTANT_UNION_INCLUDED_
      8 #define _CONSTANT_UNION_INCLUDED_
      9 
     10 #include <assert.h>
     11 
     12 class ConstantUnion {
     13 public:
     14     POOL_ALLOCATOR_NEW_DELETE();
     15     ConstantUnion()
     16     {
     17         iConst = 0;
     18         type = EbtVoid;
     19     }
     20 
     21     bool cast(TBasicType newType, const ConstantUnion &constant)
     22     {
     23         switch (newType)
     24         {
     25           case EbtFloat:
     26             switch (constant.type)
     27             {
     28               case EbtInt:   setFConst(static_cast<float>(constant.getIConst())); break;
     29               case EbtUInt:  setFConst(static_cast<float>(constant.getUConst())); break;
     30               case EbtBool:  setFConst(static_cast<float>(constant.getBConst())); break;
     31               case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
     32               default:       return false;
     33             }
     34             break;
     35           case EbtInt:
     36             switch (constant.type)
     37             {
     38               case EbtInt:   setIConst(static_cast<int>(constant.getIConst())); break;
     39               case EbtUInt:  setIConst(static_cast<int>(constant.getUConst())); break;
     40               case EbtBool:  setIConst(static_cast<int>(constant.getBConst())); break;
     41               case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
     42               default:       return false;
     43             }
     44             break;
     45           case EbtUInt:
     46             switch (constant.type)
     47             {
     48               case EbtInt:   setUConst(static_cast<unsigned int>(constant.getIConst())); break;
     49               case EbtUInt:  setUConst(static_cast<unsigned int>(constant.getUConst())); break;
     50               case EbtBool:  setUConst(static_cast<unsigned int>(constant.getBConst())); break;
     51               case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
     52               default:       return false;
     53             }
     54             break;
     55           case EbtBool:
     56             switch (constant.type)
     57             {
     58               case EbtInt:   setBConst(constant.getIConst() != 0);    break;
     59               case EbtUInt:  setBConst(constant.getUConst() != 0);    break;
     60               case EbtBool:  setBConst(constant.getBConst());         break;
     61               case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
     62               default:       return false;
     63             }
     64             break;
     65           case EbtStruct:    // Struct fields don't get cast
     66             switch (constant.type)
     67             {
     68               case EbtInt:   setIConst(constant.getIConst()); break;
     69               case EbtUInt:  setUConst(constant.getUConst()); break;
     70               case EbtBool:  setBConst(constant.getBConst()); break;
     71               case EbtFloat: setFConst(constant.getFConst()); break;
     72               default:       return false;
     73             }
     74             break;
     75           default:
     76             return false;
     77         }
     78 
     79         return true;
     80     }
     81 
     82     void setIConst(int i) {iConst = i; type = EbtInt; }
     83     void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
     84     void setFConst(float f) {fConst = f; type = EbtFloat; }
     85     void setBConst(bool b) {bConst = b; type = EbtBool; }
     86 
     87     int getIConst() const { return iConst; }
     88     unsigned int getUConst() const { return uConst; }
     89     float getFConst() const { return fConst; }
     90     bool getBConst() const { return bConst; }
     91 
     92     bool operator==(const int i) const
     93     {
     94         return i == iConst;
     95     }
     96 
     97     bool operator==(const unsigned int u) const
     98     {
     99         return u == uConst;
    100     }
    101 
    102     bool operator==(const float f) const
    103     {
    104         return f == fConst;
    105     }
    106 
    107     bool operator==(const bool b) const
    108     {
    109         return b == bConst;
    110     }
    111 
    112     bool operator==(const ConstantUnion& constant) const
    113     {
    114         if (constant.type != type)
    115             return false;
    116 
    117         switch (type) {
    118         case EbtInt:
    119             return constant.iConst == iConst;
    120         case EbtUInt:
    121             return constant.uConst == uConst;
    122         case EbtFloat:
    123             return constant.fConst == fConst;
    124         case EbtBool:
    125             return constant.bConst == bConst;
    126         default:
    127             return false;
    128         }
    129     }
    130 
    131     bool operator!=(const int i) const
    132     {
    133         return !operator==(i);
    134     }
    135 
    136     bool operator!=(const unsigned int u) const
    137     {
    138         return !operator==(u);
    139     }
    140 
    141     bool operator!=(const float f) const
    142     {
    143         return !operator==(f);
    144     }
    145 
    146     bool operator!=(const bool b) const
    147     {
    148         return !operator==(b);
    149     }
    150 
    151     bool operator!=(const ConstantUnion& constant) const
    152     {
    153         return !operator==(constant);
    154     }
    155 
    156     bool operator>(const ConstantUnion& constant) const
    157     {
    158         assert(type == constant.type);
    159         switch (type) {
    160         case EbtInt:
    161             return iConst > constant.iConst;
    162         case EbtUInt:
    163             return uConst > constant.uConst;
    164         case EbtFloat:
    165             return fConst > constant.fConst;
    166         default:
    167             return false;   // Invalid operation, handled at semantic analysis
    168         }
    169     }
    170 
    171     bool operator<(const ConstantUnion& constant) const
    172     {
    173         assert(type == constant.type);
    174         switch (type) {
    175         case EbtInt:
    176             return iConst < constant.iConst;
    177         case EbtUInt:
    178             return uConst < constant.uConst;
    179         case EbtFloat:
    180             return fConst < constant.fConst;
    181         default:
    182             return false;   // Invalid operation, handled at semantic analysis
    183         }
    184     }
    185 
    186     ConstantUnion operator+(const ConstantUnion& constant) const
    187     {
    188         ConstantUnion returnValue;
    189         assert(type == constant.type);
    190         switch (type) {
    191         case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
    192         case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break;
    193         case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
    194         default: assert(false && "Default missing");
    195         }
    196 
    197         return returnValue;
    198     }
    199 
    200     ConstantUnion operator-(const ConstantUnion& constant) const
    201     {
    202         ConstantUnion returnValue;
    203         assert(type == constant.type);
    204         switch (type) {
    205         case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
    206         case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break;
    207         case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
    208         default: assert(false && "Default missing");
    209         }
    210 
    211         return returnValue;
    212     }
    213 
    214     ConstantUnion operator*(const ConstantUnion& constant) const
    215     {
    216         ConstantUnion returnValue;
    217         assert(type == constant.type);
    218         switch (type) {
    219         case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
    220         case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break;
    221         case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break;
    222         default: assert(false && "Default missing");
    223         }
    224 
    225         return returnValue;
    226     }
    227 
    228     ConstantUnion operator%(const ConstantUnion& constant) const
    229     {
    230         ConstantUnion returnValue;
    231         assert(type == constant.type);
    232         switch (type) {
    233         case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
    234         case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break;
    235         default:     assert(false && "Default missing");
    236         }
    237 
    238         return returnValue;
    239     }
    240 
    241     ConstantUnion operator>>(const ConstantUnion& constant) const
    242     {
    243         ConstantUnion returnValue;
    244         assert(type == constant.type);
    245         switch (type) {
    246         case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
    247         case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break;
    248         default:     assert(false && "Default missing");
    249         }
    250 
    251         return returnValue;
    252     }
    253 
    254     ConstantUnion operator<<(const ConstantUnion& constant) const
    255     {
    256         ConstantUnion returnValue;
    257         assert(type == constant.type);
    258         switch (type) {
    259         case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
    260         case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
    261         default:     assert(false && "Default missing");
    262         }
    263 
    264         return returnValue;
    265     }
    266 
    267     ConstantUnion operator&(const ConstantUnion& constant) const
    268     {
    269         ConstantUnion returnValue;
    270         assert(type == constant.type);
    271         switch (type) {
    272         case EbtInt:  returnValue.setIConst(iConst & constant.iConst); break;
    273         case EbtUInt:  returnValue.setUConst(uConst & constant.uConst); break;
    274         default:     assert(false && "Default missing");
    275         }
    276 
    277         return returnValue;
    278     }
    279 
    280     ConstantUnion operator|(const ConstantUnion& constant) const
    281     {
    282         ConstantUnion returnValue;
    283         assert(type == constant.type);
    284         switch (type) {
    285         case EbtInt:  returnValue.setIConst(iConst | constant.iConst); break;
    286         case EbtUInt:  returnValue.setUConst(uConst | constant.uConst); break;
    287         default:     assert(false && "Default missing");
    288         }
    289 
    290         return returnValue;
    291     }
    292 
    293     ConstantUnion operator^(const ConstantUnion& constant) const
    294     {
    295         ConstantUnion returnValue;
    296         assert(type == constant.type);
    297         switch (type) {
    298         case EbtInt:  returnValue.setIConst(iConst ^ constant.iConst); break;
    299         case EbtUInt:  returnValue.setUConst(uConst ^ constant.uConst); break;
    300         default:     assert(false && "Default missing");
    301         }
    302 
    303         return returnValue;
    304     }
    305 
    306     ConstantUnion operator&&(const ConstantUnion& constant) const
    307     {
    308         ConstantUnion returnValue;
    309         assert(type == constant.type);
    310         switch (type) {
    311         case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
    312         default:     assert(false && "Default missing");
    313         }
    314 
    315         return returnValue;
    316     }
    317 
    318     ConstantUnion operator||(const ConstantUnion& constant) const
    319     {
    320         ConstantUnion returnValue;
    321         assert(type == constant.type);
    322         switch (type) {
    323         case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
    324         default:     assert(false && "Default missing");
    325         }
    326 
    327         return returnValue;
    328     }
    329 
    330     TBasicType getType() const { return type; }
    331 private:
    332 
    333     union  {
    334         int iConst;  // used for ivec, scalar ints
    335         unsigned int uConst; // used for uvec, scalar uints
    336         bool bConst; // used for bvec, scalar bools
    337         float fConst;   // used for vec, mat, scalar floats
    338     } ;
    339 
    340     TBasicType type;
    341 };
    342 
    343 #endif // _CONSTANT_UNION_INCLUDED_
    344