]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/generate.cpp
Create array type declarations as necessary
[libs/gl.git] / source / glsl / generate.cpp
index b91c2e2614ef2d577ce1e501893222eed678507d..c9803acc3b2afd5698b29f66c8d69a110ddfc18c 100644 (file)
@@ -99,9 +99,15 @@ void ConstantSpecializer::visit(VariableDeclaration &var)
                {
                        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;
                }
        }
@@ -114,6 +120,102 @@ void BlockHierarchyResolver::enter(Block &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),
@@ -125,7 +227,6 @@ VariableResolver::VariableResolver():
 void VariableResolver::apply(Stage &s)
 {
        stage = &s;
-       s.types.clear();
        s.interface_blocks.clear();
        s.content.visit(*this);
 }
@@ -149,12 +250,7 @@ void VariableResolver::visit(VariableReference &var)
                        var.declaration = i->second;
        }
 
-       if(var.declaration)
-       {
-               if(var.declaration->type_declaration)
-                       r_members = &var.declaration->type_declaration->members.variables;
-       }
-       else
+       if(!var.declaration)
        {
                const map<string, InterfaceBlock *> &blocks = stage->interface_blocks;
                map<string, InterfaceBlock *>::const_iterator i = blocks.find("_"+var.name);
@@ -163,6 +259,8 @@ void VariableResolver::visit(VariableReference &var)
                        /* 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;
@@ -180,6 +278,10 @@ void VariableResolver::visit(VariableReference &var)
                }
        }
 
+       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)
@@ -228,8 +330,8 @@ void VariableResolver::visit(MemberAccess &memacc)
                if(i!=r_members->end())
                {
                        memacc.declaration = i->second;
-                       if(i->second->type_declaration)
-                               r_members = &i->second->type_declaration->members.variables;
+                       if(StructDeclaration *strct = dynamic_cast<StructDeclaration *>(i->second->type_declaration))
+                               r_members = &strct->members.variables;
                }
                else
                        r_members = 0;
@@ -292,18 +394,8 @@ void VariableResolver::visit(FunctionCall &call)
        r_iface_ref = 0;
 }
 
-void VariableResolver::visit(StructDeclaration &strct)
-{
-       TraversingVisitor::visit(strct);
-       stage->types.insert(make_pair(strct.name, &strct));
-}
-
 void VariableResolver::visit(VariableDeclaration &var)
 {
-       map<string, StructDeclaration *>::iterator i = stage->types.find(var.type);
-       if(i!=stage->types.end())
-               var.type_declaration = i->second;
-
        if(!block_interface.empty() && var.interface.empty())
                var.interface = block_interface;