]> git.tdb.fi Git - libs/gl.git/blob - source/programcompiler.h
Fix unused variable decetion for self-referenging assignments
[libs/gl.git] / source / programcompiler.h
1 #ifndef MSP_GL_PROGRAMCOMPILER_H_
2 #define MSP_GL_PROGRAMCOMPILER_H_
3
4 #include <set>
5 #include "programparser.h"
6 #include "programsyntax.h"
7
8 namespace Msp {
9 namespace GL {
10
11 class Program;
12
13 class ProgramCompiler
14 {
15 private:
16         struct Visitor: ProgramSyntax::TraversingVisitor
17         {
18                 ProgramSyntax::Stage *stage;
19
20                 Visitor();
21
22                 virtual void apply(ProgramSyntax::Stage &);
23         };
24
25         struct Formatter: Visitor
26         {
27                 std::string formatted;
28                 unsigned indent;
29                 bool parameter_list;
30                 bool else_if;
31
32                 Formatter();
33
34                 virtual void visit(ProgramSyntax::Block &);
35                 virtual void visit(ProgramSyntax::Literal &);
36                 virtual void visit(ProgramSyntax::ParenthesizedExpression &);
37                 virtual void visit(ProgramSyntax::VariableReference &);
38                 virtual void visit(ProgramSyntax::MemberAccess &);
39                 virtual void visit(ProgramSyntax::UnaryExpression &);
40                 virtual void visit(ProgramSyntax::BinaryExpression &);
41                 virtual void visit(ProgramSyntax::FunctionCall &);
42                 virtual void visit(ProgramSyntax::ExpressionStatement &);
43                 virtual void visit(ProgramSyntax::Layout &);
44                 virtual void visit(ProgramSyntax::StructDeclaration &);
45                 virtual void visit(ProgramSyntax::VariableDeclaration &);
46                 virtual void visit(ProgramSyntax::InterfaceBlock &);
47                 virtual void visit(ProgramSyntax::FunctionDeclaration &);
48                 virtual void visit(ProgramSyntax::Conditional &);
49                 virtual void visit(ProgramSyntax::Iteration &);
50                 virtual void visit(ProgramSyntax::Return &);
51         };
52
53         struct VariableResolver: Visitor
54         {
55                 std::vector<ProgramSyntax::Block *> blocks;
56                 ProgramSyntax::StructDeclaration *type;
57                 bool anonymous;
58
59                 VariableResolver();
60
61                 virtual void visit(ProgramSyntax::Block &);
62                 virtual void visit(ProgramSyntax::VariableReference &);
63                 virtual void visit(ProgramSyntax::MemberAccess &);
64                 virtual void visit(ProgramSyntax::BinaryExpression &);
65                 virtual void visit(ProgramSyntax::StructDeclaration &);
66                 virtual void visit(ProgramSyntax::VariableDeclaration &);
67                 virtual void visit(ProgramSyntax::InterfaceBlock &);
68         };
69
70         struct InterfaceGenerator: Visitor
71         {
72                 std::string in_prefix;
73                 std::string out_prefix;
74                 unsigned scope_level;
75                 std::map<std::string, ProgramSyntax::VariableDeclaration *> iface_declarations;
76                 bool remove_node;
77                 std::list<ProgramSyntax::Node *> insert_nodes;
78
79                 InterfaceGenerator();
80
81                 static std::string get_out_prefix(ProgramSyntax::StageType);
82                 virtual void apply(ProgramSyntax::Stage &);
83                 virtual void visit(ProgramSyntax::Block &);
84                 std::string change_prefix(const std::string &, const std::string &) const;
85                 bool generate_interface(ProgramSyntax::VariableDeclaration &, const std::string &, const std::string &);
86                 void insert_assignment(const std::string &, ProgramSyntax::Expression *);
87                 virtual void visit(ProgramSyntax::VariableReference &);
88                 virtual void visit(ProgramSyntax::VariableDeclaration &);
89                 virtual void visit(ProgramSyntax::Passthrough &);
90         };
91
92         struct VariableRenamer: Visitor
93         {
94                 virtual void visit(ProgramSyntax::VariableReference &);
95                 virtual void visit(ProgramSyntax::VariableDeclaration &);
96         };
97
98         struct UnusedVariableLocator: Visitor
99         {
100                 std::set<ProgramSyntax::Node *> unused_nodes;
101                 std::map<ProgramSyntax::VariableDeclaration *, ProgramSyntax::Node *> assignments;
102                 bool assignment;
103                 bool record_target;
104                 ProgramSyntax::VariableDeclaration *assignment_target;
105                 bool indeterminate_target;
106                 bool self_referencing;
107
108                 UnusedVariableLocator();
109
110                 virtual void visit(ProgramSyntax::VariableReference &);
111                 virtual void visit(ProgramSyntax::MemberAccess &);
112                 virtual void visit(ProgramSyntax::BinaryExpression &);
113                 virtual void visit(ProgramSyntax::ExpressionStatement &);
114                 virtual void visit(ProgramSyntax::VariableDeclaration &);
115         };
116
117         struct NodeRemover: Visitor
118         {
119                 std::set<ProgramSyntax::Node *> to_remove;
120                 unsigned n_removed;
121                 bool immutable_block;
122                 bool remove_block;
123
124                 NodeRemover();
125
126                 virtual void visit(ProgramSyntax::Block &);
127                 virtual void visit(ProgramSyntax::StructDeclaration &);
128                 virtual void visit(ProgramSyntax::VariableDeclaration &);
129                 virtual void visit(ProgramSyntax::InterfaceBlock &);
130         };
131
132         ProgramParser parser;
133         ProgramSyntax::Module *module;
134
135 public:
136         ProgramCompiler();
137
138         void compile(const std::string &);
139         void compile(IO::Base &);
140         void add_shaders(Program &);
141
142 private:
143         void process();
144         void generate(ProgramSyntax::Stage &);
145         bool optimize(ProgramSyntax::Stage &);
146         static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &);
147         template<typename T>
148         static void apply(ProgramSyntax::Stage &);
149         std::string create_source(ProgramSyntax::Stage &);
150 };
151
152 } // namespace GL
153 } // namespace Msp
154
155 #endif