Home | History | Annotate | Download | only in ir
      1 /*
      2  * Copyright 2016 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SKSL_EXPRESSION
      9 #define SKSL_EXPRESSION
     10 
     11 #include "SkSLType.h"
     12 #include "SkSLVariable.h"
     13 
     14 #include <unordered_map>
     15 
     16 namespace SkSL {
     17 
     18 struct Expression;
     19 class IRGenerator;
     20 
     21 typedef std::unordered_map<const Variable*, std::unique_ptr<Expression>*> DefinitionMap;
     22 
     23 /**
     24  * Abstract supertype of all expressions.
     25  */
     26 struct Expression : public IRNode {
     27     enum Kind {
     28         kAppendStage_Kind,
     29         kBinary_Kind,
     30         kBoolLiteral_Kind,
     31         kConstructor_Kind,
     32         kIntLiteral_Kind,
     33         kFieldAccess_Kind,
     34         kFloatLiteral_Kind,
     35         kFunctionReference_Kind,
     36         kFunctionCall_Kind,
     37         kIndex_Kind,
     38         kNullLiteral_Kind,
     39         kPrefix_Kind,
     40         kPostfix_Kind,
     41         kSetting_Kind,
     42         kSwizzle_Kind,
     43         kVariableReference_Kind,
     44         kTernary_Kind,
     45         kTypeReference_Kind,
     46         kDefined_Kind
     47     };
     48 
     49     Expression(int offset, Kind kind, const Type& type)
     50     : INHERITED(offset)
     51     , fKind(kind)
     52     , fType(std::move(type)) {}
     53 
     54     /**
     55      * Returns true if this expression is constant. compareConstant must be implemented for all
     56      * constants!
     57      */
     58     virtual bool isConstant() const {
     59         return false;
     60     }
     61 
     62     /**
     63      * Compares this constant expression against another constant expression of the same type. It is
     64      * an error to call this on non-constant expressions, or if the types of the expressions do not
     65      * match.
     66      */
     67     virtual bool compareConstant(const Context& context, const Expression& other) const {
     68         ABORT("cannot call compareConstant on this type");
     69     }
     70 
     71     /**
     72      * For an expression which evaluates to a constant int, returns the value. Otherwise calls
     73      * ABORT.
     74      */
     75     virtual int64_t getConstantInt() const {
     76         ABORT("not a constant int");
     77     }
     78 
     79     /**
     80      * For an expression which evaluates to a constant float, returns the value. Otherwise calls
     81      * ABORT.
     82      */
     83     virtual double getConstantFloat() const {
     84         ABORT("not a constant float");
     85     }
     86 
     87     /**
     88      * Returns true if evaluating the expression potentially has side effects. Expressions may never
     89      * return false if they actually have side effects, but it is legal (though suboptimal) to
     90      * return true if there are not actually any side effects.
     91      */
     92     virtual bool hasSideEffects() const = 0;
     93 
     94     /**
     95      * Given a map of known constant variable values, substitute them in for references to those
     96      * variables occurring in this expression and its subexpressions.  Similar simplifications, such
     97      * as folding a constant binary expression down to a single value, may also be performed.
     98      * Returns a new expression which replaces this expression, or null if no replacements were
     99      * made. If a new expression is returned, this expression is no longer valid.
    100      */
    101     virtual std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
    102                                                           const DefinitionMap& definitions) {
    103         return nullptr;
    104     }
    105 
    106     virtual int coercionCost(const Type& target) const {
    107         return fType.coercionCost(target);
    108     }
    109 
    110     virtual std::unique_ptr<Expression> clone() const = 0;
    111 
    112     const Kind fKind;
    113     const Type& fType;
    114 
    115     typedef IRNode INHERITED;
    116 };
    117 
    118 } // namespace
    119 
    120 #endif
    121