From: Mikko Rasa Date: Fri, 12 Mar 2021 21:58:14 +0000 (+0200) Subject: Handle redeclaration of variables in VariableResolver X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=27e7b634d31498783ea6d24b72f02f3f1287851d;p=libs%2Fgl.git Handle redeclaration of variables in VariableResolver --- diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index 3516048c..b4b63e27 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -214,7 +214,6 @@ void Compiler::append_stage(Stage &stage) target->required_features.glsl_version = stage.required_features.glsl_version; for(NodeList::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i) target->content.body.push_back(*i); - DeclarationCombiner().apply(*target); } void Compiler::import(DataFile::Collection *resources, const string &name) diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index e5855e94..a2fd3608 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -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::iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ++i) - { - bool found = false; - for(vector::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::const_iterator i=from_layout.qualifiers.begin(); i!=from_layout.qualifiers.end(); ++i) + { + bool found = false; + for(vector::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) diff --git a/source/glsl/generate.h b/source/glsl/generate.h index 0a940cea..402f07f4 100644 --- a/source/glsl/generate.h +++ b/source/glsl/generate.h @@ -11,23 +11,6 @@ namespace Msp { namespace GL { namespace SL { -/** Combines multiple declarations of the same identifier into one. */ -class DeclarationCombiner: private TraversingVisitor -{ -private: - std::map > functions; - std::map variables; - std::set nodes_to_remove; - -public: - void apply(Stage &); - -private: - virtual void visit(Block &); - virtual void visit(VariableDeclaration &); - virtual void visit(FunctionDeclaration &) { } -}; - /** Manipulates specialization constants. If values are specified, turns specialization constants into normal constants. Without values assigns automatic constant_ids to specialization constants. */ @@ -99,6 +82,7 @@ private: bool record_target; bool r_self_referencing; Assignment::Target r_assignment_target; + std::set nodes_to_remove; public: VariableResolver(); @@ -116,6 +100,7 @@ private: virtual void visit(Swizzle &); virtual void visit(BinaryExpression &); virtual void visit(Assignment &); + void merge_layouts(Layout &, const Layout &); virtual void visit(VariableDeclaration &); virtual void visit(InterfaceBlock &); };