findLambdaEndToken handle explicit type (#1458)
* findLambdaEndToken: Add tests * Add handling of explicit return in findLambdaEndToken() * Use AST in findLambdaEndToken() * Fix ast when lambda is mutable
This commit is contained in:
parent
fafd0742d4
commit
88008fedb1
|
@ -939,18 +939,12 @@ 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();
|
||||
const Token * tok = first;
|
||||
|
||||
if (tok->astOperand1() && tok->astOperand1()->str() == "(")
|
||||
tok = tok->astOperand1();
|
||||
if (tok->astOperand1() && tok->astOperand1()->str() == "{")
|
||||
return tok->astOperand1()->link();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,6 @@ 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 }
|
||||
*/
|
||||
|
|
|
@ -680,6 +680,8 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
|
|||
if (Token::simpleMatch(squareBracket->link(), "] (")) {
|
||||
Token* const roundBracket = squareBracket->link()->next();
|
||||
Token* curlyBracket = roundBracket->link()->next();
|
||||
if (curlyBracket && curlyBracket->str() == "mutable")
|
||||
curlyBracket = curlyBracket->next();
|
||||
if (curlyBracket && curlyBracket->originalName() == "->") {
|
||||
while (Token::Match(curlyBracket, "%name%|.|::|&|*"))
|
||||
curlyBracket = curlyBracket->next();
|
||||
|
|
|
@ -33,11 +33,44 @@ public:
|
|||
private:
|
||||
|
||||
void run() override {
|
||||
TEST_CASE(findLambdaEndToken);
|
||||
TEST_CASE(isReturnScope);
|
||||
TEST_CASE(isVariableChanged);
|
||||
TEST_CASE(isVariableChangedByFunctionCall);
|
||||
}
|
||||
|
||||
bool findLambdaEndToken(const char code[]) {
|
||||
Settings settings;
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
const Token * const tokEnd = ::findLambdaEndToken(tokenizer.tokens());
|
||||
return tokEnd && tokEnd->next() == nullptr;
|
||||
}
|
||||
|
||||
void findLambdaEndToken() {
|
||||
ASSERT(nullptr == ::findLambdaEndToken(nullptr));
|
||||
ASSERT_EQUALS(false, findLambdaEndToken("void f() { }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[]{ }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[]{ return 0 }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](){ }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[&](){ }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[&, i](){ }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](void) { return -1 }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) { return a + b }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) mutable { return a + b }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) constexpr { return a + b }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](void) -> int { return -1 }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](void) mutable -> int { return -1 }"));
|
||||
ASSERT_EQUALS(false, findLambdaEndToken("[](void) foo -> int { return -1 }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> int { return -1 }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> int* { return x }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const * int { return x }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](void) mutable -> const * int { return x }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const ** int { return x }"));
|
||||
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const * const* int { return x }"));
|
||||
}
|
||||
|
||||
bool isReturnScope(const char code[], int offset) {
|
||||
Settings settings;
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
|
|
|
@ -8551,6 +8551,8 @@ private:
|
|||
ASSERT_EQUALS("{([cd,(return 0return", testAst("return [](int a, int b) -> int { return 0; }(c, d);"));
|
||||
ASSERT_EQUALS("x{([=", testAst("x = [&]()->std::string const & {};"));
|
||||
ASSERT_EQUALS("f{([=", testAst("f = []() -> foo* {};"));
|
||||
ASSERT_EQUALS("f{([=", testAst("f = [](void) mutable -> foo* {};"));
|
||||
ASSERT_EQUALS("f{([=", testAst("f = []() mutable {};"));
|
||||
|
||||
ASSERT_EQUALS("x{([= 0return", testAst("x = [](){return 0; };"));
|
||||
|
||||
|
|
Loading…
Reference in New Issue