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