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_IRNODE 9 #define SKSL_IRNODE 10 11 #include "src/sksl/SkSLPool.h" 12 #include "src/sksl/SkSLPosition.h" 13 14 #include <string> 15 16 namespace SkSL { 17 18 // The fKind field of IRNode could contain any of these values. 19 enum class ProgramElementKind { 20 kExtension = 0, 21 kFunction, 22 kFunctionPrototype, 23 kGlobalVar, 24 kInterfaceBlock, 25 kModifiers, 26 kStructDefinition, 27 28 kFirst = kExtension, 29 kLast = kStructDefinition 30 }; 31 32 enum class SymbolKind { 33 kExternal = (int) ProgramElementKind::kLast + 1, 34 kField, 35 kFunctionDeclaration, 36 kType, 37 kVariable, 38 39 kFirst = kExternal, 40 kLast = kVariable 41 }; 42 43 enum class StatementKind { 44 kBlock = (int) SymbolKind::kLast + 1, 45 kBreak, 46 kContinue, 47 kDiscard, 48 kDo, 49 kExpression, 50 kFor, 51 kIf, 52 kNop, 53 kReturn, 54 kSwitch, 55 kSwitchCase, 56 kVarDeclaration, 57 58 kFirst = kBlock, 59 kLast = kVarDeclaration, 60 }; 61 62 enum class ExpressionKind { 63 kBinary = (int) StatementKind::kLast + 1, 64 kChildCall, 65 kConstructorArray, 66 kConstructorArrayCast, 67 kConstructorCompound, 68 kConstructorCompoundCast, 69 kConstructorDiagonalMatrix, 70 kConstructorMatrixResize, 71 kConstructorScalarCast, 72 kConstructorSplat, 73 kConstructorStruct, 74 kEmpty, 75 kFieldAccess, 76 kFunctionReference, 77 kFunctionCall, 78 kIndex, 79 kLiteral, 80 kMethodReference, 81 kPoison, 82 kPostfix, 83 kPrefix, 84 kSetting, 85 kSwizzle, 86 kTernary, 87 kTypeReference, 88 kVariableReference, 89 90 kFirst = kBinary, 91 kLast = kVariableReference 92 }; 93 94 /** 95 * Represents a node in the intermediate representation (IR) tree. The IR is a fully-resolved 96 * version of the program (all types determined, everything validated), ready for code generation. 97 */ 98 class IRNode : public Poolable { 99 public: ~IRNode()100 virtual ~IRNode() {} 101 102 virtual std::string description() const = 0; 103 104 // No copy construction or assignment 105 IRNode(const IRNode&) = delete; 106 IRNode& operator=(const IRNode&) = delete; 107 108 // Position of this element within the program being compiled, for error reporting purposes. 109 Position fPosition; 110 position()111 Position position() const { 112 return fPosition; 113 } 114 setPosition(Position p)115 void setPosition(Position p) { 116 fPosition = p; 117 } 118 119 /** 120 * Use is<T> to check the type of an IRNode. 121 * e.g. replace `s.kind() == Statement::Kind::kReturn` with `s.is<ReturnStatement>()`. 122 */ 123 template <typename T> is()124 bool is() const { 125 return this->fKind == (int)T::kIRNodeKind; 126 } 127 128 /** 129 * Use as<T> to downcast IRNodes. 130 * e.g. replace `(ReturnStatement&) s` with `s.as<ReturnStatement>()`. 131 */ 132 template <typename T> as()133 const T& as() const { 134 SkASSERT(this->is<T>()); 135 return static_cast<const T&>(*this); 136 } 137 138 template <typename T> as()139 T& as() { 140 SkASSERT(this->is<T>()); 141 return static_cast<T&>(*this); 142 } 143 144 protected: IRNode(Position position,int kind)145 IRNode(Position position, int kind) 146 : fPosition(position) 147 , fKind(kind) {} 148 149 int fKind; 150 }; 151 152 } // namespace SkSL 153 154 #endif 155