• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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