| 360 | } |
| 361 | |
| 362 | bool reshadefx::symbol_table::resolve_function_call(const std::string &name, const std::vector<expression> &arguments, const scope &scope, symbol &out_data, bool &is_ambiguous) const |
| 363 | { |
| 364 | out_data.op = symbol_type::function; |
| 365 | |
| 366 | const function *result = nullptr; |
| 367 | unsigned int num_overloads = 0; |
| 368 | unsigned int overload_namespace = scope.namespace_level; |
| 369 | |
| 370 | // Look up function name in the symbol stack and loop through the associated symbols |
| 371 | const auto stack_it = _symbol_stack.find(name); |
| 372 | |
| 373 | if (stack_it != _symbol_stack.end() && !stack_it->second.empty()) |
| 374 | { |
| 375 | for (auto it = stack_it->second.rbegin(), end = stack_it->second.rend(); it != end; ++it) |
| 376 | { |
| 377 | if (it->op != symbol_type::function) |
| 378 | continue; |
| 379 | if (it->scope.level > scope.level || |
| 380 | it->scope.namespace_level > scope.namespace_level || (it->scope.namespace_level == scope.namespace_level && it->scope.name != scope.name)) |
| 381 | continue; |
| 382 | |
| 383 | const function *const function = it->function; |
| 384 | |
| 385 | if (function == nullptr) |
| 386 | continue; |
| 387 | |
| 388 | if (function->parameter_list.empty()) |
| 389 | { |
| 390 | if (arguments.empty()) |
| 391 | { |
| 392 | out_data.id = it->id; |
| 393 | out_data.type = function->return_type; |
| 394 | out_data.function = result = function; |
| 395 | num_overloads = 1; |
| 396 | break; |
| 397 | } |
| 398 | else |
| 399 | { |
| 400 | continue; |
| 401 | } |
| 402 | } |
| 403 | else if (arguments.size() > function->parameter_list.size() || (arguments.size() < function->parameter_list.size() && !function->parameter_list[arguments.size()].has_default_value)) |
| 404 | { |
| 405 | continue; |
| 406 | } |
| 407 | |
| 408 | // A new possibly-matching function was found, compare it against the current result |
| 409 | const int comparison = compare_functions(arguments, function, result); |
| 410 | |
| 411 | if (comparison < 0) // The new function is a better match |
| 412 | { |
| 413 | out_data.id = it->id; |
| 414 | out_data.type = function->return_type; |
| 415 | out_data.function = result = function; |
| 416 | num_overloads = 1; |
| 417 | overload_namespace = it->scope.namespace_level; |
| 418 | } |
| 419 | else if (comparison == 0 && overload_namespace == it->scope.namespace_level) // Both functions are equally viable, so the call is ambiguous |
nothing calls this directly
no test coverage detected