Home | History | Annotate | Download | only in translator
      1 //
      2 // Copyright (c) 2002-2013 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/translator/BaseTypes.h"
     13 #include "compiler/translator/Common.h"
     14 #include "compiler/translator/compilerdebug.h"
     15 
     16 struct TPublicType;
     17 class TType;
     18 class TSymbol;
     19 
     20 class TField
     21 {
     22   public:
     23     POOL_ALLOCATOR_NEW_DELETE();
     24     TField(TType *type, TString *name, const TSourceLoc &line)
     25         : mType(type),
     26           mName(name),
     27           mLine(line)
     28     {
     29     }
     30 
     31     // TODO(alokp): We should only return const type.
     32     // Fix it by tweaking grammar.
     33     TType *type()
     34     {
     35         return mType;
     36     }
     37     const TType *type() const
     38     {
     39         return mType;
     40     }
     41 
     42     const TString &name() const
     43     {
     44         return *mName;
     45     }
     46     const TSourceLoc &line() const
     47     {
     48         return mLine;
     49     }
     50 
     51     bool equals(const TField &other) const;
     52 
     53   private:
     54     DISALLOW_COPY_AND_ASSIGN(TField);
     55     TType *mType;
     56     TString *mName;
     57     TSourceLoc mLine;
     58 };
     59 
     60 typedef TVector<TField *> TFieldList;
     61 inline TFieldList *NewPoolTFieldList()
     62 {
     63     void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
     64     return new(memory) TFieldList;
     65 }
     66 
     67 class TFieldListCollection
     68 {
     69   public:
     70     const TString &name() const
     71     {
     72         return *mName;
     73     }
     74     const TFieldList &fields() const
     75     {
     76         return *mFields;
     77     }
     78 
     79     const TString &mangledName() const
     80     {
     81         if (mMangledName.empty())
     82             mMangledName = buildMangledName();
     83         return mMangledName;
     84     }
     85     size_t objectSize() const
     86     {
     87         if (mObjectSize == 0)
     88             mObjectSize = calculateObjectSize();
     89         return mObjectSize;
     90     };
     91 
     92   protected:
     93     TFieldListCollection(const TString *name, TFieldList *fields)
     94         : mName(name),
     95           mFields(fields),
     96           mObjectSize(0)
     97     {
     98     }
     99     TString buildMangledName() const;
    100     size_t calculateObjectSize() const;
    101     virtual TString mangledNamePrefix() const = 0;
    102 
    103     bool equals(const TFieldListCollection &other) const;
    104 
    105     const TString *mName;
    106     TFieldList *mFields;
    107 
    108     mutable TString mMangledName;
    109     mutable size_t mObjectSize;
    110 };
    111 
    112 // May also represent interface blocks
    113 class TStructure : public TFieldListCollection
    114 {
    115   public:
    116     POOL_ALLOCATOR_NEW_DELETE();
    117     TStructure(const TString *name, TFieldList *fields)
    118         : TFieldListCollection(name, fields),
    119           mDeepestNesting(0),
    120           mUniqueId(0)
    121     {
    122     }
    123 
    124     int deepestNesting() const
    125     {
    126         if (mDeepestNesting == 0)
    127             mDeepestNesting = calculateDeepestNesting();
    128         return mDeepestNesting;
    129     }
    130     bool containsArrays() const;
    131 
    132     bool equals(const TStructure &other) const;
    133 
    134     void setUniqueId(int uniqueId)
    135     {
    136         mUniqueId = uniqueId;
    137     }
    138 
    139     int uniqueId() const
    140     {
    141         ASSERT(mUniqueId != 0);
    142         return mUniqueId;
    143     }
    144 
    145   private:
    146     DISALLOW_COPY_AND_ASSIGN(TStructure);
    147     virtual TString mangledNamePrefix() const
    148     {
    149         return "struct-";
    150     }
    151     int calculateDeepestNesting() const;
    152 
    153     mutable int mDeepestNesting;
    154     int mUniqueId;
    155 };
    156 
    157 class TInterfaceBlock : public TFieldListCollection
    158 {
    159   public:
    160     POOL_ALLOCATOR_NEW_DELETE();
    161     TInterfaceBlock(const TString *name, TFieldList *fields, const TString *instanceName,
    162                     int arraySize, const TLayoutQualifier &layoutQualifier)
    163         : TFieldListCollection(name, fields),
    164           mInstanceName(instanceName),
    165           mArraySize(arraySize),
    166           mBlockStorage(layoutQualifier.blockStorage),
    167           mMatrixPacking(layoutQualifier.matrixPacking)
    168     {
    169     }
    170 
    171     const TString &instanceName() const
    172     {
    173         return *mInstanceName;
    174     }
    175     bool hasInstanceName() const
    176     {
    177         return mInstanceName != NULL;
    178     }
    179     bool isArray() const
    180     {
    181         return mArraySize > 0;
    182     }
    183     int arraySize() const
    184     {
    185         return mArraySize;
    186     }
    187     TLayoutBlockStorage blockStorage() const
    188     {
    189         return mBlockStorage;
    190     }
    191     TLayoutMatrixPacking matrixPacking() const
    192     {
    193         return mMatrixPacking;
    194     }
    195 
    196     bool equals(const TInterfaceBlock &other) const;
    197 
    198   private:
    199     DISALLOW_COPY_AND_ASSIGN(TInterfaceBlock);
    200     virtual TString mangledNamePrefix() const
    201     {
    202         return "iblock-";
    203     }
    204 
    205     const TString *mInstanceName; // for interface block instance names
    206     int mArraySize; // 0 if not an array
    207     TLayoutBlockStorage mBlockStorage;
    208     TLayoutMatrixPacking mMatrixPacking;
    209 };
    210 
    211 //
    212 // Base class for things that have a type.
    213 //
    214 class TType
    215 {
    216   public:
    217     POOL_ALLOCATOR_NEW_DELETE();
    218     TType()
    219     {
    220     }
    221     TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
    222         : type(t), precision(EbpUndefined), qualifier(EvqGlobal),
    223           layoutQualifier(TLayoutQualifier::create()),
    224           primarySize(ps), secondarySize(ss), array(false), arraySize(0),
    225           interfaceBlock(0), structure(0)
    226     {
    227     }
    228     TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary,
    229           unsigned char ps = 1, unsigned char ss = 1, bool a = false)
    230         : type(t), precision(p), qualifier(q),
    231           layoutQualifier(TLayoutQualifier::create()),
    232           primarySize(ps), secondarySize(ss), array(a), arraySize(0),
    233           interfaceBlock(0), structure(0)
    234     {
    235     }
    236     explicit TType(const TPublicType &p);
    237     TType(TStructure *userDef, TPrecision p = EbpUndefined)
    238         : type(EbtStruct), precision(p), qualifier(EvqTemporary),
    239           layoutQualifier(TLayoutQualifier::create()),
    240           primarySize(1), secondarySize(1), array(false), arraySize(0),
    241           interfaceBlock(0), structure(userDef)
    242     {
    243     }
    244     TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn,
    245           TLayoutQualifier layoutQualifierIn, int arraySizeIn)
    246         : type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn),
    247           layoutQualifier(layoutQualifierIn),
    248           primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn),
    249           interfaceBlock(interfaceBlockIn), structure(0)
    250     {
    251     }
    252 
    253     TBasicType getBasicType() const
    254     {
    255         return type;
    256     }
    257     void setBasicType(TBasicType t)
    258     {
    259         type = t;
    260     }
    261 
    262     TPrecision getPrecision() const
    263     {
    264         return precision;
    265     }
    266     void setPrecision(TPrecision p)
    267     {
    268         precision = p;
    269     }
    270 
    271     TQualifier getQualifier() const
    272     {
    273         return qualifier;
    274     }
    275     void setQualifier(TQualifier q)
    276     {
    277         qualifier = q;
    278     }
    279 
    280     TLayoutQualifier getLayoutQualifier() const
    281     {
    282         return layoutQualifier;
    283     }
    284     void setLayoutQualifier(TLayoutQualifier lq)
    285     {
    286         layoutQualifier = lq;
    287     }
    288 
    289     int getNominalSize() const
    290     {
    291         return primarySize;
    292     }
    293     int getSecondarySize() const
    294     {
    295         return secondarySize;
    296     }
    297     int getCols() const
    298     {
    299         ASSERT(isMatrix());
    300         return primarySize;
    301     }
    302     int getRows() const
    303     {
    304         ASSERT(isMatrix());
    305         return secondarySize;
    306     }
    307     void setPrimarySize(unsigned char ps)
    308     {
    309         primarySize = ps;
    310     }
    311     void setSecondarySize(unsigned char ss)
    312     {
    313         secondarySize = ss;
    314     }
    315 
    316     // Full size of single instance of type
    317     size_t getObjectSize() const;
    318 
    319     bool isMatrix() const
    320     {
    321         return primarySize > 1 && secondarySize > 1;
    322     }
    323     bool isArray() const
    324     {
    325         return array ? true : false;
    326     }
    327     int getArraySize() const
    328     {
    329         return arraySize;
    330     }
    331     void setArraySize(int s)
    332     {
    333         array = true;
    334         arraySize = s;
    335     }
    336     void clearArrayness()
    337     {
    338         array = false;
    339         arraySize = 0;
    340     }
    341 
    342     TInterfaceBlock *getInterfaceBlock() const
    343     {
    344         return interfaceBlock;
    345     }
    346     void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
    347     {
    348         interfaceBlock = interfaceBlockIn;
    349     }
    350     bool isInterfaceBlock() const
    351     {
    352         return type == EbtInterfaceBlock;
    353     }
    354 
    355     bool isVector() const
    356     {
    357         return primarySize > 1 && secondarySize == 1;
    358     }
    359     bool isScalar() const
    360     {
    361         return primarySize == 1 && secondarySize == 1 && !structure;
    362     }
    363     bool isScalarInt() const
    364     {
    365         return isScalar() && (type == EbtInt || type == EbtUInt);
    366     }
    367 
    368     TStructure *getStruct() const
    369     {
    370         return structure;
    371     }
    372     void setStruct(TStructure *s)
    373     {
    374         structure = s;
    375     }
    376 
    377     const TString &getMangledName()
    378     {
    379         if (mangled.empty())
    380         {
    381             mangled = buildMangledName();
    382             mangled += ';';
    383         }
    384 
    385         return mangled;
    386     }
    387 
    388     // This is different from operator== as we also compare
    389     // precision here.
    390     bool equals(const TType &other) const;
    391 
    392     bool sameElementType(const TType &right) const
    393     {
    394         return type == right.type &&
    395             primarySize == right.primarySize &&
    396             secondarySize == right.secondarySize &&
    397             structure == right.structure;
    398     }
    399     bool operator==(const TType &right) const
    400     {
    401         return type == right.type &&
    402             primarySize == right.primarySize &&
    403             secondarySize == right.secondarySize &&
    404             array == right.array && (!array || arraySize == right.arraySize) &&
    405             structure == right.structure;
    406         // don't check the qualifier, it's not ever what's being sought after
    407     }
    408     bool operator!=(const TType &right) const
    409     {
    410         return !operator==(right);
    411     }
    412     bool operator<(const TType &right) const
    413     {
    414         if (type != right.type)
    415             return type < right.type;
    416         if (primarySize != right.primarySize)
    417             return primarySize < right.primarySize;
    418         if (secondarySize != right.secondarySize)
    419             return secondarySize < right.secondarySize;
    420         if (array != right.array)
    421             return array < right.array;
    422         if (arraySize != right.arraySize)
    423             return arraySize < right.arraySize;
    424         if (structure != right.structure)
    425             return structure < right.structure;
    426 
    427         return false;
    428     }
    429 
    430     const char *getBasicString() const
    431     {
    432         return ::getBasicString(type);
    433     }
    434     const char *getPrecisionString() const
    435     {
    436         return ::getPrecisionString(precision);
    437     }
    438     const char *getQualifierString() const
    439     {
    440         return ::getQualifierString(qualifier);
    441     }
    442     TString getCompleteString() const;
    443 
    444     // If this type is a struct, returns the deepest struct nesting of
    445     // any field in the struct. For example:
    446     //   struct nesting1 {
    447     //     vec4 position;
    448     //   };
    449     //   struct nesting2 {
    450     //     nesting1 field1;
    451     //     vec4 field2;
    452     //   };
    453     // For type "nesting2", this method would return 2 -- the number
    454     // of structures through which indirection must occur to reach the
    455     // deepest field (nesting2.field1.position).
    456     int getDeepestStructNesting() const
    457     {
    458         return structure ? structure->deepestNesting() : 0;
    459     }
    460 
    461     bool isStructureContainingArrays() const
    462     {
    463         return structure ? structure->containsArrays() : false;
    464     }
    465 
    466   protected:
    467     TString buildMangledName() const;
    468     size_t getStructSize() const;
    469     void computeDeepestStructNesting();
    470 
    471     TBasicType type;
    472     TPrecision precision;
    473     TQualifier qualifier;
    474     TLayoutQualifier layoutQualifier;
    475     unsigned char primarySize; // size of vector or cols matrix
    476     unsigned char secondarySize; // rows of a matrix
    477     bool array;
    478     int arraySize;
    479 
    480     // 0 unless this is an interface block, or interface block member variable
    481     TInterfaceBlock *interfaceBlock;
    482 
    483     // 0 unless this is a struct
    484     TStructure *structure;
    485 
    486     mutable TString mangled;
    487 };
    488 
    489 //
    490 // This is a workaround for a problem with the yacc stack,  It can't have
    491 // types that it thinks have non-trivial constructors.  It should
    492 // just be used while recognizing the grammar, not anything else.  Pointers
    493 // could be used, but also trying to avoid lots of memory management overhead.
    494 //
    495 // Not as bad as it looks, there is no actual assumption that the fields
    496 // match up or are name the same or anything like that.
    497 //
    498 struct TPublicType
    499 {
    500     TBasicType type;
    501     TLayoutQualifier layoutQualifier;
    502     TQualifier qualifier;
    503     TPrecision precision;
    504     unsigned char primarySize;          // size of vector or cols of matrix
    505     unsigned char secondarySize;        // rows of matrix
    506     bool array;
    507     int arraySize;
    508     TType *userDef;
    509     TSourceLoc line;
    510 
    511     void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln)
    512     {
    513         type = bt;
    514         layoutQualifier = TLayoutQualifier::create();
    515         qualifier = q;
    516         precision = EbpUndefined;
    517         primarySize = 1;
    518         secondarySize = 1;
    519         array = false;
    520         arraySize = 0;
    521         userDef = 0;
    522         line = ln;
    523     }
    524 
    525     void setAggregate(unsigned char size)
    526     {
    527         primarySize = size;
    528     }
    529 
    530     void setMatrix(unsigned char c, unsigned char r)
    531     {
    532         ASSERT(c > 1 && r > 1 && c <= 4 && r <= 4);
    533         primarySize = c;
    534         secondarySize = r;
    535     }
    536 
    537     void setArray(bool a, int s = 0)
    538     {
    539         array = a;
    540         arraySize = s;
    541     }
    542 
    543     bool isStructureContainingArrays() const
    544     {
    545         if (!userDef)
    546         {
    547             return false;
    548         }
    549 
    550         return userDef->isStructureContainingArrays();
    551     }
    552 
    553     bool isMatrix() const
    554     {
    555         return primarySize > 1 && secondarySize > 1;
    556     }
    557 
    558     bool isVector() const
    559     {
    560         return primarySize > 1 && secondarySize == 1;
    561     }
    562 
    563     int getCols() const
    564     {
    565         ASSERT(isMatrix());
    566         return primarySize;
    567     }
    568 
    569     int getRows() const
    570     {
    571         ASSERT(isMatrix());
    572         return secondarySize;
    573     }
    574 
    575     int getNominalSize() const
    576     {
    577         return primarySize;
    578     }
    579 
    580     bool isAggregate() const
    581     {
    582         return array || isMatrix() || isVector();
    583     }
    584 };
    585 
    586 #endif // _TYPES_INCLUDED_
    587