| /* |
| * Copyright 2017 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SKSL_SWITCHSTATEMENT |
| #define SKSL_SWITCHSTATEMENT |
| |
| #include "include/private/SkSLDefines.h" |
| #include "include/private/SkSLStatement.h" |
| #include "include/sksl/SkSLPosition.h" |
| #include "src/sksl/ir/SkSLExpression.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| namespace SkSL { |
| |
| class Context; |
| class SwitchCase; |
| class SymbolTable; |
| |
| /** |
| * A 'switch' statement. |
| */ |
| class SwitchStatement final : public Statement { |
| public: |
| inline static constexpr Kind kStatementKind = Kind::kSwitch; |
| |
| SwitchStatement(Position pos, bool isStatic, std::unique_ptr<Expression> value, |
| StatementArray cases, std::shared_ptr<SymbolTable> symbols) |
| : INHERITED(pos, kStatementKind) |
| , fIsStatic(isStatic) |
| , fValue(std::move(value)) |
| , fCases(std::move(cases)) |
| , fSymbols(std::move(symbols)) {} |
| |
| // Create a `switch` statement with an array of case-values and case-statements. |
| // Coerces case values to the proper type and reports an error if cases are duplicated. |
| // Reports errors via the ErrorReporter. |
| static std::unique_ptr<Statement> Convert(const Context& context, |
| Position pos, |
| bool isStatic, |
| std::unique_ptr<Expression> value, |
| ExpressionArray caseValues, |
| StatementArray caseStatements, |
| std::shared_ptr<SymbolTable> symbolTable); |
| |
| // Create a `switch` statement with an array of SwitchCases. The array of SwitchCases must |
| // already contain non-overlapping, correctly-typed case values. Reports errors via ASSERT. |
| static std::unique_ptr<Statement> Make(const Context& context, |
| Position pos, |
| bool isStatic, |
| std::unique_ptr<Expression> value, |
| StatementArray cases, |
| std::shared_ptr<SymbolTable> symbolTable); |
| |
| // Returns a block containing all of the statements that will be run if the given case matches |
| // (which, owing to the statements being owned by unique_ptrs, means the switch itself will be |
| // disassembled by this call and must then be discarded). |
| // Returns null (and leaves the switch unmodified) if no such simple reduction is possible, such |
| // as when break statements appear inside conditionals. |
| static std::unique_ptr<Statement> BlockForCase(StatementArray* cases, |
| SwitchCase* caseToCapture, |
| std::shared_ptr<SymbolTable> symbolTable); |
| |
| std::unique_ptr<Expression>& value() { |
| return fValue; |
| } |
| |
| const std::unique_ptr<Expression>& value() const { |
| return fValue; |
| } |
| |
| StatementArray& cases() { |
| return fCases; |
| } |
| |
| const StatementArray& cases() const { |
| return fCases; |
| } |
| |
| bool isStatic() const { |
| return fIsStatic; |
| } |
| |
| const std::shared_ptr<SymbolTable>& symbols() const { |
| return fSymbols; |
| } |
| |
| std::unique_ptr<Statement> clone() const override; |
| |
| std::string description() const override; |
| |
| private: |
| bool fIsStatic; |
| std::unique_ptr<Expression> fValue; |
| StatementArray fCases; // every Statement inside fCases must be a SwitchCase |
| std::shared_ptr<SymbolTable> fSymbols; |
| |
| using INHERITED = Statement; |
| }; |
| |
| } // namespace SkSL |
| |
| #endif |