1 #ifndef MSP_GL_SL_GENERATE_H_
2 #define MSP_GL_SL_GENERATE_H_
14 /** Combines multiple declarations of the same identifier into one. */
15 class DeclarationCombiner: private TraversingVisitor
18 std::map<std::string, std::vector<FunctionDeclaration *> > functions;
19 std::map<std::string, VariableDeclaration *> variables;
20 std::set<Node *> nodes_to_remove;
26 virtual void visit(Block &);
27 virtual void visit(FunctionDeclaration &);
28 virtual void visit(VariableDeclaration &);
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
37 const std::map<std::string, int> *values;
40 ConstantSpecializer();
42 void apply(Stage &, const std::map<std::string, int> *);
45 virtual void visit(VariableDeclaration &);
48 /** Forms links between nested blocks in the syntax tree. */
49 class BlockHierarchyResolver: private TraversingVisitor
52 void apply(Stage &s) { s.content.visit(*this); }
55 virtual void enter(Block &);
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
65 std::map<std::string, VariableDeclaration *> *members;
66 RefPtr<InterfaceBlockReference> iface_ref;
67 std::string block_interface;
69 VariableDeclaration *assignment_target;
70 bool self_referencing;
78 Block *next_block(Block &);
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 &);
91 /** Resolves function declarations and calls. */
92 class FunctionResolver: private TraversingVisitor
96 std::map<std::string, std::vector<FunctionDeclaration *> > functions;
102 virtual void visit(FunctionCall &);
103 virtual void visit(FunctionDeclaration &);
106 /** Materializes implicitly declared interfaces.
108 Out variable declarations inside functions are moved to the global scope.
110 Passthrough statements are processed, generating out variables to match in
111 variables and copying values.
113 Unresolved variables are looked up in the previous stage's out variables. */
114 class InterfaceGenerator: private TraversingVisitor
118 std::string in_prefix;
119 std::string out_prefix;
121 InterfaceBlock *iface_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;
129 InterfaceGenerator();
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 &);
147 /** Reorders declarations to ensure that declarations always appear before
149 class DeclarationReorderer: private TraversingVisitor
161 DeclarationKind kind;
162 std::set<Node *> ordered_funcs;
163 std::set<Node *> needed_funcs;
166 DeclarationReorderer();
168 void apply(Stage &s) { s.content.visit(*this); }
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 &);