1 #include <msp/core/raii.h>
11 DeclarationCombiner::DeclarationCombiner():
15 void DeclarationCombiner::visit(Block &block)
20 SetForScope<bool> set(toplevel, false);
21 BlockModifier::visit(block);
24 void DeclarationCombiner::visit(FunctionDeclaration &func)
26 vector<FunctionDeclaration *> &decls = functions[func.name];
29 for(vector<FunctionDeclaration *>::iterator i=decls.begin(); i!=decls.end(); ++i)
31 (*i)->definition = func.definition;
32 (*i)->body.body.clear();
35 decls.push_back(&func);
38 void DeclarationCombiner::visit(VariableDeclaration &var)
40 VariableDeclaration *&ptr = variables[var.name];
44 if(var.init_expression)
45 ptr->init_expression = var.init_expression;
50 for(vector<Layout::Qualifier>::iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ++i)
53 for(vector<Layout::Qualifier>::iterator j=ptr->layout->qualifiers.begin(); (!found && j!=ptr->layout->qualifiers.end()); ++j)
54 if(j->identifier==i->identifier)
61 ptr->layout->qualifiers.push_back(*i);
65 ptr->layout = var.layout;
74 VariableResolver::VariableResolver():
78 self_referencing(false)
81 void VariableResolver::apply(Stage &stage)
83 Stage *builtins = get_builtins(stage.type);
85 blocks.push_back(&builtins->content);
91 void VariableResolver::visit(Block &block)
93 blocks.push_back(&block);
94 block.variables.clear();
95 TraversingVisitor::visit(block);
99 void VariableResolver::visit(VariableReference &var)
103 for(vector<Block *>::iterator i=blocks.end(); i!=blocks.begin(); )
106 map<string, VariableDeclaration *>::iterator j = (*i)->variables.find(var.name);
107 if(j!=(*i)->variables.end())
109 var.declaration = j->second;
110 type = j->second->type_declaration;
117 if(assignment_target)
119 record_target = false;
120 assignment_target = 0;
123 assignment_target = var.declaration;
125 else if(var.declaration && var.declaration==assignment_target)
126 self_referencing = true;
129 void VariableResolver::visit(MemberAccess &memacc)
132 TraversingVisitor::visit(memacc);
133 memacc.declaration = 0;
136 map<string, VariableDeclaration *>::iterator i = type->members.variables.find(memacc.member);
137 if(i!=type->members.variables.end())
139 memacc.declaration = i->second;
140 type = i->second->type_declaration;
147 void VariableResolver::visit(BinaryExpression &binary)
152 SetForScope<bool> set(record_target, false);
153 binary.right->visit(*this);
156 binary.left->visit(*this);
160 TraversingVisitor::visit(binary);
165 void VariableResolver::visit(Assignment &assign)
168 SetFlag set(record_target);
169 assignment_target = 0;
170 assign.left->visit(*this);
173 self_referencing = false;
174 assign.right->visit(*this);
176 assign.self_referencing = (self_referencing || assign.oper!="=");
177 assign.target_declaration = assignment_target;
180 void VariableResolver::visit(StructDeclaration &strct)
182 TraversingVisitor::visit(strct);
183 blocks.back()->types[strct.name] = &strct;
186 void VariableResolver::visit(VariableDeclaration &var)
188 for(vector<Block *>::iterator i=blocks.end(); i!=blocks.begin(); )
191 map<string, StructDeclaration *>::iterator j = (*i)->types.find(var.type);
192 if(j!=(*i)->types.end())
193 var.type_declaration = j->second;
196 if(!block_interface.empty() && var.interface.empty())
197 var.interface = block_interface;
199 TraversingVisitor::visit(var);
200 blocks.back()->variables[var.name] = &var;
201 if(anonymous && blocks.size()>1)
202 blocks[blocks.size()-2]->variables[var.name] = &var;
205 void VariableResolver::visit(InterfaceBlock &iface)
207 SetFlag set(anonymous);
208 SetForScope<string> set2(block_interface, iface.interface);
209 TraversingVisitor::visit(iface);
213 void FunctionResolver::visit(FunctionCall &call)
215 map<string, vector<FunctionDeclaration *> >::iterator i = functions.find(call.name);
216 if(i!=functions.end())
217 call.declaration = i->second.back();
219 TraversingVisitor::visit(call);
222 void FunctionResolver::visit(FunctionDeclaration &func)
224 vector<FunctionDeclaration *> &decls = functions[func.name];
227 for(vector<FunctionDeclaration *>::iterator i=decls.begin(); i!=decls.end(); ++i)
228 (*i)->definition = func.definition;
230 decls.push_back(&func);
232 else if(!decls.empty() && decls.back()->definition)
233 func.definition = decls.back()->definition;
235 decls.push_back(&func);
237 TraversingVisitor::visit(func);
241 InterfaceGenerator::InterfaceGenerator():
246 string InterfaceGenerator::get_out_prefix(Stage::Type type)
248 if(type==Stage::VERTEX)
250 else if(type==Stage::GEOMETRY)
256 void InterfaceGenerator::apply(Stage &s)
258 SetForScope<Stage *> set(stage, &s);
260 in_prefix = get_out_prefix(stage->previous->type);
261 out_prefix = get_out_prefix(stage->type);
265 void InterfaceGenerator::visit(Block &block)
267 SetForScope<unsigned> set(scope_level, scope_level+1);
268 for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); )
274 for(map<string, RefPtr<VariableDeclaration> >::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j)
276 NodeList<Statement>::iterator k = block.body.insert(i, j->second);
279 iface_declarations.clear();
282 apply_and_increment(block, i);
286 string InterfaceGenerator::change_prefix(const string &name, const string &prefix) const
288 unsigned offset = (name.compare(0, in_prefix.size(), in_prefix) ? 0 : in_prefix.size());
289 return prefix+name.substr(offset);
292 bool InterfaceGenerator::generate_interface(VariableDeclaration &var, const string &iface, const string &name)
294 const map<string, VariableDeclaration *> &stage_vars = (iface=="in" ? stage->in_variables : stage->out_variables);
295 if(stage_vars.count(name) || iface_declarations.count(name))
298 VariableDeclaration* iface_var = new VariableDeclaration;
299 iface_var->sampling = var.sampling;
300 iface_var->interface = iface;
301 iface_var->type = var.type;
302 iface_var->type_declaration = var.type_declaration;
303 iface_var->name = name;
304 if(stage->type==Stage::GEOMETRY)
305 iface_var->array = ((var.array && var.interface!="in") || iface=="in");
307 iface_var->array = var.array;
309 iface_var->array_size = var.array_size;
311 iface_var->linked_declaration = &var;
312 iface_declarations[name] = iface_var;
317 ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, Expression *right)
319 Assignment *assign = new Assignment;
320 VariableReference *ref = new VariableReference;
324 assign->right = right;
326 ExpressionStatement *stmt = new ExpressionStatement;
327 stmt->expression = assign;
329 insert_nodes.push_back(stmt);
334 void InterfaceGenerator::visit(VariableReference &var)
336 if(var.declaration || !stage->previous)
338 if(iface_declarations.count(var.name))
341 const map<string, VariableDeclaration *> &prev_out = stage->previous->out_variables;
342 map<string, VariableDeclaration *>::const_iterator i = prev_out.find(var.name);
343 if(i==prev_out.end())
344 i = prev_out.find(in_prefix+var.name);
345 if(i!=prev_out.end())
347 generate_interface(*i->second, "in", i->second->name);
348 var.name = i->second->name;
352 void InterfaceGenerator::visit(VariableDeclaration &var)
354 if(var.interface=="out")
357 stage->out_variables[var.name] = &var;
358 else if(generate_interface(var, "out", change_prefix(var.name, string())))
361 if(var.init_expression)
363 ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression->clone());
364 stmt.source = var.source;
365 stmt.line = var.line;
370 else if(var.interface=="in")
372 stage->in_variables[var.name] = &var;
373 if(var.linked_declaration)
374 var.linked_declaration->linked_declaration = &var;
375 else if(stage->previous)
377 const map<string, VariableDeclaration *> &prev_out = stage->previous->out_variables;
378 map<string, VariableDeclaration *>::const_iterator i = prev_out.find(var.name);
379 if(i!=prev_out.end())
381 var.linked_declaration = i->second;
382 i->second->linked_declaration = &var;
387 TraversingVisitor::visit(var);
390 void InterfaceGenerator::visit(Passthrough &pass)
392 vector<VariableDeclaration *> pass_vars;
394 for(map<string, VariableDeclaration *>::const_iterator i=stage->in_variables.begin(); i!=stage->in_variables.end(); ++i)
395 pass_vars.push_back(i->second);
396 for(map<string, RefPtr<VariableDeclaration> >::const_iterator i=iface_declarations.begin(); i!=iface_declarations.end(); ++i)
397 if(i->second->interface=="in")
398 pass_vars.push_back(i->second.get());
402 const map<string, VariableDeclaration *> &prev_out = stage->previous->out_variables;
403 for(map<string, VariableDeclaration *>::const_iterator i=prev_out.begin(); i!=prev_out.end(); ++i)
406 for(vector<VariableDeclaration *>::const_iterator j=pass_vars.begin(); (!linked && j!=pass_vars.end()); ++j)
407 linked = ((*j)->linked_declaration==i->second);
409 if(!linked && generate_interface(*i->second, "in", i->second->name))
410 pass_vars.push_back(i->second);
414 if(stage->type==Stage::GEOMETRY)
416 VariableReference *ref = new VariableReference;
419 BinaryExpression *subscript = new BinaryExpression;
420 subscript->left = ref;
421 subscript->oper = "[";
422 subscript->right = pass.subscript;
423 subscript->after = "]";
425 MemberAccess *memacc = new MemberAccess;
426 memacc->left = subscript;
427 memacc->member = "gl_Position";
429 insert_assignment("gl_Position", memacc);
432 for(vector<VariableDeclaration *>::const_iterator i=pass_vars.begin(); i!=pass_vars.end(); ++i)
434 string out_name = change_prefix((*i)->name, out_prefix);
435 generate_interface(**i, "out", out_name);
437 VariableReference *ref = new VariableReference;
438 ref->name = (*i)->name;
441 BinaryExpression *subscript = new BinaryExpression;
442 subscript->left = ref;
443 subscript->oper = "[";
444 subscript->right = pass.subscript;
445 subscript->after = "]";
446 insert_assignment(out_name, subscript);
449 insert_assignment(out_name, ref);
456 DeclarationReorderer::DeclarationReorderer():
461 void DeclarationReorderer::visit(FunctionCall &call)
463 FunctionDeclaration *def = call.declaration;
465 def = def->definition;
466 if(def && !ordered_funcs.count(def))
467 needed_funcs.insert(def);
470 void DeclarationReorderer::visit(Block &block)
472 SetForScope<unsigned> set(scope_level, scope_level+1);
474 return TraversingVisitor::visit(block);
476 NodeList<Statement>::iterator struct_insert_point = block.body.end();
477 NodeList<Statement>::iterator variable_insert_point = block.body.end();
478 NodeList<Statement>::iterator function_insert_point = block.body.end();
479 unsigned unordered_func_count = 0;
480 bool ordered_any_funcs = false;
482 for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); )
484 kind = NO_DECLARATION;
488 if(kind==STRUCT && struct_insert_point!=block.body.end())
490 block.body.insert(struct_insert_point, *i);
493 else if(kind>STRUCT && struct_insert_point==block.body.end())
494 struct_insert_point = i;
496 if(kind==VARIABLE && variable_insert_point!=block.body.end())
498 block.body.insert(variable_insert_point, *i);
501 else if(kind>VARIABLE && variable_insert_point==block.body.end())
502 variable_insert_point = i;
506 if(function_insert_point==block.body.end())
507 function_insert_point = i;
509 if(needed_funcs.empty())
511 ordered_funcs.insert(i->get());
512 if(i!=function_insert_point)
514 block.body.insert(function_insert_point, *i);
518 ++function_insert_point;
519 ordered_any_funcs = true;
522 ++unordered_func_count;
527 if(function_insert_point==i)
528 ++function_insert_point;
529 block.body.erase(i++);
534 if(i==block.body.end() && unordered_func_count)
536 if(!ordered_any_funcs)
537 // A subset of the remaining functions forms a recursive loop
538 /* TODO pick a function and move it up, adding any necessary
542 i = function_insert_point;
543 unordered_func_count = 0;
548 void DeclarationReorderer::visit(VariableDeclaration &var)
550 TraversingVisitor::visit(var);
554 void DeclarationReorderer::visit(FunctionDeclaration &func)
556 needed_funcs.clear();
557 func.body.visit(*this);
558 needed_funcs.erase(&func);