]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/generate.cpp
Follow type aliases in TypeResolver
[libs/gl.git] / source / glsl / generate.cpp
index b91c2e2614ef2d577ce1e501893222eed678507d..f5b6b7adb91769277f95de93d56d605e38cc88f7 100644 (file)
@@ -114,6 +114,71 @@ 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(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;
+
+       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)
+{
+       var.type_declaration = resolve_type(var.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 +190,6 @@ VariableResolver::VariableResolver():
 void VariableResolver::apply(Stage &s)
 {
        stage = &s;
-       s.types.clear();
        s.interface_blocks.clear();
        s.content.visit(*this);
 }
@@ -149,12 +213,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 +222,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 +241,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 +293,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 +357,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;