xref: /aosp_15_r20/external/skia/src/sksl/ir/SkSLForStatement.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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_FORSTATEMENT
9 #define SKSL_FORSTATEMENT
10 
11 #include "src/sksl/SkSLPosition.h"
12 #include "src/sksl/ir/SkSLExpression.h"
13 #include "src/sksl/ir/SkSLIRNode.h"
14 #include "src/sksl/ir/SkSLStatement.h"
15 #include "src/sksl/ir/SkSLSymbolTable.h"
16 
17 #include <memory>
18 #include <string>
19 #include <utility>
20 
21 namespace SkSL {
22 
23 class Context;
24 class Variable;
25 
26 /**
27  * The unrollability information for an ES2-compatible loop.
28  */
29 struct LoopUnrollInfo {
30     const Variable* fIndex;
31     double fStart;
32     double fDelta;
33     int fCount;
34 };
35 
36 /**
37  * A 'for' statement.
38  */
39 class ForStatement final : public Statement {
40 public:
41     inline static constexpr Kind kIRNodeKind = Kind::kFor;
42 
ForStatement(Position pos,ForLoopPositions forLoopPositions,std::unique_ptr<Statement> initializer,std::unique_ptr<Expression> test,std::unique_ptr<Expression> next,std::unique_ptr<Statement> statement,std::unique_ptr<LoopUnrollInfo> unrollInfo,std::unique_ptr<SymbolTable> symbols)43     ForStatement(Position pos,
44                  ForLoopPositions forLoopPositions,
45                  std::unique_ptr<Statement> initializer,
46                  std::unique_ptr<Expression> test,
47                  std::unique_ptr<Expression> next,
48                  std::unique_ptr<Statement> statement,
49                  std::unique_ptr<LoopUnrollInfo> unrollInfo,
50                  std::unique_ptr<SymbolTable> symbols)
51             : INHERITED(pos, kIRNodeKind)
52             , fForLoopPositions(forLoopPositions)
53             , fSymbolTable(std::move(symbols))
54             , fInitializer(std::move(initializer))
55             , fTest(std::move(test))
56             , fNext(std::move(next))
57             , fStatement(std::move(statement))
58             , fUnrollInfo(std::move(unrollInfo)) {}
59 
60     // Creates an SkSL for loop; handles type-coercion and uses the ErrorReporter to report errors.
61     static std::unique_ptr<Statement> Convert(const Context& context,
62                                               Position pos,
63                                               ForLoopPositions forLoopPositions,
64                                               std::unique_ptr<Statement> initializer,
65                                               std::unique_ptr<Expression> test,
66                                               std::unique_ptr<Expression> next,
67                                               std::unique_ptr<Statement> statement,
68                                               std::unique_ptr<SymbolTable> symbolTable);
69 
70     // Creates an SkSL while loop; handles type-coercion and uses the ErrorReporter for errors.
71     static std::unique_ptr<Statement> ConvertWhile(const Context& context,
72                                                    Position pos,
73                                                    std::unique_ptr<Expression> test,
74                                                    std::unique_ptr<Statement> statement);
75 
76     // Creates an SkSL for/while loop. Assumes properly coerced types and reports errors via assert.
77     static std::unique_ptr<Statement> Make(const Context& context,
78                                            Position pos,
79                                            ForLoopPositions forLoopPositions,
80                                            std::unique_ptr<Statement> initializer,
81                                            std::unique_ptr<Expression> test,
82                                            std::unique_ptr<Expression> next,
83                                            std::unique_ptr<Statement> statement,
84                                            std::unique_ptr<LoopUnrollInfo> unrollInfo,
85                                            std::unique_ptr<SymbolTable> symbolTable);
86 
forLoopPositions()87     ForLoopPositions forLoopPositions() const {
88         return fForLoopPositions;
89     }
90 
initializer()91     std::unique_ptr<Statement>& initializer() {
92         return fInitializer;
93     }
94 
initializer()95     const std::unique_ptr<Statement>& initializer() const {
96         return fInitializer;
97     }
98 
test()99     std::unique_ptr<Expression>& test() {
100         return fTest;
101     }
102 
test()103     const std::unique_ptr<Expression>& test() const {
104         return fTest;
105     }
106 
next()107     std::unique_ptr<Expression>& next() {
108         return fNext;
109     }
110 
next()111     const std::unique_ptr<Expression>& next() const {
112         return fNext;
113     }
114 
statement()115     std::unique_ptr<Statement>& statement() {
116         return fStatement;
117     }
118 
statement()119     const std::unique_ptr<Statement>& statement() const {
120         return fStatement;
121     }
122 
symbols()123     SymbolTable* symbols() const {
124         return fSymbolTable.get();
125     }
126 
127     /** Loop-unroll information is only supported in strict-ES2 code. Null is returned in ES3+. */
unrollInfo()128     const LoopUnrollInfo* unrollInfo() const {
129         return fUnrollInfo.get();
130     }
131 
132     std::string description() const override;
133 
134 private:
135     ForLoopPositions fForLoopPositions;
136     std::unique_ptr<SymbolTable> fSymbolTable;
137     std::unique_ptr<Statement> fInitializer;
138     std::unique_ptr<Expression> fTest;
139     std::unique_ptr<Expression> fNext;
140     std::unique_ptr<Statement> fStatement;
141     std::unique_ptr<LoopUnrollInfo> fUnrollInfo;
142 
143     using INHERITED = Statement;
144 };
145 
146 }  // namespace SkSL
147 
148 #endif
149