• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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();
TField(TType * type,TString * name,const TSourceLoc & line)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.
type()33     TType *type()
34     {
35         return mType;
36     }
type()37     const TType *type() const
38     {
39         return mType;
40     }
41 
name()42     const TString &name() const
43     {
44         return *mName;
45     }
line()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;
NewPoolTFieldList()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:
name()70     const TString &name() const
71     {
72         return *mName;
73     }
fields()74     const TFieldList &fields() const
75     {
76         return *mFields;
77     }
78 
mangledName()79     const TString &mangledName() const
80     {
81         if (mMangledName.empty())
82             mMangledName = buildMangledName();
83         return mMangledName;
84     }
objectSize()85     size_t objectSize() const
86     {
87         if (mObjectSize == 0)
88             mObjectSize = calculateObjectSize();
89         return mObjectSize;
90     };
91 
92   protected:
TFieldListCollection(const TString * name,TFieldList * fields)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();
TStructure(const TString * name,TFieldList * fields)117     TStructure(const TString *name, TFieldList *fields)
118         : TFieldListCollection(name, fields),
119           mDeepestNesting(0),
120           mUniqueId(0)
121     {
122     }
123 
deepestNesting()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 
setUniqueId(int uniqueId)134     void setUniqueId(int uniqueId)
135     {
136         mUniqueId = uniqueId;
137     }
138 
uniqueId()139     int uniqueId() const
140     {
141         ASSERT(mUniqueId != 0);
142         return mUniqueId;
143     }
144 
145   private:
146     DISALLOW_COPY_AND_ASSIGN(TStructure);
mangledNamePrefix()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();
TInterfaceBlock(const TString * name,TFieldList * fields,const TString * instanceName,int arraySize,const TLayoutQualifier & layoutQualifier)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 
instanceName()171     const TString &instanceName() const
172     {
173         return *mInstanceName;
174     }
hasInstanceName()175     bool hasInstanceName() const
176     {
177         return mInstanceName != NULL;
178     }
isArray()179     bool isArray() const
180     {
181         return mArraySize > 0;
182     }
arraySize()183     int arraySize() const
184     {
185         return mArraySize;
186     }
blockStorage()187     TLayoutBlockStorage blockStorage() const
188     {
189         return mBlockStorage;
190     }
matrixPacking()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);
mangledNamePrefix()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();
TType()218     TType()
219     {
220     }
221     TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
type(t)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)
type(t)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)
type(EbtStruct)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     }
TType(TInterfaceBlock * interfaceBlockIn,TQualifier qualifierIn,TLayoutQualifier layoutQualifierIn,int arraySizeIn)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 
getBasicType()253     TBasicType getBasicType() const
254     {
255         return type;
256     }
setBasicType(TBasicType t)257     void setBasicType(TBasicType t)
258     {
259         type = t;
260     }
261 
getPrecision()262     TPrecision getPrecision() const
263     {
264         return precision;
265     }
setPrecision(TPrecision p)266     void setPrecision(TPrecision p)
267     {
268         precision = p;
269     }
270 
getQualifier()271     TQualifier getQualifier() const
272     {
273         return qualifier;
274     }
setQualifier(TQualifier q)275     void setQualifier(TQualifier q)
276     {
277         qualifier = q;
278     }
279 
getLayoutQualifier()280     TLayoutQualifier getLayoutQualifier() const
281     {
282         return layoutQualifier;
283     }
setLayoutQualifier(TLayoutQualifier lq)284     void setLayoutQualifier(TLayoutQualifier lq)
285     {
286         layoutQualifier = lq;
287     }
288 
getNominalSize()289     int getNominalSize() const
290     {
291         return primarySize;
292     }
getSecondarySize()293     int getSecondarySize() const
294     {
295         return secondarySize;
296     }
getCols()297     int getCols() const
298     {
299         ASSERT(isMatrix());
300         return primarySize;
301     }
getRows()302     int getRows() const
303     {
304         ASSERT(isMatrix());
305         return secondarySize;
306     }
setPrimarySize(unsigned char ps)307     void setPrimarySize(unsigned char ps)
308     {
309         primarySize = ps;
310     }
setSecondarySize(unsigned char ss)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 
isMatrix()319     bool isMatrix() const
320     {
321         return primarySize > 1 && secondarySize > 1;
322     }
isArray()323     bool isArray() const
324     {
325         return array ? true : false;
326     }
getArraySize()327     int getArraySize() const
328     {
329         return arraySize;
330     }
setArraySize(int s)331     void setArraySize(int s)
332     {
333         array = true;
334         arraySize = s;
335     }
clearArrayness()336     void clearArrayness()
337     {
338         array = false;
339         arraySize = 0;
340     }
341 
getInterfaceBlock()342     TInterfaceBlock *getInterfaceBlock() const
343     {
344         return interfaceBlock;
345     }
setInterfaceBlock(TInterfaceBlock * interfaceBlockIn)346     void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
347     {
348         interfaceBlock = interfaceBlockIn;
349     }
isInterfaceBlock()350     bool isInterfaceBlock() const
351     {
352         return type == EbtInterfaceBlock;
353     }
354 
isVector()355     bool isVector() const
356     {
357         return primarySize > 1 && secondarySize == 1;
358     }
isScalar()359     bool isScalar() const
360     {
361         return primarySize == 1 && secondarySize == 1 && !structure;
362     }
isScalarInt()363     bool isScalarInt() const
364     {
365         return isScalar() && (type == EbtInt || type == EbtUInt);
366     }
367 
getStruct()368     TStructure *getStruct() const
369     {
370         return structure;
371     }
setStruct(TStructure * s)372     void setStruct(TStructure *s)
373     {
374         structure = s;
375     }
376 
getMangledName()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 
sameElementType(const TType & right)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 
getBasicString()430     const char *getBasicString() const
431     {
432         return ::getBasicString(type);
433     }
getPrecisionString()434     const char *getPrecisionString() const
435     {
436         return ::getPrecisionString(precision);
437     }
getQualifierString()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).
getDeepestStructNesting()456     int getDeepestStructNesting() const
457     {
458         return structure ? structure->deepestNesting() : 0;
459     }
460 
isStructureContainingArrays()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 
setBasicTPublicType511     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 
setAggregateTPublicType525     void setAggregate(unsigned char size)
526     {
527         primarySize = size;
528     }
529 
setMatrixTPublicType530     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 
isStructureContainingArraysTPublicType543     bool isStructureContainingArrays() const
544     {
545         if (!userDef)
546         {
547             return false;
548         }
549 
550         return userDef->isStructureContainingArrays();
551     }
552 
isMatrixTPublicType553     bool isMatrix() const
554     {
555         return primarySize > 1 && secondarySize > 1;
556     }
557 
isVectorTPublicType558     bool isVector() const
559     {
560         return primarySize > 1 && secondarySize == 1;
561     }
562 
getColsTPublicType563     int getCols() const
564     {
565         ASSERT(isMatrix());
566         return primarySize;
567     }
568 
getRowsTPublicType569     int getRows() const
570     {
571         ASSERT(isMatrix());
572         return secondarySize;
573     }
574 
getNominalSizeTPublicType575     int getNominalSize() const
576     {
577         return primarySize;
578     }
579 
isAggregateTPublicType580     bool isAggregate() const
581     {
582         return array || isMatrix() || isVector();
583     }
584 };
585 
586 #endif // _TYPES_INCLUDED_
587