tor-browser

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

FoldExpressions.cpp (3330B)


      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 // FoldExpressions.cpp: Fold expressions. This may fold expressions so that the qualifier of the
      7 // folded node differs from the qualifier of the original expression, so it needs to be done after
      8 // parsing and validation of qualifiers is complete. Expressions that are folded:
      9 //  1. Ternary ops with a constant condition.
     10 //  2. Sequence aka comma ops where the left side has no side effects.
     11 //  3. Any expressions containing any of the above.
     12 
     13 #include "compiler/translator/tree_ops/FoldExpressions.h"
     14 
     15 #include "compiler/translator/Diagnostics.h"
     16 #include "compiler/translator/IntermNode.h"
     17 #include "compiler/translator/tree_util/IntermTraverse.h"
     18 
     19 namespace sh
     20 {
     21 
     22 namespace
     23 {
     24 
     25 class FoldExpressionsTraverser : public TIntermTraverser
     26 {
     27  public:
     28    FoldExpressionsTraverser(TDiagnostics *diagnostics)
     29        : TIntermTraverser(true, false, false), mDiagnostics(diagnostics), mDidReplace(false)
     30    {}
     31 
     32    bool didReplace() { return mDidReplace; }
     33 
     34    void nextIteration() { mDidReplace = false; }
     35 
     36  protected:
     37    bool visitTernary(Visit visit, TIntermTernary *node) override
     38    {
     39        TIntermTyped *folded = node->fold(mDiagnostics);
     40        if (folded != node)
     41        {
     42            queueReplacement(folded, OriginalNode::IS_DROPPED);
     43            mDidReplace = true;
     44            return false;
     45        }
     46        return true;
     47    }
     48 
     49    bool visitAggregate(Visit visit, TIntermAggregate *node) override
     50    {
     51        TIntermTyped *folded = node->fold(mDiagnostics);
     52        if (folded != node)
     53        {
     54            queueReplacement(folded, OriginalNode::IS_DROPPED);
     55            mDidReplace = true;
     56            return false;
     57        }
     58        return true;
     59    }
     60 
     61    bool visitBinary(Visit visit, TIntermBinary *node) override
     62    {
     63        TIntermTyped *folded = node->fold(mDiagnostics);
     64        if (folded != node)
     65        {
     66            queueReplacement(folded, OriginalNode::IS_DROPPED);
     67            mDidReplace = true;
     68            return false;
     69        }
     70        return true;
     71    }
     72 
     73    bool visitUnary(Visit visit, TIntermUnary *node) override
     74    {
     75        TIntermTyped *folded = node->fold(mDiagnostics);
     76        if (folded != node)
     77        {
     78            queueReplacement(folded, OriginalNode::IS_DROPPED);
     79            mDidReplace = true;
     80            return false;
     81        }
     82        return true;
     83    }
     84 
     85    bool visitSwizzle(Visit visit, TIntermSwizzle *node) override
     86    {
     87        TIntermTyped *folded = node->fold(mDiagnostics);
     88        if (folded != node)
     89        {
     90            queueReplacement(folded, OriginalNode::IS_DROPPED);
     91            mDidReplace = true;
     92            return false;
     93        }
     94        return true;
     95    }
     96 
     97  private:
     98    TDiagnostics *mDiagnostics;
     99    bool mDidReplace;
    100 };
    101 
    102 }  // anonymous namespace
    103 
    104 bool FoldExpressions(TCompiler *compiler, TIntermBlock *root, TDiagnostics *diagnostics)
    105 {
    106    FoldExpressionsTraverser traverser(diagnostics);
    107    do
    108    {
    109        traverser.nextIteration();
    110        root->traverse(&traverser);
    111        if (!traverser.updateTree(compiler, root))
    112        {
    113            return false;
    114        }
    115    } while (traverser.didReplace());
    116 
    117    return true;
    118 }
    119 
    120 }  // namespace sh