]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/generate.h
Record assignment targets more precisely
[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         Assignment::Target 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         void check_assignment_target(Statement *);
112         virtual void visit(VariableReference &);
113         virtual void visit(InterfaceBlockReference &);
114         void add_to_chain(Assignment::Target::ChainType, unsigned);
115         virtual void visit(MemberAccess &);
116         virtual void visit(Swizzle &);
117         virtual void visit(UnaryExpression &);
118         virtual void visit(BinaryExpression &);
119         virtual void visit(Assignment &);
120         virtual void visit(FunctionCall &);
121         virtual void visit(VariableDeclaration &);
122         virtual void visit(InterfaceBlock &);
123 };
124
125 /** Resolves types and lvalueness of expressions. */
126 class ExpressionResolver: private TraversingVisitor
127 {
128 private:
129         enum Compatibility
130         {
131                 NOT_COMPATIBLE,
132                 LEFT_CONVERTIBLE,
133                 RIGHT_CONVERTIBLE,
134                 SAME_TYPE
135         };
136
137         Stage *stage;
138         std::vector<BasicTypeDeclaration *> basic_types;
139         bool r_any_resolved;
140
141 public:
142         ExpressionResolver();
143
144         bool apply(Stage &);
145
146 private:
147         static bool is_scalar(BasicTypeDeclaration &);
148         static bool is_vector_or_matrix(BasicTypeDeclaration &);
149         static BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &);
150         static bool can_convert(BasicTypeDeclaration &, BasicTypeDeclaration &);
151         static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
152         BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned);
153         BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
154         void convert_to(RefPtr<Expression> &, BasicTypeDeclaration &);
155         bool convert_to_element(RefPtr<Expression> &, BasicTypeDeclaration &);
156         void resolve(Expression &, TypeDeclaration *, bool);
157
158         virtual void visit(Literal &);
159         virtual void visit(ParenthesizedExpression &);
160         virtual void visit(VariableReference &);
161         virtual void visit(InterfaceBlockReference &);
162         virtual void visit(MemberAccess &);
163         virtual void visit(Swizzle &);
164         virtual void visit(UnaryExpression &);
165         void visit(BinaryExpression &, bool);
166         virtual void visit(BinaryExpression &);
167         virtual void visit(Assignment &);
168         virtual void visit(FunctionCall &);
169         virtual void visit(BasicTypeDeclaration &);
170         virtual void visit(VariableDeclaration &);
171 };
172
173 /** Resolves function declarations and calls. */
174 class FunctionResolver: private TraversingVisitor
175 {
176 private:
177         Stage *stage;
178         std::map<std::string, std::vector<FunctionDeclaration *> > declarations;
179         bool r_any_resolved;
180
181 public:
182         bool apply(Stage &);
183
184 private:
185         virtual void visit(FunctionCall &);
186         virtual void visit(FunctionDeclaration &);
187 };
188
189 /** Materializes implicitly declared interfaces.
190
191 Out variable declarations inside functions are moved to the global scope.
192
193 Passthrough statements are processed, generating out variables to match in
194 variables and copying values.
195
196 Unresolved variables are looked up in the previous stage's out variables. */
197 class InterfaceGenerator: private TraversingVisitor
198 {
199 private:
200         Stage *stage;
201         std::string in_prefix;
202         std::string out_prefix;
203         bool function_scope;
204         bool copy_block;
205         Block *iface_target_block;
206         NodeList<Statement>::iterator iface_insert_point;
207         NodeList<Statement>::iterator assignment_insert_point;
208         std::set<Node *> nodes_to_remove;
209
210 public:
211         InterfaceGenerator();
212
213         void apply(Stage &);
214
215 private:
216         static std::string get_out_prefix(Stage::Type);
217         std::string change_prefix(const std::string &, const std::string &) const;
218         virtual void visit(Block &);
219         VariableDeclaration *generate_interface(VariableDeclaration &, const std::string &, const std::string &);
220         InterfaceBlock *generate_interface(InterfaceBlock &);
221         ExpressionStatement &insert_assignment(const std::string &, Expression *);
222         virtual void visit(VariableReference &);
223         virtual void visit(VariableDeclaration &);
224         virtual void visit(InterfaceBlock &);
225         virtual void visit(FunctionDeclaration &);
226         virtual void visit(Passthrough &);
227 };
228
229 } // namespace SL
230 } // namespace GL
231 } // namespace Msp
232
233 #endif