1 // 2 // Copyright (c) 2002-2013 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 _TYPES_INCLUDED 8 #define _TYPES_INCLUDED 9 10 #include "common/angleutils.h" 11 12 #include "compiler/BaseTypes.h" 13 #include "compiler/Common.h" 14 #include "compiler/debug.h" 15 16 struct TPublicType; 17 class TType; 18 19 class TField 20 { 21 public: 22 POOL_ALLOCATOR_NEW_DELETE(); 23 TField(TType* type, TString* name) : mType(type), mName(name) {} 24 25 // TODO(alokp): We should only return const type. 26 // Fix it by tweaking grammar. 27 TType* type() { return mType; } 28 const TType* type() const { return mType; } 29 30 const TString& name() const { return *mName; } 31 32 private: 33 DISALLOW_COPY_AND_ASSIGN(TField); 34 TType* mType; 35 TString* mName; 36 }; 37 38 typedef TVector<TField*> TFieldList; 39 inline TFieldList* NewPoolTFieldList() 40 { 41 void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList)); 42 return new(memory) TFieldList; 43 } 44 45 class TStructure 46 { 47 public: 48 POOL_ALLOCATOR_NEW_DELETE(); 49 TStructure(TString* name, TFieldList* fields) 50 : mName(name), 51 mFields(fields), 52 mObjectSize(0), 53 mDeepestNesting(0) { 54 } 55 56 const TString& name() const { return *mName; } 57 const TFieldList& fields() const { return *mFields; } 58 59 const TString& mangledName() const { 60 if (mMangledName.empty()) 61 mMangledName = buildMangledName(); 62 return mMangledName; 63 } 64 size_t objectSize() const { 65 if (mObjectSize == 0) 66 mObjectSize = calculateObjectSize(); 67 return mObjectSize; 68 }; 69 int deepestNesting() const { 70 if (mDeepestNesting == 0) 71 mDeepestNesting = calculateDeepestNesting(); 72 return mDeepestNesting; 73 } 74 bool containsArrays() const; 75 76 private: 77 DISALLOW_COPY_AND_ASSIGN(TStructure); 78 TString buildMangledName() const; 79 size_t calculateObjectSize() const; 80 int calculateDeepestNesting() const; 81 82 TString* mName; 83 TFieldList* mFields; 84 85 mutable TString mMangledName; 86 mutable size_t mObjectSize; 87 mutable int mDeepestNesting; 88 }; 89 90 // 91 // Base class for things that have a type. 92 // 93 class TType 94 { 95 public: 96 POOL_ALLOCATOR_NEW_DELETE(); 97 TType() {} 98 TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, unsigned char s = 1, bool m = false, bool a = false) : 99 type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0) 100 { 101 } 102 explicit TType(const TPublicType &p); 103 TType(TStructure* userDef, TPrecision p = EbpUndefined) : 104 type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef) 105 { 106 } 107 108 TBasicType getBasicType() const { return type; } 109 void setBasicType(TBasicType t) { type = t; } 110 111 TPrecision getPrecision() const { return precision; } 112 void setPrecision(TPrecision p) { precision = p; } 113 114 TQualifier getQualifier() const { return qualifier; } 115 void setQualifier(TQualifier q) { qualifier = q; } 116 117 // One-dimensional size of single instance type 118 int getNominalSize() const { return size; } 119 void setNominalSize(unsigned char s) { size = s; } 120 // Full size of single instance of type 121 size_t getObjectSize() const; 122 123 int elementRegisterCount() const 124 { 125 if (structure) 126 { 127 const TFieldList &fields = getStruct()->fields(); 128 int registerCount = 0; 129 130 for (size_t i = 0; i < fields.size(); i++) 131 { 132 registerCount += fields[i]->type()->totalRegisterCount(); 133 } 134 135 return registerCount; 136 } 137 else if (isMatrix()) 138 { 139 return getNominalSize(); 140 } 141 else 142 { 143 return 1; 144 } 145 } 146 147 int totalRegisterCount() const 148 { 149 if (array) 150 { 151 return arraySize * elementRegisterCount(); 152 } 153 else 154 { 155 return elementRegisterCount(); 156 } 157 } 158 159 bool isMatrix() const { return matrix ? true : false; } 160 void setMatrix(bool m) { matrix = m; } 161 162 bool isArray() const { return array ? true : false; } 163 int getArraySize() const { return arraySize; } 164 void setArraySize(int s) { array = true; arraySize = s; } 165 void clearArrayness() { array = false; arraySize = 0; } 166 167 bool isVector() const { return size > 1 && !matrix; } 168 bool isScalar() const { return size == 1 && !matrix && !structure; } 169 170 TStructure* getStruct() const { return structure; } 171 void setStruct(TStructure* s) { structure = s; } 172 173 const TString& getMangledName() const { 174 if (mangled.empty()) { 175 mangled = buildMangledName(); 176 mangled += ';'; 177 } 178 return mangled; 179 } 180 181 bool sameElementType(const TType& right) const { 182 return type == right.type && 183 size == right.size && 184 matrix == right.matrix && 185 structure == right.structure; 186 } 187 bool operator==(const TType& right) const { 188 return type == right.type && 189 size == right.size && 190 matrix == right.matrix && 191 array == right.array && (!array || arraySize == right.arraySize) && 192 structure == right.structure; 193 // don't check the qualifier, it's not ever what's being sought after 194 } 195 bool operator!=(const TType& right) const { 196 return !operator==(right); 197 } 198 bool operator<(const TType& right) const { 199 if (type != right.type) return type < right.type; 200 if (size != right.size) return size < right.size; 201 if (matrix != right.matrix) return matrix < right.matrix; 202 if (array != right.array) return array < right.array; 203 if (arraySize != right.arraySize) return arraySize < right.arraySize; 204 if (structure != right.structure) return structure < right.structure; 205 206 return false; 207 } 208 209 const char* getBasicString() const { return ::getBasicString(type); } 210 const char* getPrecisionString() const { return ::getPrecisionString(precision); } 211 const char* getQualifierString() const { return ::getQualifierString(qualifier); } 212 TString getCompleteString() const; 213 214 // If this type is a struct, returns the deepest struct nesting of 215 // any field in the struct. For example: 216 // struct nesting1 { 217 // vec4 position; 218 // }; 219 // struct nesting2 { 220 // nesting1 field1; 221 // vec4 field2; 222 // }; 223 // For type "nesting2", this method would return 2 -- the number 224 // of structures through which indirection must occur to reach the 225 // deepest field (nesting2.field1.position). 226 int getDeepestStructNesting() const { 227 return structure ? structure->deepestNesting() : 0; 228 } 229 230 bool isStructureContainingArrays() const { 231 return structure ? structure->containsArrays() : false; 232 } 233 234 private: 235 TString buildMangledName() const; 236 237 TBasicType type; 238 TPrecision precision; 239 TQualifier qualifier; 240 unsigned char size; 241 bool matrix; 242 bool array; 243 int arraySize; 244 245 TStructure* structure; // 0 unless this is a struct 246 247 mutable TString mangled; 248 }; 249 250 // 251 // This is a workaround for a problem with the yacc stack, It can't have 252 // types that it thinks have non-trivial constructors. It should 253 // just be used while recognizing the grammar, not anything else. Pointers 254 // could be used, but also trying to avoid lots of memory management overhead. 255 // 256 // Not as bad as it looks, there is no actual assumption that the fields 257 // match up or are name the same or anything like that. 258 // 259 struct TPublicType 260 { 261 TBasicType type; 262 TQualifier qualifier; 263 TPrecision precision; 264 unsigned char size; // size of vector or matrix, not size of array 265 bool matrix; 266 bool array; 267 int arraySize; 268 TType* userDef; 269 TSourceLoc line; 270 271 void setBasic(TBasicType bt, TQualifier q, const TSourceLoc& ln) 272 { 273 type = bt; 274 qualifier = q; 275 precision = EbpUndefined; 276 size = 1; 277 matrix = false; 278 array = false; 279 arraySize = 0; 280 userDef = 0; 281 line = ln; 282 } 283 284 void setAggregate(unsigned char s, bool m = false) 285 { 286 size = s; 287 matrix = m; 288 } 289 290 void setArray(bool a, int s = 0) 291 { 292 array = a; 293 arraySize = s; 294 } 295 296 bool isStructureContainingArrays() const 297 { 298 if (!userDef) 299 { 300 return false; 301 } 302 303 return userDef->isStructureContainingArrays(); 304 } 305 }; 306 307 #endif // _TYPES_INCLUDED_ 308