tor-browser

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

Symbol.cpp (9068B)


      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.cpp: Symbols representing variables, functions, structures and interface blocks.
      7 //
      8 
      9 #if defined(_MSC_VER)
     10 #    pragma warning(disable : 4718)
     11 #endif
     12 
     13 #include "compiler/translator/Symbol.h"
     14 
     15 #include "compiler/translator/ImmutableStringBuilder.h"
     16 #include "compiler/translator/SymbolTable.h"
     17 
     18 namespace sh
     19 {
     20 
     21 namespace
     22 {
     23 
     24 constexpr const ImmutableString kMainName("main");
     25 constexpr const ImmutableString kImageLoadName("imageLoad");
     26 constexpr const ImmutableString kImageStoreName("imageStore");
     27 constexpr const ImmutableString kImageSizeName("imageSize");
     28 constexpr const ImmutableString kImageAtomicExchangeName("imageAtomicExchange");
     29 constexpr const ImmutableString kAtomicCounterName("atomicCounter");
     30 
     31 static const char kFunctionMangledNameSeparator = '(';
     32 
     33 }  // anonymous namespace
     34 
     35 TSymbol::TSymbol(TSymbolTable *symbolTable,
     36                 const ImmutableString &name,
     37                 SymbolType symbolType,
     38                 SymbolClass symbolClass,
     39                 TExtension extension)
     40    : mName(name),
     41      mUniqueId(symbolTable->nextUniqueId()),
     42      mExtensions(
     43          std::array<TExtension, 3u>{{extension, TExtension::UNDEFINED, TExtension::UNDEFINED}}),
     44      mSymbolType(symbolType),
     45      mSymbolClass(symbolClass)
     46 {
     47    ASSERT(mSymbolType == SymbolType::BuiltIn || extension == TExtension::UNDEFINED);
     48    ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
     49           mSymbolType == SymbolType::Empty);
     50 }
     51 
     52 TSymbol::TSymbol(TSymbolTable *symbolTable,
     53                 const ImmutableString &name,
     54                 SymbolType symbolType,
     55                 SymbolClass symbolClass,
     56                 const std::array<TExtension, 3u> &extensions)
     57    : mName(name),
     58      mUniqueId(symbolTable->nextUniqueId()),
     59      mExtensions(extensions),
     60      mSymbolType(symbolType),
     61      mSymbolClass(symbolClass)
     62 {
     63    ASSERT(mSymbolType == SymbolType::BuiltIn || extensions[0] == TExtension::UNDEFINED);
     64    ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
     65           mSymbolType == SymbolType::Empty);
     66 }
     67 
     68 ImmutableString TSymbol::name() const
     69 {
     70    if (!mName.empty())
     71    {
     72        return mName;
     73    }
     74    // This can be called for nameless function parameters in HLSL.
     75    ASSERT(mSymbolType == SymbolType::AngleInternal ||
     76           (mSymbolType == SymbolType::Empty && isVariable()));
     77    int uniqueId = mUniqueId.get();
     78    ImmutableStringBuilder symbolNameOut(sizeof(uniqueId) * 2u + 1u);
     79    symbolNameOut << 's';
     80    symbolNameOut.appendHex(mUniqueId.get());
     81    return symbolNameOut;
     82 }
     83 
     84 ImmutableString TSymbol::getMangledName() const
     85 {
     86    if (mSymbolClass == SymbolClass::Function)
     87    {
     88        // We do this instead of using proper virtual functions so that we can better support
     89        // constexpr symbols.
     90        return static_cast<const TFunction *>(this)->getFunctionMangledName();
     91    }
     92    ASSERT(mSymbolType != SymbolType::Empty);
     93    return name();
     94 }
     95 
     96 TVariable::TVariable(TSymbolTable *symbolTable,
     97                     const ImmutableString &name,
     98                     const TType *type,
     99                     SymbolType symbolType,
    100                     TExtension extension)
    101    : TSymbol(symbolTable, name, symbolType, SymbolClass::Variable, extension),
    102      mType(type),
    103      unionArray(nullptr)
    104 {
    105    ASSERT(mType);
    106    ASSERT(name.empty() || symbolType != SymbolType::Empty);
    107 }
    108 
    109 TVariable::TVariable(TSymbolTable *symbolTable,
    110                     const ImmutableString &name,
    111                     const TType *type,
    112                     SymbolType symbolType,
    113                     const std::array<TExtension, 3u> &extensions)
    114    : TSymbol(symbolTable, name, symbolType, SymbolClass::Variable, extensions),
    115      mType(type),
    116      unionArray(nullptr)
    117 {
    118    ASSERT(mType);
    119    ASSERT(name.empty() || symbolType != SymbolType::Empty);
    120 }
    121 
    122 TStructure::TStructure(TSymbolTable *symbolTable,
    123                       const ImmutableString &name,
    124                       const TFieldList *fields,
    125                       SymbolType symbolType)
    126    : TSymbol(symbolTable, name, symbolType, SymbolClass::Struct), TFieldListCollection(fields)
    127 {}
    128 
    129 void TStructure::createSamplerSymbols(const char *namePrefix,
    130                                      const TString &apiNamePrefix,
    131                                      TVector<const TVariable *> *outputSymbols,
    132                                      TMap<const TVariable *, TString> *outputSymbolsToAPINames,
    133                                      TSymbolTable *symbolTable) const
    134 {
    135    ASSERT(containsSamplers());
    136    for (const auto *field : *mFields)
    137    {
    138        const TType *fieldType = field->type();
    139        if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
    140        {
    141            std::stringstream fieldName = sh::InitializeStream<std::stringstream>();
    142            fieldName << namePrefix << "_" << field->name();
    143            TString fieldApiName = apiNamePrefix + ".";
    144            fieldApiName += field->name().data();
    145            fieldType->createSamplerSymbols(ImmutableString(fieldName.str()), fieldApiName,
    146                                            outputSymbols, outputSymbolsToAPINames, symbolTable);
    147        }
    148    }
    149 }
    150 
    151 void TStructure::setName(const ImmutableString &name)
    152 {
    153    ImmutableString *mutableName = const_cast<ImmutableString *>(&mName);
    154    *mutableName                 = name;
    155 }
    156 
    157 TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
    158                                 const ImmutableString &name,
    159                                 const TFieldList *fields,
    160                                 const TLayoutQualifier &layoutQualifier,
    161                                 SymbolType symbolType,
    162                                 TExtension extension)
    163    : TSymbol(symbolTable, name, symbolType, SymbolClass::InterfaceBlock, extension),
    164      TFieldListCollection(fields),
    165      mBlockStorage(layoutQualifier.blockStorage),
    166      mBinding(layoutQualifier.binding)
    167 {
    168    ASSERT(name != nullptr);
    169 }
    170 
    171 TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
    172                                 const ImmutableString &name,
    173                                 const TFieldList *fields,
    174                                 const TLayoutQualifier &layoutQualifier,
    175                                 SymbolType symbolType,
    176                                 const std::array<TExtension, 3u> &extensions)
    177    : TSymbol(symbolTable, name, symbolType, SymbolClass::InterfaceBlock, extensions),
    178      TFieldListCollection(fields),
    179      mBlockStorage(layoutQualifier.blockStorage),
    180      mBinding(layoutQualifier.binding)
    181 {
    182    ASSERT(name != nullptr);
    183 }
    184 
    185 TFunction::TFunction(TSymbolTable *symbolTable,
    186                     const ImmutableString &name,
    187                     SymbolType symbolType,
    188                     const TType *retType,
    189                     bool knownToNotHaveSideEffects)
    190    : TSymbol(symbolTable, name, symbolType, SymbolClass::Function, TExtension::UNDEFINED),
    191      mParametersVector(new TParamVector()),
    192      mParameters(nullptr),
    193      returnType(retType),
    194      mMangledName(""),
    195      mParamCount(0u),
    196      mOp(EOpNull),
    197      defined(false),
    198      mHasPrototypeDeclaration(false),
    199      mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
    200      mHasVoidParameter(false)
    201 {
    202    // Functions with an empty name are not allowed.
    203    ASSERT(symbolType != SymbolType::Empty);
    204    ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
    205 }
    206 
    207 void TFunction::addParameter(const TVariable *p)
    208 {
    209    ASSERT(mParametersVector);
    210    mParametersVector->push_back(p);
    211    mParameters  = mParametersVector->data();
    212    mParamCount  = mParametersVector->size();
    213    mMangledName = kEmptyImmutableString;
    214 }
    215 
    216 void TFunction::shareParameters(const TFunction &parametersSource)
    217 {
    218    mParametersVector = nullptr;
    219    mParameters       = parametersSource.mParameters;
    220    mParamCount       = parametersSource.mParamCount;
    221    ASSERT(parametersSource.name() == name());
    222    mMangledName = parametersSource.mMangledName;
    223 }
    224 
    225 ImmutableString TFunction::buildMangledName() const
    226 {
    227    ImmutableString name = this->name();
    228    std::string newName(name.data(), name.length());
    229    newName += kFunctionMangledNameSeparator;
    230 
    231    for (size_t i = 0u; i < mParamCount; ++i)
    232    {
    233        newName += mParameters[i]->getType().getMangledName();
    234    }
    235    return ImmutableString(newName);
    236 }
    237 
    238 bool TFunction::isMain() const
    239 {
    240    return symbolType() == SymbolType::UserDefined && name() == kMainName;
    241 }
    242 
    243 bool TFunction::isImageFunction() const
    244 {
    245    return symbolType() == SymbolType::BuiltIn &&
    246           (name() == kImageSizeName || name() == kImageLoadName || name() == kImageStoreName ||
    247            name() == kImageAtomicExchangeName);
    248 }
    249 
    250 bool TFunction::isAtomicCounterFunction() const
    251 {
    252    return SymbolType() == SymbolType::BuiltIn && name().beginsWith(kAtomicCounterName);
    253 }
    254 }  // namespace sh