1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2017 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker // Symbol.h: Symbols representing variables, functions, structures and interface blocks. 7*8975f5c5SAndroid Build Coastguard Worker // 8*8975f5c5SAndroid Build Coastguard Worker 9*8975f5c5SAndroid Build Coastguard Worker #ifndef COMPILER_TRANSLATOR_SYMBOL_H_ 10*8975f5c5SAndroid Build Coastguard Worker #define COMPILER_TRANSLATOR_SYMBOL_H_ 11*8975f5c5SAndroid Build Coastguard Worker 12*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h" 13*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ExtensionBehavior.h" 14*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ImmutableString.h" 15*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/IntermNode.h" 16*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/SymbolUniqueId.h" 17*8975f5c5SAndroid Build Coastguard Worker 18*8975f5c5SAndroid Build Coastguard Worker namespace sh 19*8975f5c5SAndroid Build Coastguard Worker { 20*8975f5c5SAndroid Build Coastguard Worker 21*8975f5c5SAndroid Build Coastguard Worker class TSymbolTable; 22*8975f5c5SAndroid Build Coastguard Worker 23*8975f5c5SAndroid Build Coastguard Worker // Symbol base class. (Can build functions or variables out of these...) 24*8975f5c5SAndroid Build Coastguard Worker class TSymbol : angle::NonCopyable 25*8975f5c5SAndroid Build Coastguard Worker { 26*8975f5c5SAndroid Build Coastguard Worker public: 27*8975f5c5SAndroid Build Coastguard Worker POOL_ALLOCATOR_NEW_DELETE 28*8975f5c5SAndroid Build Coastguard Worker TSymbol(TSymbolTable *symbolTable, 29*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 30*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 31*8975f5c5SAndroid Build Coastguard Worker SymbolClass symbolClass, 32*8975f5c5SAndroid Build Coastguard Worker TExtension extension = TExtension::UNDEFINED); 33*8975f5c5SAndroid Build Coastguard Worker 34*8975f5c5SAndroid Build Coastguard Worker TSymbol(TSymbolTable *symbolTable, 35*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 36*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 37*8975f5c5SAndroid Build Coastguard Worker SymbolClass symbolClass, 38*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, 3u> &extensions); 39*8975f5c5SAndroid Build Coastguard Worker 40*8975f5c5SAndroid Build Coastguard Worker // Note that we can't have a virtual destructor in order to support constexpr symbols. Data is 41*8975f5c5SAndroid Build Coastguard Worker // either statically allocated or pool allocated. 42*8975f5c5SAndroid Build Coastguard Worker ~TSymbol() = default; 43*8975f5c5SAndroid Build Coastguard Worker 44*8975f5c5SAndroid Build Coastguard Worker // Calling name() for empty symbols (symbolType == SymbolType::Empty) generates a similar name 45*8975f5c5SAndroid Build Coastguard Worker // as for internal variables. 46*8975f5c5SAndroid Build Coastguard Worker ImmutableString name() const; 47*8975f5c5SAndroid Build Coastguard Worker // Don't call getMangledName() for empty symbols (symbolType == SymbolType::Empty). 48*8975f5c5SAndroid Build Coastguard Worker ImmutableString getMangledName() const; 49*8975f5c5SAndroid Build Coastguard Worker isFunction()50*8975f5c5SAndroid Build Coastguard Worker bool isFunction() const { return mSymbolClass == SymbolClass::Function; } isVariable()51*8975f5c5SAndroid Build Coastguard Worker bool isVariable() const { return mSymbolClass == SymbolClass::Variable; } isStruct()52*8975f5c5SAndroid Build Coastguard Worker bool isStruct() const { return mSymbolClass == SymbolClass::Struct; } isInterfaceBlock()53*8975f5c5SAndroid Build Coastguard Worker bool isInterfaceBlock() const { return mSymbolClass == SymbolClass::InterfaceBlock; } 54*8975f5c5SAndroid Build Coastguard Worker uniqueId()55*8975f5c5SAndroid Build Coastguard Worker const TSymbolUniqueId &uniqueId() const { return mUniqueId; } symbolType()56*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType() const { return mSymbolType; } extensions()57*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, 3u> extensions() const { return mExtensions; } 58*8975f5c5SAndroid Build Coastguard Worker 59*8975f5c5SAndroid Build Coastguard Worker template <size_t ExtensionCount> CreateExtensionList(const std::array<TExtension,ExtensionCount> & extensions)60*8975f5c5SAndroid Build Coastguard Worker constexpr const std::array<TExtension, 3u> CreateExtensionList( 61*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, ExtensionCount> &extensions) 62*8975f5c5SAndroid Build Coastguard Worker { 63*8975f5c5SAndroid Build Coastguard Worker switch (extensions.size()) 64*8975f5c5SAndroid Build Coastguard Worker { 65*8975f5c5SAndroid Build Coastguard Worker case 1: 66*8975f5c5SAndroid Build Coastguard Worker return std::array<TExtension, 3u>{ 67*8975f5c5SAndroid Build Coastguard Worker {extensions[0], TExtension::UNDEFINED, TExtension::UNDEFINED}}; 68*8975f5c5SAndroid Build Coastguard Worker case 2: 69*8975f5c5SAndroid Build Coastguard Worker return std::array<TExtension, 3u>{ 70*8975f5c5SAndroid Build Coastguard Worker {extensions[0], extensions[1], TExtension::UNDEFINED}}; 71*8975f5c5SAndroid Build Coastguard Worker case 3: 72*8975f5c5SAndroid Build Coastguard Worker return std::array<TExtension, 3u>{{extensions[0], extensions[1], extensions[2]}}; 73*8975f5c5SAndroid Build Coastguard Worker default: 74*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE(); 75*8975f5c5SAndroid Build Coastguard Worker return std::array<TExtension, 3u>{ 76*8975f5c5SAndroid Build Coastguard Worker {TExtension::UNDEFINED, TExtension::UNDEFINED, TExtension::UNDEFINED}}; 77*8975f5c5SAndroid Build Coastguard Worker } 78*8975f5c5SAndroid Build Coastguard Worker } 79*8975f5c5SAndroid Build Coastguard Worker 80*8975f5c5SAndroid Build Coastguard Worker protected: 81*8975f5c5SAndroid Build Coastguard Worker template <size_t ExtensionCount> TSymbol(const TSymbolUniqueId & id,const ImmutableString & name,SymbolType symbolType,const std::array<TExtension,ExtensionCount> & extensions,SymbolClass symbolClass)82*8975f5c5SAndroid Build Coastguard Worker constexpr TSymbol(const TSymbolUniqueId &id, 83*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 84*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 85*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, ExtensionCount> &extensions, 86*8975f5c5SAndroid Build Coastguard Worker SymbolClass symbolClass) 87*8975f5c5SAndroid Build Coastguard Worker : mName(name), 88*8975f5c5SAndroid Build Coastguard Worker mUniqueId(id), 89*8975f5c5SAndroid Build Coastguard Worker mExtensions(CreateExtensionList(extensions)), 90*8975f5c5SAndroid Build Coastguard Worker mSymbolType(symbolType), 91*8975f5c5SAndroid Build Coastguard Worker mSymbolClass(symbolClass) 92*8975f5c5SAndroid Build Coastguard Worker {} 93*8975f5c5SAndroid Build Coastguard Worker 94*8975f5c5SAndroid Build Coastguard Worker const ImmutableString mName; 95*8975f5c5SAndroid Build Coastguard Worker 96*8975f5c5SAndroid Build Coastguard Worker private: 97*8975f5c5SAndroid Build Coastguard Worker const TSymbolUniqueId mUniqueId; 98*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, 3u> mExtensions; 99*8975f5c5SAndroid Build Coastguard Worker const SymbolType mSymbolType : 4; 100*8975f5c5SAndroid Build Coastguard Worker 101*8975f5c5SAndroid Build Coastguard Worker // We use this instead of having virtual functions for querying the class in order to support 102*8975f5c5SAndroid Build Coastguard Worker // constexpr symbols. 103*8975f5c5SAndroid Build Coastguard Worker const SymbolClass mSymbolClass : 4; 104*8975f5c5SAndroid Build Coastguard Worker }; 105*8975f5c5SAndroid Build Coastguard Worker 106*8975f5c5SAndroid Build Coastguard Worker static_assert(sizeof(TSymbol) <= 24, "Size check failed"); 107*8975f5c5SAndroid Build Coastguard Worker 108*8975f5c5SAndroid Build Coastguard Worker // Variable. 109*8975f5c5SAndroid Build Coastguard Worker // May store the value of a constant variable of any type (float, int, bool or struct). 110*8975f5c5SAndroid Build Coastguard Worker class TVariable : public TSymbol 111*8975f5c5SAndroid Build Coastguard Worker { 112*8975f5c5SAndroid Build Coastguard Worker public: 113*8975f5c5SAndroid Build Coastguard Worker TVariable(TSymbolTable *symbolTable, 114*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 115*8975f5c5SAndroid Build Coastguard Worker const TType *type, 116*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 117*8975f5c5SAndroid Build Coastguard Worker TExtension ext = TExtension::UNDEFINED); 118*8975f5c5SAndroid Build Coastguard Worker 119*8975f5c5SAndroid Build Coastguard Worker TVariable(TSymbolTable *symbolTable, 120*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 121*8975f5c5SAndroid Build Coastguard Worker const TType *type, 122*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 123*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, 3u> &extensions); 124*8975f5c5SAndroid Build Coastguard Worker getType()125*8975f5c5SAndroid Build Coastguard Worker const TType &getType() const { return *mType; } 126*8975f5c5SAndroid Build Coastguard Worker getConstPointer()127*8975f5c5SAndroid Build Coastguard Worker const TConstantUnion *getConstPointer() const { return unionArray; } 128*8975f5c5SAndroid Build Coastguard Worker shareConstPointer(const TConstantUnion * constArray)129*8975f5c5SAndroid Build Coastguard Worker void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; } 130*8975f5c5SAndroid Build Coastguard Worker 131*8975f5c5SAndroid Build Coastguard Worker // Note: only to be used for built-in variables with autogenerated ids! TVariable(const TSymbolUniqueId & id,const ImmutableString & name,SymbolType symbolType,TExtension extension,const TType * type)132*8975f5c5SAndroid Build Coastguard Worker constexpr TVariable(const TSymbolUniqueId &id, 133*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 134*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 135*8975f5c5SAndroid Build Coastguard Worker TExtension extension, 136*8975f5c5SAndroid Build Coastguard Worker const TType *type) 137*8975f5c5SAndroid Build Coastguard Worker : TSymbol(id, 138*8975f5c5SAndroid Build Coastguard Worker name, 139*8975f5c5SAndroid Build Coastguard Worker symbolType, 140*8975f5c5SAndroid Build Coastguard Worker std::array<TExtension, 1u>{{extension}}, 141*8975f5c5SAndroid Build Coastguard Worker SymbolClass::Variable), 142*8975f5c5SAndroid Build Coastguard Worker mType(type), 143*8975f5c5SAndroid Build Coastguard Worker unionArray(nullptr) 144*8975f5c5SAndroid Build Coastguard Worker {} 145*8975f5c5SAndroid Build Coastguard Worker 146*8975f5c5SAndroid Build Coastguard Worker template <size_t ExtensionCount> TVariable(const TSymbolUniqueId & id,const ImmutableString & name,SymbolType symbolType,const std::array<TExtension,ExtensionCount> & extensions,const TType * type)147*8975f5c5SAndroid Build Coastguard Worker constexpr TVariable(const TSymbolUniqueId &id, 148*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 149*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 150*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, ExtensionCount> &extensions, 151*8975f5c5SAndroid Build Coastguard Worker const TType *type) 152*8975f5c5SAndroid Build Coastguard Worker : TSymbol(id, name, symbolType, extensions, SymbolClass::Variable), 153*8975f5c5SAndroid Build Coastguard Worker mType(type), 154*8975f5c5SAndroid Build Coastguard Worker unionArray(nullptr) 155*8975f5c5SAndroid Build Coastguard Worker {} 156*8975f5c5SAndroid Build Coastguard Worker 157*8975f5c5SAndroid Build Coastguard Worker private: 158*8975f5c5SAndroid Build Coastguard Worker const TType *mType; 159*8975f5c5SAndroid Build Coastguard Worker const TConstantUnion *unionArray; 160*8975f5c5SAndroid Build Coastguard Worker }; 161*8975f5c5SAndroid Build Coastguard Worker 162*8975f5c5SAndroid Build Coastguard Worker // Struct type. 163*8975f5c5SAndroid Build Coastguard Worker class TStructure : public TSymbol, public TFieldListCollection 164*8975f5c5SAndroid Build Coastguard Worker { 165*8975f5c5SAndroid Build Coastguard Worker public: 166*8975f5c5SAndroid Build Coastguard Worker TStructure(TSymbolTable *symbolTable, 167*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 168*8975f5c5SAndroid Build Coastguard Worker const TFieldList *fields, 169*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType); 170*8975f5c5SAndroid Build Coastguard Worker 171*8975f5c5SAndroid Build Coastguard Worker // The char arrays passed in must be pool allocated or static. 172*8975f5c5SAndroid Build Coastguard Worker void createSamplerSymbols(const char *namePrefix, 173*8975f5c5SAndroid Build Coastguard Worker const TString &apiNamePrefix, 174*8975f5c5SAndroid Build Coastguard Worker TVector<const TVariable *> *outputSymbols, 175*8975f5c5SAndroid Build Coastguard Worker TMap<const TVariable *, TString> *outputSymbolsToAPINames, 176*8975f5c5SAndroid Build Coastguard Worker TSymbolTable *symbolTable) const; 177*8975f5c5SAndroid Build Coastguard Worker setAtGlobalScope(bool atGlobalScope)178*8975f5c5SAndroid Build Coastguard Worker void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; } atGlobalScope()179*8975f5c5SAndroid Build Coastguard Worker bool atGlobalScope() const { return mAtGlobalScope; } 180*8975f5c5SAndroid Build Coastguard Worker 181*8975f5c5SAndroid Build Coastguard Worker private: 182*8975f5c5SAndroid Build Coastguard Worker friend class TSymbolTable; 183*8975f5c5SAndroid Build Coastguard Worker // For creating built-in structs. TStructure(const TSymbolUniqueId & id,const ImmutableString & name,TExtension extension,const TFieldList * fields)184*8975f5c5SAndroid Build Coastguard Worker TStructure(const TSymbolUniqueId &id, 185*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 186*8975f5c5SAndroid Build Coastguard Worker TExtension extension, 187*8975f5c5SAndroid Build Coastguard Worker const TFieldList *fields) 188*8975f5c5SAndroid Build Coastguard Worker : TSymbol(id, 189*8975f5c5SAndroid Build Coastguard Worker name, 190*8975f5c5SAndroid Build Coastguard Worker SymbolType::BuiltIn, 191*8975f5c5SAndroid Build Coastguard Worker std::array<TExtension, 1u>{{extension}}, 192*8975f5c5SAndroid Build Coastguard Worker SymbolClass::Struct), 193*8975f5c5SAndroid Build Coastguard Worker TFieldListCollection(fields) 194*8975f5c5SAndroid Build Coastguard Worker {} 195*8975f5c5SAndroid Build Coastguard Worker 196*8975f5c5SAndroid Build Coastguard Worker template <size_t ExtensionCount> TStructure(const TSymbolUniqueId & id,const ImmutableString & name,const std::array<TExtension,ExtensionCount> & extensions,const TFieldList * fields)197*8975f5c5SAndroid Build Coastguard Worker TStructure(const TSymbolUniqueId &id, 198*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 199*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, ExtensionCount> &extensions, 200*8975f5c5SAndroid Build Coastguard Worker const TFieldList *fields) 201*8975f5c5SAndroid Build Coastguard Worker : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Struct), 202*8975f5c5SAndroid Build Coastguard Worker TFieldListCollection(fields) 203*8975f5c5SAndroid Build Coastguard Worker {} 204*8975f5c5SAndroid Build Coastguard Worker 205*8975f5c5SAndroid Build Coastguard Worker // TODO(zmo): Find a way to get rid of the const_cast in function 206*8975f5c5SAndroid Build Coastguard Worker // setName(). At the moment keep this function private so only 207*8975f5c5SAndroid Build Coastguard Worker // friend class RegenerateStructNames may call it. 208*8975f5c5SAndroid Build Coastguard Worker friend class RegenerateStructNamesTraverser; 209*8975f5c5SAndroid Build Coastguard Worker void setName(const ImmutableString &name); 210*8975f5c5SAndroid Build Coastguard Worker 211*8975f5c5SAndroid Build Coastguard Worker bool mAtGlobalScope; 212*8975f5c5SAndroid Build Coastguard Worker }; 213*8975f5c5SAndroid Build Coastguard Worker 214*8975f5c5SAndroid Build Coastguard Worker // Interface block. Note that this contains the block name, not the instance name. Interface block 215*8975f5c5SAndroid Build Coastguard Worker // instances are stored as TVariable. 216*8975f5c5SAndroid Build Coastguard Worker class TInterfaceBlock : public TSymbol, public TFieldListCollection 217*8975f5c5SAndroid Build Coastguard Worker { 218*8975f5c5SAndroid Build Coastguard Worker public: 219*8975f5c5SAndroid Build Coastguard Worker TInterfaceBlock(TSymbolTable *symbolTable, 220*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 221*8975f5c5SAndroid Build Coastguard Worker const TFieldList *fields, 222*8975f5c5SAndroid Build Coastguard Worker const TLayoutQualifier &layoutQualifier, 223*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 224*8975f5c5SAndroid Build Coastguard Worker TExtension extension = TExtension::UNDEFINED); 225*8975f5c5SAndroid Build Coastguard Worker 226*8975f5c5SAndroid Build Coastguard Worker TInterfaceBlock(TSymbolTable *symbolTable, 227*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 228*8975f5c5SAndroid Build Coastguard Worker const TFieldList *fields, 229*8975f5c5SAndroid Build Coastguard Worker const TLayoutQualifier &layoutQualifier, 230*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 231*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, 3u> &extensions); 232*8975f5c5SAndroid Build Coastguard Worker blockStorage()233*8975f5c5SAndroid Build Coastguard Worker TLayoutBlockStorage blockStorage() const { return mBlockStorage; } blockBinding()234*8975f5c5SAndroid Build Coastguard Worker int blockBinding() const { return mBinding; } 235*8975f5c5SAndroid Build Coastguard Worker 236*8975f5c5SAndroid Build Coastguard Worker private: 237*8975f5c5SAndroid Build Coastguard Worker friend class TSymbolTable; 238*8975f5c5SAndroid Build Coastguard Worker // For creating built-in interface blocks. TInterfaceBlock(const TSymbolUniqueId & id,const ImmutableString & name,TExtension extension,const TFieldList * fields)239*8975f5c5SAndroid Build Coastguard Worker TInterfaceBlock(const TSymbolUniqueId &id, 240*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 241*8975f5c5SAndroid Build Coastguard Worker TExtension extension, 242*8975f5c5SAndroid Build Coastguard Worker const TFieldList *fields) 243*8975f5c5SAndroid Build Coastguard Worker : TSymbol(id, 244*8975f5c5SAndroid Build Coastguard Worker name, 245*8975f5c5SAndroid Build Coastguard Worker SymbolType::BuiltIn, 246*8975f5c5SAndroid Build Coastguard Worker std::array<TExtension, 1u>{{extension}}, 247*8975f5c5SAndroid Build Coastguard Worker SymbolClass::InterfaceBlock), 248*8975f5c5SAndroid Build Coastguard Worker TFieldListCollection(fields), 249*8975f5c5SAndroid Build Coastguard Worker mBlockStorage(EbsUnspecified), 250*8975f5c5SAndroid Build Coastguard Worker mBinding(0) 251*8975f5c5SAndroid Build Coastguard Worker {} 252*8975f5c5SAndroid Build Coastguard Worker 253*8975f5c5SAndroid Build Coastguard Worker template <size_t ExtensionCount> TInterfaceBlock(const TSymbolUniqueId & id,const ImmutableString & name,const std::array<TExtension,ExtensionCount> & extensions,const TFieldList * fields)254*8975f5c5SAndroid Build Coastguard Worker TInterfaceBlock(const TSymbolUniqueId &id, 255*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 256*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, ExtensionCount> &extensions, 257*8975f5c5SAndroid Build Coastguard Worker const TFieldList *fields) 258*8975f5c5SAndroid Build Coastguard Worker : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::InterfaceBlock), 259*8975f5c5SAndroid Build Coastguard Worker TFieldListCollection(fields), 260*8975f5c5SAndroid Build Coastguard Worker mBlockStorage(EbsUnspecified), 261*8975f5c5SAndroid Build Coastguard Worker mBinding(0) 262*8975f5c5SAndroid Build Coastguard Worker {} 263*8975f5c5SAndroid Build Coastguard Worker 264*8975f5c5SAndroid Build Coastguard Worker TLayoutBlockStorage mBlockStorage; 265*8975f5c5SAndroid Build Coastguard Worker int mBinding; 266*8975f5c5SAndroid Build Coastguard Worker 267*8975f5c5SAndroid Build Coastguard Worker // Note that we only record matrix packing on a per-field granularity. 268*8975f5c5SAndroid Build Coastguard Worker }; 269*8975f5c5SAndroid Build Coastguard Worker 270*8975f5c5SAndroid Build Coastguard Worker // Parameter class used for parsing user-defined function parameters. 271*8975f5c5SAndroid Build Coastguard Worker struct TParameter 272*8975f5c5SAndroid Build Coastguard Worker { 273*8975f5c5SAndroid Build Coastguard Worker // Destructively converts to TVariable. 274*8975f5c5SAndroid Build Coastguard Worker // This method resets name and type to nullptrs to make sure 275*8975f5c5SAndroid Build Coastguard Worker // their content cannot be modified after the call. createVariableTParameter276*8975f5c5SAndroid Build Coastguard Worker const TVariable *createVariable(TSymbolTable *symbolTable) 277*8975f5c5SAndroid Build Coastguard Worker { 278*8975f5c5SAndroid Build Coastguard Worker const ImmutableString constName(name); 279*8975f5c5SAndroid Build Coastguard Worker const TType *constType = new TType(type); 280*8975f5c5SAndroid Build Coastguard Worker name = nullptr; 281*8975f5c5SAndroid Build Coastguard Worker return new TVariable(symbolTable, constName, constType, 282*8975f5c5SAndroid Build Coastguard Worker constName.empty() ? SymbolType::Empty : SymbolType::UserDefined); 283*8975f5c5SAndroid Build Coastguard Worker } 284*8975f5c5SAndroid Build Coastguard Worker 285*8975f5c5SAndroid Build Coastguard Worker const char *name; // either pool allocated or static. 286*8975f5c5SAndroid Build Coastguard Worker TPublicType type; 287*8975f5c5SAndroid Build Coastguard Worker }; 288*8975f5c5SAndroid Build Coastguard Worker 289*8975f5c5SAndroid Build Coastguard Worker // The function sub-class of a symbol. 290*8975f5c5SAndroid Build Coastguard Worker class TFunction : public TSymbol 291*8975f5c5SAndroid Build Coastguard Worker { 292*8975f5c5SAndroid Build Coastguard Worker public: 293*8975f5c5SAndroid Build Coastguard Worker // User-defined function 294*8975f5c5SAndroid Build Coastguard Worker TFunction(TSymbolTable *symbolTable, 295*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 296*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType, 297*8975f5c5SAndroid Build Coastguard Worker const TType *retType, 298*8975f5c5SAndroid Build Coastguard Worker bool knownToNotHaveSideEffects); 299*8975f5c5SAndroid Build Coastguard Worker 300*8975f5c5SAndroid Build Coastguard Worker void addParameter(const TVariable *p); 301*8975f5c5SAndroid Build Coastguard Worker void shareParameters(const TFunction ¶metersSource); 302*8975f5c5SAndroid Build Coastguard Worker getFunctionMangledName()303*8975f5c5SAndroid Build Coastguard Worker ImmutableString getFunctionMangledName() const 304*8975f5c5SAndroid Build Coastguard Worker { 305*8975f5c5SAndroid Build Coastguard Worker ASSERT(symbolType() != SymbolType::BuiltIn); 306*8975f5c5SAndroid Build Coastguard Worker if (mMangledName.empty()) 307*8975f5c5SAndroid Build Coastguard Worker { 308*8975f5c5SAndroid Build Coastguard Worker mMangledName = buildMangledName(); 309*8975f5c5SAndroid Build Coastguard Worker } 310*8975f5c5SAndroid Build Coastguard Worker return mMangledName; 311*8975f5c5SAndroid Build Coastguard Worker } 312*8975f5c5SAndroid Build Coastguard Worker getReturnType()313*8975f5c5SAndroid Build Coastguard Worker const TType &getReturnType() const { return *returnType; } 314*8975f5c5SAndroid Build Coastguard Worker getBuiltInOp()315*8975f5c5SAndroid Build Coastguard Worker TOperator getBuiltInOp() const { return mOp; } 316*8975f5c5SAndroid Build Coastguard Worker setDefined()317*8975f5c5SAndroid Build Coastguard Worker void setDefined() { defined = true; } isDefined()318*8975f5c5SAndroid Build Coastguard Worker bool isDefined() const { return defined; } setHasPrototypeDeclaration()319*8975f5c5SAndroid Build Coastguard Worker void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; } hasPrototypeDeclaration()320*8975f5c5SAndroid Build Coastguard Worker bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; } setHasVoidParameter()321*8975f5c5SAndroid Build Coastguard Worker void setHasVoidParameter() { mHasVoidParameter = true; } hasVoidParameter()322*8975f5c5SAndroid Build Coastguard Worker bool hasVoidParameter() const { return mHasVoidParameter; } 323*8975f5c5SAndroid Build Coastguard Worker getParamCount()324*8975f5c5SAndroid Build Coastguard Worker size_t getParamCount() const { return mParamCount; } getParam(size_t i)325*8975f5c5SAndroid Build Coastguard Worker const TVariable *getParam(size_t i) const { return mParameters[i]; } 326*8975f5c5SAndroid Build Coastguard Worker isKnownToNotHaveSideEffects()327*8975f5c5SAndroid Build Coastguard Worker bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; } 328*8975f5c5SAndroid Build Coastguard Worker 329*8975f5c5SAndroid Build Coastguard Worker bool isMain() const; 330*8975f5c5SAndroid Build Coastguard Worker bool isImageFunction() const; 331*8975f5c5SAndroid Build Coastguard Worker bool isAtomicCounterFunction() const; 332*8975f5c5SAndroid Build Coastguard Worker 333*8975f5c5SAndroid Build Coastguard Worker // Note: Only to be used for static built-in functions! TFunction(const TSymbolUniqueId & id,const ImmutableString & name,TExtension extension,const TVariable * const * parameters,size_t paramCount,const TType * retType,TOperator op,bool knownToNotHaveSideEffects)334*8975f5c5SAndroid Build Coastguard Worker constexpr TFunction(const TSymbolUniqueId &id, 335*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 336*8975f5c5SAndroid Build Coastguard Worker TExtension extension, 337*8975f5c5SAndroid Build Coastguard Worker const TVariable *const *parameters, 338*8975f5c5SAndroid Build Coastguard Worker size_t paramCount, 339*8975f5c5SAndroid Build Coastguard Worker const TType *retType, 340*8975f5c5SAndroid Build Coastguard Worker TOperator op, 341*8975f5c5SAndroid Build Coastguard Worker bool knownToNotHaveSideEffects) 342*8975f5c5SAndroid Build Coastguard Worker : TSymbol(id, 343*8975f5c5SAndroid Build Coastguard Worker name, 344*8975f5c5SAndroid Build Coastguard Worker SymbolType::BuiltIn, 345*8975f5c5SAndroid Build Coastguard Worker std::array<TExtension, 1u>{{extension}}, 346*8975f5c5SAndroid Build Coastguard Worker SymbolClass::Function), 347*8975f5c5SAndroid Build Coastguard Worker mParametersVector(nullptr), 348*8975f5c5SAndroid Build Coastguard Worker mParameters(parameters), 349*8975f5c5SAndroid Build Coastguard Worker returnType(retType), 350*8975f5c5SAndroid Build Coastguard Worker mMangledName(nullptr), 351*8975f5c5SAndroid Build Coastguard Worker mParamCount(paramCount), 352*8975f5c5SAndroid Build Coastguard Worker mOp(op), 353*8975f5c5SAndroid Build Coastguard Worker defined(false), 354*8975f5c5SAndroid Build Coastguard Worker mHasPrototypeDeclaration(false), 355*8975f5c5SAndroid Build Coastguard Worker mKnownToNotHaveSideEffects(knownToNotHaveSideEffects), 356*8975f5c5SAndroid Build Coastguard Worker mHasVoidParameter(false) 357*8975f5c5SAndroid Build Coastguard Worker {} 358*8975f5c5SAndroid Build Coastguard Worker 359*8975f5c5SAndroid Build Coastguard Worker template <size_t ExtensionCount> TFunction(const TSymbolUniqueId & id,const ImmutableString & name,const std::array<TExtension,ExtensionCount> & extensions,const TVariable * const * parameters,size_t paramCount,const TType * retType,TOperator op,bool knownToNotHaveSideEffects)360*8975f5c5SAndroid Build Coastguard Worker constexpr TFunction(const TSymbolUniqueId &id, 361*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name, 362*8975f5c5SAndroid Build Coastguard Worker const std::array<TExtension, ExtensionCount> &extensions, 363*8975f5c5SAndroid Build Coastguard Worker const TVariable *const *parameters, 364*8975f5c5SAndroid Build Coastguard Worker size_t paramCount, 365*8975f5c5SAndroid Build Coastguard Worker const TType *retType, 366*8975f5c5SAndroid Build Coastguard Worker TOperator op, 367*8975f5c5SAndroid Build Coastguard Worker bool knownToNotHaveSideEffects) 368*8975f5c5SAndroid Build Coastguard Worker : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Function), 369*8975f5c5SAndroid Build Coastguard Worker mParametersVector(nullptr), 370*8975f5c5SAndroid Build Coastguard Worker mParameters(parameters), 371*8975f5c5SAndroid Build Coastguard Worker returnType(retType), 372*8975f5c5SAndroid Build Coastguard Worker mMangledName(nullptr), 373*8975f5c5SAndroid Build Coastguard Worker mParamCount(paramCount), 374*8975f5c5SAndroid Build Coastguard Worker mOp(op), 375*8975f5c5SAndroid Build Coastguard Worker defined(false), 376*8975f5c5SAndroid Build Coastguard Worker mHasPrototypeDeclaration(false), 377*8975f5c5SAndroid Build Coastguard Worker mKnownToNotHaveSideEffects(knownToNotHaveSideEffects), 378*8975f5c5SAndroid Build Coastguard Worker mHasVoidParameter(false) 379*8975f5c5SAndroid Build Coastguard Worker {} 380*8975f5c5SAndroid Build Coastguard Worker 381*8975f5c5SAndroid Build Coastguard Worker private: 382*8975f5c5SAndroid Build Coastguard Worker ImmutableString buildMangledName() const; 383*8975f5c5SAndroid Build Coastguard Worker 384*8975f5c5SAndroid Build Coastguard Worker typedef TVector<const TVariable *> TParamVector; 385*8975f5c5SAndroid Build Coastguard Worker TParamVector *mParametersVector; 386*8975f5c5SAndroid Build Coastguard Worker const TVariable *const *mParameters; 387*8975f5c5SAndroid Build Coastguard Worker const TType *const returnType; 388*8975f5c5SAndroid Build Coastguard Worker mutable ImmutableString mMangledName; 389*8975f5c5SAndroid Build Coastguard Worker size_t mParamCount : 32; 390*8975f5c5SAndroid Build Coastguard Worker const TOperator mOp; // Only set for built-ins 391*8975f5c5SAndroid Build Coastguard Worker bool defined : 1; 392*8975f5c5SAndroid Build Coastguard Worker bool mHasPrototypeDeclaration : 1; 393*8975f5c5SAndroid Build Coastguard Worker bool mKnownToNotHaveSideEffects : 1; 394*8975f5c5SAndroid Build Coastguard Worker // Whether the parameter list of the function starts with void. This is used to generate an 395*8975f5c5SAndroid Build Coastguard Worker // error if any other parameter follows. 396*8975f5c5SAndroid Build Coastguard Worker bool mHasVoidParameter : 1; 397*8975f5c5SAndroid Build Coastguard Worker }; 398*8975f5c5SAndroid Build Coastguard Worker 399*8975f5c5SAndroid Build Coastguard Worker } // namespace sh 400*8975f5c5SAndroid Build Coastguard Worker 401*8975f5c5SAndroid Build Coastguard Worker #endif // COMPILER_TRANSLATOR_SYMBOL_H_ 402