]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/generate.h
Refactor resolution of declarations for MemberAccess
[libs/gl.git] / source / glsl / generate.h
1 #ifndef MSP_GL_SL_GENERATE_H_
2 #define MSP_GL_SL_GENERATE_H_
3
4 #include <map>
5 #include <set>
6 #include <string>
7 #include <vector>
8 #include "visitor.h"
9
10 namespace Msp {
11 namespace GL {
12 namespace SL {
13
14 /** Combines multiple declarations of the same identifier into one. */
15 class DeclarationCombiner: private TraversingVisitor
16 {
17 private:
18         std::map<std::string, std::vector<FunctionDeclaration *> > functions;
19         std::map<std::string, VariableDeclaration *> variables;
20         std::set<Node *> nodes_to_remove;
21
22 public:
23         void apply(Stage &);
24
25 private:
26         virtual void visit(Block &);
27         virtual void visit(VariableDeclaration &);
28         virtual void visit(FunctionDeclaration &) { }
29 };
30
31 /** Manipulates specialization constants.  If values are specified, turns
32 specialization constants into normal constants.  Without values assigns
33 automatic constant_ids to specialization constants. */
34 class ConstantSpecializer: private TraversingVisitor
35 {
36 private:
37         const std::map<std::string, int> *values;
38
39 public:
40         ConstantSpecializer();
41
42         void apply(Stage &, const std::map<std::string, int> *);
43
44 private:
45         virtual void visit(VariableDeclaration &);
46 };
47
48 /** Forms links between nested blocks in the syntax tree. */
49 class BlockHierarchyResolver: private TraversingVisitor
50 {
51 public:
52         void apply(Stage &s) { s.content.visit(*this); }
53
54 private:
55         virtual void enter(Block &);
56 };
57
58 /** Resolves types of variables and base types of other types. */
59 class TypeResolver: private TraversingVisitor
60 {
61 private:
62         Stage *stage;
63         std::map<TypeDeclaration *, TypeDeclaration *> alias_map;
64         std::map<TypeDeclaration *, TypeDeclaration *> array_types;
65         NodeList<Statement>::iterator type_insert_point;
66
67 public:
68         TypeResolver();
69
70         void apply(Stage &);
71
72 private:
73         TypeDeclaration *resolve_type(const std::string &);
74         virtual void visit(Block &);
75         virtual void visit(BasicTypeDeclaration &);
76         virtual void visit(ImageTypeDeclaration &);
77         virtual void visit(StructDeclaration &);
78         virtual void visit(VariableDeclaration &);
79         virtual void visit(FunctionDeclaration &);
80 };
81
82 /** Resolves variable references.  Variable references which match the name
83 of an interface block are turned into interface block references. */
84 class VariableResolver: private TraversingVisitor
85 {
86 private:
87         Stage *stage;
88         RefPtr<InterfaceBlockReference> r_iface_ref;
89         std::string block_interface;
90         bool r_any_resolved;
91         bool record_target;
92         bool r_self_referencing;
93         VariableDeclaration *r_assignment_target;
94
95 public:
96         VariableResolver();
97
98         bool apply(Stage &);
99
100 private:
101         virtual void enter(Block &);
102         virtual void visit(VariableReference &);
103         virtual void visit(InterfaceBlockReference &);
104         virtual void visit(MemberAccess &);
105         virtual void visit(UnaryExpression &);
106         virtual void visit(BinaryExpression &);
107         virtual void visit(Assignment &);
108         virtual void visit(FunctionCall &);
109         virtual void visit(VariableDeclaration &);
110         virtual void visit(InterfaceBlock &);
111 };
112
113 /** Resolves types and lvalueness of expressions. */
114 class ExpressionResolver: private TraversingVisitor
115 {
116 private:
117         enum Compatibility
118         {
119                 NOT_COMPATIBLE,
120                 LEFT_CONVERTIBLE,
121                 RIGHT_CONVERTIBLE,
122                 SAME_TYPE
123         };
124
125         Stage *stage;
126         std::vector<BasicTypeDeclaration *> basic_types;
127         bool r_any_resolved;
128
129 public:
130         ExpressionResolver();
131
132         bool apply(Stage &);
133
134 private:
135         static bool is_scalar(BasicTypeDeclaration &);
136         static bool is_vector_or_matrix(BasicTypeDeclaration &);
137         static BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &);
138         static bool can_convert(BasicTypeDeclaration &, BasicTypeDeclaration &);
139         static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
140         BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned);
141         BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
142         void convert_to(RefPtr<Expression> &, BasicTypeDeclaration &);
143         bool convert_to_element(RefPtr<Expression> &, BasicTypeDeclaration &);
144         void resolve(Expression &, TypeDeclaration *, bool);
145
146         virtual void visit(Literal &);
147         virtual void visit(ParenthesizedExpression &);
148         virtual void visit(VariableReference &);
149         virtual void visit(InterfaceBlockReference &);
150         virtual void visit(MemberAccess &);
151         virtual void visit(UnaryExpression &);
152         virtual void visit(BinaryExpression &);
153         virtual void visit(Assignment &);
154         virtual void visit(FunctionCall &);
155         virtual void visit(BasicTypeDeclaration &);
156         virtual void visit(VariableDeclaration &);
157 };
158
159 /** Resolves function declarations and calls. */
160 class FunctionResolver: private TraversingVisitor
161 {
162 private:
163         Stage *stage;
164         std::map<std::string, std::vector<FunctionDeclaration *> > declarations;
165
166 public:
167         void apply(Stage &);
168
169 private:
170         virtual void visit(FunctionCall &);
171         virtual void visit(FunctionDeclaration &);
172 };
173
174 /** Materializes implicitly declared interfaces.
175
176 Out variable declarations inside functions are moved to the global scope.
177
178 Passthrough statements are processed, generating out variables to match in
179 variables and copying values.
180
181 Unresolved variables are looked up in the previous stage's out variables. */
182 class InterfaceGenerator: private TraversingVisitor
183 {
184 private:
185         Stage *stage;
186         std::string in_prefix;
187         std::string out_prefix;
188         bool function_scope;
189         InterfaceBlock *iface_block;
190         bool copy_block;
191         Block *iface_target_block;
192         NodeList<Statement>::iterator iface_insert_point;
193         NodeList<Statement>::iterator assignment_insert_point;
194         std::set<Node *> nodes_to_remove;
195
196 public:
197         InterfaceGenerator();
198
199         void apply(Stage &);
200
201 private:
202         static std::string get_out_prefix(Stage::Type);
203         std::string change_prefix(const std::string &, const std::string &) const;
204         virtual void visit(Block &);
205         VariableDeclaration *generate_interface(VariableDeclaration &, const std::string &, const std::string &);
206         InterfaceBlock *generate_interface(InterfaceBlock &);
207         ExpressionStatement &insert_assignment(const std::string &, Expression *);
208         virtual void visit(VariableReference &);
209         virtual void visit(VariableDeclaration &);
210         virtual void visit(InterfaceBlock &);
211         virtual void visit(FunctionDeclaration &);
212         virtual void visit(Passthrough &);
213 };
214
215 } // namespace SL
216 } // namespace GL
217 } // namespace Msp
218
219 #endif