Home | History | Annotate | Download | only in compiler
      1 //
      2 // Copyright (c) 2002-2012 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 _TYPES_INCLUDED
      8 #define _TYPES_INCLUDED
      9 
     10 #include "common/angleutils.h"
     11 
     12 #include "compiler/BaseTypes.h"
     13 #include "compiler/Common.h"
     14 #include "compiler/debug.h"
     15 
     16 struct TPublicType;
     17 class TType;
     18 
     19 class TField
     20 {
     21 public:
     22     POOL_ALLOCATOR_NEW_DELETE();
     23     TField(TType* type, TString* name) : mType(type), mName(name) {}
     24 
     25     // TODO(alokp): We should only return const type.
     26     // Fix it by tweaking grammar.
     27     TType* type() { return mType; }
     28     const TType* type() const { return mType; }
     29 
     30     const TString& name() const { return *mName; }
     31 
     32 private:
     33     DISALLOW_COPY_AND_ASSIGN(TField);
     34     TType* mType;
     35     TString* mName;
     36 };
     37 
     38 typedef TVector<TField*> TFieldList;
     39 inline TFieldList* NewPoolTFieldList()
     40 {
     41     void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
     42     return new(memory) TFieldList;
     43 }
     44 
     45 class TStructure
     46 {
     47 public:
     48     POOL_ALLOCATOR_NEW_DELETE();
     49     TStructure(TString* name, TFieldList* fields)
     50         : mName(name),
     51           mFields(fields),
     52           mObjectSize(0),
     53           mDeepestNesting(0) {
     54     }
     55 
     56     const TString& name() const { return *mName; }
     57     const TFieldList& fields() const { return *mFields; }
     58 
     59     const TString& mangledName() const {
     60         if (mMangledName.empty())
     61             mMangledName = buildMangledName();
     62         return mMangledName;
     63     }
     64     size_t objectSize() const {
     65         if (mObjectSize == 0)
     66             mObjectSize = calculateObjectSize();
     67         return mObjectSize;
     68     };
     69     int deepestNesting() const {
     70         if (mDeepestNesting == 0)
     71             mDeepestNesting = calculateDeepestNesting();
     72         return mDeepestNesting;
     73     }
     74     bool containsArrays() const;
     75 
     76 private:
     77     DISALLOW_COPY_AND_ASSIGN(TStructure);
     78     TString buildMangledName() const;
     79     size_t calculateObjectSize() const;
     80     int calculateDeepestNesting() const;
     81 
     82     TString* mName;
     83     TFieldList* mFields;
     84 
     85     mutable TString mMangledName;
     86     mutable size_t mObjectSize;
     87     mutable int mDeepestNesting;
     88 };
     89 
     90 //
     91 // Base class for things that have a type.
     92 //
     93 class TType
     94 {
     95 public:
     96     POOL_ALLOCATOR_NEW_DELETE();
     97     TType() {}
     98     TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
     99             type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0)
    100     {
    101     }
    102     explicit TType(const TPublicType &p);
    103     TType(TStructure* userDef, TPrecision p = EbpUndefined) :
    104             type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef)
    105     {
    106     }
    107 
    108     TBasicType getBasicType() const { return type; }
    109     void setBasicType(TBasicType t) { type = t; }
    110 
    111     TPrecision getPrecision() const { return precision; }
    112     void setPrecision(TPrecision p) { precision = p; }
    113 
    114     TQualifier getQualifier() const { return qualifier; }
    115     void setQualifier(TQualifier q) { qualifier = q; }
    116 
    117     // One-dimensional size of single instance type
    118     int getNominalSize() const { return size; }
    119     void setNominalSize(int s) { size = s; }
    120     // Full size of single instance of type
    121     size_t getObjectSize() const;
    122 
    123     int elementRegisterCount() const
    124     {
    125         if (structure)
    126         {
    127             const TFieldList &fields = getStruct()->fields();
    128             int registerCount = 0;
    129 
    130             for (size_t i = 0; i < fields.size(); i++)
    131             {
    132                 registerCount += fields[i]->type()->totalRegisterCount();
    133             }
    134 
    135             return registerCount;
    136         }
    137         else if (isMatrix())
    138         {
    139             return getNominalSize();
    140         }
    141         else
    142         {
    143             return 1;
    144         }
    145     }
    146 
    147     int totalRegisterCount() const
    148     {
    149         if (array)
    150         {
    151             return arraySize * elementRegisterCount();
    152         }
    153         else
    154         {
    155             return elementRegisterCount();
    156         }
    157     }
    158 
    159     bool isMatrix() const { return matrix ? true : false; }
    160     void setMatrix(bool m) { matrix = m; }
    161 
    162     bool isArray() const  { return array ? true : false; }
    163     int getArraySize() const { return arraySize; }
    164     void setArraySize(int s) { array = true; arraySize = s; }
    165     void clearArrayness() { array = false; arraySize = 0; }
    166 
    167     bool isVector() const { return size > 1 && !matrix; }
    168     bool isScalar() const { return size == 1 && !matrix && !structure; }
    169 
    170     TStructure* getStruct() const { return structure; }
    171     void setStruct(TStructure* s) { structure = s; }
    172 
    173     const TString& getMangledName() const {
    174         if (mangled.empty()) {
    175             mangled = buildMangledName();
    176             mangled += ';';
    177         }
    178         return mangled;
    179     }
    180 
    181     bool sameElementType(const TType& right) const {
    182         return      type == right.type   &&
    183                     size == right.size   &&
    184                   matrix == right.matrix &&
    185                structure == right.structure;
    186     }
    187     bool operator==(const TType& right) const {
    188         return      type == right.type   &&
    189                     size == right.size   &&
    190                   matrix == right.matrix &&
    191                    array == right.array  && (!array || arraySize == right.arraySize) &&
    192                structure == right.structure;
    193         // don't check the qualifier, it's not ever what's being sought after
    194     }
    195     bool operator!=(const TType& right) const {
    196         return !operator==(right);
    197     }
    198     bool operator<(const TType& right) const {
    199         if (type != right.type) return type < right.type;
    200         if (size != right.size) return size < right.size;
    201         if (matrix != right.matrix) return matrix < right.matrix;
    202         if (array != right.array) return array < right.array;
    203         if (arraySize != right.arraySize) return arraySize < right.arraySize;
    204         if (structure != right.structure) return structure < right.structure;
    205 
    206         return false;
    207     }
    208 
    209     const char* getBasicString() const { return ::getBasicString(type); }
    210     const char* getPrecisionString() const { return ::getPrecisionString(precision); }
    211     const char* getQualifierString() const { return ::getQualifierString(qualifier); }
    212     TString getCompleteString() const;
    213 
    214     // If this type is a struct, returns the deepest struct nesting of
    215     // any field in the struct. For example:
    216     //   struct nesting1 {
    217     //     vec4 position;
    218     //   };
    219     //   struct nesting2 {
    220     //     nesting1 field1;
    221     //     vec4 field2;
    222     //   };
    223     // For type "nesting2", this method would return 2 -- the number
    224     // of structures through which indirection must occur to reach the
    225     // deepest field (nesting2.field1.position).
    226     int getDeepestStructNesting() const {
    227         return structure ? structure->deepestNesting() : 0;
    228     }
    229 
    230     bool isStructureContainingArrays() const {
    231         return structure ? structure->containsArrays() : false;
    232     }
    233 
    234 private:
    235     TString buildMangledName() const;
    236 
    237     TBasicType type      : 6;
    238     TPrecision precision;
    239     TQualifier qualifier : 7;
    240     int size             : 8; // size of vector or matrix, not size of array
    241     unsigned int matrix  : 1;
    242     unsigned int array   : 1;
    243     int arraySize;
    244 
    245     TStructure* structure;      // 0 unless this is a struct
    246 
    247     mutable TString mangled;
    248 };
    249 
    250 //
    251 // This is a workaround for a problem with the yacc stack,  It can't have
    252 // types that it thinks have non-trivial constructors.  It should
    253 // just be used while recognizing the grammar, not anything else.  Pointers
    254 // could be used, but also trying to avoid lots of memory management overhead.
    255 //
    256 // Not as bad as it looks, there is no actual assumption that the fields
    257 // match up or are name the same or anything like that.
    258 //
    259 struct TPublicType
    260 {
    261     TBasicType type;
    262     TQualifier qualifier;
    263     TPrecision precision;
    264     int size;          // size of vector or matrix, not size of array
    265     bool matrix;
    266     bool array;
    267     int arraySize;
    268     TType* userDef;
    269     TSourceLoc line;
    270 
    271     void setBasic(TBasicType bt, TQualifier q, const TSourceLoc& ln)
    272     {
    273         type = bt;
    274         qualifier = q;
    275         precision = EbpUndefined;
    276         size = 1;
    277         matrix = false;
    278         array = false;
    279         arraySize = 0;
    280         userDef = 0;
    281         line = ln;
    282     }
    283 
    284     void setAggregate(int s, bool m = false)
    285     {
    286         size = s;
    287         matrix = m;
    288     }
    289 
    290     void setArray(bool a, int s = 0)
    291     {
    292         array = a;
    293         arraySize = s;
    294     }
    295 
    296     bool isStructureContainingArrays() const
    297     {
    298         if (!userDef)
    299         {
    300             return false;
    301         }
    302 
    303         return userDef->isStructureContainingArrays();
    304     }
    305 };
    306 
    307 #endif // _TYPES_INCLUDED_
    308