]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/syntax.cpp
Validate location overlap and type matching for GLSL interfaces
[libs/gl.git] / source / glsl / syntax.cpp
index 32a7b12c6639aebd69344aa7a2f6408c67de308f..23b8f0301e9bd76196ec15b7388ef74f5ed2887e 100644 (file)
@@ -485,6 +485,66 @@ string get_unused_variable_name(const Block &block, const string &base)
        }
 }
 
+bool is_same_type(const TypeDeclaration &type1, const TypeDeclaration &type2)
+{
+       if(const BasicTypeDeclaration *basic1 = dynamic_cast<const BasicTypeDeclaration *>(&type1))
+       {
+               const BasicTypeDeclaration *basic2 = dynamic_cast<const BasicTypeDeclaration *>(&type2);
+               if(!basic2)
+                       return false;
+
+               if(basic1->kind!=basic2->kind || basic1->size!=basic2->size)
+                       return false;
+
+               if(basic1->base_type && basic2->base_type)
+                       return is_same_type(*basic1->base_type, *basic2->base_type);
+               else
+                       return (!basic1->base_type && !basic2->base_type);
+       }
+       else if(const ImageTypeDeclaration *image1 = dynamic_cast<const ImageTypeDeclaration *>(&type1))
+       {
+               const ImageTypeDeclaration *image2 = dynamic_cast<const ImageTypeDeclaration *>(&type2);
+               if(!image2)
+                       return false;
+
+               if(image1->dimensions!=image2->dimensions || image1->array!=image2->array)
+                       return false;
+               if(image1->sampled!=image2->sampled || image1->shadow!=image2->shadow)
+                       return false;
+
+               if(image1->base_type && image2->base_type)
+                       return is_same_type(*image1->base_type, *image2->base_type);
+               else
+                       return (!image1->base_type && !image2->base_type);
+       }
+       else if(const StructDeclaration *strct1 = dynamic_cast<const StructDeclaration *>(&type1))
+       {
+               const StructDeclaration *strct2 = dynamic_cast<const StructDeclaration *>(&type2);
+               if(!strct2)
+                       return false;
+
+               NodeList<Statement>::const_iterator i = strct1->members.body.begin();
+               NodeList<Statement>::const_iterator j = strct2->members.body.begin();
+               for(; (i!=strct1->members.body.end() && j!=strct2->members.body.end()); ++i, ++j)
+               {
+                       const VariableDeclaration *var1 = dynamic_cast<const VariableDeclaration *>(i->get());
+                       const VariableDeclaration *var2 = dynamic_cast<const VariableDeclaration *>(j->get());
+                       if(!var1 || !var1->type_declaration || !var2 || !var2->type_declaration)
+                               return false;
+                       if(!is_same_type(*var1->type_declaration, *var2->type_declaration))
+                               return false;
+                       if(var1->name!=var2->name || var1->array!=var2->array)
+                               return false;
+                       // TODO Compare array sizes
+                       // TODO Compare layout qualifiers for interface block members
+               }
+
+               return (i==strct1->members.body.end() && j==strct2->members.body.end());
+       }
+       else
+               return false;
+}
+
 } // namespace SL
 } // namespace GL
 } // namespace Msp