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