xref: /aosp_15_r20/external/angle/src/compiler/translator/Symbol.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 &parametersSource);
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