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_STATEMENT 9 #define SKSL_STATEMENT 10 11 #include "include/private/SkSLIRNode.h" 12 #include "include/private/SkSLSymbol.h" 13 14 namespace SkSL { 15 16 /** 17 * Abstract supertype of all statements. 18 */ 19 class Statement : public IRNode { 20 public: 21 enum Kind { 22 kBlock = (int) Symbol::Kind::kLast + 1, 23 kBreak, 24 kContinue, 25 kDiscard, 26 kDo, 27 kExpression, 28 kFor, 29 kIf, 30 kInlineMarker, 31 kNop, 32 kReturn, 33 kSwitch, 34 kSwitchCase, 35 kVarDeclaration, 36 37 kFirst = kBlock, 38 kLast = kVarDeclaration, 39 }; 40 Statement(int line,Kind kind)41 Statement(int line, Kind kind) 42 : INHERITED(line, (int) kind) { 43 SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast); 44 } 45 kind()46 Kind kind() const { 47 return (Kind) fKind; 48 } 49 50 /** 51 * Use is<T> to check the type of a statement. 52 * e.g. replace `s.kind() == Statement::Kind::kReturn` with `s.is<ReturnStatement>()`. 53 */ 54 template <typename T> is()55 bool is() const { 56 return this->fKind == T::kStatementKind; 57 } 58 59 /** 60 * Use as<T> to downcast statements. 61 * e.g. replace `(ReturnStatement&) s` with `s.as<ReturnStatement>()`. 62 */ 63 template <typename T> as()64 const T& as() const { 65 SkASSERT(this->is<T>()); 66 return static_cast<const T&>(*this); 67 } 68 69 template <typename T> as()70 T& as() { 71 SkASSERT(this->is<T>()); 72 return static_cast<T&>(*this); 73 } 74 isEmpty()75 virtual bool isEmpty() const { 76 return false; 77 } 78 79 virtual std::unique_ptr<Statement> clone() const = 0; 80 81 private: 82 using INHERITED = IRNode; 83 }; 84 85 } // namespace SkSL 86 87 #endif 88