]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/generate.cpp
Further refactor the resolving process in SL::Compiler
[libs/gl.git] / source / glsl / generate.cpp
index 1e57ed649041cacdfaa58b56fa0a56dee5642dc9..4e225ae520569dab6188666ba1bc7a2c026a5bb2 100644 (file)
@@ -116,31 +116,57 @@ void ConstantSpecializer::visit(VariableDeclaration &var)
 
 void BlockHierarchyResolver::enter(Block &block)
 {
+       r_any_resolved |= (current_block!=block.parent);
        block.parent = current_block;
 }
 
 
 TypeResolver::TypeResolver():
-       stage(0)
+       stage(0),
+       r_any_resolved(false)
 { }
 
-void TypeResolver::apply(Stage &s)
+bool TypeResolver::apply(Stage &s)
 {
        stage = &s;
        s.types.clear();
+       r_any_resolved = false;
        s.content.visit(*this);
+       return r_any_resolved;
+}
+
+TypeDeclaration *TypeResolver::get_or_create_array_type(TypeDeclaration &type)
+{
+       map<TypeDeclaration *, TypeDeclaration *>::iterator i = array_types.find(&type);
+       if(i!=array_types.end())
+               return i->second;
+
+       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_types[&type] = array;
+       return array;
 }
 
-TypeDeclaration *TypeResolver::resolve_type(const string &name)
+void TypeResolver::resolve_type(TypeDeclaration *&type, const string &name, bool array)
 {
+       TypeDeclaration *resolved = 0;
        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);
+               resolved = (j!=alias_map.end() ? j->second : i->second);
        }
-       else
-               return 0;
+
+       if(resolved && array)
+               resolved = get_or_create_array_type(*resolved);
+
+       r_any_resolved |= (resolved!=type);
+       type=resolved;
 }
 
 void TypeResolver::visit(Block &block)
@@ -155,7 +181,7 @@ void TypeResolver::visit(Block &block)
 
 void TypeResolver::visit(BasicTypeDeclaration &type)
 {
-       type.base_type = resolve_type(type.base);
+       resolve_type(type.base_type, type.base, false);
 
        if(type.kind==BasicTypeDeclaration::VECTOR && type.base_type)
                if(BasicTypeDeclaration *basic_base = dynamic_cast<BasicTypeDeclaration *>(type.base_type))
@@ -175,7 +201,7 @@ void TypeResolver::visit(BasicTypeDeclaration &type)
 
 void TypeResolver::visit(ImageTypeDeclaration &type)
 {
-       type.base_type = resolve_type(type.base);
+       resolve_type(type.base_type, type.base, false);
        stage->types.insert(make_pair(type.name, &type));
 }
 
@@ -187,31 +213,12 @@ void TypeResolver::visit(StructDeclaration &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;
+       resolve_type(var.type_declaration, var.type, var.array);
 }
 
 void TypeResolver::visit(FunctionDeclaration &func)
 {
-       func.return_type_declaration = resolve_type(func.return_type);
+       resolve_type(func.return_type_declaration, func.return_type, false);
        TraversingVisitor::visit(func);
 }
 
@@ -799,11 +806,13 @@ void ExpressionResolver::visit(VariableDeclaration &var)
 }
 
 
-void FunctionResolver::apply(Stage &s)
+bool FunctionResolver::apply(Stage &s)
 {
        stage = &s;
        s.functions.clear();
+       r_any_resolved = false;
        s.content.visit(*this);
+       return r_any_resolved;
 }
 
 void FunctionResolver::visit(FunctionCall &call)