]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/generate.h
Move function override processing to FunctionResolver
[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 variable references.  Variable references which match the name
59 of an interface block are turned into interface block references. */
60 class VariableResolver: private TraversingVisitor
61 {
62 private:
63         Stage *stage;
64         Block *builtins;
65         std::map<std::string, VariableDeclaration *> *members;
66         RefPtr<InterfaceBlockReference> iface_ref;
67         std::string block_interface;
68         bool record_target;
69         VariableDeclaration *assignment_target;
70         bool self_referencing;
71
72 public:
73         VariableResolver();
74
75         void apply(Stage &);
76
77 private:
78         Block *next_block(Block &);
79
80         virtual void enter(Block &);
81         virtual void visit(VariableReference &);
82         virtual void visit(InterfaceBlockReference &);
83         virtual void visit(MemberAccess &);
84         virtual void visit(BinaryExpression &);
85         virtual void visit(Assignment &);
86         virtual void visit(StructDeclaration &);
87         virtual void visit(VariableDeclaration &);
88         virtual void visit(InterfaceBlock &);
89 };
90
91 /** Resolves function declarations and calls. */
92 class FunctionResolver: private TraversingVisitor
93 {
94 private:
95         Stage *stage;
96         std::map<std::string, std::vector<FunctionDeclaration *> > functions;
97
98 public:
99         void apply(Stage &);
100
101 private:
102         virtual void visit(FunctionCall &);
103         virtual void visit(FunctionDeclaration &);
104 };
105
106 /** Materializes implicitly declared interfaces.
107
108 Out variable declarations inside functions are moved to the global scope.
109
110 Passthrough statements are processed, generating out variables to match in
111 variables and copying values.
112
113 Unresolved variables are looked up in the previous stage's out variables. */
114 class InterfaceGenerator: private TraversingVisitor
115 {
116 private:
117         Stage *stage;
118         std::string in_prefix;
119         std::string out_prefix;
120         bool function_scope;
121         InterfaceBlock *iface_block;
122         bool copy_block;
123         Block *iface_target_block;
124         NodeList<Statement>::iterator iface_insert_point;
125         NodeList<Statement>::iterator assignment_insert_point;
126         std::set<Node *> nodes_to_remove;
127
128 public:
129         InterfaceGenerator();
130
131         void apply(Stage &);
132
133 private:
134         static std::string get_out_prefix(Stage::Type);
135         std::string change_prefix(const std::string &, const std::string &) const;
136         virtual void visit(Block &);
137         bool generate_interface(VariableDeclaration &, const std::string &, const std::string &);
138         bool generate_interface(InterfaceBlock &);
139         ExpressionStatement &insert_assignment(const std::string &, Expression *);
140         virtual void visit(VariableReference &);
141         virtual void visit(VariableDeclaration &);
142         virtual void visit(InterfaceBlock &);
143         virtual void visit(FunctionDeclaration &);
144         virtual void visit(Passthrough &);
145 };
146
147 /** Reorders declarations to ensure that declarations always appear before
148 references. */
149 class DeclarationReorderer: private TraversingVisitor
150 {
151 private:
152         enum DeclarationKind
153         {
154                 NO_DECLARATION,
155                 LAYOUT,
156                 STRUCT,
157                 VARIABLE,
158                 FUNCTION
159         };
160
161         DeclarationKind kind;
162         std::set<Node *> ordered_funcs;
163         std::set<Node *> needed_funcs;
164
165 public:
166         DeclarationReorderer();
167
168         void apply(Stage &s) { s.content.visit(*this); }
169
170 private:
171         virtual void visit(Block &);
172         virtual void visit(FunctionCall &);
173         virtual void visit(InterfaceLayout &) { kind = LAYOUT; }
174         virtual void visit(StructDeclaration &) { kind = STRUCT; }
175         virtual void visit(VariableDeclaration &);
176         virtual void visit(InterfaceBlock &) { kind = VARIABLE; }
177         virtual void visit(FunctionDeclaration &);
178 };
179
180 } // namespace SL
181 } // namespace GL
182 } // namespace Msp
183
184 #endif