tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Symbol.h (14749B)


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