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