Refactoring, reuse code to skip lambda functions

This commit is contained in:
Daniel Marjamäki 2017-08-29 22:35:55 +02:00
parent 9d41b272a1
commit 59034e17f1
4 changed files with 39 additions and 37 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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();

View File

@ -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)