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