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_VARIABLEREFERENCE 9 #define SKSL_VARIABLEREFERENCE 10 11 #include "SkSLExpression.h" 12 #include "SkSLFloatLiteral.h" 13 #include "SkSLIRGenerator.h" 14 #include "SkSLIntLiteral.h" 15 16 namespace SkSL { 17 18 /** 19 * A reference to a variable, through which it can be read or written. In the statement: 20 * 21 * x = x + 1; 22 * 23 * there is only one Variable 'x', but two VariableReferences to it. 24 */ 25 struct VariableReference : public Expression { 26 enum RefKind { 27 kRead_RefKind, 28 kWrite_RefKind, 29 kReadWrite_RefKind 30 }; 31 32 VariableReference(Position position, const Variable& variable, RefKind refKind = kRead_RefKind) 33 : INHERITED(position, kVariableReference_Kind, variable.fType) 34 , fVariable(variable) 35 , fRefKind(refKind) { 36 if (refKind != kRead_RefKind) { 37 fVariable.fWriteCount++; 38 } 39 if (refKind != kWrite_RefKind) { 40 fVariable.fReadCount++; 41 } 42 } 43 44 virtual ~VariableReference() override { 45 if (fRefKind != kWrite_RefKind) { 46 fVariable.fReadCount--; 47 } 48 } 49 50 RefKind refKind() { 51 return fRefKind; 52 } 53 54 void setRefKind(RefKind refKind) { 55 if (fRefKind != kRead_RefKind) { 56 fVariable.fWriteCount--; 57 } 58 if (fRefKind != kWrite_RefKind) { 59 fVariable.fReadCount--; 60 } 61 if (refKind != kRead_RefKind) { 62 fVariable.fWriteCount++; 63 } 64 if (refKind != kWrite_RefKind) { 65 fVariable.fReadCount++; 66 } 67 fRefKind = refKind; 68 } 69 70 SkString description() const override { 71 return fVariable.fName; 72 } 73 74 virtual std::unique_ptr<Expression> constantPropagate( 75 const IRGenerator& irGenerator, 76 const DefinitionMap& definitions) override { 77 auto exprIter = definitions.find(&fVariable); 78 if (exprIter != definitions.end() && exprIter->second) { 79 const Expression* expr = exprIter->second->get(); 80 switch (expr->fKind) { 81 case Expression::kIntLiteral_Kind: 82 return std::unique_ptr<Expression>(new IntLiteral( 83 irGenerator.fContext, 84 Position(), 85 ((IntLiteral*) expr)->fValue)); 86 case Expression::kFloatLiteral_Kind: 87 return std::unique_ptr<Expression>(new FloatLiteral( 88 irGenerator.fContext, 89 Position(), 90 ((FloatLiteral*) expr)->fValue)); 91 default: 92 break; 93 } 94 } 95 return nullptr; 96 } 97 98 const Variable& fVariable; 99 100 private: 101 RefKind fRefKind; 102 103 typedef Expression INHERITED; 104 }; 105 106 } // namespace 107 108 #endif 109