X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fvalidate.cpp;h=6d0f8e51ac2cb9a95ee94883f8a7449f0c97fa44;hb=4c805f55d89919d6971d600102ab4d6d65d56dc3;hp=6368c069244629217b32f04bb78987d3784f39b7;hpb=1f09306906fbf57c05dccb27189264706cc64cfa;p=libs%2Fgl.git diff --git a/source/glsl/validate.cpp b/source/glsl/validate.cpp index 6368c069..6d0f8e51 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); } @@ -30,6 +27,12 @@ DeclarationValidator::DeclarationValidator(): anonymous_block(false) { } +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"); +} + Statement *DeclarationValidator::find_definition(const string &name) { BlockDeclarationMap *decls = &declarations[current_block]; @@ -45,15 +48,27 @@ Statement *DeclarationValidator::find_definition(const string &name) void DeclarationValidator::check_definition(const string &name, Statement &statement) { if(Statement *previous = find_definition(name)) - { - error(&statement, format("Multiple definition of '%s'", name)); - diagnose(previous, Diagnostic::INFO, "Previous definition is here"); - return; - } + multiple_definition(format("'%s'", name), statement, *previous); + else + record_definition(name, statement); +} - declarations[current_block][name] = &statement; +void DeclarationValidator::record_definition(const string &name, Statement &statement) +{ + declarations[current_block].insert(make_pair(name, &statement)); if(anonymous_block) - declarations[current_block->parent][name] = &statement; + 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) @@ -64,15 +79,34 @@ void DeclarationValidator::visit(VariableDeclaration &var) void DeclarationValidator::visit(InterfaceBlock &iface) { - check_definition(iface.name, iface); + string key = iface.interface+iface.name; + map::const_iterator i = interface_blocks.find(key); + if(i!=interface_blocks.end()) + multiple_definition(format("interface block '%s %s'", iface.interface, iface.name), iface, *i->second); + else + interface_blocks.insert(make_pair(key, &iface)); + + if(Statement *previous = find_definition(iface.name)) + { + if(!dynamic_cast(previous)) + multiple_definition(format("'%s'", iface.name), iface, *previous); + } + else + record_definition(iface.name, iface); + if(!iface.instance_name.empty()) check_definition(iface.instance_name, iface); + SetFlag set_anon(anonymous_block, iface.instance_name.empty()); TraversingVisitor::visit(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);