1 /* 2 * Copyright 2022 Google LLC 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 #include "include/core/SkTypes.h" 9 #include "src/sksl/SkSLAnalysis.h" 10 #include "src/sksl/SkSLOperator.h" 11 #include "src/sksl/analysis/SkSLProgramVisitor.h" 12 #include "src/sksl/ir/SkSLBinaryExpression.h" 13 #include "src/sksl/ir/SkSLExpression.h" 14 #include "src/sksl/ir/SkSLFunctionCall.h" 15 #include "src/sksl/ir/SkSLFunctionDeclaration.h" 16 #include "src/sksl/ir/SkSLIRNode.h" 17 #include "src/sksl/ir/SkSLModifierFlags.h" 18 #include "src/sksl/ir/SkSLPrefixExpression.h" 19 20 namespace SkSL { 21 HasSideEffects(const Expression & expr)22bool Analysis::HasSideEffects(const Expression& expr) { 23 class HasSideEffectsVisitor : public ProgramVisitor { 24 public: 25 bool visitExpression(const Expression& expr) override { 26 switch (expr.kind()) { 27 case Expression::Kind::kFunctionCall: { 28 const FunctionCall& call = expr.as<FunctionCall>(); 29 if (!call.function().modifierFlags().isPure()) { 30 return true; 31 } 32 break; 33 } 34 case Expression::Kind::kPrefix: { 35 const PrefixExpression& prefix = expr.as<PrefixExpression>(); 36 if (prefix.getOperator().kind() == Operator::Kind::PLUSPLUS || 37 prefix.getOperator().kind() == Operator::Kind::MINUSMINUS) { 38 return true; 39 } 40 break; 41 } 42 case Expression::Kind::kBinary: { 43 const BinaryExpression& binary = expr.as<BinaryExpression>(); 44 if (binary.getOperator().isAssignment()) { 45 return true; 46 } 47 break; 48 } 49 case Expression::Kind::kPostfix: 50 return true; 51 52 default: 53 break; 54 } 55 return INHERITED::visitExpression(expr); 56 } 57 58 using INHERITED = ProgramVisitor; 59 }; 60 61 HasSideEffectsVisitor visitor; 62 return visitor.visitExpression(expr); 63 } 64 65 } // namespace SkSL 66