1 /* 2 * Copyright 2017 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_SWITCHSTATEMENT 9 #define SKSL_SWITCHSTATEMENT 10 11 #include "include/private/SkSLStatement.h" 12 #include "src/sksl/ir/SkSLSwitchCase.h" 13 14 #include <memory> 15 #include <vector> 16 17 namespace SkSL { 18 19 class Expression; 20 class SymbolTable; 21 22 /** 23 * A 'switch' statement. 24 */ 25 class SwitchStatement final : public Statement { 26 public: 27 inline static constexpr Kind kStatementKind = Kind::kSwitch; 28 SwitchStatement(int line,bool isStatic,std::unique_ptr<Expression> value,StatementArray cases,std::shared_ptr<SymbolTable> symbols)29 SwitchStatement(int line, bool isStatic, std::unique_ptr<Expression> value, 30 StatementArray cases, std::shared_ptr<SymbolTable> symbols) 31 : INHERITED(line, kStatementKind) 32 , fIsStatic(isStatic) 33 , fValue(std::move(value)) 34 , fCases(std::move(cases)) 35 , fSymbols(std::move(symbols)) {} 36 37 // Create a `switch` statement with an array of case-values and case-statements. 38 // Coerces case values to the proper type and reports an error if cases are duplicated. 39 // Reports errors via the ErrorReporter. 40 static std::unique_ptr<Statement> Convert(const Context& context, 41 int line, 42 bool isStatic, 43 std::unique_ptr<Expression> value, 44 ExpressionArray caseValues, 45 StatementArray caseStatements, 46 std::shared_ptr<SymbolTable> symbolTable); 47 48 // Create a `switch` statement with an array of SwitchCases. The array of SwitchCases must 49 // already contain non-overlapping, correctly-typed case values. Reports errors via ASSERT. 50 static std::unique_ptr<Statement> Make(const Context& context, 51 int line, 52 bool isStatic, 53 std::unique_ptr<Expression> value, 54 StatementArray cases, 55 std::shared_ptr<SymbolTable> symbolTable); 56 57 // Returns a block containing all of the statements that will be run if the given case matches 58 // (which, owing to the statements being owned by unique_ptrs, means the switch itself will be 59 // disassembled by this call and must then be discarded). 60 // Returns null (and leaves the switch unmodified) if no such simple reduction is possible, such 61 // as when break statements appear inside conditionals. 62 static std::unique_ptr<Statement> BlockForCase(StatementArray* cases, 63 SwitchCase* caseToCapture, 64 std::shared_ptr<SymbolTable> symbolTable); 65 value()66 std::unique_ptr<Expression>& value() { 67 return fValue; 68 } 69 value()70 const std::unique_ptr<Expression>& value() const { 71 return fValue; 72 } 73 cases()74 StatementArray& cases() { 75 return fCases; 76 } 77 cases()78 const StatementArray& cases() const { 79 return fCases; 80 } 81 isStatic()82 bool isStatic() const { 83 return fIsStatic; 84 } 85 symbols()86 const std::shared_ptr<SymbolTable>& symbols() const { 87 return fSymbols; 88 } 89 90 std::unique_ptr<Statement> clone() const override; 91 92 String description() const override; 93 94 private: 95 bool fIsStatic; 96 std::unique_ptr<Expression> fValue; 97 StatementArray fCases; // every Statement inside fCases must be a SwitchCase 98 std::shared_ptr<SymbolTable> fSymbols; 99 100 using INHERITED = Statement; 101 }; 102 103 } // namespace SkSL 104 105 #endif 106