]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/generate.cpp
Handle redeclaration of variables in VariableResolver
[libs/gl.git] / source / glsl / generate.cpp
index e5855e94cacb701c4ab96bec16324335fcccf910..a2fd3608220e836d268d2310ad1ec6c8915e4550 100644 (file)
@@ -12,57 +12,6 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
-void DeclarationCombiner::apply(Stage &stage)
-{
-       stage.content.visit(*this);
-       NodeRemover().apply(stage, nodes_to_remove);
-}
-
-void DeclarationCombiner::visit(Block &block)
-{
-       if(current_block)
-               return;
-
-       TraversingVisitor::visit(block);
-}
-
-void DeclarationCombiner::visit(VariableDeclaration &var)
-{
-       VariableDeclaration *&ptr = variables[var.name];
-       if(ptr)
-       {
-               ptr->type = var.type;
-               if(var.init_expression)
-                       ptr->init_expression = var.init_expression;
-               if(var.layout)
-               {
-                       if(ptr->layout)
-                       {
-                               for(vector<Layout::Qualifier>::iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ++i)
-                               {
-                                       bool found = false;
-                                       for(vector<Layout::Qualifier>::iterator j=ptr->layout->qualifiers.begin(); (!found && j!=ptr->layout->qualifiers.end()); ++j)
-                                               if(j->name==i->name)
-                                               {
-                                                       j->has_value = i->value;
-                                                       j->value = i->value;
-                                                       found = true;
-                                               }
-
-                                       if(!found)
-                                               ptr->layout->qualifiers.push_back(*i);
-                               }
-                       }
-                       else
-                               ptr->layout = var.layout;
-               }
-               nodes_to_remove.insert(&var);
-       }
-       else
-               ptr = &var;
-}
-
-
 ConstantSpecializer::ConstantSpecializer():
        values(0)
 { }
@@ -270,6 +219,7 @@ bool VariableResolver::apply(Stage &s)
        s.interface_blocks.clear();
        r_any_resolved = false;
        s.content.visit(*this);
+       NodeRemover().apply(s, nodes_to_remove);
        return r_any_resolved;
 }
 
@@ -485,10 +435,45 @@ void VariableResolver::visit(Assignment &assign)
        assign.self_referencing = (r_self_referencing || assign.oper->token[0]!='=');
 }
 
+void VariableResolver::merge_layouts(Layout &to_layout, const Layout &from_layout)
+{
+       for(vector<Layout::Qualifier>::const_iterator i=from_layout.qualifiers.begin(); i!=from_layout.qualifiers.end(); ++i)
+       {
+               bool found = false;
+               for(vector<Layout::Qualifier>::iterator j=to_layout.qualifiers.begin(); (!found && j!=to_layout.qualifiers.end()); ++j)
+                       if(j->name==i->name)
+                       {
+                               j->has_value = i->value;
+                               j->value = i->value;
+                               found = true;
+                       }
+
+               if(!found)
+                       to_layout.qualifiers.push_back(*i);
+       }
+}
+
 void VariableResolver::visit(VariableDeclaration &var)
 {
        TraversingVisitor::visit(var);
-       current_block->variables.insert(make_pair(var.name, &var));
+       VariableDeclaration *&ptr = current_block->variables[var.name];
+       if(!ptr)
+               ptr = &var;
+       else if(!current_block->parent && ptr->interface==var.interface && ptr->type==var.type)
+       {
+               if(var.init_expression)
+                       ptr->init_expression = var.init_expression;
+               if(var.layout)
+               {
+                       if(ptr->layout)
+                               merge_layouts(*ptr->layout, *var.layout);
+                       else
+                               ptr->layout = var.layout;
+               }
+               nodes_to_remove.insert(&var);
+
+               r_any_resolved = true;
+       }
 }
 
 void VariableResolver::visit(InterfaceBlock &iface)