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 TSpan<const unsigned int> arraySizes,const char * mangledName)110 constexpr TType(TBasicType t, 111 TPrecision p, 112 TQualifier q, 113 unsigned char ps, 114 unsigned char ss, 115 const TSpan<const unsigned int> arraySizes, 116 const char *mangledName) 117 : type(t), 118 precision(p), 119 qualifier(q), 120 invariant(false), 121 precise(false), 122 memoryQualifier(TMemoryQualifier::Create()), 123 layoutQualifier(TLayoutQualifier::Create()), 124 primarySize(ps), 125 secondarySize(ss), 126 mArraySizes(arraySizes), 127 mArraySizesStorage(nullptr), 128 mInterfaceBlock(nullptr), 129 mStructure(nullptr), 130 mIsStructSpecifier(false), 131 mMangledName(mangledName) 132 {} 133 TType(TType && t)134 constexpr TType(TType &&t) 135 : type(t.type), 136 precision(t.precision), 137 qualifier(t.qualifier), 138 invariant(t.invariant), 139 precise(t.precise), 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 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 getMemoryQualifier()169 TMemoryQualifier getMemoryQualifier() const { return memoryQualifier; } setMemoryQualifier(const TMemoryQualifier & mq)170 void setMemoryQualifier(const TMemoryQualifier &mq) { memoryQualifier = mq; } 171 getLayoutQualifier()172 TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; } setLayoutQualifier(TLayoutQualifier lq)173 void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; } 174 getNominalSize()175 int getNominalSize() const { return primarySize; } getSecondarySize()176 int getSecondarySize() const { return secondarySize; } getCols()177 int getCols() const 178 { 179 ASSERT(isMatrix()); 180 return primarySize; 181 } getRows()182 int getRows() const 183 { 184 ASSERT(isMatrix()); 185 return secondarySize; 186 } 187 void setPrimarySize(unsigned char ps); 188 void setSecondarySize(unsigned char ss); 189 190 // Full size of single instance of type 191 size_t getObjectSize() const; 192 193 // Get how many locations this type consumes as a uniform. 194 int getLocationCount() const; 195 isMatrix()196 bool isMatrix() const { return primarySize > 1 && secondarySize > 1; } isNonSquareMatrix()197 bool isNonSquareMatrix() const { return isMatrix() && primarySize != secondarySize; } isArray()198 bool isArray() const { return !mArraySizes.empty(); } isArrayOfArrays()199 bool isArrayOfArrays() const { return mArraySizes.size() > 1u; } getNumArraySizes()200 size_t getNumArraySizes() const { return mArraySizes.size(); } getArraySizes()201 const TSpan<const unsigned int> &getArraySizes() const { return mArraySizes; } 202 unsigned int getArraySizeProduct() const; 203 bool isUnsizedArray() const; getOutermostArraySize()204 unsigned int getOutermostArraySize() const 205 { 206 ASSERT(isArray()); 207 return mArraySizes.back(); 208 } 209 void makeArray(unsigned int s); 210 211 // sizes contain new outermost array sizes. 212 void makeArrays(const TSpan<const unsigned int> &sizes); 213 // Here, the array dimension value 0 corresponds to the innermost array. 214 void setArraySize(size_t arrayDimension, unsigned int s); 215 216 // Will set unsized array sizes according to newArraySizes. In case there are more 217 // unsized arrays than there are sizes in newArraySizes, defaults to setting any 218 // remaining array sizes to 1. 219 void sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes); 220 221 // Will size the outermost array according to arraySize. 222 void sizeOutermostUnsizedArray(unsigned int arraySize); 223 224 // Note that the array element type might still be an array type in GLSL ES version >= 3.10. 225 void toArrayElementType(); 226 // Removes all array sizes. 227 void toArrayBaseType(); 228 getInterfaceBlock()229 const TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; } 230 void setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn); isInterfaceBlock()231 bool isInterfaceBlock() const { return type == EbtInterfaceBlock; } 232 isVector()233 bool isVector() const { return primarySize > 1 && secondarySize == 1; } isScalar()234 bool isScalar() const 235 { 236 return primarySize == 1 && secondarySize == 1 && !mStructure && !isArray(); 237 } isScalarFloat()238 bool isScalarFloat() const { return isScalar() && type == EbtFloat; } isScalarInt()239 bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); } 240 241 bool canBeConstructed() const; 242 getStruct()243 const TStructure *getStruct() const { return mStructure; } 244 GetSizeMangledName(unsigned char primarySize,unsigned char secondarySize)245 static constexpr char GetSizeMangledName(unsigned char primarySize, unsigned char secondarySize) 246 { 247 unsigned int sizeKey = (secondarySize - 1u) * 4u + primarySize - 1u; 248 if (sizeKey < 10u) 249 { 250 return static_cast<char>('0' + sizeKey); 251 } 252 return static_cast<char>('A' + sizeKey - 10); 253 } 254 const char *getMangledName() const; 255 256 bool sameNonArrayType(const TType &right) const; 257 258 // Returns true if arrayType is an array made of this type. 259 bool isElementTypeOf(const TType &arrayType) const; 260 261 bool operator==(const TType &right) const 262 { 263 size_t numArraySizesL = getNumArraySizes(); 264 size_t numArraySizesR = right.getNumArraySizes(); 265 bool arraySizesEqual = numArraySizesL == numArraySizesR && 266 (numArraySizesL == 0 || mArraySizes == right.mArraySizes); 267 return type == right.type && primarySize == right.primarySize && 268 secondarySize == right.secondarySize && arraySizesEqual && 269 mStructure == right.mStructure; 270 // don't check the qualifier, it's not ever what's being sought after 271 } 272 bool operator!=(const TType &right) const { return !operator==(right); } 273 bool operator<(const TType &right) const 274 { 275 if (type != right.type) 276 return type < right.type; 277 if (primarySize != right.primarySize) 278 return primarySize < right.primarySize; 279 if (secondarySize != right.secondarySize) 280 return secondarySize < right.secondarySize; 281 size_t numArraySizesL = getNumArraySizes(); 282 size_t numArraySizesR = right.getNumArraySizes(); 283 if (numArraySizesL != numArraySizesR) 284 return numArraySizesL < numArraySizesR; 285 for (size_t i = 0; i < numArraySizesL; ++i) 286 { 287 if (mArraySizes[i] != right.mArraySizes[i]) 288 return mArraySizes[i] < right.mArraySizes[i]; 289 } 290 if (mStructure != right.mStructure) 291 return mStructure < right.mStructure; 292 293 return false; 294 } 295 getBasicString()296 const char *getBasicString() const { return sh::getBasicString(type); } 297 getPrecisionString()298 const char *getPrecisionString() const { return sh::getPrecisionString(precision); } getQualifierString()299 const char *getQualifierString() const { return sh::getQualifierString(qualifier); } 300 301 const char *getBuiltInTypeNameString() const; 302 303 // If this type is a struct, returns the deepest struct nesting of 304 // any field in the struct. For example: 305 // struct nesting1 { 306 // vec4 position; 307 // }; 308 // struct nesting2 { 309 // nesting1 field1; 310 // vec4 field2; 311 // }; 312 // For type "nesting2", this method would return 2 -- the number 313 // of structures through which indirection must occur to reach the 314 // deepest field (nesting2.field1.position). 315 int getDeepestStructNesting() const; 316 317 bool isNamelessStruct() const; 318 319 bool isStructureContainingArrays() const; 320 bool isStructureContainingMatrices() const; 321 bool isStructureContainingType(TBasicType t) const; 322 bool isStructureContainingSamplers() const; 323 isStructSpecifier()324 bool isStructSpecifier() const { return mIsStructSpecifier; } 325 326 // Return true if variables of this type should be replaced with an inline constant value if 327 // such is available. False will be returned in cases where output doesn't support 328 // TIntermConstantUnion nodes of the type, or if the type contains a lot of fields and creating 329 // several copies of it in the output code is undesirable for performance. 330 bool canReplaceWithConstantUnion() const; 331 332 // The char arrays passed in must be pool allocated or static. 333 void createSamplerSymbols(const ImmutableString &namePrefix, 334 const TString &apiNamePrefix, 335 TVector<const TVariable *> *outputSymbols, 336 TMap<const TVariable *, TString> *outputSymbolsToAPINames, 337 TSymbolTable *symbolTable) const; 338 339 // Initializes all lazily-initialized members. 340 void realize(); 341 isSampler()342 bool isSampler() const { return IsSampler(type); } isSamplerCube()343 bool isSamplerCube() const { return type == EbtSamplerCube; } isAtomicCounter()344 bool isAtomicCounter() const { return IsAtomicCounter(type); } isSamplerVideoWEBGL()345 bool isSamplerVideoWEBGL() const { return type == EbtSamplerVideoWEBGL; } 346 347 private: invalidateMangledName()348 constexpr void invalidateMangledName() { mMangledName = nullptr; } 349 const char *buildMangledName() const; onArrayDimensionsChange(const TSpan<const unsigned int> & sizes)350 constexpr void onArrayDimensionsChange(const TSpan<const unsigned int> &sizes) 351 { 352 mArraySizes = sizes; 353 invalidateMangledName(); 354 } 355 356 TBasicType type; 357 TPrecision precision; 358 TQualifier qualifier; 359 bool invariant; 360 bool precise; 361 362 TMemoryQualifier memoryQualifier; 363 TLayoutQualifier layoutQualifier; 364 unsigned char primarySize; // size of vector or cols matrix 365 unsigned char secondarySize; // rows of a matrix 366 367 // Used to make an array type. Outermost array size is stored at the end of the vector. Having 0 368 // in this vector means an unsized array. 369 TSpan<const unsigned int> mArraySizes; 370 // Storage for mArraySizes, if any. This is usually the case, except for constexpr TTypes which 371 // only have a valid mArraySizes (with mArraySizesStorage being nullptr). Therefore, all 372 // modifications to array sizes happen on the storage (and if dimensions change, mArraySizes is 373 // also updated) and all reads are from mArraySizes. 374 TVector<unsigned int> *mArraySizesStorage; 375 376 // This is set only in the following two cases: 377 // 1) Represents an interface block. 378 // 2) Represents the member variable of an unnamed interface block. 379 // It's nullptr also for members of named interface blocks. 380 const TInterfaceBlock *mInterfaceBlock; 381 382 // nullptr unless this is a struct 383 const TStructure *mStructure; 384 bool mIsStructSpecifier; 385 386 mutable const char *mMangledName; 387 }; 388 389 // TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the 390 // grammar 391 struct TTypeSpecifierNonArray 392 { 393 TBasicType type; 394 unsigned char primarySize; // size of vector or cols of matrix 395 unsigned char secondarySize; // rows of matrix 396 const TStructure *userDef; 397 TSourceLoc line; 398 399 // true if the type was defined by a struct specifier rather than a reference to a type name. 400 bool isStructSpecifier; 401 initializeTTypeSpecifierNonArray402 void initialize(TBasicType aType, const TSourceLoc &aLine) 403 { 404 ASSERT(aType != EbtStruct); 405 type = aType; 406 primarySize = 1; 407 secondarySize = 1; 408 userDef = nullptr; 409 line = aLine; 410 isStructSpecifier = false; 411 } 412 initializeStructTTypeSpecifierNonArray413 void initializeStruct(const TStructure *aUserDef, 414 bool aIsStructSpecifier, 415 const TSourceLoc &aLine) 416 { 417 type = EbtStruct; 418 primarySize = 1; 419 secondarySize = 1; 420 userDef = aUserDef; 421 line = aLine; 422 isStructSpecifier = aIsStructSpecifier; 423 } 424 setAggregateTTypeSpecifierNonArray425 void setAggregate(unsigned char size) { primarySize = size; } 426 setMatrixTTypeSpecifierNonArray427 void setMatrix(unsigned char columns, unsigned char rows) 428 { 429 ASSERT(columns > 1 && rows > 1 && columns <= 4 && rows <= 4); 430 primarySize = columns; 431 secondarySize = rows; 432 } 433 isMatrixTTypeSpecifierNonArray434 bool isMatrix() const { return primarySize > 1 && secondarySize > 1; } 435 isVectorTTypeSpecifierNonArray436 bool isVector() const { return primarySize > 1 && secondarySize == 1; } 437 }; 438 439 // 440 // This is a workaround for a problem with the yacc stack, It can't have 441 // types that it thinks have non-trivial constructors. It should 442 // just be used while recognizing the grammar, not anything else. Pointers 443 // could be used, but also trying to avoid lots of memory management overhead. 444 // 445 // Not as bad as it looks, there is no actual assumption that the fields 446 // match up or are name the same or anything like that. 447 // 448 struct TPublicType 449 { 450 // Must have a trivial default constructor since it is used in YYSTYPE. 451 TPublicType() = default; 452 453 void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q); 454 void initializeBasicType(TBasicType basicType); 455 getBasicTypeTPublicType456 TBasicType getBasicType() const { return typeSpecifierNonArray.type; } setBasicTypeTPublicType457 void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; } 458 getPrimarySizeTPublicType459 unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; } getSecondarySizeTPublicType460 unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; } 461 getUserDefTPublicType462 const TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; } getLineTPublicType463 const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; } 464 isStructSpecifierTPublicType465 bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; } 466 467 bool isStructureContainingArrays() const; 468 bool isStructureContainingType(TBasicType t) const; 469 void setArraySizes(TVector<unsigned int> *sizes); 470 bool isArray() const; 471 void clearArrayness(); 472 bool isAggregate() const; 473 474 TTypeSpecifierNonArray typeSpecifierNonArray; 475 TLayoutQualifier layoutQualifier; 476 TMemoryQualifier memoryQualifier; 477 TQualifier qualifier; 478 bool invariant; 479 bool precise; 480 TPrecision precision; 481 482 // Either nullptr or empty in case the type is not an array. The last element is the outermost 483 // array size. Note that due to bison restrictions, copies of the public type created by the 484 // copy constructor share the same arraySizes pointer. 485 const TVector<unsigned int> *arraySizes; 486 }; 487 488 } // namespace sh 489 490 #endif // COMPILER_TRANSLATOR_TYPES_H_ 491