+void ReferenceValidator::visit(FunctionCall &call)
+{
+ if((!call.constructor && !call.declaration) || (call.constructor && !call.type))
+ {
+ bool have_declaration = call.constructor;
+ if(!call.constructor)
+ {
+ map<string, FunctionDeclaration *>::iterator i = stage->functions.lower_bound(call.name);
+ have_declaration = (i!=stage->functions.end() && i->second->name==call.name);
+ }
+
+ if(have_declaration)
+ {
+ bool valid_types = true;
+ string signature;
+ for(NodeArray<Expression>::const_iterator j=call.arguments.begin(); (valid_types && j!=call.arguments.end()); ++j)
+ {
+ if((*j)->type)
+ append(signature, ", ", (*j)->type->name);
+ else
+ valid_types = false;
+ }
+
+ if(valid_types)
+ error(call, format("No matching %s found for '%s(%s)'", (call.constructor ? "constructor" : "overload"), call.name, signature));
+ }
+ else
+ error(call, format("Call to undeclared function '%s'", call.name));
+ }
+ TraversingVisitor::visit(call);
+}
+