Skip to content

Commit cf7f74d

Browse files
authored
refs #11342 - Library: avoid redundant lookups in getarg() (#6791)
1 parent e2efe8e commit cf7f74d

3 files changed

Lines changed: 29 additions & 18 deletions

File tree

lib/library.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,16 +1249,14 @@ int Library::getReallocId(const Token *tok, int arg) const
12491249

12501250
const Library::ArgumentChecks * Library::getarg(const Token *ftok, int argnr) const
12511251
{
1252-
if (isNotLibraryFunction(ftok))
1252+
const Function* func = nullptr;
1253+
if (isNotLibraryFunction(ftok, &func))
12531254
return nullptr;
1254-
const std::unordered_map<std::string, Function>::const_iterator it1 = mData->mFunctions.find(getFunctionName(ftok));
1255-
if (it1 == mData->mFunctions.cend())
1256-
return nullptr;
1257-
const std::map<int,ArgumentChecks>::const_iterator it2 = it1->second.argumentChecks.find(argnr);
1258-
if (it2 != it1->second.argumentChecks.cend())
1255+
const std::map<int,ArgumentChecks>::const_iterator it2 = func->argumentChecks.find(argnr);
1256+
if (it2 != func->argumentChecks.cend())
12591257
return &it2->second;
1260-
const std::map<int,ArgumentChecks>::const_iterator it3 = it1->second.argumentChecks.find(-1);
1261-
if (it3 != it1->second.argumentChecks.cend())
1258+
const std::map<int,ArgumentChecks>::const_iterator it3 = func->argumentChecks.find(-1);
1259+
if (it3 != func->argumentChecks.cend())
12621260
return &it3->second;
12631261
return nullptr;
12641262
}
@@ -1414,7 +1412,7 @@ Library::Container::Yield Library::getContainerYield(const Token* const cond)
14141412
}
14151413

14161414
// returns true if ftok is not a library function
1417-
bool Library::isNotLibraryFunction(const Token *ftok) const
1415+
bool Library::isNotLibraryFunction(const Token *ftok, const Function **func) const
14181416
{
14191417
if (ftok->isKeyword() || ftok->isStandardType())
14201418
return true;
@@ -1426,10 +1424,10 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
14261424
if (ftok->varId())
14271425
return true;
14281426

1429-
return !matchArguments(ftok, getFunctionName(ftok));
1427+
return !matchArguments(ftok, getFunctionName(ftok), func);
14301428
}
14311429

1432-
bool Library::matchArguments(const Token *ftok, const std::string &functionName) const
1430+
bool Library::matchArguments(const Token *ftok, const std::string &functionName, const Function **func) const
14331431
{
14341432
if (functionName.empty())
14351433
return false;
@@ -1444,10 +1442,17 @@ bool Library::matchArguments(const Token *ftok, const std::string &functionName)
14441442
if (argCheck.second.optional && (firstOptionalArg == -1 || firstOptionalArg > argCheck.first))
14451443
firstOptionalArg = argCheck.first;
14461444

1447-
if (argCheck.second.formatstr || argCheck.second.variadic)
1448-
return args <= callargs;
1445+
if (argCheck.second.formatstr || argCheck.second.variadic) {
1446+
const bool b = args <= callargs;
1447+
if (b && func)
1448+
*func = &it->second;
1449+
return b;
1450+
}
14491451
}
1450-
return (firstOptionalArg < 0) ? args == callargs : (callargs >= firstOptionalArg-1 && callargs <= args);
1452+
const bool b = (firstOptionalArg < 0) ? args == callargs : (callargs >= firstOptionalArg-1 && callargs <= args);
1453+
if (b && func)
1454+
*func = &it->second;
1455+
return b;
14511456
}
14521457

14531458
const std::map<std::string, Library::WarnInfo>& Library::functionwarn() const

lib/library.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,11 @@ class CPPCHECKLIB Library {
163163

164164
const WarnInfo* getWarnInfo(const Token* ftok) const;
165165

166+
struct Function;
167+
166168
// returns true if ftok is not a library function
167-
bool isNotLibraryFunction(const Token *ftok) const;
168-
bool matchArguments(const Token *ftok, const std::string &functionName) const;
169+
bool isNotLibraryFunction(const Token *ftok, const Function **func = nullptr) const;
170+
bool matchArguments(const Token *ftok, const std::string &functionName, const Function **func = nullptr) const;
169171

170172
enum class UseRetValType : std::uint8_t { NONE, DEFAULT, ERROR_CODE };
171173
UseRetValType getUseRetValType(const Token* ftok) const;

test/testlibrary.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,9 @@ class TestLibrary : public TestFixture {
191191
Token::createMutualLinks(tokenList.front()->next(), tokenList.back()->previous());
192192
tokenList.createAst();
193193

194-
ASSERT(!library.isNotLibraryFunction(tokenList.front()));
194+
const Library::Function* func = nullptr;
195+
ASSERT(!library.isNotLibraryFunction(tokenList.front(), &func));
196+
ASSERT(func);
195197
}
196198
{
197199
TokenList tokenList(&settings);
@@ -200,7 +202,9 @@ class TestLibrary : public TestFixture {
200202
Token::createMutualLinks(tokenList.front()->next(), tokenList.back()->previous());
201203
tokenList.createAst();
202204

203-
ASSERT(!library.isNotLibraryFunction(tokenList.front()));
205+
const Library::Function* func = nullptr;
206+
ASSERT(!library.isNotLibraryFunction(tokenList.front(), &func));
207+
ASSERT(func);
204208
}
205209
{
206210
TokenList tokenList(&settings);

0 commit comments

Comments
 (0)