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