]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/generate.h
Transform interface block contents into structs
[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 private:
52         bool r_any_resolved;
53
54 public:
55         BlockHierarchyResolver(): r_any_resolved(false) { }
56
57         bool apply(Stage &s) { r_any_resolved = false; s.content.visit(*this); return r_any_resolved; }
58
59 private:
60         virtual void enter(Block &);
61 };
62
63 /** Resolves types of variables and base types of other types. */
64 class TypeResolver: private TraversingVisitor
65 {
66 private:
67         Stage *stage;
68         std::map<TypeDeclaration *, TypeDeclaration *> alias_map;
69         std::map<TypeDeclaration *, TypeDeclaration *> array_types;
70         NodeList<Statement>::iterator type_insert_point;
71         InterfaceBlock *iface_block;
72         bool r_any_resolved;
73
74 public:
75         TypeResolver();
76
77         bool apply(Stage &);
78
79 private:
80         TypeDeclaration *get_or_create_array_type(TypeDeclaration &);
81         void resolve_type(TypeDeclaration *&, const std::string &, bool);
82         virtual void visit(Block &);
83         virtual void visit(BasicTypeDeclaration &);
84         virtual void visit(ImageTypeDeclaration &);
85         virtual void visit(StructDeclaration &);
86         virtual void visit(VariableDeclaration &);
87         virtual void visit(InterfaceBlock &);
88         virtual void visit(FunctionDeclaration &);
89 };
90
91 /** Resolves variable references.  Variable references which match the name
92 of an interface block are turned into interface block references. */
93 class VariableResolver: private TraversingVisitor
94 {
95 private:
96         Stage *stage;
97         RefPtr<Expression> r_replacement_expr;
98         bool r_any_resolved;
99         bool record_target;
100         bool r_self_referencing;
101         VariableDeclaration *r_assignment_target;
102
103 public:
104         VariableResolver();
105
106         bool apply(Stage &);
107
108 private:
109         virtual void enter(Block &);
110         void visit_and_replace(RefPtr<Expression> &);
111         virtual void visit(VariableReference &);
112         virtual void visit(InterfaceBlockReference &);
113         virtual void visit(MemberAccess &);
114         virtual void visit(UnaryExpression &);
115         virtual void visit(BinaryExpression &);
116         virtual void visit(Assignment &);
117         virtual void visit(FunctionCall &);
118         virtual void visit(VariableDeclaration &);
119         virtual void visit(InterfaceBlock &);
120 };
121
122 /** Resolves types and lvalueness of expressions. */
123 class ExpressionResolver: private TraversingVisitor
124 {
125 private:
126         enum Compatibility
127         {
128                 NOT_COMPATIBLE,
129                 LEFT_CONVERTIBLE,
130                 RIGHT_CONVERTIBLE,
131                 SAME_TYPE
132         };
133
134         Stage *stage;
135         std::vector<BasicTypeDeclaration *> basic_types;
136         bool r_any_resolved;
137
138 public:
139         ExpressionResolver();
140
141         bool apply(Stage &);
142
143 private:
144         static bool is_scalar(BasicTypeDeclaration &);
145         static bool is_vector_or_matrix(BasicTypeDeclaration &);
146         static BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &);
147         static bool can_convert(BasicTypeDeclaration &, BasicTypeDeclaration &);
148         static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
149         BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned);
150         BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
151         void convert_to(RefPtr<Expression> &, BasicTypeDeclaration &);
152         bool convert_to_element(RefPtr<Expression> &, BasicTypeDeclaration &);
153         void resolve(Expression &, TypeDeclaration *, bool);
154
155         virtual void visit(Literal &);
156         virtual void visit(ParenthesizedExpression &);
157         virtual void visit(VariableReference &);
158         virtual void visit(InterfaceBlockReference &);
159         virtual void visit(MemberAccess &);
160         virtual void visit(UnaryExpression &);
161         void visit(BinaryExpression &, bool);
162         virtual void visit(BinaryExpression &);
163         virtual void visit(Assignment &);
164         virtual void visit(FunctionCall &);
165         virtual void visit(BasicTypeDeclaration &);
166         virtual void visit(VariableDeclaration &);
167 };
168
169 /** Resolves function declarations and calls. */
170 class FunctionResolver: private TraversingVisitor
171 {
172 private:
173         Stage *stage;
174         std::map<std::string, std::vector<FunctionDeclaration *> > declarations;
175         bool r_any_resolved;
176
177 public:
178         bool apply(Stage &);
179
180 private:
181         virtual void visit(FunctionCall &);
182         virtual void visit(FunctionDeclaration &);
183 };
184
185 /** Materializes implicitly declared interfaces.
186
187 Out variable declarations inside functions are moved to the global scope.
188
189 Passthrough statements are processed, generating out variables to match in
190 variables and copying values.
191
192 Unresolved variables are looked up in the previous stage's out variables. */
193 class InterfaceGenerator: private TraversingVisitor
194 {
195 private:
196         Stage *stage;
197         std::string in_prefix;
198         std::string out_prefix;
199         bool function_scope;
200         bool copy_block;
201         Block *iface_target_block;
202         NodeList<Statement>::iterator iface_insert_point;
203         NodeList<Statement>::iterator assignment_insert_point;
204         std::set<Node *> nodes_to_remove;
205
206 public:
207         InterfaceGenerator();
208
209         void apply(Stage &);
210
211 private:
212         static std::string get_out_prefix(Stage::Type);
213         std::string change_prefix(const std::string &, const std::string &) const;
214         virtual void visit(Block &);
215         VariableDeclaration *generate_interface(VariableDeclaration &, const std::string &, const std::string &);
216         InterfaceBlock *generate_interface(InterfaceBlock &);
217         ExpressionStatement &insert_assignment(const std::string &, Expression *);
218         virtual void visit(VariableReference &);
219         virtual void visit(VariableDeclaration &);
220         virtual void visit(InterfaceBlock &);
221         virtual void visit(FunctionDeclaration &);
222         virtual void visit(Passthrough &);
223 };
224
225 } // namespace SL
226 } // namespace GL
227 } // namespace Msp
228
229 #endif