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