-void BlockHierarchyResolver::enter(Block &block)
-{
- block.parent = current_block;
-}
-
-
-TypeResolver::TypeResolver():
- stage(0)
-{ }
-
-void TypeResolver::apply(Stage &s)
-{
- stage = &s;
- s.types.clear();
- s.content.visit(*this);
-}
-
-void TypeResolver::visit(BasicTypeDeclaration &type)
-{
- map<string, TypeDeclaration *>::iterator i = stage->types.find(type.base);
- type.base_type = (i!=stage->types.end() ? i->second : 0);
-
- if(type.kind==BasicTypeDeclaration::VECTOR && type.base_type)
- if(BasicTypeDeclaration *basic_base = dynamic_cast<BasicTypeDeclaration *>(type.base_type))
- if(basic_base->kind==BasicTypeDeclaration::VECTOR)
- {
- type.kind = BasicTypeDeclaration::MATRIX;
- type.size |= basic_base->size<<16;
- }
-
- stage->types.insert(make_pair(type.name, &type));
-}
-
-void TypeResolver::visit(ImageTypeDeclaration &type)
-{
- map<string, TypeDeclaration *>::iterator i = stage->types.find(type.base);
- type.base_type = (i!=stage->types.end() ? i->second : 0);
-
- stage->types.insert(make_pair(type.name, &type));
-}
-
-void TypeResolver::visit(StructDeclaration &strct)
-{
- stage->types.insert(make_pair(strct.name, &strct));
- TraversingVisitor::visit(strct);
-}
-
-void TypeResolver::visit(VariableDeclaration &var)
-{
- map<string, TypeDeclaration *>::iterator i = stage->types.find(var.type);
- if(i!=stage->types.end())
- var.type_declaration = i->second;
-}
-
-void TypeResolver::visit(FunctionDeclaration &func)
-{
- map<string, TypeDeclaration *>::iterator i = stage->types.find(func.return_type);
- func.return_type_declaration = (i!=stage->types.end() ? i->second : 0);
- TraversingVisitor::visit(func);
-}
-
-
-VariableResolver::VariableResolver():
- stage(0),
- r_members(0),
- record_target(false),
- r_self_referencing(false),
- r_assignment_target(0)
-{ }
-
-void VariableResolver::apply(Stage &s)
-{
- stage = &s;
- s.interface_blocks.clear();
- s.content.visit(*this);
-}
-
-void VariableResolver::enter(Block &block)
-{
- block.variables.clear();
-}
-
-void VariableResolver::visit(VariableReference &var)
-{
- var.declaration = 0;
- r_members = 0;
- /* Look for variable declarations in the block hierarchy first. Interface
- blocks are always defined in the top level so we can't accidentally skip
- one. */
- for(Block *block=current_block; (!var.declaration && block); block=block->parent)
- {
- map<string, VariableDeclaration *>::iterator i = block->variables.find(var.name);
- if(i!=block->variables.end())
- var.declaration = i->second;
- }
-
- if(!var.declaration)
- {
- const map<string, InterfaceBlock *> &blocks = stage->interface_blocks;
- 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. */
- r_iface_ref = new InterfaceBlockReference;
- r_iface_ref->source = var.source;
- r_iface_ref->line = var.line;
- r_iface_ref->name = var.name;
- r_iface_ref->declaration = i->second;
- r_members = &i->second->members.variables;
- }
- else
- {
- // Look for the variable in anonymous interface blocks.
- for(i=blocks.begin(); (!var.declaration && i!=blocks.end()); ++i)
- if(i->second->instance_name.empty())
- {
- map<string, VariableDeclaration *>::iterator j = i->second->members.variables.find(var.name);
- if(j!=i->second->members.variables.end())
- var.declaration = j->second;
- }
- }
- }
-
- if(var.declaration)
- if(StructDeclaration *strct = dynamic_cast<StructDeclaration *>(var.declaration->type_declaration))
- r_members = &strct->members.variables;
-
- if(record_target)
- {
- if(r_assignment_target)
- {
- /* More than one variable reference found in assignment target.
- Unable to determine what the primary target is. */
- record_target = false;
- r_assignment_target = 0;
- }
- else
- r_assignment_target = var.declaration;
- }
- else if(var.declaration && var.declaration==r_assignment_target)
- r_self_referencing = true;
-}
-
-void VariableResolver::visit(InterfaceBlockReference &iface)
-{
- iface.declaration = 0;
- for(Block *block=current_block; block; block=block->parent)
- {
- map<string, InterfaceBlock *>::iterator i = stage->interface_blocks.find("_"+iface.name);
- if(i!=stage->interface_blocks.end())
- {
- iface.declaration = i->second;
- r_members = &i->second->members.variables;
- break;
- }
- }
-}
-
-void VariableResolver::visit(MemberAccess &memacc)
-{
- r_members = 0;
- r_iface_ref = 0;
- memacc.left->visit(*this);
-
- if(r_iface_ref)
- memacc.left = r_iface_ref;
- r_iface_ref = 0;
-
- memacc.declaration = 0;
- if(r_members)
- {
- map<string, VariableDeclaration *>::iterator i = r_members->find(memacc.member);
- if(i!=r_members->end())
- {
- memacc.declaration = i->second;
- if(StructDeclaration *strct = dynamic_cast<StructDeclaration *>(i->second->type_declaration))
- r_members = &strct->members.variables;
- }
- else
- r_members = 0;
- }
-}
-
-void VariableResolver::visit(UnaryExpression &unary)
-{
- TraversingVisitor::visit(unary);
- r_members = 0;
- r_iface_ref = 0;
-}
-
-void VariableResolver::visit(BinaryExpression &binary)
-{
- if(binary.oper->token[0]=='[')
- {
- {
- /* The subscript expression is not a part of the primary assignment
- target. */
- SetFlag set(record_target, false);
- binary.right->visit(*this);
- }
- r_members = 0;
- r_iface_ref = 0;
- binary.left->visit(*this);
- if(r_iface_ref)
- binary.left = r_iface_ref;
- }
- else
- {
- TraversingVisitor::visit(binary);
- r_members = 0;
- }
-
- r_iface_ref = 0;
-}
-
-void VariableResolver::visit(Assignment &assign)
-{
- {
- SetFlag set(record_target);
- r_assignment_target = 0;
- assign.left->visit(*this);
- assign.target_declaration = r_assignment_target;
- }
-
- r_self_referencing = false;
- assign.right->visit(*this);
- assign.self_referencing = (r_self_referencing || assign.oper->token[0]!='=');
-
- r_members = 0;
- r_iface_ref = 0;
-}
-
-void VariableResolver::visit(FunctionCall &call)
-{
- TraversingVisitor::visit(call);
- r_members = 0;
- r_iface_ref = 0;
-}
-
-void VariableResolver::visit(VariableDeclaration &var)
-{
- if(!block_interface.empty() && var.interface.empty())
- var.interface = block_interface;
-
- TraversingVisitor::visit(var);
- current_block->variables.insert(make_pair(var.name, &var));
-}
-
-void VariableResolver::visit(InterfaceBlock &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));
-
- SetForScope<string> set_iface(block_interface, iface.interface);
- TraversingVisitor::visit(iface);
-}
-
-
-void FunctionResolver::apply(Stage &s)
-{
- stage = &s;
- s.functions.clear();
- s.content.visit(*this);
-}
-
-void FunctionResolver::visit(FunctionCall &call)
-{
- map<string, FunctionDeclaration *>::iterator i = stage->functions.find(call.name);
- if(i!=stage->functions.end())
- call.declaration = i->second;
-
- TraversingVisitor::visit(call);
-}
-
-void FunctionResolver::visit(FunctionDeclaration &func)
-{
- FunctionDeclaration *&stage_decl = stage->functions[func.name];
- vector<FunctionDeclaration *> &decls = declarations[func.name];
- if(func.definition==&func)
- {
- stage_decl = &func;
-
- // Set all previous declarations to use this definition.
- for(vector<FunctionDeclaration *>::iterator i=decls.begin(); i!=decls.end(); ++i)
- {
- (*i)->definition = func.definition;
- (*i)->body.body.clear();
- }
- }
- else
- {
- func.definition = 0;
- if(!stage_decl)
- stage_decl = &func;
- else
- func.definition = stage_decl->definition;
- }
- decls.push_back(&func);
-
- TraversingVisitor::visit(func);
-}
-
-