X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fvalidate.cpp;h=6f0869ea141897813c4e4f3190a81082457ceed1;hb=9bec9da4ec633a541cf6048beed99629fefae2b9;hp=5fd4ebcae76a8d050285fcb17c48336dbfce315b;hpb=d72d8a9163e342167f35360c807ee9ea5ebacdc2;p=libs%2Fgl.git diff --git a/source/glsl/validate.cpp b/source/glsl/validate.cpp index 5fd4ebca..6f0869ea 100644 --- a/source/glsl/validate.cpp +++ b/source/glsl/validate.cpp @@ -12,15 +12,12 @@ Validator::Validator(): stage(0) { } -void Validator::diagnose(Statement *statement, Diagnostic::Severity severity, const string &message) +void Validator::diagnose(Node &node, Diagnostic::Severity severity, const string &message) { Diagnostic diag; diag.severity = severity; - if(statement) - { - diag.source = statement->source; - diag.line = statement->line; - } + diag.source = node.source; + diag.line = node.line; diag.message = message; stage->diagnostics.push_back(diag); } @@ -32,8 +29,8 @@ DeclarationValidator::DeclarationValidator(): void DeclarationValidator::multiple_definition(const string &name, Statement &statement, Statement &previous) { - error(&statement, format("Multiple definition of %s", name)); - diagnose(&previous, Diagnostic::INFO, "Previous definition is here"); + error(statement, format("Multiple definition of %s", name)); + diagnose(previous, Diagnostic::INFO, "Previous definition is here"); } Statement *DeclarationValidator::find_definition(const string &name) @@ -63,6 +60,17 @@ void DeclarationValidator::record_definition(const string &name, Statement &stat declarations[current_block->parent].insert(make_pair(name, &statement)); } +void DeclarationValidator::visit(TypeDeclaration &type) +{ + check_definition(type.name, type); +} + +void DeclarationValidator::visit(StructDeclaration &strct) +{ + check_definition(strct.name, strct); + TraversingVisitor::visit(strct); +} + void DeclarationValidator::visit(VariableDeclaration &var) { check_definition(var.name, var); @@ -95,11 +103,41 @@ void DeclarationValidator::visit(InterfaceBlock &iface) void DeclarationValidator::visit(FunctionDeclaration &func) { + if(Statement *previous = find_definition(func.name)) + if(!dynamic_cast(previous)) + multiple_definition(format("'%s'", func.name), func, *previous); + if(func.definition==&func) check_definition(func.name, func); TraversingVisitor::visit(func); } + +void ReferenceValidator::visit(VariableReference &var) +{ + if(!var.declaration) + error(var, format("Use of undeclared variable '%s'", var.name)); + else if(stage->type!=Stage::VERTEX && var.declaration->interface=="in" && !var.declaration->linked_declaration) + error(var, format("Use of unlinked input variable '%s'", var.name)); +} + +void ReferenceValidator::visit(InterfaceBlockReference &iface) +{ + /* An interface block reference without a declaration should be impossible + since references are generated based on existing declarations. */ + if(!iface.declaration) + error(iface, format("Use of undeclared interface block '%s'", iface.name)); + else if(stage->type!=Stage::VERTEX && iface.declaration->interface=="in" && !iface.declaration->linked_block) + error(iface, format("Use of unlinked input block '%s'", iface.name)); +} + +void ReferenceValidator::visit(VariableDeclaration &var) +{ + if(!var.type_declaration) + error(var, format("Use of undeclared type '%s'", var.type)); + TraversingVisitor::visit(var); +} + } // namespace SL } // namespace GL } // namespace Msp