X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fgenerate.cpp;h=064d217e7da7b9b47f2c90dbab59a8f5006f9a77;hb=99719790df8a1215465a68c7b1d87a495bff87eb;hp=f3c57a2f0f9190352860bc5f7bc22ff634433123;hpb=1fa69bb8eec3070f5da296d6dd0bd67aea62d3bf;p=libs%2Fgl.git diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index f3c57a2f..064d217e 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -8,17 +8,18 @@ namespace Msp { namespace GL { namespace SL { -DeclarationCombiner::DeclarationCombiner(): - toplevel(true) -{ } +void DeclarationCombiner::apply(Stage &stage) +{ + visit(stage.content); + NodeRemover().apply(stage, nodes_to_remove); +} void DeclarationCombiner::visit(Block &block) { - if(!toplevel) + if(current_block) return; - SetForScope set(toplevel, false); - BlockModifier::visit(block); + TraversingVisitor::visit(block); } void DeclarationCombiner::visit(FunctionDeclaration &func) @@ -64,15 +65,27 @@ void DeclarationCombiner::visit(VariableDeclaration &var) else ptr->layout = var.layout; } - remove_node = true; + nodes_to_remove.insert(&var); } else ptr = &var; } +void BlockResolver::visit(Block &block) +{ + block.parent = current_block; + TraversingVisitor::visit(block); +} + +void BlockResolver::visit(InterfaceBlock &iface) +{ + iface.members.anonymous = true; + TraversingVisitor::visit(iface); +} + + VariableResolver::VariableResolver(): - anonymous(false), record_target(false), assignment_target(0), self_referencing(false) @@ -80,31 +93,32 @@ VariableResolver::VariableResolver(): void VariableResolver::apply(Stage &stage) { - Stage *builtins = get_builtins(stage.type); - if(builtins) - blocks.push_back(&builtins->content); + Stage *builtin_stage = get_builtins(stage.type); + builtins = (builtin_stage ? &builtin_stage->content : 0); visit(stage.content); - if(builtins) - blocks.pop_back(); +} + +Block *VariableResolver::next_block(Block &block) +{ + return block.parent ? block.parent : &block!=builtins ? builtins : 0; } void VariableResolver::visit(Block &block) { - blocks.push_back(&block); - block.variables.clear(); + if(current_block!=&block) + block.variables.clear(); + TraversingVisitor::visit(block); - blocks.pop_back(); } void VariableResolver::visit(VariableReference &var) { var.declaration = 0; type = 0; - for(vector::iterator i=blocks.end(); i!=blocks.begin(); ) + for(Block *block=current_block; block; block=next_block(*block)) { - --i; - map::iterator j = (*i)->variables.find(var.name); - if(j!=(*i)->variables.end()) + map::iterator j = block->variables.find(var.name); + if(j!=block->variables.end()) { var.declaration = j->second; type = j->second->type_declaration; @@ -180,16 +194,15 @@ void VariableResolver::visit(Assignment &assign) void VariableResolver::visit(StructDeclaration &strct) { TraversingVisitor::visit(strct); - blocks.back()->types[strct.name] = &strct; + current_block->types[strct.name] = &strct; } void VariableResolver::visit(VariableDeclaration &var) { - for(vector::iterator i=blocks.end(); i!=blocks.begin(); ) + for(Block *block=current_block; block; block=next_block(*block)) { - --i; - map::iterator j = (*i)->types.find(var.type); - if(j!=(*i)->types.end()) + map::iterator j = block->types.find(var.type); + if(j!=block->types.end()) var.type_declaration = j->second; } @@ -197,18 +210,31 @@ void VariableResolver::visit(VariableDeclaration &var) var.interface = block_interface; TraversingVisitor::visit(var); - blocks.back()->variables[var.name] = &var; - if(anonymous && blocks.size()>1) - blocks[blocks.size()-2]->variables[var.name] = &var; + current_block->variables[var.name] = &var; + if(current_block->anonymous && current_block->parent) + current_block->parent->variables[var.name] = &var; } void VariableResolver::visit(InterfaceBlock &iface) { - SetFlag set(anonymous); - SetForScope set2(block_interface, iface.interface); + SetForScope set_iface(block_interface, iface.interface); TraversingVisitor::visit(iface); } +void VariableResolver::visit(FunctionDeclaration &func) +{ + SetForScope set_block(current_block, &func.body); + func.body.variables.clear(); + TraversingVisitor::visit(func); +} + +void VariableResolver::visit(Iteration &iter) +{ + SetForScope set_block(current_block, &iter.body); + iter.body.variables.clear(); + TraversingVisitor::visit(iter); +} + void FunctionResolver::visit(FunctionCall &call) { @@ -239,8 +265,7 @@ void FunctionResolver::visit(FunctionDeclaration &func) InterfaceGenerator::InterfaceGenerator(): - stage(0), - scope_level(0) + stage(0) { } string InterfaceGenerator::get_out_prefix(Stage::Type type) @@ -255,31 +280,24 @@ string InterfaceGenerator::get_out_prefix(Stage::Type type) void InterfaceGenerator::apply(Stage &s) { - SetForScope set(stage, &s); + stage = &s; if(stage->previous) in_prefix = get_out_prefix(stage->previous->type); out_prefix = get_out_prefix(stage->type); visit(s.content); + NodeRemover().apply(s, nodes_to_remove); } void InterfaceGenerator::visit(Block &block) { - SetForScope set(scope_level, scope_level+1); - for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ) + SetForScope set_block(current_block, &block); + for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) { - (*i)->visit(*this); + assignment_insert_point = i; + if(&block==&stage->content) + iface_insert_point = i; - if(scope_level==1) - { - for(map >::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j) - { - NodeList::iterator k = block.body.insert(i, j->second); - (*k)->visit(*this); - } - iface_declarations.clear(); - } - - apply_and_increment(block, i); + (*i)->visit(*this); } } @@ -292,7 +310,7 @@ string InterfaceGenerator::change_prefix(const string &name, const string &prefi bool InterfaceGenerator::generate_interface(VariableDeclaration &var, const string &iface, const string &name) { const map &stage_vars = (iface=="in" ? stage->in_variables : stage->out_variables); - if(stage_vars.count(name) || iface_declarations.count(name)) + if(stage_vars.count(name)) return false; VariableDeclaration* iface_var = new VariableDeclaration; @@ -309,7 +327,11 @@ bool InterfaceGenerator::generate_interface(VariableDeclaration &var, const stri iface_var->array_size = var.array_size; if(iface=="in") iface_var->linked_declaration = &var; - iface_declarations[name] = iface_var; + stage->content.body.insert(iface_insert_point, iface_var); + { + SetForScope set_block(current_block, &stage->content); + iface_var->visit(*this); + } return true; } @@ -325,8 +347,8 @@ ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, E ExpressionStatement *stmt = new ExpressionStatement; stmt->expression = assign; + current_block->body.insert(assignment_insert_point, stmt); stmt->visit(*this); - insert_nodes.push_back(stmt); return *stmt; } @@ -335,8 +357,6 @@ void InterfaceGenerator::visit(VariableReference &var) { if(var.declaration || !stage->previous) return; - if(iface_declarations.count(var.name)) - return; const map &prev_out = stage->previous->out_variables; map::const_iterator i = prev_out.find(var.name); @@ -353,11 +373,11 @@ void InterfaceGenerator::visit(VariableDeclaration &var) { if(var.interface=="out") { - if(scope_level==1) + if(current_block==&stage->content) stage->out_variables[var.name] = &var; else if(generate_interface(var, "out", change_prefix(var.name, string()))) { - remove_node = true; + nodes_to_remove.insert(&var); if(var.init_expression) { ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression->clone()); @@ -393,9 +413,6 @@ void InterfaceGenerator::visit(Passthrough &pass) for(map::const_iterator i=stage->in_variables.begin(); i!=stage->in_variables.end(); ++i) pass_vars.push_back(i->second); - for(map >::const_iterator i=iface_declarations.begin(); i!=iface_declarations.end(); ++i) - if(i->second->interface=="in") - pass_vars.push_back(i->second.get()); if(stage->previous) { @@ -449,12 +466,11 @@ void InterfaceGenerator::visit(Passthrough &pass) insert_assignment(out_name, ref); } - remove_node = true; + nodes_to_remove.insert(&pass); } DeclarationReorderer::DeclarationReorderer(): - scope_level(0), kind(NO_DECLARATION) { } @@ -469,8 +485,7 @@ void DeclarationReorderer::visit(FunctionCall &call) void DeclarationReorderer::visit(Block &block) { - SetForScope set(scope_level, scope_level+1); - if(scope_level>1) + if(block.parent) return TraversingVisitor::visit(block); NodeList::iterator struct_insert_point = block.body.end();