Remove usage of std::vector and getArguments from getTokenArgumentFunction (#3435)

getTokenArgumentFunction can be called many many times, and the vector
is not needed, but it can become quite costly.
This patch replaces getArguments with a function simply returning the
position of the token, if it is found in the arguments (thus saving the
cost of std::vector).
This commit is contained in:
Ken-Patrick Lehrmann 2021-09-01 10:51:44 +02:00 committed by GitHub
parent 34efa89e23
commit 4296859c1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 44 additions and 4 deletions

View File

@ -101,6 +101,49 @@ const Token* findExpression(const nonneg int exprid,
return nullptr;
}
static int findArgumentPosRecursive(const Token* tok, const Token* tokToFind, bool &found, nonneg int depth=0)
{
++depth;
if (!tok || depth >= 100)
return -1;
if (tok->str() == ",") {
int res = findArgumentPosRecursive(tok->astOperand1(), tokToFind, found, depth);
if (res == -1)
return -1;
if (found)
return res;
int argn = res;
res = findArgumentPosRecursive(tok->astOperand2(), tokToFind, found, depth);
if (res == -1)
return -1;
return argn + res;
} else {
if (tokToFind == tok)
found = true;
return 1;
}
}
static int findArgumentPos(const Token* tok, const Token* tokToFind){
bool found = false;
int argn = findArgumentPosRecursive(tok, tokToFind, found, 0);
if (found)
return argn - 1;
return -1;
}
static int getArgumentPos(const Token* ftok, const Token* tokToFind){
const Token* tok = ftok;
if (Token::Match(tok, "%name% (|{"))
tok = ftok->next();
if (!Token::Match(tok, "(|{|["))
return -1;
const Token* startTok = tok->astOperand2();
if (!startTok && tok->next() != tok->link())
startTok = tok->astOperand1();
return findArgumentPos(startTok, tokToFind);
}
static void astFlattenRecursive(const Token *tok, std::vector<const Token *> *result, const char* op, nonneg int depth = 0)
{
++depth;
@ -1747,10 +1790,7 @@ const Token * getTokenArgumentFunction(const Token * tok, int& argn)
if (Token::Match(tok, "(|{"))
break;
}
std::vector<const Token*> args = getArguments(tok);
auto it = std::find(args.begin(), args.end(), argtok);
if (it != args.end())
argn = std::distance(args.begin(), it);
argn = getArgumentPos(tok, argtok);
if (argn == -1)
return nullptr;
if (!Token::Match(tok, "{|("))