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