• 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/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();
TField(TType * type,TString * name)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.
type()27     TType* type() { return mType; }
type()28     const TType* type() const { return mType; }
29 
name()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;
NewPoolTFieldList()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();
TStructure(TString * name,TFieldList * fields)49     TStructure(TString* name, TFieldList* fields)
50         : mName(name),
51           mFields(fields),
52           mObjectSize(0),
53           mDeepestNesting(0) {
54     }
55 
name()56     const TString& name() const { return *mName; }
fields()57     const TFieldList& fields() const { return *mFields; }
58 
mangledName()59     const TString& mangledName() const {
60         if (mMangledName.empty())
61             mMangledName = buildMangledName();
62         return mMangledName;
63     }
objectSize()64     size_t objectSize() const {
65         if (mObjectSize == 0)
66             mObjectSize = calculateObjectSize();
67         return mObjectSize;
68     };
deepestNesting()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();
TType()97     TType() {}
98     TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, unsigned char s = 1, bool m = false, bool a = false) :
type(t)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) :
type(EbtStruct)104             type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef)
105     {
106     }
107 
getBasicType()108     TBasicType getBasicType() const { return type; }
setBasicType(TBasicType t)109     void setBasicType(TBasicType t) { type = t; }
110 
getPrecision()111     TPrecision getPrecision() const { return precision; }
setPrecision(TPrecision p)112     void setPrecision(TPrecision p) { precision = p; }
113 
getQualifier()114     TQualifier getQualifier() const { return qualifier; }
setQualifier(TQualifier q)115     void setQualifier(TQualifier q) { qualifier = q; }
116 
117     // One-dimensional size of single instance type
getNominalSize()118     int getNominalSize() const { return size; }
setNominalSize(unsigned char s)119     void setNominalSize(unsigned char s) { size = s; }
120     // Full size of single instance of type
121     size_t getObjectSize() const;
122 
elementRegisterCount()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 
totalRegisterCount()147     int totalRegisterCount() const
148     {
149         if (array)
150         {
151             return arraySize * elementRegisterCount();
152         }
153         else
154         {
155             return elementRegisterCount();
156         }
157     }
158 
isMatrix()159     bool isMatrix() const { return matrix ? true : false; }
setMatrix(bool m)160     void setMatrix(bool m) { matrix = m; }
161 
isArray()162     bool isArray() const  { return array ? true : false; }
getArraySize()163     int getArraySize() const { return arraySize; }
setArraySize(int s)164     void setArraySize(int s) { array = true; arraySize = s; }
clearArrayness()165     void clearArrayness() { array = false; arraySize = 0; }
166 
isVector()167     bool isVector() const { return size > 1 && !matrix; }
isScalar()168     bool isScalar() const { return size == 1 && !matrix && !structure; }
169 
getStruct()170     TStructure* getStruct() const { return structure; }
setStruct(TStructure * s)171     void setStruct(TStructure* s) { structure = s; }
172 
getMangledName()173     const TString& getMangledName() const {
174         if (mangled.empty()) {
175             mangled = buildMangledName();
176             mangled += ';';
177         }
178         return mangled;
179     }
180 
sameElementType(const TType & right)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 
getBasicString()209     const char* getBasicString() const { return ::getBasicString(type); }
getPrecisionString()210     const char* getPrecisionString() const { return ::getPrecisionString(precision); }
getQualifierString()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).
getDeepestStructNesting()226     int getDeepestStructNesting() const {
227         return structure ? structure->deepestNesting() : 0;
228     }
229 
isStructureContainingArrays()230     bool isStructureContainingArrays() const {
231         return structure ? structure->containsArrays() : false;
232     }
233 
234 private:
235     TString buildMangledName() const;
236 
237     TBasicType type;
238     TPrecision precision;
239     TQualifier qualifier;
240     unsigned char size;
241     bool matrix;
242     bool array;
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     unsigned char 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 
setBasicTPublicType271     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(unsigned char 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 
isStructureContainingArraysTPublicType296     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