| 5999 | } |
| 6000 | |
| 6001 | const Function* Scope::findFunction(const Token *tok, bool requireConst, Reference ref) const |
| 6002 | { |
| 6003 | const bool isCall = Token::Match(tok->next(), "(|{"); |
| 6004 | |
| 6005 | const std::vector<const Token *> arguments = getArguments(tok); |
| 6006 | |
| 6007 | std::vector<const Function *> matches; |
| 6008 | |
| 6009 | // find all the possible functions that could match |
| 6010 | const std::size_t args = arguments.size(); |
| 6011 | |
| 6012 | auto addMatchingFunctions = [&](const Scope *scope) { |
| 6013 | auto range = scope->functionMap.equal_range(tok->str()); |
| 6014 | for (auto it = range.first; it != range.second; ++it) { |
| 6015 | const Function *func = it->second; |
| 6016 | if (ref == Reference::LValue && func->hasRvalRefQualifier()) |
| 6017 | continue; |
| 6018 | if (ref == Reference::None && func->hasRvalRefQualifier()) { |
| 6019 | if (Token::simpleMatch(tok->astParent(), ".")) { |
| 6020 | const Token* obj = tok->astParent()->astOperand1(); |
| 6021 | while (obj && obj->str() == "[") |
| 6022 | obj = obj->astOperand1(); |
| 6023 | if (!obj || obj->isName()) |
| 6024 | continue; |
| 6025 | } |
| 6026 | } |
| 6027 | if (func->isDestructor() && !Token::simpleMatch(tok->tokAt(-1), "~")) |
| 6028 | continue; |
| 6029 | if (!isCall || args == func->argCount() || |
| 6030 | (func->isVariadic() && args >= (func->minArgCount() - 1)) || |
| 6031 | (args < func->argCount() && args >= func->minArgCount())) { |
| 6032 | matches.push_back(func); |
| 6033 | } |
| 6034 | } |
| 6035 | }; |
| 6036 | |
| 6037 | addMatchingFunctions(this); |
| 6038 | |
| 6039 | // check in anonymous namespaces |
| 6040 | for (const Scope *nestedScope : nestedList) { |
| 6041 | if (nestedScope->type == ScopeType::eNamespace && nestedScope->className.empty()) |
| 6042 | addMatchingFunctions(nestedScope); |
| 6043 | } |
| 6044 | |
| 6045 | const std::size_t numberOfMatchesNonBase = matches.size(); |
| 6046 | |
| 6047 | // check in base classes |
| 6048 | findFunctionInBase(tok, args, matches); |
| 6049 | |
| 6050 | // Non-call => Do not match parameters |
| 6051 | if (!isCall) { |
| 6052 | return matches.empty() ? nullptr : matches[0]; |
| 6053 | } |
| 6054 | |
| 6055 | // store function and number of matching arguments |
| 6056 | std::vector<std::pair<const Function*, size_t>> fallback1Func, fallback2Func; |
| 6057 | |
| 6058 | // check each function against the arguments in the function call for a match |