1 #include <msp/core/raii.h>
2 #include <msp/strings/format.h>
11 Validator::Validator():
15 void Validator::diagnose(Node &node, Diagnostic::Severity severity, const string &message)
18 diag.severity = severity;
19 diag.source = node.source;
20 diag.line = node.line;
21 diag.message = message;
22 stage->diagnostics.push_back(diag);
26 DeclarationValidator::DeclarationValidator():
27 anonymous_block(false)
30 void DeclarationValidator::multiple_definition(const string &name, Statement &statement, Statement &previous)
32 error(statement, format("Multiple definition of %s", name));
33 diagnose(previous, Diagnostic::INFO, "Previous definition is here");
36 Statement *DeclarationValidator::find_definition(const string &name)
38 BlockDeclarationMap *decls = &declarations[current_block];
39 BlockDeclarationMap::const_iterator i = decls->find(name);
40 if(i==decls->end() && anonymous_block)
42 decls = &declarations[current_block->parent];
43 i = decls->find(name);
45 return (i!=decls->end() ? i->second : 0);
48 void DeclarationValidator::check_definition(const string &name, Statement &statement)
50 if(Statement *previous = find_definition(name))
51 multiple_definition(format("'%s'", name), statement, *previous);
53 record_definition(name, statement);
56 void DeclarationValidator::record_definition(const string &name, Statement &statement)
58 declarations[current_block].insert(make_pair(name, &statement));
60 declarations[current_block->parent].insert(make_pair(name, &statement));
63 void DeclarationValidator::visit(TypeDeclaration &type)
65 check_definition(type.name, type);
68 void DeclarationValidator::visit(StructDeclaration &strct)
70 check_definition(strct.name, strct);
71 TraversingVisitor::visit(strct);
74 void DeclarationValidator::visit(VariableDeclaration &var)
76 check_definition(var.name, var);
77 TraversingVisitor::visit(var);
80 void DeclarationValidator::visit(InterfaceBlock &iface)
82 string key = iface.interface+iface.name;
83 map<string, InterfaceBlock *>::const_iterator i = interface_blocks.find(key);
84 if(i!=interface_blocks.end())
85 multiple_definition(format("interface block '%s %s'", iface.interface, iface.name), iface, *i->second);
87 interface_blocks.insert(make_pair(key, &iface));
89 if(Statement *previous = find_definition(iface.name))
91 if(!dynamic_cast<InterfaceBlock *>(previous))
92 multiple_definition(format("'%s'", iface.name), iface, *previous);
95 record_definition(iface.name, iface);
97 if(!iface.instance_name.empty())
98 check_definition(iface.instance_name, iface);
100 SetFlag set_anon(anonymous_block, iface.instance_name.empty());
101 TraversingVisitor::visit(iface);
104 void DeclarationValidator::visit(FunctionDeclaration &func)
106 if(Statement *previous = find_definition(func.name))
107 if(!dynamic_cast<FunctionDeclaration *>(previous))
108 multiple_definition(format("'%s'", func.name), func, *previous);
110 if(func.definition==&func)
111 check_definition(func.name, func);
112 TraversingVisitor::visit(func);
116 void ReferenceValidator::visit(VariableReference &var)
119 error(var, format("Use of undeclared variable '%s'", var.name));
120 else if(stage->type!=Stage::VERTEX && var.declaration->interface=="in" && !var.declaration->linked_declaration)
121 error(var, format("Use of unlinked input variable '%s'", var.name));
124 void ReferenceValidator::visit(InterfaceBlockReference &iface)
126 /* An interface block reference without a declaration should be impossible
127 since references are generated based on existing declarations. */
128 if(!iface.declaration)
129 error(iface, format("Use of undeclared interface block '%s'", iface.name));
130 else if(stage->type!=Stage::VERTEX && iface.declaration->interface=="in" && !iface.declaration->linked_block)
131 error(iface, format("Use of unlinked input block '%s'", iface.name));
134 void ReferenceValidator::visit(VariableDeclaration &var)
136 if(!var.type_declaration)
137 error(var, format("Use of undeclared type '%s'", var.type));
138 TraversingVisitor::visit(var);