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);
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);
/**
* 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

View File

@ -22,6 +22,7 @@
#include "checkautovariables.h"
#include "astutils.h"
#include "errorlogger.h"
#include "library.h"
#include "settings.h"
@ -438,33 +439,6 @@ static bool astHasAutoResult(const Token *tok)
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()
{
if (_tokenizer->isC())
@ -489,9 +463,9 @@ void CheckAutoVariables::returnReference()
}
// Skip over lambdas
tok2 = skipLambda(tok2);
if (!tok2)
break;
const Token *lambdaEndToken = findLambdaEndToken(tok2);
if (lambdaEndToken)
tok2 = lambdaEndToken->next();
if (tok2->str() == "(")
tok2 = tok2->link();

View File

@ -1348,13 +1348,14 @@ static bool valueFlowForward(Token * const startToken,
}
}
// jump over lambda function
if (Token::simpleMatch(tok2, "= [") && Token::simpleMatch(tok2->linkAt(1), "] (") && Token::simpleMatch(tok2->linkAt(1)->linkAt(1), ") {")) {
// TODO: handle lambda functions
tok2 = tok2->linkAt(1); // Goto ]
tok2 = tok2->linkAt(1); // Goto )
tok2 = tok2->linkAt(1); // Goto }
continue;
// skip lambda functions
// TODO: handle lambda functions
if (Token::simpleMatch(tok2, "= [")) {
Token *lambdaEndToken = const_cast<Token *>(findLambdaEndToken(tok2->next()));
if (lambdaEndToken) {
tok2 = lambdaEndToken;
continue;
}
}
if (Token::Match(tok2, "[;{}] %name% :") || tok2->str() == "case") {