tor-browser

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

ReplaceVariable.cpp (4676B)


      1 //
      2 // Copyright 2018 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 // ReplaceVariable.cpp: Replace all references to a specific variable in the AST with references to
      7 // another variable.
      8 
      9 #include "compiler/translator/tree_util/ReplaceVariable.h"
     10 
     11 #include "compiler/translator/IntermNode.h"
     12 #include "compiler/translator/Symbol.h"
     13 #include "compiler/translator/tree_util/IntermTraverse.h"
     14 
     15 namespace sh
     16 {
     17 
     18 namespace
     19 {
     20 
     21 class ReplaceVariableTraverser : public TIntermTraverser
     22 {
     23  public:
     24    ReplaceVariableTraverser(const TVariable *toBeReplaced, const TIntermTyped *replacement)
     25        : TIntermTraverser(true, false, false),
     26          mToBeReplaced(toBeReplaced),
     27          mReplacement(replacement)
     28    {}
     29 
     30    void visitSymbol(TIntermSymbol *node) override
     31    {
     32        if (&node->variable() == mToBeReplaced)
     33        {
     34            queueReplacement(mReplacement->deepCopy(), OriginalNode::IS_DROPPED);
     35        }
     36    }
     37 
     38  private:
     39    const TVariable *const mToBeReplaced;
     40    const TIntermTyped *const mReplacement;
     41 };
     42 
     43 class ReplaceVariablesTraverser : public TIntermTraverser
     44 {
     45  public:
     46    ReplaceVariablesTraverser(const VariableReplacementMap &variableMap)
     47        : TIntermTraverser(true, false, false), mVariableMap(variableMap)
     48    {}
     49 
     50    void visitSymbol(TIntermSymbol *node) override
     51    {
     52        auto iter = mVariableMap.find(&node->variable());
     53        if (iter != mVariableMap.end())
     54        {
     55            queueReplacement(iter->second->deepCopy(), OriginalNode::IS_DROPPED);
     56        }
     57    }
     58 
     59  private:
     60    const VariableReplacementMap &mVariableMap;
     61 };
     62 
     63 class GetDeclaratorReplacementsTraverser : public TIntermTraverser
     64 {
     65  public:
     66    GetDeclaratorReplacementsTraverser(TSymbolTable *symbolTable,
     67                                       VariableReplacementMap *variableMap)
     68        : TIntermTraverser(true, false, false, symbolTable), mVariableMap(variableMap)
     69    {}
     70 
     71    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
     72    {
     73        const TIntermSequence &sequence = *(node->getSequence());
     74 
     75        for (TIntermNode *decl : sequence)
     76        {
     77            TIntermSymbol *asSymbol = decl->getAsSymbolNode();
     78            TIntermBinary *asBinary = decl->getAsBinaryNode();
     79 
     80            if (asBinary != nullptr)
     81            {
     82                ASSERT(asBinary->getOp() == EOpInitialize);
     83                asSymbol = asBinary->getLeft()->getAsSymbolNode();
     84            }
     85 
     86            ASSERT(asSymbol);
     87            const TVariable &variable = asSymbol->variable();
     88 
     89            ASSERT(mVariableMap->find(&variable) == mVariableMap->end());
     90 
     91            const TVariable *replacementVariable = new TVariable(
     92                mSymbolTable, variable.name(), &variable.getType(), variable.symbolType());
     93 
     94            (*mVariableMap)[&variable] = new TIntermSymbol(replacementVariable);
     95        }
     96 
     97        return false;
     98    }
     99 
    100  private:
    101    VariableReplacementMap *mVariableMap;
    102 };
    103 
    104 }  // anonymous namespace
    105 
    106 // Replaces every occurrence of a variable with another variable.
    107 [[nodiscard]] bool ReplaceVariable(TCompiler *compiler,
    108                                   TIntermBlock *root,
    109                                   const TVariable *toBeReplaced,
    110                                   const TVariable *replacement)
    111 {
    112    ReplaceVariableTraverser traverser(toBeReplaced, new TIntermSymbol(replacement));
    113    root->traverse(&traverser);
    114    return traverser.updateTree(compiler, root);
    115 }
    116 
    117 [[nodiscard]] bool ReplaceVariables(TCompiler *compiler,
    118                                    TIntermBlock *root,
    119                                    const VariableReplacementMap &variableMap)
    120 {
    121    ReplaceVariablesTraverser traverser(variableMap);
    122    root->traverse(&traverser);
    123    return traverser.updateTree(compiler, root);
    124 }
    125 
    126 void GetDeclaratorReplacements(TSymbolTable *symbolTable,
    127                               TIntermBlock *root,
    128                               VariableReplacementMap *variableMap)
    129 {
    130    GetDeclaratorReplacementsTraverser traverser(symbolTable, variableMap);
    131    root->traverse(&traverser);
    132 }
    133 
    134 // Replaces every occurrence of a variable with a TIntermNode.
    135 [[nodiscard]] bool ReplaceVariableWithTyped(TCompiler *compiler,
    136                                            TIntermBlock *root,
    137                                            const TVariable *toBeReplaced,
    138                                            const TIntermTyped *replacement)
    139 {
    140    ReplaceVariableTraverser traverser(toBeReplaced, replacement);
    141    root->traverse(&traverser);
    142    return traverser.updateTree(compiler, root);
    143 }
    144 
    145 }  // namespace sh