Edit

kc3-lang/angle/src/compiler/translator/SymbolTable.h

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2019-10-24 12:55:09
    Hash : 68945f1c
    Message : Enable "-Wredundant-parens". This one is also required by Skia. It's purely for consistency and code readability. Bug: angleproject:4046 Change-Id: I9ed418a0bf6c7661f0970fef6da7088ca6ae6204 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1877478 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/compiler/translator/SymbolTable.h
  • //
    // Copyright 2002 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    #ifndef COMPILER_TRANSLATOR_SYMBOLTABLE_H_
    #define COMPILER_TRANSLATOR_SYMBOLTABLE_H_
    
    //
    // Symbol table for parsing.  Has these design characteristics:
    //
    // * Same symbol table can be used to compile many shaders, to preserve
    //   effort of creating and loading with the large numbers of built-in
    //   symbols.
    //
    // * Name mangling will be used to give each function a unique name
    //   so that symbol table lookups are never ambiguous.  This allows
    //   a simpler symbol table structure.
    //
    // * Pushing and popping of scope, so symbol table will really be a stack
    //   of symbol tables.  Searched from the top, with new inserts going into
    //   the top.
    //
    // * Constants:  Compile time constant symbols will keep their values
    //   in the symbol table.  The parser can substitute constants at parse
    //   time, including doing constant folding and constant propagation.
    //
    // * No temporaries:  Temporaries made from operations (+, --, .xy, etc.)
    //   are tracked in the intermediate representation, not the symbol table.
    //
    
    #include <limits>
    #include <memory>
    #include <set>
    
    #include "common/angleutils.h"
    #include "compiler/translator/ExtensionBehavior.h"
    #include "compiler/translator/ImmutableString.h"
    #include "compiler/translator/InfoSink.h"
    #include "compiler/translator/IntermNode.h"
    #include "compiler/translator/Symbol.h"
    #include "compiler/translator/SymbolTable_autogen.h"
    
    enum class Shader
    {
        ALL,
        FRAGMENT,      // GL_FRAGMENT_SHADER
        VERTEX,        // GL_VERTEX_SHADER
        COMPUTE,       // GL_COMPUTE_SHADER
        GEOMETRY,      // GL_GEOMETRY_SHADER
        GEOMETRY_EXT,  // GL_GEOMETRY_SHADER_EXT
        NOT_COMPUTE
    };
    
    namespace sh
    {
    
    struct UnmangledBuiltIn
    {
        constexpr UnmangledBuiltIn(TExtension extension) : extension(extension) {}
    
        TExtension extension;
    };
    
    using VarPointer        = TSymbol *(TSymbolTableBase::*);
    using ValidateExtension = int ShBuiltInResources::*;
    
    enum class Spec
    {
        GLSL,
        ESSL
    };
    
    constexpr uint16_t kESSL1Only = 100;
    
    static_assert(offsetof(ShBuiltInResources, OES_standard_derivatives) != 0,
                  "Update SymbolTable extension logic");
    
    #define EXT_INDEX(Ext) (offsetof(ShBuiltInResources, Ext) / sizeof(int))
    
    class SymbolRule
    {
      public:
        const TSymbol *get(ShShaderSpec shaderSpec,
                           int shaderVersion,
                           sh::GLenum shaderType,
                           const ShBuiltInResources &resources,
                           const TSymbolTableBase &symbolTable) const;
    
        template <Spec spec, int version, Shader shaders, size_t extensionIndex, typename T>
        constexpr static SymbolRule Get(T value);
    
      private:
        constexpr SymbolRule(Spec spec,
                             int version,
                             Shader shaders,
                             size_t extensionIndex,
                             const TSymbol *symbol);
    
        constexpr SymbolRule(Spec spec,
                             int version,
                             Shader shaders,
                             size_t extensionIndex,
                             VarPointer resourceVar);
    
        union SymbolOrVar
        {
            constexpr SymbolOrVar(const TSymbol *symbolIn) : symbol(symbolIn) {}
            constexpr SymbolOrVar(VarPointer varIn) : var(varIn) {}
    
            const TSymbol *symbol;
            VarPointer var;
        };
    
        uint16_t mIsDesktop : 1;
        uint16_t mIsVar : 1;
        uint16_t mVersion : 14;
        uint8_t mShaders;
        uint8_t mExtensionIndex;
        SymbolOrVar mSymbolOrVar;
    };
    
    constexpr SymbolRule::SymbolRule(Spec spec,
                                     int version,
                                     Shader shaders,
                                     size_t extensionIndex,
                                     const TSymbol *symbol)
        : mIsDesktop(spec == Spec::GLSL ? 1u : 0u),
          mIsVar(0u),
          mVersion(static_cast<uint16_t>(version)),
          mShaders(static_cast<uint8_t>(shaders)),
          mExtensionIndex(extensionIndex),
          mSymbolOrVar(symbol)
    {}
    
    constexpr SymbolRule::SymbolRule(Spec spec,
                                     int version,
                                     Shader shaders,
                                     size_t extensionIndex,
                                     VarPointer resourceVar)
        : mIsDesktop(spec == Spec::GLSL ? 1u : 0u),
          mIsVar(1u),
          mVersion(static_cast<uint16_t>(version)),
          mShaders(static_cast<uint8_t>(shaders)),
          mExtensionIndex(extensionIndex),
          mSymbolOrVar(resourceVar)
    {}
    
    template <Spec spec, int version, Shader shaders, size_t extensionIndex, typename T>
    // static
    constexpr SymbolRule SymbolRule::Get(T value)
    {
        static_assert(version < 0x4000u, "version OOR");
        static_assert(static_cast<uint8_t>(shaders) < 0xFFu, "shaders OOR");
        static_assert(static_cast<uint8_t>(extensionIndex) < 0xFF, "extensionIndex OOR");
        return SymbolRule(spec, version, shaders, extensionIndex, value);
    }
    
    const TSymbol *FindMangledBuiltIn(ShShaderSpec shaderSpec,
                                      int shaderVersion,
                                      sh::GLenum shaderType,
                                      const ShBuiltInResources &resources,
                                      const TSymbolTableBase &symbolTable,
                                      const SymbolRule *rules,
                                      uint16_t startIndex,
                                      uint16_t endIndex);
    
    class UnmangledEntry
    {
      public:
        constexpr UnmangledEntry(const char *name,
                                 TExtension esslExtension,
                                 TExtension glslExtension,
                                 int esslVersion,
                                 int glslVersion,
                                 Shader shaderType);
    
        bool matches(const ImmutableString &name,
                     ShShaderSpec shaderSpec,
                     int shaderVersion,
                     sh::GLenum shaderType,
                     const TExtensionBehavior &extensions) const;
    
      private:
        const char *mName;
        uint8_t mESSLExtension;
        uint8_t mGLSLExtension;
        uint8_t mShaderType;
        uint16_t mESSLVersion;
        uint16_t mGLSLVersion;
    };
    
    constexpr UnmangledEntry::UnmangledEntry(const char *name,
                                             TExtension esslExtension,
                                             TExtension glslExtension,
                                             int esslVersion,
                                             int glslVersion,
                                             Shader shaderType)
        : mName(name),
          mESSLExtension(static_cast<uint8_t>(esslExtension)),
          mGLSLExtension(static_cast<uint8_t>(glslExtension)),
          mShaderType(static_cast<uint8_t>(shaderType)),
          mESSLVersion(esslVersion < 0 ? std::numeric_limits<uint16_t>::max()
                                       : static_cast<uint16_t>(esslVersion)),
          mGLSLVersion(glslVersion < 0 ? std::numeric_limits<uint16_t>::max()
                                       : static_cast<uint16_t>(glslVersion))
    {}
    
    class TSymbolTable : angle::NonCopyable, TSymbolTableBase
    {
      public:
        TSymbolTable();
        // To start using the symbol table after construction:
        // * initializeBuiltIns() needs to be called.
        // * push() needs to be called to push the global level.
    
        ~TSymbolTable();
    
        bool isEmpty() const;
        bool atGlobalLevel() const;
    
        void push();
        void pop();
    
        // Declare a non-function symbol at the current scope. Return true in case the declaration was
        // successful, and false if the declaration failed due to redefinition.
        bool declare(TSymbol *symbol);
    
        // Only used to declare internal variables.
        bool declareInternal(TSymbol *symbol);
    
        // Functions are always declared at global scope.
        void declareUserDefinedFunction(TFunction *function, bool insertUnmangledName);
    
        // These return the TFunction pointer to keep using to refer to this function.
        const TFunction *markFunctionHasPrototypeDeclaration(const ImmutableString &mangledName,
                                                             bool *hadPrototypeDeclarationOut) const;
        const TFunction *setFunctionParameterNamesFromDefinition(const TFunction *function,
                                                                 bool *wasDefinedOut) const;
    
        // Return false if the gl_in array size has already been initialized with a mismatching value.
        bool setGlInArraySize(unsigned int inputArraySize);
        TVariable *getGlInVariableWithArraySize() const;
    
        const TVariable *gl_FragData() const;
        const TVariable *gl_SecondaryFragDataEXT() const;
    
        void markStaticRead(const TVariable &variable);
        void markStaticWrite(const TVariable &variable);
    
        // Note: Should not call this for constant variables.
        bool isStaticallyUsed(const TVariable &variable) const;
    
        // find() is guaranteed not to retain a reference to the ImmutableString, so an ImmutableString
        // with a reference to a short-lived char * is fine to pass here.
        const TSymbol *find(const ImmutableString &name, int shaderVersion) const;
    
        const TSymbol *findUserDefined(const ImmutableString &name) const;
    
        TFunction *findUserDefinedFunction(const ImmutableString &name) const;
    
        const TSymbol *findGlobal(const ImmutableString &name) const;
        const TSymbol *findGlobalWithConversion(const std::vector<ImmutableString> &names) const;
    
        const TSymbol *findBuiltIn(const ImmutableString &name, int shaderVersion) const;
        const TSymbol *findBuiltInWithConversion(const std::vector<ImmutableString> &names,
                                                 int shaderVersion) const;
    
        void setDefaultPrecision(TBasicType type, TPrecision prec);
    
        // Searches down the precisionStack for a precision qualifier
        // for the specified TBasicType
        TPrecision getDefaultPrecision(TBasicType type) const;
    
        // This records invariant varyings declared through "invariant varying_name;".
        void addInvariantVarying(const TVariable &variable);
    
        // If this returns false, the varying could still be invariant if it is set as invariant during
        // the varying variable declaration - this piece of information is stored in the variable's
        // type, not here.
        bool isVaryingInvariant(const TVariable &variable) const;
    
        void setGlobalInvariant(bool invariant);
    
        const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); }
    
        // Gets the built-in accessible by a shader with the specified version, if any.
        bool isUnmangledBuiltInName(const ImmutableString &name,
                                    int shaderVersion,
                                    const TExtensionBehavior &extensions) const;
    
        void initializeBuiltIns(sh::GLenum type,
                                ShShaderSpec spec,
                                const ShBuiltInResources &resources);
        void clearCompilationResults();
    
      private:
        friend class TSymbolUniqueId;
    
        struct VariableMetadata
        {
            VariableMetadata();
            bool staticRead;
            bool staticWrite;
            bool invariant;
        };
    
        int nextUniqueIdValue();
    
        class TSymbolTableLevel;
    
        void initSamplerDefaultPrecision(TBasicType samplerType);
    
        void initializeBuiltInVariables(sh::GLenum shaderType,
                                        ShShaderSpec spec,
                                        const ShBuiltInResources &resources);
    
        VariableMetadata *getOrCreateVariableMetadata(const TVariable &variable);
    
        std::vector<std::unique_ptr<TSymbolTableLevel>> mTable;
    
        // There's one precision stack level for predefined precisions and then one level for each scope
        // in table.
        typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
        std::vector<std::unique_ptr<PrecisionStackLevel>> mPrecisionStack;
    
        bool mGlobalInvariant;
    
        int mUniqueIdCounter;
    
        static const int kLastBuiltInId;
    
        sh::GLenum mShaderType;
        ShShaderSpec mShaderSpec;
        ShBuiltInResources mResources;
    
        // Indexed by unique id. Map instead of vector since the variables are fairly sparse.
        std::map<int, VariableMetadata> mVariableMetadata;
    
        // Store gl_in variable with its array size once the array size can be determined. The array
        // size can also be checked against latter input primitive type declaration.
        TVariable *mGlInVariableWithArraySize;
    };
    
    }  // namespace sh
    
    #endif  // COMPILER_TRANSLATOR_SYMBOLTABLE_H_