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