blob: d4d98d0c1c07734126a048b73b54d4bce846218c [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
Nicolas Capens978ddc52014-11-11 12:42:08 -05002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
Nicolas Capens978ddc52014-11-11 12:42:08 -05006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Nicolas Capens978ddc52014-11-11 12:42:08 -050014
15#ifndef _TYPES_INCLUDED
16#define _TYPES_INCLUDED
17
Nicolas Capenscc863da2015-01-21 15:50:55 -050018#include "BaseTypes.h"
19#include "Common.h"
20#include "debug.h"
Nicolas Capens978ddc52014-11-11 12:42:08 -050021
22#include <algorithm>
23
24class TType;
25struct TPublicType;
26
Alexis Hetua8b364b2015-06-10 11:48:40 -040027class TField
Nicolas Capens978ddc52014-11-11 12:42:08 -050028{
Alexis Hetua8b364b2015-06-10 11:48:40 -040029public:
30 POOL_ALLOCATOR_NEW_DELETE();
31 TField(TType *type, TString *name, const TSourceLoc &line)
32 : mType(type),
33 mName(name),
34 mLine(line)
35 {
36 }
37
38 // TODO(alokp): We should only return const type.
39 // Fix it by tweaking grammar.
40 TType *type()
41 {
42 return mType;
43 }
44 const TType *type() const
45 {
46 return mType;
47 }
48
49 const TString &name() const
50 {
51 return *mName;
52 }
53 const TSourceLoc &line() const
54 {
55 return mLine;
56 }
57
58private:
59 TType *mType;
60 TString *mName;
61 TSourceLoc mLine;
62};
63
64typedef TVector<TField *> TFieldList;
65inline TFieldList *NewPoolTFieldList()
66{
67 void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
68 return new(memory)TFieldList;
Nicolas Capens978ddc52014-11-11 12:42:08 -050069}
70
Alexis Hetua8b364b2015-06-10 11:48:40 -040071class TFieldListCollection
72{
73public:
Nicolas Capensd71948f2015-06-10 19:51:05 -070074 virtual ~TFieldListCollection() { }
Alexis Hetua8b364b2015-06-10 11:48:40 -040075 const TString &name() const
76 {
77 return *mName;
78 }
79 const TFieldList &fields() const
80 {
81 return *mFields;
82 }
83
84 const TString &mangledName() const
85 {
86 if(mMangledName.empty())
87 mMangledName = buildMangledName();
88 return mMangledName;
89 }
90 size_t objectSize() const
91 {
92 if(mObjectSize == 0)
93 mObjectSize = calculateObjectSize();
94 return mObjectSize;
95 };
96
97protected:
98 TFieldListCollection(const TString *name, TFieldList *fields)
99 : mName(name),
100 mFields(fields),
101 mObjectSize(0)
102 {
103 }
104 TString buildMangledName() const;
105 size_t calculateObjectSize() const;
106 virtual TString mangledNamePrefix() const = 0;
107
108 const TString *mName;
109 TFieldList *mFields;
110
111 mutable TString mMangledName;
112 mutable size_t mObjectSize;
113};
114
115// May also represent interface blocks
116class TStructure : public TFieldListCollection
117{
118public:
119 POOL_ALLOCATOR_NEW_DELETE();
120 TStructure(const TString *name, TFieldList *fields)
121 : TFieldListCollection(name, fields),
122 mDeepestNesting(0),
123 mUniqueId(0),
124 mAtGlobalScope(false)
125 {
126 }
127
128 int deepestNesting() const
129 {
130 if(mDeepestNesting == 0)
131 mDeepestNesting = calculateDeepestNesting();
132 return mDeepestNesting;
133 }
134 bool containsArrays() const;
Alexis Hetuec93b1d2016-12-09 16:01:29 -0500135 bool containsType(TBasicType type) const;
Alexis Hetua8b364b2015-06-10 11:48:40 -0400136 bool containsSamplers() const;
137
138 bool equals(const TStructure &other) const;
139
140 void setUniqueId(int uniqueId)
141 {
142 mUniqueId = uniqueId;
143 }
144
145 int uniqueId() const
146 {
147 ASSERT(mUniqueId != 0);
148 return mUniqueId;
149 }
150
151 void setAtGlobalScope(bool atGlobalScope)
152 {
153 mAtGlobalScope = atGlobalScope;
154 }
155
156 bool atGlobalScope() const
157 {
158 return mAtGlobalScope;
159 }
160
161private:
162 // TODO(zmo): Find a way to get rid of the const_cast in function
163 // setName(). At the moment keep this function private so only
164 // friend class RegenerateStructNames may call it.
165 friend class RegenerateStructNames;
166 void setName(const TString &name)
167 {
168 TString *mutableName = const_cast<TString *>(mName);
169 *mutableName = name;
170 }
171
172 virtual TString mangledNamePrefix() const
173 {
174 return "struct-";
175 }
176 int calculateDeepestNesting() const;
177
178 mutable int mDeepestNesting;
179 int mUniqueId;
180 bool mAtGlobalScope;
181};
182
183class TInterfaceBlock : public TFieldListCollection
184{
185public:
186 POOL_ALLOCATOR_NEW_DELETE();
187 TInterfaceBlock(const TString *name, TFieldList *fields, const TString *instanceName,
188 int arraySize, const TLayoutQualifier &layoutQualifier)
189 : TFieldListCollection(name, fields),
190 mInstanceName(instanceName),
191 mArraySize(arraySize),
192 mBlockStorage(layoutQualifier.blockStorage),
193 mMatrixPacking(layoutQualifier.matrixPacking)
194 {
195 }
196
197 const TString &instanceName() const
198 {
199 return *mInstanceName;
200 }
201 bool hasInstanceName() const
202 {
Nicolas Capens0bac2852016-05-07 06:09:58 -0400203 return mInstanceName != nullptr;
Alexis Hetua8b364b2015-06-10 11:48:40 -0400204 }
205 bool isArray() const
206 {
207 return mArraySize > 0;
208 }
209 int arraySize() const
210 {
211 return mArraySize;
212 }
213 TLayoutBlockStorage blockStorage() const
214 {
215 return mBlockStorage;
216 }
217 TLayoutMatrixPacking matrixPacking() const
218 {
219 return mMatrixPacking;
220 }
221
222private:
223 virtual TString mangledNamePrefix() const
224 {
225 return "iblock-";
226 }
227
228 const TString *mInstanceName; // for interface block instance names
229 int mArraySize; // 0 if not an array
230 TLayoutBlockStorage mBlockStorage;
231 TLayoutMatrixPacking mMatrixPacking;
232};
233
Nicolas Capens978ddc52014-11-11 12:42:08 -0500234//
235// Base class for things that have a type.
236//
237class TType
238{
239public:
Nicolas Capens0bac2852016-05-07 06:09:58 -0400240 POOL_ALLOCATOR_NEW_DELETE();
241 TType() {}
Alexis Hetub14178b2015-04-13 13:23:20 -0400242 TType(TBasicType t, int s0 = 1, int s1 = 1) :
Alexis Hetua8b364b2015-06-10 11:48:40 -0400243 type(t), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false), layoutQualifier(TLayoutQualifier::create()),
244 primarySize(s0), secondarySize(s1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
245 structure(0), deepestStructNesting(0), mangled(0)
Nicolas Capens0bac2852016-05-07 06:09:58 -0400246 {
247 }
248 TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s0 = 1, int s1 = 1, bool a = false) :
Alexis Hetua8b364b2015-06-10 11:48:40 -0400249 type(t), precision(p), qualifier(q), invariant(false), layoutQualifier(TLayoutQualifier::create()),
250 primarySize(s0), secondarySize(s1), array(a), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
251 structure(0), deepestStructNesting(0), mangled(0)
Nicolas Capens0bac2852016-05-07 06:09:58 -0400252 {
253 }
254 explicit TType(const TPublicType &p);
Alexis Hetua8b364b2015-06-10 11:48:40 -0400255 TType(TStructure* userDef, TPrecision p = EbpUndefined) :
256 type(EbtStruct), precision(p), qualifier(EvqTemporary), invariant(false), layoutQualifier(TLayoutQualifier::create()),
257 primarySize(1), secondarySize(1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
258 structure(userDef), deepestStructNesting(0), mangled(0)
Nicolas Capens0bac2852016-05-07 06:09:58 -0400259 {
260 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500261
Alexis Hetua8b364b2015-06-10 11:48:40 -0400262 TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn,
263 TLayoutQualifier layoutQualifierIn, int arraySizeIn)
264 : type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn),
265 invariant(false), layoutQualifier(layoutQualifierIn),
266 primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn), maxArraySize(0), arrayInformationType(0),
267 interfaceBlock(interfaceBlockIn), structure(0), deepestStructNesting(0), mangled(0)
268 {
269 }
270
Nicolas Capens0bac2852016-05-07 06:09:58 -0400271 TBasicType getBasicType() const { return type; }
272 void setBasicType(TBasicType t) { type = t; }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500273
Nicolas Capens0bac2852016-05-07 06:09:58 -0400274 TPrecision getPrecision() const { return precision; }
275 void setPrecision(TPrecision p) { precision = p; }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500276
Nicolas Capens0bac2852016-05-07 06:09:58 -0400277 TQualifier getQualifier() const { return qualifier; }
278 void setQualifier(TQualifier q) { qualifier = q; }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500279
Alexis Hetua8b364b2015-06-10 11:48:40 -0400280 bool isInvariant() const { return invariant; }
281
282 TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
283 void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
284
Nicolas Capens0bac2852016-05-07 06:09:58 -0400285 // One-dimensional size of single instance type
Alexis Hetub14178b2015-04-13 13:23:20 -0400286 int getNominalSize() const { return primarySize; }
287 void setNominalSize(int s) { primarySize = s; }
Nicolas Capens0bac2852016-05-07 06:09:58 -0400288 // Full size of single instance of type
Alexis Hetuab752792016-04-21 16:11:31 -0400289 size_t getObjectSize() const
Nicolas Capens978ddc52014-11-11 12:42:08 -0500290 {
291 if(isArray())
292 {
293 return getElementSize() * std::max(getArraySize(), getMaxArraySize());
294 }
295 else
296 {
297 return getElementSize();
298 }
299 }
300
Alexis Hetuab752792016-04-21 16:11:31 -0400301 size_t getElementSize() const
Nicolas Capens978ddc52014-11-11 12:42:08 -0500302 {
303 if(getBasicType() == EbtStruct)
304 {
305 return getStructSize();
306 }
Alexis Hetu3f5af3a2015-06-29 13:51:16 -0400307 else if(isInterfaceBlock())
308 {
309 return interfaceBlock->objectSize();
310 }
Alexis Hetub14178b2015-04-13 13:23:20 -0400311 else if(isMatrix())
Nicolas Capens978ddc52014-11-11 12:42:08 -0500312 {
Alexis Hetub14178b2015-04-13 13:23:20 -0400313 return primarySize * secondarySize;
Nicolas Capens978ddc52014-11-11 12:42:08 -0500314 }
315 else // Vector or scalar
316 {
Alexis Hetub14178b2015-04-13 13:23:20 -0400317 return primarySize;
Nicolas Capens978ddc52014-11-11 12:42:08 -0500318 }
319 }
320
321 int elementRegisterCount() const
322 {
Alexis Hetu3f5af3a2015-06-29 13:51:16 -0400323 if(structure || isInterfaceBlock())
Nicolas Capens978ddc52014-11-11 12:42:08 -0500324 {
325 int registerCount = 0;
326
Alexis Hetu3f5af3a2015-06-29 13:51:16 -0400327 const TFieldList& fields = isInterfaceBlock() ? interfaceBlock->fields() : structure->fields();
Alexis Hetua8b364b2015-06-10 11:48:40 -0400328 for(size_t i = 0; i < fields.size(); i++)
Nicolas Capens978ddc52014-11-11 12:42:08 -0500329 {
Alexis Hetua8b364b2015-06-10 11:48:40 -0400330 registerCount += fields[i]->type()->totalRegisterCount();
Nicolas Capens978ddc52014-11-11 12:42:08 -0500331 }
332
333 return registerCount;
334 }
335 else if(isMatrix())
336 {
337 return getNominalSize();
338 }
339 else
340 {
341 return 1;
342 }
343 }
344
Alexis Hetu3a7b29c2016-04-07 10:29:41 -0400345 int blockRegisterCount() const
346 {
347 // If this TType object is a block member, return the register count of the parent block
348 // Otherwise, return the register count of the current TType object
349 if(interfaceBlock && !isInterfaceBlock())
350 {
351 int registerCount = 0;
352 const TFieldList& fieldList = interfaceBlock->fields();
353 for(size_t i = 0; i < fieldList.size(); i++)
354 {
355 const TType &fieldType = *(fieldList[i]->type());
356 registerCount += fieldType.totalRegisterCount();
357 }
358 return registerCount;
359 }
360 return totalRegisterCount();
361 }
362
Nicolas Capens978ddc52014-11-11 12:42:08 -0500363 int totalRegisterCount() const
364 {
365 if(array)
366 {
367 return arraySize * elementRegisterCount();
368 }
369 else
370 {
371 return elementRegisterCount();
372 }
373 }
374
Alexis Hetu909b8bc2015-07-15 16:55:56 -0400375 int registerSize() const
376 {
377 return isMatrix() ? secondarySize : primarySize;
378 }
379
Alexis Hetub14178b2015-04-13 13:23:20 -0400380 bool isMatrix() const { return secondarySize > 1; }
381 void setSecondarySize(int s1) { secondarySize = s1; }
382 int getSecondarySize() const { return secondarySize; }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500383
Nicolas Capens0bac2852016-05-07 06:09:58 -0400384 bool isArray() const { return array ? true : false; }
Alexis Hetuec93b1d2016-12-09 16:01:29 -0500385 bool isUnsizedArray() const { return array && arraySize == 0; }
Nicolas Capens0bac2852016-05-07 06:09:58 -0400386 int getArraySize() const { return arraySize; }
387 void setArraySize(int s) { array = true; arraySize = s; }
388 int getMaxArraySize () const { return maxArraySize; }
389 void setMaxArraySize (int s) { maxArraySize = s; }
390 void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
391 void setArrayInformationType(TType* t) { arrayInformationType = t; }
392 TType* getArrayInformationType() const { return arrayInformationType; }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500393
Alexis Hetua8b364b2015-06-10 11:48:40 -0400394 TInterfaceBlock *getInterfaceBlock() const { return interfaceBlock; }
395 void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn) { interfaceBlock = interfaceBlockIn; }
396 bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
Alexis Hetu36427ff2015-06-29 14:31:19 -0400397 TInterfaceBlock *getAsInterfaceBlock() const { return isInterfaceBlock() ? getInterfaceBlock() : nullptr; }
Alexis Hetua8b364b2015-06-10 11:48:40 -0400398
Alexis Hetub14178b2015-04-13 13:23:20 -0400399 bool isVector() const { return primarySize > 1 && !isMatrix(); }
Alexis Hetuc8b0f542016-01-12 16:19:22 -0500400 bool isScalar() const { return primarySize == 1 && !isMatrix() && !structure && !isInterfaceBlock(); }
401 bool isRegister() const { return !isMatrix() && !structure && !array && !isInterfaceBlock(); } // Fits in a 4-element register
Nicolas Capens978ddc52014-11-11 12:42:08 -0500402 bool isStruct() const { return structure != 0; }
Alexis Hetu9085c8d2015-06-01 13:48:07 -0400403 bool isScalarInt() const { return isScalar() && IsInteger(type); }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500404
Alexis Hetua8b364b2015-06-10 11:48:40 -0400405 TStructure* getStruct() const { return structure; }
406 void setStruct(TStructure* s) { structure = s; computeDeepestStructNesting(); }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500407
Nicolas Capens0bac2852016-05-07 06:09:58 -0400408 TString& getMangledName() {
409 if (!mangled) {
410 mangled = NewPoolTString("");
411 buildMangledName(*mangled);
412 *mangled += ';' ;
413 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500414
Nicolas Capens0bac2852016-05-07 06:09:58 -0400415 return *mangled;
416 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500417
Nicolas Capens0bac2852016-05-07 06:09:58 -0400418 bool sameElementType(const TType& right) const {
419 return type == right.type &&
Alexis Hetub14178b2015-04-13 13:23:20 -0400420 primarySize == right.primarySize &&
421 secondarySize == right.secondarySize &&
Nicolas Capens0bac2852016-05-07 06:09:58 -0400422 structure == right.structure;
423 }
424 bool operator==(const TType& right) const {
425 return type == right.type &&
Alexis Hetub14178b2015-04-13 13:23:20 -0400426 primarySize == right.primarySize &&
427 secondarySize == right.secondarySize &&
428 array == right.array && (!array || arraySize == right.arraySize) &&
Nicolas Capens0bac2852016-05-07 06:09:58 -0400429 structure == right.structure;
430 // don't check the qualifier, it's not ever what's being sought after
431 }
432 bool operator!=(const TType& right) const {
433 return !operator==(right);
434 }
435 bool operator<(const TType& right) const {
436 if (type != right.type) return type < right.type;
Alexis Hetub14178b2015-04-13 13:23:20 -0400437 if(primarySize != right.primarySize) return (primarySize * secondarySize) < (right.primarySize * right.secondarySize);
438 if(secondarySize != right.secondarySize) return secondarySize < right.secondarySize;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400439 if (array != right.array) return array < right.array;
440 if (arraySize != right.arraySize) return arraySize < right.arraySize;
441 if (structure != right.structure) return structure < right.structure;
Nicolas Capens978ddc52014-11-11 12:42:08 -0500442
Nicolas Capens0bac2852016-05-07 06:09:58 -0400443 return false;
444 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500445
Nicolas Capens0bac2852016-05-07 06:09:58 -0400446 const char* getBasicString() const { return ::getBasicString(type); }
447 const char* getPrecisionString() const { return ::getPrecisionString(precision); }
448 const char* getQualifierString() const { return ::getQualifierString(qualifier); }
449 TString getCompleteString() const;
Nicolas Capens978ddc52014-11-11 12:42:08 -0500450
Nicolas Capens0bac2852016-05-07 06:09:58 -0400451 // If this type is a struct, returns the deepest struct nesting of
452 // any field in the struct. For example:
453 // struct nesting1 {
454 // vec4 position;
455 // };
456 // struct nesting2 {
457 // nesting1 field1;
458 // vec4 field2;
459 // };
460 // For type "nesting2", this method would return 2 -- the number
461 // of structures through which indirection must occur to reach the
462 // deepest field (nesting2.field1.position).
463 int getDeepestStructNesting() const
464 {
465 return structure ? structure->deepestNesting() : 0;
466 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500467
Nicolas Capens0bac2852016-05-07 06:09:58 -0400468 bool isStructureContainingArrays() const
469 {
470 return structure ? structure->containsArrays() : false;
471 }
Alexis Hetua8b364b2015-06-10 11:48:40 -0400472
Alexis Hetuec93b1d2016-12-09 16:01:29 -0500473 bool isStructureContainingType(TBasicType t) const
474 {
475 return structure ? structure->containsType(t) : false;
476 }
477
Nicolas Capens0bac2852016-05-07 06:09:58 -0400478 bool isStructureContainingSamplers() const
479 {
480 return structure ? structure->containsSamplers() : false;
481 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500482
483protected:
Nicolas Capens0bac2852016-05-07 06:09:58 -0400484 void buildMangledName(TString&);
485 size_t getStructSize() const;
486 void computeDeepestStructNesting();
Nicolas Capens978ddc52014-11-11 12:42:08 -0500487
Nicolas Capens0bac2852016-05-07 06:09:58 -0400488 TBasicType type;
489 TPrecision precision;
490 TQualifier qualifier;
Alexis Hetua8b364b2015-06-10 11:48:40 -0400491 bool invariant;
492 TLayoutQualifier layoutQualifier;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400493 unsigned char primarySize; // size of vector or matrix, not size of array
Alexis Hetub14178b2015-04-13 13:23:20 -0400494 unsigned char secondarySize; // secondarySize: 1 for vectors, >1 for matrices
Nicolas Capens0bac2852016-05-07 06:09:58 -0400495 bool array;
496 int arraySize;
497 int maxArraySize;
498 TType *arrayInformationType;
Nicolas Capens978ddc52014-11-11 12:42:08 -0500499
Alexis Hetua8b364b2015-06-10 11:48:40 -0400500 // 0 unless this is an interface block, or interface block member variable
501 TInterfaceBlock *interfaceBlock;
502
503 TStructure *structure; // 0 unless this is a struct
Nicolas Capens0bac2852016-05-07 06:09:58 -0400504 int deepestStructNesting;
Nicolas Capens978ddc52014-11-11 12:42:08 -0500505
Nicolas Capens0bac2852016-05-07 06:09:58 -0400506 TString *mangled;
Nicolas Capens978ddc52014-11-11 12:42:08 -0500507};
508
509//
510// This is a workaround for a problem with the yacc stack, It can't have
511// types that it thinks have non-trivial constructors. It should
512// just be used while recognizing the grammar, not anything else. Pointers
513// could be used, but also trying to avoid lots of memory management overhead.
514//
515// Not as bad as it looks, there is no actual assumption that the fields
516// match up or are name the same or anything like that.
517//
518struct TPublicType
519{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400520 TBasicType type;
521 TLayoutQualifier layoutQualifier;
522 TQualifier qualifier;
523 bool invariant;
524 TPrecision precision;
525 int primarySize; // size of vector or matrix, not size of array
Alexis Hetub14178b2015-04-13 13:23:20 -0400526 int secondarySize; // 1 for scalars/vectors, >1 for matrices
Nicolas Capens0bac2852016-05-07 06:09:58 -0400527 bool array;
528 int arraySize;
529 TType* userDef;
530 TSourceLoc line;
Nicolas Capens978ddc52014-11-11 12:42:08 -0500531
Nicolas Capens0bac2852016-05-07 06:09:58 -0400532 void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln)
533 {
534 type = bt;
535 layoutQualifier = TLayoutQualifier::create();
536 qualifier = q;
537 invariant = false;
538 precision = EbpUndefined;
Alexis Hetub14178b2015-04-13 13:23:20 -0400539 primarySize = 1;
540 secondarySize = 1;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400541 array = false;
542 arraySize = 0;
543 userDef = 0;
544 line = ln;
545 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500546
Nicolas Capens0bac2852016-05-07 06:09:58 -0400547 void setAggregate(int s)
548 {
Alexis Hetub14178b2015-04-13 13:23:20 -0400549 primarySize = s;
550 secondarySize = 1;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400551 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500552
Alexis Hetub14178b2015-04-13 13:23:20 -0400553 void setMatrix(int s0, int s1)
554 {
555 primarySize = s0;
556 secondarySize = s1;
557 }
558
Alexis Hetua8b364b2015-06-10 11:48:40 -0400559 bool isUnsizedArray() const
560 {
561 return array && arraySize == 0;
562 }
563
Nicolas Capens0bac2852016-05-07 06:09:58 -0400564 void setArray(bool a, int s = 0)
565 {
566 array = a;
567 arraySize = s;
568 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500569
Alexis Hetu42ff6b12015-06-03 16:03:48 -0400570 void clearArrayness()
571 {
572 array = false;
573 arraySize = 0;
574 }
575
Nicolas Capens0bac2852016-05-07 06:09:58 -0400576 bool isStructureContainingArrays() const
577 {
578 if (!userDef)
579 {
580 return false;
581 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500582
Nicolas Capens0bac2852016-05-07 06:09:58 -0400583 return userDef->isStructureContainingArrays();
584 }
Alexis Hetua8b364b2015-06-10 11:48:40 -0400585
Alexis Hetuec93b1d2016-12-09 16:01:29 -0500586 bool isStructureContainingType(TBasicType t) const
587 {
588 if(!userDef)
589 {
590 return false;
591 }
592
593 return userDef->isStructureContainingType(t);
594 }
595
Alexis Hetua8b364b2015-06-10 11:48:40 -0400596 bool isMatrix() const
597 {
598 return primarySize > 1 && secondarySize > 1;
599 }
600
601 bool isVector() const
602 {
603 return primarySize > 1 && secondarySize == 1;
604 }
605
606 int getCols() const
607 {
608 ASSERT(isMatrix());
609 return primarySize;
610 }
611
612 int getRows() const
613 {
614 ASSERT(isMatrix());
615 return secondarySize;
616 }
617
618 int getNominalSize() const
619 {
620 return primarySize;
621 }
622
623 bool isAggregate() const
624 {
625 return array || isMatrix() || isVector();
626 }
Nicolas Capens978ddc52014-11-11 12:42:08 -0500627};
628
629#endif // _TYPES_INCLUDED_