// // Copyright (c) 2002-2012 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 _TYPES_INCLUDED #define _TYPES_INCLUDED #include "compiler/BaseTypes.h" #include "compiler/Common.h" #include "compiler/debug.h" class TType; struct TPublicType; // // Need to have association of line numbers to types in a list for building structs. // struct TTypeLine { TType* type; int line; }; typedef TVector TTypeList; inline TTypeList* NewPoolTTypeList() { void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList)); return new(memory) TTypeList; } typedef TMap TStructureMap; typedef TMap::iterator TStructureMapIterator; // // Base class for things that have a type. // class TType { public: POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) TType() {} TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) : type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0) { } explicit TType(const TPublicType &p); TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) : type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0) { typeName = NewPoolTString(n.c_str()); } void copyType(const TType& copyOf, TStructureMap& remapper) { type = copyOf.type; precision = copyOf.precision; qualifier = copyOf.qualifier; size = copyOf.size; matrix = copyOf.matrix; array = copyOf.array; arraySize = copyOf.arraySize; TStructureMapIterator iter; if (copyOf.structure) { if ((iter = remapper.find(structure)) == remapper.end()) { // create the new structure here structure = NewPoolTTypeList(); for (unsigned int i = 0; i < copyOf.structure->size(); ++i) { TTypeLine typeLine; typeLine.line = (*copyOf.structure)[i].line; typeLine.type = (*copyOf.structure)[i].type->clone(remapper); structure->push_back(typeLine); } } else { structure = iter->second; } } else structure = 0; fieldName = 0; if (copyOf.fieldName) fieldName = NewPoolTString(copyOf.fieldName->c_str()); typeName = 0; if (copyOf.typeName) typeName = NewPoolTString(copyOf.typeName->c_str()); mangled = 0; if (copyOf.mangled) mangled = NewPoolTString(copyOf.mangled->c_str()); structureSize = copyOf.structureSize; maxArraySize = copyOf.maxArraySize; deepestStructNesting = copyOf.deepestStructNesting; assert(copyOf.arrayInformationType == 0); arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level } TType* clone(TStructureMap& remapper) { TType *newType = new TType(); newType->copyType(*this, remapper); return newType; } TBasicType getBasicType() const { return type; } void setBasicType(TBasicType t) { type = t; } TPrecision getPrecision() const { return precision; } void setPrecision(TPrecision p) { precision = p; } TQualifier getQualifier() const { return qualifier; } void setQualifier(TQualifier q) { qualifier = q; } // One-dimensional size of single instance type int getNominalSize() const { return size; } void setNominalSize(int s) { size = s; } // Full size of single instance of type int getObjectSize() const { int totalSize; if (getBasicType() == EbtStruct) totalSize = getStructSize(); else if (matrix) totalSize = size * size; else totalSize = size; if (isArray()) totalSize *= std::max(getArraySize(), getMaxArraySize()); return totalSize; } int elementRegisterCount() const { TTypeList *structure = getStruct(); if (structure) { int registerCount = 0; for (size_t i = 0; i < structure->size(); i++) { registerCount += (*structure)[i].type->totalRegisterCount(); } return registerCount; } else if (isMatrix()) { return getNominalSize(); } else { return 1; } } int totalRegisterCount() const { if (array) { return arraySize * elementRegisterCount(); } else { return elementRegisterCount(); } } bool isMatrix() const { return matrix ? true : false; } void setMatrix(bool m) { matrix = m; } bool isArray() const { return array ? true : false; } int getArraySize() const { return arraySize; } void setArraySize(int s) { array = true; arraySize = s; } int getMaxArraySize () const { return maxArraySize; } void setMaxArraySize (int s) { maxArraySize = s; } void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; } void setArrayInformationType(TType* t) { arrayInformationType = t; } TType* getArrayInformationType() const { return arrayInformationType; } bool isVector() const { return size > 1 && !matrix; } bool isScalar() const { return size == 1 && !matrix && !structure; } TTypeList* getStruct() const { return structure; } void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); } const TString& getTypeName() const { assert(typeName); return *typeName; } void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); } bool isField() const { return fieldName != 0; } const TString& getFieldName() const { assert(fieldName); return *fieldName; } void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); } TString& getMangledName() { if (!mangled) { mangled = NewPoolTString(""); buildMangledName(*mangled); *mangled += ';' ; } return *mangled; } bool sameElementType(const TType& right) const { return type == right.type && size == right.size && matrix == right.matrix && structure == right.structure; } bool operator==(const TType& right) const { return type == right.type && size == right.size && matrix == right.matrix && array == right.array && (!array || arraySize == right.arraySize) && structure == right.structure; // 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 (size != right.size) return size < right.size; if (matrix != right.matrix) return matrix < right.matrix; if (array != right.array) return array < right.array; if (arraySize != right.arraySize) return arraySize < right.arraySize; if (structure != right.structure) return structure < right.structure; return false; } const char* getBasicString() const { return ::getBasicString(type); } const char* getPrecisionString() const { return ::getPrecisionString(precision); } const char* getQualifierString() const { return ::getQualifierString(qualifier); } TString getCompleteString() 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 { return deepestStructNesting; } bool isStructureContainingArrays() const; protected: void buildMangledName(TString&); int getStructSize() const; void computeDeepestStructNesting(); TBasicType type : 6; TPrecision precision; TQualifier qualifier : 7; int size : 8; // size of vector or matrix, not size of array unsigned int matrix : 1; unsigned int array : 1; int arraySize; int maxArraySize; TType* arrayInformationType; TTypeList* structure; // 0 unless this is a struct mutable int structureSize; int deepestStructNesting; TString *fieldName; // for structure field names TString *mangled; TString *typeName; // for structure field type name }; // // 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 { TBasicType type; TQualifier qualifier; TPrecision precision; int size; // size of vector or matrix, not size of array bool matrix; bool array; int arraySize; TType* userDef; int line; void setBasic(TBasicType bt, TQualifier q, int ln = 0) { type = bt; qualifier = q; precision = EbpUndefined; size = 1; matrix = false; array = false; arraySize = 0; userDef = 0; line = ln; } void setAggregate(int s, bool m = false) { size = s; matrix = m; } void setArray(bool a, int s = 0) { array = a; arraySize = s; } bool isStructureContainingArrays() const { if (!userDef) { return false; } return userDef->isStructureContainingArrays(); } }; #endif // _TYPES_INCLUDED_