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 "include/sksl/SkSLPosition.h" 12 #include "src/sksl/SkSLPool.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 kFieldAccess, 75 kFunctionReference, 76 kFunctionCall, 77 kIndex, 78 kLiteral, 79 kMethodReference, 80 kPoison, 81 kPostfix, 82 kPrefix, 83 kSetting, 84 kSwizzle, 85 kTernary, 86 kTypeReference, 87 kVariableReference, 88 89 kFirst = kBinary, 90 kLast = kVariableReference 91 }; 92 93 /** 94 * Represents a node in the intermediate representation (IR) tree. The IR is a fully-resolved 95 * version of the program (all types determined, everything validated), ready for code generation. 96 */ 97 class IRNode : public Poolable { 98 public: ~IRNode()99 virtual ~IRNode() {} 100 101 virtual std::string description() const = 0; 102 103 // No copy construction or assignment 104 IRNode(const IRNode&) = delete; 105 IRNode& operator=(const IRNode&) = delete; 106 107 // position of this element within the program being compiled, for error reporting purposes 108 Position fPosition; 109 110 /** 111 * Use is<T> to check the type of an IRNode. 112 * e.g. replace `s.kind() == Statement::Kind::kReturn` with `s.is<ReturnStatement>()`. 113 */ 114 template <typename T> is()115 bool is() const { 116 return this->fKind == (int)T::kIRNodeKind; 117 } 118 119 /** 120 * Use as<T> to downcast IRNodes. 121 * e.g. replace `(ReturnStatement&) s` with `s.as<ReturnStatement>()`. 122 */ 123 template <typename T> as()124 const T& as() const { 125 SkASSERT(this->is<T>()); 126 return static_cast<const T&>(*this); 127 } 128 129 template <typename T> as()130 T& as() { 131 SkASSERT(this->is<T>()); 132 return static_cast<T&>(*this); 133 } 134 135 protected: IRNode(Position position,int kind)136 IRNode(Position position, int kind) 137 : fPosition(position) 138 , fKind(kind) {} 139 140 int fKind; 141 }; 142 143 } // namespace SkSL 144 145 #endif 146