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