summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/compiler/translator/Types.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/Types.h')
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Types.h508
1 files changed, 508 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/Types.h b/gfx/angle/checkout/src/compiler/translator/Types.h
new file mode 100644
index 0000000000..623a3b335b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Types.h
@@ -0,0 +1,508 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TYPES_H_
+#define COMPILER_TRANSLATOR_TYPES_H_
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+struct TPublicType;
+class TType;
+class TInterfaceBlock;
+class TStructure;
+class TSymbol;
+class TVariable;
+class TIntermSymbol;
+class TSymbolTable;
+
+class TField : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TField(TType *type, const ImmutableString &name, const TSourceLoc &line, SymbolType symbolType)
+ : mType(type), mName(name), mLine(line), mSymbolType(symbolType)
+ {
+ ASSERT(mSymbolType != SymbolType::Empty);
+ }
+
+ // TODO(alokp): We should only return const type.
+ // Fix it by tweaking grammar.
+ TType *type() { return mType; }
+ const TType *type() const { return mType; }
+ const ImmutableString &name() const { return mName; }
+ const TSourceLoc &line() const { return mLine; }
+ SymbolType symbolType() const { return mSymbolType; }
+
+ private:
+ TType *mType;
+ const ImmutableString mName;
+ const TSourceLoc mLine;
+ const SymbolType mSymbolType;
+};
+
+typedef TVector<TField *> TFieldList;
+
+class TFieldListCollection : angle::NonCopyable
+{
+ public:
+ const TFieldList &fields() const { return *mFields; }
+
+ bool containsArrays() const;
+ bool containsMatrices() const;
+ bool containsType(TBasicType t) const;
+ bool containsSamplers() const;
+
+ size_t objectSize() const;
+ // How many locations the field list consumes as a uniform.
+ int getLocationCount() const;
+ int deepestNesting() const;
+ const TString &mangledFieldList() const;
+
+ protected:
+ TFieldListCollection(const TFieldList *fields);
+
+ const TFieldList *mFields;
+
+ private:
+ size_t calculateObjectSize() const;
+ int calculateDeepestNesting() const;
+ TString buildMangledFieldList() const;
+
+ mutable size_t mObjectSize;
+ mutable int mDeepestNesting;
+ mutable TString mMangledFieldList;
+};
+
+//
+// Base class for things that have a type.
+//
+class TType
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TType();
+ explicit TType(TBasicType t, uint8_t ps = 1, uint8_t ss = 1);
+ TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, uint8_t ps = 1, uint8_t ss = 1);
+ explicit TType(const TPublicType &p);
+ TType(const TStructure *userDef, bool isStructSpecifier);
+ TType(const TInterfaceBlock *interfaceBlockIn,
+ TQualifier qualifierIn,
+ TLayoutQualifier layoutQualifierIn);
+ TType(const TType &t);
+ TType &operator=(const TType &t);
+
+ constexpr TType(TBasicType t,
+ TPrecision p,
+ TQualifier q,
+ uint8_t ps,
+ uint8_t ss,
+ const TSpan<const unsigned int> arraySizes,
+ const char *mangledName)
+ : type(t),
+ precision(p),
+ qualifier(q),
+ invariant(false),
+ precise(false),
+ memoryQualifier(TMemoryQualifier::Create()),
+ layoutQualifier(TLayoutQualifier::Create()),
+ primarySize(ps),
+ secondarySize(ss),
+ mArraySizes(arraySizes),
+ mArraySizesStorage(nullptr),
+ mInterfaceBlock(nullptr),
+ mStructure(nullptr),
+ mIsStructSpecifier(false),
+ mInterfaceBlockFieldIndex(0),
+ mMangledName(mangledName)
+ {}
+
+ constexpr TType(TType &&t)
+ : type(t.type),
+ precision(t.precision),
+ qualifier(t.qualifier),
+ invariant(t.invariant),
+ precise(t.precise),
+ memoryQualifier(t.memoryQualifier),
+ layoutQualifier(t.layoutQualifier),
+ primarySize(t.primarySize),
+ secondarySize(t.secondarySize),
+ mArraySizes(t.mArraySizes),
+ mArraySizesStorage(t.mArraySizesStorage),
+ mInterfaceBlock(t.mInterfaceBlock),
+ mStructure(t.mStructure),
+ mIsStructSpecifier(t.mIsStructSpecifier),
+ mInterfaceBlockFieldIndex(0),
+ mMangledName(t.mMangledName)
+ {
+ t.mArraySizesStorage = nullptr;
+ }
+
+ constexpr TBasicType getBasicType() const { return type; }
+ void setBasicType(TBasicType t);
+
+ TPrecision getPrecision() const { return precision; }
+ void setPrecision(TPrecision p) { precision = p; }
+
+ constexpr TQualifier getQualifier() const { return qualifier; }
+ void setQualifier(TQualifier q) { qualifier = q; }
+
+ bool isInvariant() const { return invariant; }
+ void setInvariant(bool i) { invariant = i; }
+
+ bool isPrecise() const { return precise; }
+ void setPrecise(bool i) { precise = i; }
+
+ TMemoryQualifier getMemoryQualifier() const { return memoryQualifier; }
+ void setMemoryQualifier(const TMemoryQualifier &mq) { memoryQualifier = mq; }
+
+ TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
+ void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
+
+ uint8_t getNominalSize() const { return primarySize; }
+ uint8_t getSecondarySize() const { return secondarySize; }
+ uint8_t getCols() const
+ {
+ ASSERT(isMatrix());
+ return primarySize;
+ }
+ uint8_t getRows() const
+ {
+ ASSERT(isMatrix());
+ return secondarySize;
+ }
+ void setPrimarySize(uint8_t ps);
+ void setSecondarySize(uint8_t ss);
+
+ // Full size of single instance of type
+ size_t getObjectSize() const;
+
+ // Get how many locations this type consumes as a uniform.
+ int getLocationCount() const;
+
+ bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
+ bool isNonSquareMatrix() const { return isMatrix() && primarySize != secondarySize; }
+ bool isArray() const { return !mArraySizes.empty(); }
+ bool isArrayOfArrays() const { return mArraySizes.size() > 1u; }
+ size_t getNumArraySizes() const { return mArraySizes.size(); }
+ const TSpan<const unsigned int> &getArraySizes() const { return mArraySizes; }
+ unsigned int getArraySizeProduct() const;
+ bool isUnsizedArray() const;
+ unsigned int getOutermostArraySize() const
+ {
+ ASSERT(isArray());
+ return mArraySizes.back();
+ }
+ void makeArray(unsigned int s);
+
+ // sizes contain new outermost array sizes.
+ void makeArrays(const TSpan<const unsigned int> &sizes);
+ // Here, the array dimension value 0 corresponds to the innermost array.
+ void setArraySize(size_t arrayDimension, unsigned int s);
+
+ // Will set unsized array sizes according to newArraySizes. In case there are more
+ // unsized arrays than there are sizes in newArraySizes, defaults to setting any
+ // remaining array sizes to 1.
+ void sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes);
+
+ // Will size the outermost array according to arraySize.
+ void sizeOutermostUnsizedArray(unsigned int arraySize);
+
+ // Note that the array element type might still be an array type in GLSL ES version >= 3.10.
+ void toArrayElementType();
+ // Removes all array sizes.
+ void toArrayBaseType();
+ // Turns a matrix into a column of it.
+ void toMatrixColumnType();
+ // Turns a matrix or vector into a component of it.
+ void toComponentType();
+
+ const TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; }
+ void setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn);
+ bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
+
+ void setInterfaceBlockField(const TInterfaceBlock *interfaceBlockIn, size_t fieldIndex);
+ size_t getInterfaceBlockFieldIndex() const { return mInterfaceBlockFieldIndex; }
+
+ bool isVector() const { return primarySize > 1 && secondarySize == 1; }
+ bool isVectorArray() const { return primarySize > 1 && secondarySize == 1 && isArray(); }
+ bool isRank0() const { return primarySize == 1 && secondarySize == 1; }
+ bool isScalar() const
+ {
+ return primarySize == 1 && secondarySize == 1 && !mStructure && !isArray();
+ }
+ bool isScalarArray() const
+ {
+ return primarySize == 1 && secondarySize == 1 && !mStructure && isArray();
+ }
+ bool isScalarFloat() const { return isScalar() && type == EbtFloat; }
+ bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
+
+ bool canBeConstructed() const;
+
+ const TStructure *getStruct() const { return mStructure; }
+
+ static constexpr char GetSizeMangledName(uint8_t primarySize, uint8_t secondarySize)
+ {
+ unsigned int sizeKey = (secondarySize - 1u) * 4u + primarySize - 1u;
+ if (sizeKey < 10u)
+ {
+ return static_cast<char>('0' + sizeKey);
+ }
+ return static_cast<char>('A' + sizeKey - 10);
+ }
+ const char *getMangledName() const;
+
+ bool sameNonArrayType(const TType &right) const;
+
+ // Returns true if arrayType is an array made of this type.
+ bool isElementTypeOf(const TType &arrayType) const;
+
+ bool operator==(const TType &right) const
+ {
+ size_t numArraySizesL = getNumArraySizes();
+ size_t numArraySizesR = right.getNumArraySizes();
+ bool arraySizesEqual = numArraySizesL == numArraySizesR &&
+ (numArraySizesL == 0 || mArraySizes == right.mArraySizes);
+ return type == right.type && primarySize == right.primarySize &&
+ secondarySize == right.secondarySize && arraySizesEqual &&
+ mStructure == right.mStructure;
+ // don't check the qualifier, it's not ever what's being sought after
+ }
+ bool operator!=(const TType &right) const { return !operator==(right); }
+ bool operator<(const TType &right) const
+ {
+ if (type != right.type)
+ return type < right.type;
+ if (primarySize != right.primarySize)
+ return primarySize < right.primarySize;
+ if (secondarySize != right.secondarySize)
+ return secondarySize < right.secondarySize;
+ size_t numArraySizesL = getNumArraySizes();
+ size_t numArraySizesR = right.getNumArraySizes();
+ if (numArraySizesL != numArraySizesR)
+ return numArraySizesL < numArraySizesR;
+ for (size_t i = 0; i < numArraySizesL; ++i)
+ {
+ if (mArraySizes[i] != right.mArraySizes[i])
+ return mArraySizes[i] < right.mArraySizes[i];
+ }
+ if (mStructure != right.mStructure)
+ return mStructure < right.mStructure;
+
+ return false;
+ }
+
+ const char *getBasicString() const { return sh::getBasicString(type); }
+
+ const char *getPrecisionString() const { return sh::getPrecisionString(precision); }
+ const char *getQualifierString() const { return sh::getQualifierString(qualifier); }
+
+ const char *getBuiltInTypeNameString() const;
+
+ // If this type is a struct, returns the deepest struct nesting of
+ // any field in the struct. For example:
+ // struct nesting1 {
+ // vec4 position;
+ // };
+ // struct nesting2 {
+ // nesting1 field1;
+ // vec4 field2;
+ // };
+ // For type "nesting2", this method would return 2 -- the number
+ // of structures through which indirection must occur to reach the
+ // deepest field (nesting2.field1.position).
+ int getDeepestStructNesting() const;
+
+ bool isNamelessStruct() const;
+
+ bool isStructureContainingArrays() const;
+ bool isStructureContainingMatrices() const;
+ bool isStructureContainingType(TBasicType t) const;
+ bool isStructureContainingSamplers() const;
+ bool isInterfaceBlockContainingType(TBasicType t) const;
+
+ bool isStructSpecifier() const { return mIsStructSpecifier; }
+
+ // Return true if variables of this type should be replaced with an inline constant value if
+ // such is available. False will be returned in cases where output doesn't support
+ // TIntermConstantUnion nodes of the type, or if the type contains a lot of fields and creating
+ // several copies of it in the output code is undesirable for performance.
+ bool canReplaceWithConstantUnion() const;
+
+ // The char arrays passed in must be pool allocated or static.
+ void createSamplerSymbols(const ImmutableString &namePrefix,
+ const TString &apiNamePrefix,
+ TVector<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const;
+
+ // Initializes all lazily-initialized members.
+ void realize();
+
+ bool isSampler() const { return IsSampler(type); }
+ bool isSamplerCube() const { return type == EbtSamplerCube; }
+ bool isAtomicCounter() const { return IsAtomicCounter(type); }
+ bool isSamplerVideoWEBGL() const { return type == EbtSamplerVideoWEBGL; }
+ bool isImage() const { return IsImage(type); }
+ bool isPixelLocal() const { return IsPixelLocal(type); }
+
+ private:
+ constexpr void invalidateMangledName() { mMangledName = nullptr; }
+ const char *buildMangledName() const;
+ constexpr void onArrayDimensionsChange(const TSpan<const unsigned int> &sizes)
+ {
+ mArraySizes = sizes;
+ invalidateMangledName();
+ }
+
+ TBasicType type;
+ TPrecision precision;
+ TQualifier qualifier;
+ bool invariant;
+ bool precise;
+
+ TMemoryQualifier memoryQualifier;
+ TLayoutQualifier layoutQualifier;
+ uint8_t primarySize; // size of vector or cols matrix
+ uint8_t secondarySize; // rows of a matrix
+
+ // Used to make an array type. Outermost array size is stored at the end of the vector. Having 0
+ // in this vector means an unsized array.
+ TSpan<const unsigned int> mArraySizes;
+ // Storage for mArraySizes, if any. This is usually the case, except for constexpr TTypes which
+ // only have a valid mArraySizes (with mArraySizesStorage being nullptr). Therefore, all
+ // modifications to array sizes happen on the storage (and if dimensions change, mArraySizes is
+ // also updated) and all reads are from mArraySizes.
+ TVector<unsigned int> *mArraySizesStorage;
+
+ // This is set only in the following two cases:
+ // 1) Represents an interface block.
+ // 2) Represents the member variable of an unnamed interface block.
+ // It's nullptr also for members of named interface blocks.
+ const TInterfaceBlock *mInterfaceBlock;
+
+ // nullptr unless this is a struct
+ const TStructure *mStructure;
+ bool mIsStructSpecifier;
+
+ // If this is a field of a nameless interface block, this would indicate which member it's
+ // refering to.
+ size_t mInterfaceBlockFieldIndex;
+
+ mutable const char *mMangledName;
+};
+
+// TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the
+// grammar
+struct TTypeSpecifierNonArray
+{
+ TBasicType type;
+ uint8_t primarySize; // size of vector or cols of matrix
+ uint8_t secondarySize; // rows of matrix
+ const TStructure *userDef;
+ TSourceLoc line;
+
+ // true if the type was defined by a struct specifier rather than a reference to a type name.
+ bool isStructSpecifier;
+
+ void initialize(TBasicType aType, const TSourceLoc &aLine)
+ {
+ ASSERT(aType != EbtStruct);
+ type = aType;
+ primarySize = 1;
+ secondarySize = 1;
+ userDef = nullptr;
+ line = aLine;
+ isStructSpecifier = false;
+ }
+
+ void initializeStruct(const TStructure *aUserDef,
+ bool aIsStructSpecifier,
+ const TSourceLoc &aLine)
+ {
+ type = EbtStruct;
+ primarySize = 1;
+ secondarySize = 1;
+ userDef = aUserDef;
+ line = aLine;
+ isStructSpecifier = aIsStructSpecifier;
+ }
+
+ void setAggregate(uint8_t size) { primarySize = size; }
+
+ void setMatrix(uint8_t columns, uint8_t rows)
+ {
+ ASSERT(columns > 1 && rows > 1 && columns <= 4 && rows <= 4);
+ primarySize = columns;
+ secondarySize = rows;
+ }
+
+ bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
+
+ bool isVector() const { return primarySize > 1 && secondarySize == 1; }
+};
+
+//
+// This is a workaround for a problem with the yacc stack, It can't have
+// types that it thinks have non-trivial constructors. It should
+// just be used while recognizing the grammar, not anything else. Pointers
+// could be used, but also trying to avoid lots of memory management overhead.
+//
+// Not as bad as it looks, there is no actual assumption that the fields
+// match up or are name the same or anything like that.
+//
+struct TPublicType
+{
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ TPublicType() = default;
+
+ void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q);
+ void initializeBasicType(TBasicType basicType);
+
+ TBasicType getBasicType() const { return typeSpecifierNonArray.type; }
+ void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; }
+
+ uint8_t getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
+ uint8_t getSecondarySize() const { return typeSpecifierNonArray.secondarySize; }
+
+ const TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; }
+ const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }
+
+ bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }
+
+ bool isStructureContainingArrays() const;
+ bool isStructureContainingType(TBasicType t) const;
+ void setArraySizes(TVector<unsigned int> *sizes);
+ bool isArray() const;
+ void clearArrayness();
+ bool isAggregate() const;
+
+ TTypeSpecifierNonArray typeSpecifierNonArray;
+ TLayoutQualifier layoutQualifier;
+ TMemoryQualifier memoryQualifier;
+ TQualifier qualifier;
+ bool invariant;
+ bool precise;
+ TPrecision precision;
+
+ // Either nullptr or empty in case the type is not an array. The last element is the outermost
+ // array size. Note that due to bison restrictions, copies of the public type created by the
+ // copy constructor share the same arraySizes pointer.
+ const TVector<unsigned int> *arraySizes;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TYPES_H_