- 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)
-{ }
-
-void ConstantSpecializer::apply(Stage &stage, const map<string, int> *v)
-{
- values = v;
- stage.content.visit(*this);
-}
-
-void ConstantSpecializer::visit(VariableDeclaration &var)
-{
- bool specializable = false;
- if(var.layout)
- {
- vector<Layout::Qualifier> &qualifiers = var.layout->qualifiers;
- for(vector<Layout::Qualifier>::iterator i=qualifiers.begin(); i!=qualifiers.end(); ++i)
- if(i->name=="constant_id")
- {
- specializable = true;
- if(values)
- qualifiers.erase(i);
- else if(i->value==-1)
- i->value = hash32(var.name)&0x7FFFFFFF;
- break;
- }
-
- if(qualifiers.empty())
- var.layout = 0;
- }
-
- if(specializable && values)
- {
- map<string, int>::const_iterator i = values->find(var.name);
- if(i!=values->end())
- {
- RefPtr<Literal> literal = new Literal;
- if(var.type=="bool")
- {
- literal->token = (i->second ? "true" : "false");
- literal->value = static_cast<bool>(i->second);
- }
- else if(var.type=="int")
- {
- literal->token = lexical_cast<string>(i->second);
- literal->value = i->second;
- }
- var.init_expression = literal;
- }
- }
-}
-
-
-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);
-}
-
-TypeDeclaration *TypeResolver::resolve_type(const string &name)
-{
- map<string, TypeDeclaration *>::iterator i = stage->types.find(name);
- if(i!=stage->types.end())
- {
- map<TypeDeclaration *, TypeDeclaration *>::iterator j = alias_map.find(i->second);
- return (j!=alias_map.end() ? j->second : i->second);
- }
- else
- return 0;
-}
-
-void TypeResolver::visit(Block &block)
-{
- for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
- {
- if(!block.parent)
- type_insert_point = i;
- (*i)->visit(*this);
- }
-}
-
-void TypeResolver::visit(BasicTypeDeclaration &type)
-{
- type.base_type = resolve_type(type.base);
-
- 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;
- }
-
- if(type.kind==BasicTypeDeclaration::ALIAS && type.base_type)
- alias_map[&type] = type.base_type;
- else if(type.kind==BasicTypeDeclaration::ARRAY && type.base_type)
- array_types[type.base_type] = &type;
-
- stage->types.insert(make_pair(type.name, &type));
-}
-
-void TypeResolver::visit(ImageTypeDeclaration &type)
-{
- type.base_type = resolve_type(type.base);
- 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)
-{
- TypeDeclaration *type = resolve_type(var.type);
- if(var.array && type)
- {
- map<TypeDeclaration *, TypeDeclaration *>::iterator i = array_types.find(type);
- if(i==array_types.end())
- {
- BasicTypeDeclaration *array = new BasicTypeDeclaration;
- array->source = BUILTIN_SOURCE;
- array->name = type->name+"[]";
- array->kind = BasicTypeDeclaration::ARRAY;
- array->base = type->name;
- array->base_type = type;
- stage->content.body.insert(type_insert_point, array);
- array->visit(*this);
- type = array;
- }
- else
- type = i->second;
- }
- var.type_declaration = type;
-}
-
-void TypeResolver::visit(FunctionDeclaration &func)
-{
- func.return_type_declaration = resolve_type(func.return_type);
- 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();
-}