Refactoring, reuse code to skip lambda functions
This commit is contained in:
parent
9d41b272a1
commit
59034e17f1
|
@ -487,3 +487,22 @@ std::vector<const Token *> getArguments(const Token *ftok)
|
||||||
getArgumentsRecursive(ftok->next()->astOperand2(), &arguments);
|
getArgumentsRecursive(ftok->next()->astOperand2(), &arguments);
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Token *findLambdaEndToken(const Token *first)
|
||||||
|
{
|
||||||
|
if (!first || first->str() != "[")
|
||||||
|
return nullptr;
|
||||||
|
const Token* tok = first->link();
|
||||||
|
if (Token::simpleMatch(tok, "] {"))
|
||||||
|
return tok->linkAt(1);
|
||||||
|
if (!Token::simpleMatch(tok, "] ("))
|
||||||
|
return nullptr;
|
||||||
|
tok = tok->linkAt(1)->next();
|
||||||
|
if (tok && tok->str() == "constexpr")
|
||||||
|
tok = tok->next();
|
||||||
|
if (tok && tok->str() == "mutable")
|
||||||
|
tok = tok->next();
|
||||||
|
if (tok && tok->str() == "{")
|
||||||
|
return tok->link();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
|
@ -98,4 +98,12 @@ int numberOfArguments(const Token *start);
|
||||||
*/
|
*/
|
||||||
std::vector<const Token *> getArguments(const Token *ftok);
|
std::vector<const Token *> getArguments(const Token *ftok);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find lambda function end token
|
||||||
|
* \todo handle explicit return type
|
||||||
|
* \param first The [ token
|
||||||
|
* \return nullptr or the }
|
||||||
|
*/
|
||||||
|
const Token *findLambdaEndToken(const Token *first);
|
||||||
|
|
||||||
#endif // astutilsH
|
#endif // astutilsH
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "checkautovariables.h"
|
#include "checkautovariables.h"
|
||||||
|
|
||||||
|
#include "astutils.h"
|
||||||
#include "errorlogger.h"
|
#include "errorlogger.h"
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
@ -438,33 +439,6 @@ static bool astHasAutoResult(const Token *tok)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* Skip over a lambda expression
|
|
||||||
* \return next token - or next token beyond lambda
|
|
||||||
* \todo handle explicit return type
|
|
||||||
*/
|
|
||||||
static const Token* skipLambda(const Token* first)
|
|
||||||
{
|
|
||||||
if (!first)
|
|
||||||
return nullptr;
|
|
||||||
if (first->str() != "[")
|
|
||||||
return first;
|
|
||||||
const Token* tok = first->link()->next();
|
|
||||||
if (!tok)
|
|
||||||
return nullptr;
|
|
||||||
if (tok->str() == "(") {
|
|
||||||
tok = tok->link()->next();
|
|
||||||
}
|
|
||||||
if (tok->str() == "constexpr")
|
|
||||||
tok = tok->next();
|
|
||||||
if (tok->str() == "mutable")
|
|
||||||
tok = tok->next();
|
|
||||||
if (tok->str() == "{") {
|
|
||||||
tok = tok->link()->next();
|
|
||||||
}
|
|
||||||
return tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckAutoVariables::returnReference()
|
void CheckAutoVariables::returnReference()
|
||||||
{
|
{
|
||||||
if (_tokenizer->isC())
|
if (_tokenizer->isC())
|
||||||
|
@ -489,9 +463,9 @@ void CheckAutoVariables::returnReference()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip over lambdas
|
// Skip over lambdas
|
||||||
tok2 = skipLambda(tok2);
|
const Token *lambdaEndToken = findLambdaEndToken(tok2);
|
||||||
if (!tok2)
|
if (lambdaEndToken)
|
||||||
break;
|
tok2 = lambdaEndToken->next();
|
||||||
|
|
||||||
if (tok2->str() == "(")
|
if (tok2->str() == "(")
|
||||||
tok2 = tok2->link();
|
tok2 = tok2->link();
|
||||||
|
|
|
@ -1348,14 +1348,15 @@ static bool valueFlowForward(Token * const startToken,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// jump over lambda function
|
// skip lambda functions
|
||||||
if (Token::simpleMatch(tok2, "= [") && Token::simpleMatch(tok2->linkAt(1), "] (") && Token::simpleMatch(tok2->linkAt(1)->linkAt(1), ") {")) {
|
|
||||||
// TODO: handle lambda functions
|
// TODO: handle lambda functions
|
||||||
tok2 = tok2->linkAt(1); // Goto ]
|
if (Token::simpleMatch(tok2, "= [")) {
|
||||||
tok2 = tok2->linkAt(1); // Goto )
|
Token *lambdaEndToken = const_cast<Token *>(findLambdaEndToken(tok2->next()));
|
||||||
tok2 = tok2->linkAt(1); // Goto }
|
if (lambdaEndToken) {
|
||||||
|
tok2 = lambdaEndToken;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Token::Match(tok2, "[;{}] %name% :") || tok2->str() == "case") {
|
if (Token::Match(tok2, "[;{}] %name% :") || tok2->str() == "case") {
|
||||||
for (std::list<ValueFlow::Value>::iterator it = values.begin(); it != values.end(); ++it)
|
for (std::list<ValueFlow::Value>::iterator it = values.begin(); it != values.end(); ++it)
|
||||||
|
|
Loading…
Reference in New Issue