• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2002 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 COMPILER_TRANSLATOR_TYPES_H_
8 #define COMPILER_TRANSLATOR_TYPES_H_
9 
10 #include "common/angleutils.h"
11 #include "common/debug.h"
12 
13 #include "compiler/translator/BaseTypes.h"
14 #include "compiler/translator/Common.h"
15 #include "compiler/translator/ImmutableString.h"
16 #include "compiler/translator/SymbolUniqueId.h"
17 
18 namespace sh
19 {
20 
21 struct TPublicType;
22 class TType;
23 class TInterfaceBlock;
24 class TStructure;
25 class TSymbol;
26 class TVariable;
27 class TIntermSymbol;
28 class TSymbolTable;
29 
30 class TField : angle::NonCopyable
31 {
32   public:
33     POOL_ALLOCATOR_NEW_DELETE
TField(TType * type,const ImmutableString & name,const TSourceLoc & line,SymbolType symbolType)34     TField(TType *type, const ImmutableString &name, const TSourceLoc &line, SymbolType symbolType)
35         : mType(type), mName(name), mLine(line), mSymbolType(symbolType)
36     {
37         ASSERT(mSymbolType != SymbolType::Empty);
38     }
39 
40     // TODO(alokp): We should only return const type.
41     // Fix it by tweaking grammar.
type()42     TType *type() { return mType; }
type()43     const TType *type() const { return mType; }
name()44     const ImmutableString &name() const { return mName; }
line()45     const TSourceLoc &line() const { return mLine; }
symbolType()46     SymbolType symbolType() const { return mSymbolType; }
47 
48   private:
49     TType *mType;
50     const ImmutableString mName;
51     const TSourceLoc mLine;
52     const SymbolType mSymbolType;
53 };
54 
55 typedef TVector<TField *> TFieldList;
56 
57 class TFieldListCollection : angle::NonCopyable
58 {
59   public:
fields()60     const TFieldList &fields() const { return *mFields; }
61 
62     bool containsArrays() const;
63     bool containsMatrices() const;
64     bool containsType(TBasicType t) const;
65     bool containsSamplers() const;
66 
67     size_t objectSize() const;
68     // How many locations the field list consumes as a uniform.
69     int getLocationCount() const;
70     int deepestNesting() const;
71     const TString &mangledFieldList() const;
72 
73   protected:
74     TFieldListCollection(const TFieldList *fields);
75 
76     const TFieldList *mFields;
77 
78   private:
79     size_t calculateObjectSize() const;
80     int calculateDeepestNesting() const;
81     TString buildMangledFieldList() const;
82 
83     mutable size_t mObjectSize;
84     mutable int mDeepestNesting;
85     mutable TString mMangledFieldList;
86 };
87 
88 //
89 // Base class for things that have a type.
90 //
91 class TType
92 {
93   public:
94     POOL_ALLOCATOR_NEW_DELETE
95     TType();
96     explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1);
97     TType(TBasicType t,
98           TPrecision p,
99           TQualifier q     = EvqTemporary,
100           unsigned char ps = 1,
101           unsigned char ss = 1);
102     explicit TType(const TPublicType &p);
103     TType(const TStructure *userDef, bool isStructSpecifier);
104     TType(const TInterfaceBlock *interfaceBlockIn,
105           TQualifier qualifierIn,
106           TLayoutQualifier layoutQualifierIn);
107     TType(const TType &t);
108     TType &operator=(const TType &t);
109 
TType(TBasicType t,TPrecision p,TQualifier q,unsigned char ps,unsigned char ss,const char * mangledName)110     constexpr TType(TBasicType t,
111                     TPrecision p,
112                     TQualifier q,
113                     unsigned char ps,
114                     unsigned char ss,
115                     const char *mangledName)
116         : type(t),
117           precision(p),
118           qualifier(q),
119           invariant(false),
120           memoryQualifier(TMemoryQualifier::Create()),
121           layoutQualifier(TLayoutQualifier::Create()),
122           primarySize(ps),
123           secondarySize(ss),
124           mArraySizes(nullptr),
125           mInterfaceBlock(nullptr),
126           mStructure(nullptr),
127           mIsStructSpecifier(false),
128           mMangledName(mangledName)
129     {}
130 
TType(TType && t)131     constexpr TType(TType &&t)
132         : type(t.type),
133           precision(t.precision),
134           qualifier(t.qualifier),
135           invariant(t.invariant),
136           memoryQualifier(t.memoryQualifier),
137           layoutQualifier(t.layoutQualifier),
138           primarySize(t.primarySize),
139           secondarySize(t.secondarySize),
140           mArraySizes(t.mArraySizes),
141           mInterfaceBlock(t.mInterfaceBlock),
142           mStructure(t.mStructure),
143           mIsStructSpecifier(t.mIsStructSpecifier),
144           mMangledName(t.mMangledName)
145     {}
146 
getBasicType()147     constexpr TBasicType getBasicType() const { return type; }
148     void setBasicType(TBasicType t);
149 
getPrecision()150     TPrecision getPrecision() const { return precision; }
setPrecision(TPrecision p)151     void setPrecision(TPrecision p) { precision = p; }
152 
getQualifier()153     constexpr TQualifier getQualifier() const { return qualifier; }
setQualifier(TQualifier q)154     void setQualifier(TQualifier q) { qualifier = q; }
155 
isInvariant()156     bool isInvariant() const { return invariant; }
157 
setInvariant(bool i)158     void setInvariant(bool i) { invariant = i; }
159 
getMemoryQualifier()160     TMemoryQualifier getMemoryQualifier() const { return memoryQualifier; }
setMemoryQualifier(const TMemoryQualifier & mq)161     void setMemoryQualifier(const TMemoryQualifier &mq) { memoryQualifier = mq; }
162 
getLayoutQualifier()163     TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
setLayoutQualifier(TLayoutQualifier lq)164     void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
165 
getNominalSize()166     int getNominalSize() const { return primarySize; }
getSecondarySize()167     int getSecondarySize() const { return secondarySize; }
getCols()168     int getCols() const
169     {
170         ASSERT(isMatrix());
171         return primarySize;
172     }
getRows()173     int getRows() const
174     {
175         ASSERT(isMatrix());
176         return secondarySize;
177     }
178     void setPrimarySize(unsigned char ps);
179     void setSecondarySize(unsigned char ss);
180 
181     // Full size of single instance of type
182     size_t getObjectSize() const;
183 
184     // Get how many locations this type consumes as a uniform.
185     int getLocationCount() const;
186 
isMatrix()187     bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
isNonSquareMatrix()188     bool isNonSquareMatrix() const { return isMatrix() && primarySize != secondarySize; }
isArray()189     bool isArray() const { return mArraySizes != nullptr && !mArraySizes->empty(); }
isArrayOfArrays()190     bool isArrayOfArrays() const { return isArray() && mArraySizes->size() > 1u; }
getNumArraySizes()191     size_t getNumArraySizes() const { return isArray() ? mArraySizes->size() : 0; }
getArraySizes()192     const TVector<unsigned int> *getArraySizes() const { return mArraySizes; }
193     unsigned int getArraySizeProduct() const;
194     bool isUnsizedArray() const;
getOutermostArraySize()195     unsigned int getOutermostArraySize() const
196     {
197         ASSERT(isArray());
198         return mArraySizes->back();
199     }
200     void makeArray(unsigned int s);
201 
202     // sizes contain new outermost array sizes.
203     void makeArrays(const TVector<unsigned int> &sizes);
204     // Here, the array dimension value 0 corresponds to the innermost array.
205     void setArraySize(size_t arrayDimension, unsigned int s);
206 
207     // Will set unsized array sizes according to newArraySizes. In case there are more
208     // unsized arrays than there are sizes in newArraySizes, defaults to setting any
209     // remaining array sizes to 1.
210     void sizeUnsizedArrays(const TVector<unsigned int> *newArraySizes);
211 
212     // Will size the outermost array according to arraySize.
213     void sizeOutermostUnsizedArray(unsigned int arraySize);
214 
215     // Note that the array element type might still be an array type in GLSL ES version >= 3.10.
216     void toArrayElementType();
217 
getInterfaceBlock()218     const TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; }
219     void setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn);
isInterfaceBlock()220     bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
221 
isVector()222     bool isVector() const { return primarySize > 1 && secondarySize == 1; }
isScalar()223     bool isScalar() const
224     {
225         return primarySize == 1 && secondarySize == 1 && !mStructure && !isArray();
226     }
isScalarFloat()227     bool isScalarFloat() const { return isScalar() && type == EbtFloat; }
isScalarInt()228     bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
229 
230     bool canBeConstructed() const;
231 
getStruct()232     const TStructure *getStruct() const { return mStructure; }
233 
GetSizeMangledName(unsigned char primarySize,unsigned char secondarySize)234     static constexpr char GetSizeMangledName(unsigned char primarySize, unsigned char secondarySize)
235     {
236         unsigned int sizeKey = (secondarySize - 1u) * 4u + primarySize - 1u;
237         if (sizeKey < 10u)
238         {
239             return static_cast<char>('0' + sizeKey);
240         }
241         return static_cast<char>('A' + sizeKey - 10);
242     }
243     const char *getMangledName() const;
244 
245     bool sameNonArrayType(const TType &right) const;
246 
247     // Returns true if arrayType is an array made of this type.
248     bool isElementTypeOf(const TType &arrayType) const;
249 
250     bool operator==(const TType &right) const
251     {
252         size_t numArraySizesL = getNumArraySizes();
253         size_t numArraySizesR = right.getNumArraySizes();
254         bool arraySizesEqual  = numArraySizesL == numArraySizesR &&
255                                (numArraySizesL == 0 || *mArraySizes == *right.mArraySizes);
256         return type == right.type && primarySize == right.primarySize &&
257                secondarySize == right.secondarySize && arraySizesEqual &&
258                mStructure == right.mStructure;
259         // don't check the qualifier, it's not ever what's being sought after
260     }
261     bool operator!=(const TType &right) const { return !operator==(right); }
262     bool operator<(const TType &right) const
263     {
264         if (type != right.type)
265             return type < right.type;
266         if (primarySize != right.primarySize)
267             return primarySize < right.primarySize;
268         if (secondarySize != right.secondarySize)
269             return secondarySize < right.secondarySize;
270         size_t numArraySizesL = getNumArraySizes();
271         size_t numArraySizesR = right.getNumArraySizes();
272         if (numArraySizesL != numArraySizesR)
273             return numArraySizesL < numArraySizesR;
274         for (size_t i = 0; i < numArraySizesL; ++i)
275         {
276             if ((*mArraySizes)[i] != (*right.mArraySizes)[i])
277                 return (*mArraySizes)[i] < (*right.mArraySizes)[i];
278         }
279         if (mStructure != right.mStructure)
280             return mStructure < right.mStructure;
281 
282         return false;
283     }
284 
getBasicString()285     const char *getBasicString() const { return sh::getBasicString(type); }
286 
getPrecisionString()287     const char *getPrecisionString() const { return sh::getPrecisionString(precision); }
getQualifierString()288     const char *getQualifierString() const { return sh::getQualifierString(qualifier); }
289 
290     const char *getBuiltInTypeNameString() const;
291 
292     // If this type is a struct, returns the deepest struct nesting of
293     // any field in the struct. For example:
294     //   struct nesting1 {
295     //     vec4 position;
296     //   };
297     //   struct nesting2 {
298     //     nesting1 field1;
299     //     vec4 field2;
300     //   };
301     // For type "nesting2", this method would return 2 -- the number
302     // of structures through which indirection must occur to reach the
303     // deepest field (nesting2.field1.position).
304     int getDeepestStructNesting() const;
305 
306     bool isNamelessStruct() const;
307 
308     bool isStructureContainingArrays() const;
309     bool isStructureContainingMatrices() const;
310     bool isStructureContainingType(TBasicType t) const;
311     bool isStructureContainingSamplers() const;
312 
isStructSpecifier()313     bool isStructSpecifier() const { return mIsStructSpecifier; }
314 
315     // Return true if variables of this type should be replaced with an inline constant value if
316     // such is available. False will be returned in cases where output doesn't support
317     // TIntermConstantUnion nodes of the type, or if the type contains a lot of fields and creating
318     // several copies of it in the output code is undesirable for performance.
319     bool canReplaceWithConstantUnion() const;
320 
321     // The char arrays passed in must be pool allocated or static.
322     void createSamplerSymbols(const ImmutableString &namePrefix,
323                               const TString &apiNamePrefix,
324                               TVector<const TVariable *> *outputSymbols,
325                               TMap<const TVariable *, TString> *outputSymbolsToAPINames,
326                               TSymbolTable *symbolTable) const;
327 
328     // Initializes all lazily-initialized members.
329     void realize();
330 
isSampler()331     bool isSampler() const { return IsSampler(type); }
isSamplerCube()332     bool isSamplerCube() const { return type == EbtSamplerCube; }
isAtomicCounter()333     bool isAtomicCounter() const { return IsAtomicCounter(type); }
334 
335   private:
336     void invalidateMangledName();
337     const char *buildMangledName() const;
338 
339     TBasicType type;
340     TPrecision precision;
341     TQualifier qualifier;
342     bool invariant;
343     TMemoryQualifier memoryQualifier;
344     TLayoutQualifier layoutQualifier;
345     unsigned char primarySize;    // size of vector or cols matrix
346     unsigned char secondarySize;  // rows of a matrix
347 
348     // Used to make an array type. Outermost array size is stored at the end of the vector. Having 0
349     // in this vector means an unsized array.
350     TVector<unsigned int> *mArraySizes;
351 
352     // This is set only in the following two cases:
353     // 1) Represents an interface block.
354     // 2) Represents the member variable of an unnamed interface block.
355     // It's nullptr also for members of named interface blocks.
356     const TInterfaceBlock *mInterfaceBlock;
357 
358     // nullptr unless this is a struct
359     const TStructure *mStructure;
360     bool mIsStructSpecifier;
361 
362     mutable const char *mMangledName;
363 };
364 
365 // TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the
366 // grammar
367 struct TTypeSpecifierNonArray
368 {
369     TBasicType type;
370     unsigned char primarySize;    // size of vector or cols of matrix
371     unsigned char secondarySize;  // rows of matrix
372     const TStructure *userDef;
373     TSourceLoc line;
374 
375     // true if the type was defined by a struct specifier rather than a reference to a type name.
376     bool isStructSpecifier;
377 
initializeTTypeSpecifierNonArray378     void initialize(TBasicType aType, const TSourceLoc &aLine)
379     {
380         ASSERT(aType != EbtStruct);
381         type              = aType;
382         primarySize       = 1;
383         secondarySize     = 1;
384         userDef           = nullptr;
385         line              = aLine;
386         isStructSpecifier = false;
387     }
388 
initializeStructTTypeSpecifierNonArray389     void initializeStruct(const TStructure *aUserDef,
390                           bool aIsStructSpecifier,
391                           const TSourceLoc &aLine)
392     {
393         type              = EbtStruct;
394         primarySize       = 1;
395         secondarySize     = 1;
396         userDef           = aUserDef;
397         line              = aLine;
398         isStructSpecifier = aIsStructSpecifier;
399     }
400 
setAggregateTTypeSpecifierNonArray401     void setAggregate(unsigned char size) { primarySize = size; }
402 
setMatrixTTypeSpecifierNonArray403     void setMatrix(unsigned char columns, unsigned char rows)
404     {
405         ASSERT(columns > 1 && rows > 1 && columns <= 4 && rows <= 4);
406         primarySize   = columns;
407         secondarySize = rows;
408     }
409 
isMatrixTTypeSpecifierNonArray410     bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
411 
isVectorTTypeSpecifierNonArray412     bool isVector() const { return primarySize > 1 && secondarySize == 1; }
413 };
414 
415 //
416 // This is a workaround for a problem with the yacc stack,  It can't have
417 // types that it thinks have non-trivial constructors.  It should
418 // just be used while recognizing the grammar, not anything else.  Pointers
419 // could be used, but also trying to avoid lots of memory management overhead.
420 //
421 // Not as bad as it looks, there is no actual assumption that the fields
422 // match up or are name the same or anything like that.
423 //
424 struct TPublicType
425 {
426     // Must have a trivial default constructor since it is used in YYSTYPE.
427     TPublicType() = default;
428 
429     void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q);
430     void initializeBasicType(TBasicType basicType);
431 
getBasicTypeTPublicType432     TBasicType getBasicType() const { return typeSpecifierNonArray.type; }
setBasicTypeTPublicType433     void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; }
434 
getPrimarySizeTPublicType435     unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
getSecondarySizeTPublicType436     unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; }
437 
getUserDefTPublicType438     const TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; }
getLineTPublicType439     const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }
440 
isStructSpecifierTPublicType441     bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }
442 
443     bool isStructureContainingArrays() const;
444     bool isStructureContainingType(TBasicType t) const;
445     void setArraySizes(TVector<unsigned int> *sizes);
446     bool isArray() const;
447     void clearArrayness();
448     bool isAggregate() const;
449 
450     TTypeSpecifierNonArray typeSpecifierNonArray;
451     TLayoutQualifier layoutQualifier;
452     TMemoryQualifier memoryQualifier;
453     TQualifier qualifier;
454     bool invariant;
455     TPrecision precision;
456 
457     // Either nullptr or empty in case the type is not an array. The last element is the outermost
458     // array size. Note that due to bison restrictions, copies of the public type created by the
459     // copy constructor share the same arraySizes pointer.
460     const TVector<unsigned int> *arraySizes;
461 };
462 
463 }  // namespace sh
464 
465 #endif  // COMPILER_TRANSLATOR_TYPES_H_
466