else
{
const map<string, InterfaceBlock *> &blocks = stage->interface_blocks;
- map<string, InterfaceBlock *>::const_iterator i = blocks.find(var.name);
- if(i!=blocks.end() && i->second->instance_name==var.name)
+ map<string, InterfaceBlock *>::const_iterator i = blocks.find("_"+var.name);
+ if(i!=blocks.end())
{
/* The name refers to an interface block with an instance name rather
than a variable. Prepare a new syntax tree node accordingly. */
iface.declaration = 0;
for(Block *block=current_block; block; block=block->parent)
{
- map<string, InterfaceBlock *>::iterator i = stage->interface_blocks.find(iface.name);
+ map<string, InterfaceBlock *>::iterator i = stage->interface_blocks.find("_"+iface.name);
if(i!=stage->interface_blocks.end())
{
iface.declaration = i->second;
void VariableResolver::visit(InterfaceBlock &iface)
{
- /* Block names can't be used for any other identifiers so we can put them
- in the same map with instance names. */
- stage->interface_blocks.insert(make_pair(iface.name, &iface));
+ /* Block names can be reused in different interfaces. Prefix the name with
+ the first character of the interface to avoid conflicts. */
+ stage->interface_blocks.insert(make_pair(iface.interface+iface.name, &iface));
if(!iface.instance_name.empty())
- stage->interface_blocks.insert(make_pair(iface.instance_name, &iface));
+ stage->interface_blocks.insert(make_pair("_"+iface.instance_name, &iface));
SetForScope<string> set_iface(block_interface, iface.interface);
TraversingVisitor::visit(iface);
InterfaceBlock *InterfaceGenerator::generate_interface(InterfaceBlock &out_block)
{
- if(stage->interface_blocks.count(out_block.name))
+ if(stage->interface_blocks.count("in"+out_block.name))
return 0;
InterfaceBlock *in_block = new InterfaceBlock;
}
iface_target_block->body.insert(iface_insert_point, in_block);
- stage->interface_blocks.insert(make_pair(in_block->name, in_block));
+ stage->interface_blocks.insert(make_pair("in"+in_block->name, in_block));
if(!in_block->instance_name.empty())
- stage->interface_blocks.insert(make_pair(in_block->instance_name, in_block));
+ stage->interface_blocks.insert(make_pair("_"+in_block->instance_name, in_block));
SetFlag set_scope(function_scope, false);
SetForScope<Block *> set_block(current_block, &stage->content);
}
const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
- map<string, InterfaceBlock *>::const_iterator j = prev_blocks.find(var.name);
- if(j!=prev_blocks.end() && j->second->interface=="out" && j->second->instance_name==var.name)
+ map<string, InterfaceBlock *>::const_iterator j = prev_blocks.find("_"+var.name);
+ if(j!=prev_blocks.end() && j->second->interface=="out")
{
generate_interface(*j->second);
+ /* Let VariableResolver convert the variable reference into an interface
+ block reference. */
return;
}
if(!iface.linked_block && stage->previous)
{
const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
- map<string, InterfaceBlock *>::const_iterator i = prev_blocks.find(iface.name);
- if(i!=prev_blocks.end() && i->second->interface=="out" && i->second->name==iface.name)
+ map<string, InterfaceBlock *>::const_iterator i = prev_blocks.find("out"+iface.name);
+ if(i!=prev_blocks.end())
{
iface.linked_block = i->second;
i->second->linked_block = &iface;
anonymous_block(false)
{ }
+void DeclarationValidator::multiple_definition(const string &name, Statement &statement, Statement &previous)
+{
+ error(&statement, format("Multiple definition of %s", name));
+ diagnose(&previous, Diagnostic::INFO, "Previous definition is here");
+}
+
Statement *DeclarationValidator::find_definition(const string &name)
{
BlockDeclarationMap *decls = &declarations[current_block];
void DeclarationValidator::check_definition(const string &name, Statement &statement)
{
if(Statement *previous = find_definition(name))
- {
- error(&statement, format("Multiple definition of '%s'", name));
- diagnose(previous, Diagnostic::INFO, "Previous definition is here");
- return;
- }
+ multiple_definition(format("'%s'", name), statement, *previous);
+ else
+ record_definition(name, statement);
+}
+void DeclarationValidator::record_definition(const string &name, Statement &statement)
+{
declarations[current_block].insert(make_pair(name, &statement));
if(anonymous_block)
declarations[current_block->parent].insert(make_pair(name, &statement));
void DeclarationValidator::visit(InterfaceBlock &iface)
{
- check_definition(iface.name, iface);
+ string key = iface.interface+iface.name;
+ map<string, InterfaceBlock *>::const_iterator i = interface_blocks.find(key);
+ if(i!=interface_blocks.end())
+ multiple_definition(format("interface block '%s %s'", iface.interface, iface.name), iface, *i->second);
+ else
+ interface_blocks.insert(make_pair(key, &iface));
+
+ if(Statement *previous = find_definition(iface.name))
+ {
+ if(!dynamic_cast<InterfaceBlock *>(previous))
+ multiple_definition(format("'%s'", iface.name), iface, *previous);
+ }
+ else
+ record_definition(iface.name, iface);
+
if(!iface.instance_name.empty())
check_definition(iface.instance_name, iface);
+
SetFlag set_anon(anonymous_block, iface.instance_name.empty());
TraversingVisitor::visit(iface);
}
typedef std::map<std::string, Statement *> BlockDeclarationMap;
std::map<Block *, BlockDeclarationMap> declarations;
+ std::map<std::string, InterfaceBlock *> interface_blocks;
bool anonymous_block;
public:
void apply(Stage &s) { stage = &s; s.content.visit(*this); }
private:
+ void multiple_definition(const std::string &, Statement &, Statement &);
Statement *find_definition(const std::string &);
void check_definition(const std::string &, Statement &);
+ void record_definition(const std::string &, Statement &);
virtual void visit(VariableDeclaration &);
virtual void visit(InterfaceBlock &);