• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2002 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 COMPILER_TRANSLATOR_SYMBOLTABLE_H_
8 #define COMPILER_TRANSLATOR_SYMBOLTABLE_H_
9 
10 //
11 // Symbol table for parsing.  Has these design characteristics:
12 //
13 // * Same symbol table can be used to compile many shaders, to preserve
14 //   effort of creating and loading with the large numbers of built-in
15 //   symbols.
16 //
17 // * Name mangling will be used to give each function a unique name
18 //   so that symbol table lookups are never ambiguous.  This allows
19 //   a simpler symbol table structure.
20 //
21 // * Pushing and popping of scope, so symbol table will really be a stack
22 //   of symbol tables.  Searched from the top, with new inserts going into
23 //   the top.
24 //
25 // * Constants:  Compile time constant symbols will keep their values
26 //   in the symbol table.  The parser can substitute constants at parse
27 //   time, including doing constant folding and constant propagation.
28 //
29 // * No temporaries:  Temporaries made from operations (+, --, .xy, etc.)
30 //   are tracked in the intermediate representation, not the symbol table.
31 //
32 
33 #include <memory>
34 #include <set>
35 
36 #include "common/angleutils.h"
37 #include "compiler/translator/ExtensionBehavior.h"
38 #include "compiler/translator/ImmutableString.h"
39 #include "compiler/translator/InfoSink.h"
40 #include "compiler/translator/IntermNode.h"
41 #include "compiler/translator/Symbol.h"
42 #include "compiler/translator/SymbolTable_autogen.h"
43 
44 namespace sh
45 {
46 
47 // Define ESymbolLevel as int rather than an enum so that we can do arithmetic on it.
48 typedef int ESymbolLevel;
49 const int COMMON_BUILTINS  = 0;
50 const int ESSL1_BUILTINS   = 1;
51 const int ESSL3_BUILTINS   = 2;
52 const int ESSL3_1_BUILTINS = 3;
53 // GLSL_BUILTINS are desktop GLSL builtins that don't exist in ESSL but are used to implement
54 // features in ANGLE's GLSL backend. They're not visible to the parser.
55 const int GLSL_BUILTINS      = 4;
56 const int LAST_BUILTIN_LEVEL = GLSL_BUILTINS;
57 
58 struct UnmangledBuiltIn
59 {
UnmangledBuiltInUnmangledBuiltIn60     constexpr UnmangledBuiltIn(TExtension extension) : extension(extension) {}
61 
62     TExtension extension;
63 };
64 
65 class TSymbolTable : angle::NonCopyable, TSymbolTableBase
66 {
67   public:
68     TSymbolTable();
69     // To start using the symbol table after construction:
70     // * initializeBuiltIns() needs to be called.
71     // * push() needs to be called to push the global level.
72 
73     ~TSymbolTable();
74 
75     bool isEmpty() const;
76     bool atGlobalLevel() const;
77 
78     void push();
79     void pop();
80 
81     // Declare a non-function symbol at the current scope. Return true in case the declaration was
82     // successful, and false if the declaration failed due to redefinition.
83     bool declare(TSymbol *symbol);
84 
85     // Only used to declare internal variables.
86     bool declareInternal(TSymbol *symbol);
87 
88     // Functions are always declared at global scope.
89     void declareUserDefinedFunction(TFunction *function, bool insertUnmangledName);
90 
91     // These return the TFunction pointer to keep using to refer to this function.
92     const TFunction *markFunctionHasPrototypeDeclaration(const ImmutableString &mangledName,
93                                                          bool *hadPrototypeDeclarationOut) const;
94     const TFunction *setFunctionParameterNamesFromDefinition(const TFunction *function,
95                                                              bool *wasDefinedOut) const;
96 
97     // Return false if the gl_in array size has already been initialized with a mismatching value.
98     bool setGlInArraySize(unsigned int inputArraySize);
99     TVariable *getGlInVariableWithArraySize() const;
100 
101     const TVariable *gl_FragData() const;
102     const TVariable *gl_SecondaryFragDataEXT() const;
103 
104     void markStaticRead(const TVariable &variable);
105     void markStaticWrite(const TVariable &variable);
106 
107     // Note: Should not call this for constant variables.
108     bool isStaticallyUsed(const TVariable &variable) const;
109 
110     // find() is guaranteed not to retain a reference to the ImmutableString, so an ImmutableString
111     // with a reference to a short-lived char * is fine to pass here.
112     const TSymbol *find(const ImmutableString &name, int shaderVersion) const;
113 
114     const TSymbol *findUserDefined(const ImmutableString &name) const;
115 
116     TFunction *findUserDefinedFunction(const ImmutableString &name) const;
117 
118     const TSymbol *findGlobal(const ImmutableString &name) const;
119     const TSymbol *findGlobalWithConversion(const std::vector<ImmutableString> &names) const;
120 
121     const TSymbol *findBuiltIn(const ImmutableString &name, int shaderVersion) const;
122     const TSymbol *findBuiltInWithConversion(const std::vector<ImmutableString> &names,
123                                              int shaderVersion) const;
124 
125     void setDefaultPrecision(TBasicType type, TPrecision prec);
126 
127     // Searches down the precisionStack for a precision qualifier
128     // for the specified TBasicType
129     TPrecision getDefaultPrecision(TBasicType type) const;
130 
131     // This records invariant varyings declared through "invariant varying_name;".
132     void addInvariantVarying(const TVariable &variable);
133 
134     // If this returns false, the varying could still be invariant if it is set as invariant during
135     // the varying variable declaration - this piece of information is stored in the variable's
136     // type, not here.
137     bool isVaryingInvariant(const TVariable &variable) const;
138 
139     void setGlobalInvariant(bool invariant);
140 
nextUniqueId()141     const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); }
142 
143     // Gets the built-in accessible by a shader with the specified version, if any.
144     const UnmangledBuiltIn *getUnmangledBuiltInForShaderVersion(const ImmutableString &name,
145                                                                 int shaderVersion);
146 
147     void initializeBuiltIns(sh::GLenum type,
148                             ShShaderSpec spec,
149                             const ShBuiltInResources &resources);
150     void clearCompilationResults();
151 
152   private:
153     friend class TSymbolUniqueId;
154 
155     struct VariableMetadata
156     {
157         VariableMetadata();
158         bool staticRead;
159         bool staticWrite;
160         bool invariant;
161     };
162 
163     int nextUniqueIdValue();
164 
165     class TSymbolTableLevel;
166 
167     void initSamplerDefaultPrecision(TBasicType samplerType);
168 
169     void initializeBuiltInVariables(sh::GLenum shaderType,
170                                     ShShaderSpec spec,
171                                     const ShBuiltInResources &resources);
172 
173     VariableMetadata *getOrCreateVariableMetadata(const TVariable &variable);
174 
175     std::vector<std::unique_ptr<TSymbolTableLevel>> mTable;
176 
177     // There's one precision stack level for predefined precisions and then one level for each scope
178     // in table.
179     typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
180     std::vector<std::unique_ptr<PrecisionStackLevel>> mPrecisionStack;
181 
182     bool mGlobalInvariant;
183 
184     int mUniqueIdCounter;
185 
186     static const int kLastBuiltInId;
187 
188     sh::GLenum mShaderType;
189     ShBuiltInResources mResources;
190 
191     // Indexed by unique id. Map instead of vector since the variables are fairly sparse.
192     std::map<int, VariableMetadata> mVariableMetadata;
193 
194     // Store gl_in variable with its array size once the array size can be determined. The array
195     // size can also be checked against latter input primitive type declaration.
196     TVariable *mGlInVariableWithArraySize;
197 };
198 
199 }  // namespace sh
200 
201 #endif  // COMPILER_TRANSLATOR_SYMBOLTABLE_H_
202