}
-TypeResolver::TypeResolver():
- stage(0),
- iface_block(0),
- r_any_resolved(false)
-{ }
-
bool TypeResolver::apply(Stage &s)
{
stage = &s;
}
-VariableResolver::VariableResolver():
- stage(0),
- r_any_resolved(false),
- record_target(false),
- r_self_referencing(false)
-{ }
-
bool VariableResolver::apply(Stage &s)
{
stage = &s;
s.interface_blocks.clear();
r_any_resolved = false;
s.content.visit(*this);
- for(VariableDeclaration *v: redeclared_builtins)
- v->source = GENERATED_SOURCE;
+ for(Statement *b: redeclared_builtins)
+ b->source = GENERATED_SOURCE;
NodeRemover().apply(s, nodes_to_remove);
return r_any_resolved;
}
void VariableResolver::visit(VariableDeclaration &var)
{
TraversingVisitor::visit(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)
+
+ auto i = current_block->variables.find(var.name);
+ VariableDeclaration *existing = 0;
+ InterfaceBlock *block = 0;
+ if(i!=current_block->variables.end())
+ existing = i->second;
+ else if(!current_block->parent)
{
- if(ptr->source==BUILTIN_SOURCE)
- redeclared_builtins.push_back(&var);
- else
- stage->diagnostics.push_back(Diagnostic(Diagnostic::WARN, var.source, var.line,
- format("Redeclaring non-builtin variable '%s' is deprecated", var.name)));
+ const map<string, InterfaceBlock *> &blocks = stage->interface_blocks;
+ for(auto j=blocks.begin(); j!=blocks.end(); ++j)
+ if(j->second->instance_name.empty() && j->second->struct_declaration)
+ {
+ map<string, VariableDeclaration *> &block_vars = j->second->struct_declaration->members.variables;
+ i = block_vars.find(var.name);
+ if(i!=block_vars.end())
+ {
+ existing = i->second;
+ block = j->second;
+ break;
+ }
+ }
+ }
- if(var.init_expression)
- ptr->init_expression = var.init_expression;
- if(var.layout)
+ if(!existing)
+ current_block->variables.insert(make_pair(var.name, &var));
+ else if(!current_block->parent && (block ? block->interface : existing->interface)==var.interface && existing->type==var.type && existing->array==var.array)
+ {
+ if(existing->source==BUILTIN_SOURCE)
{
- if(ptr->layout)
- merge_layouts(*ptr->layout, *var.layout);
- else
- ptr->layout = var.layout;
- }
- nodes_to_remove.insert(&var);
+ if(var.layout)
+ {
+ if(existing->layout)
+ merge_layouts(*existing->layout, *var.layout);
+ else
+ existing->layout = var.layout;
+ }
+ if(var.array_size)
+ existing->array_size = var.array_size;
- r_any_resolved = true;
+ redeclared_builtins.push_back(existing);
+ if(block)
+ {
+ redeclared_builtins.push_back(block);
+ for(const auto &kvp: block->struct_declaration->members.variables)
+ redeclared_builtins.push_back(kvp.second);
+ }
+
+ nodes_to_remove.insert(&var);
+ r_any_resolved = true;
+ }
+ else if(existing->array && !existing->array_size && !var.layout && !var.init_expression)
+ {
+ existing->array_size = var.array_size;
+ nodes_to_remove.insert(&var);
+ r_any_resolved = true;
+ }
}
}
}
-ExpressionResolver::ExpressionResolver():
- stage(0),
- r_any_resolved(false)
-{ }
-
bool ExpressionResolver::apply(Stage &s)
{
stage = &s;