+ if(var.constant)
+ {
+ if(scope==STRUCT || scope==INTERFACE_BLOCK)
+ error(var, format("Constant qualifier not allowed on %s", descr));
+ }
+
+ if(!var.interpolation.empty() || !var.sampling.empty())
+ {
+ if(var.interface!="in" && stage->type==Stage::VERTEX)
+ error(var, "Interpolation qualifier not allowed on vertex input");
+ else if(var.interface!="out" && stage->type==Stage::FRAGMENT)
+ error(var, "Interpolation qualifier not allowed on fragment output");
+ else if((var.interface!="in" && var.interface!="out") || (scope==FUNCTION_PARAM || scope==FUNCTION))
+ error(var, "Interpolation qualifier not allowed on non-interpolated variable");
+ }
+
+ if(!var.interface.empty())
+ {
+ if(iface_block && var.interface!=iface_block->interface)
+ error(var, format("Mismatched interface qualifier '%s' inside '%s' block", var.interface, iface_block->interface));
+ else if(scope==STRUCT || scope==FUNCTION)
+ error(var, format("Interface qualifier not allowed on %s", descr));
+ }
+
+ TypeDeclaration *type = var.type_declaration;
+ while(BasicTypeDeclaration *basic = dynamic_cast<BasicTypeDeclaration *>(type))
+ type = basic->base_type;
+ if(dynamic_cast<ImageTypeDeclaration *>(type))
+ {
+ if(scope!=GLOBAL && scope!=FUNCTION_PARAM)
+ error(var, format("Type '%s' not allowed on %s", type->name, descr));
+ else if(scope==GLOBAL && var.interface!="uniform")
+ error(var, format("Type '%s' only allowed with uniform interface", type->name));
+ }
+
+ if(var.init_expression)
+ {
+ if(scope==GLOBAL && !var.constant)
+ error(var, format("Initializer not allowed on non-constant %s", descr));
+ else if(scope!=GLOBAL && scope!=FUNCTION)
+ error(var, format("Initializer not allowed on %s", descr));
+ else
+ var.init_expression->visit(*this);
+ }
+}
+
+void DeclarationValidator::visit(InterfaceBlock &iface)
+{
+ SetForScope<ScopeType> set_scope(scope, INTERFACE_BLOCK);
+ SetForScope<InterfaceBlock *> set_iface(iface_block, &iface);
+
+ if(stage->type==Stage::VERTEX && iface.interface=="in")
+ error(iface, "Interface block not allowed on vertex shader input");
+ else if(stage->type==Stage::FRAGMENT && iface.interface=="out")
+ error(iface, "Interface block not allowed on fragment shader output");
+
+ TraversingVisitor::visit(iface);
+ if(iface.struct_declaration)
+ iface.struct_declaration->visit(*this);