xref: /aosp_15_r20/external/skia/src/sksl/analysis/SkSLHasSideEffects.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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)22 bool 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