Simple handling of coroutines

This commit is contained in:
Daniel Marjamäki 2021-04-18 19:42:22 +02:00
parent fe87afb2f9
commit 56773b82c4
3 changed files with 52 additions and 0 deletions

View File

@ -4811,6 +4811,9 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
// convert C++17 style nested namespaces to old style namespaces
simplifyNestedNamespace();
// convert c++20 coroutines
simplifyCoroutines();
// simplify namespace aliases
simplifyNamespaceAliases();
@ -12340,6 +12343,29 @@ void Tokenizer::simplifyNestedNamespace()
}
}
void Tokenizer::simplifyCoroutines()
{
if (!isCPP() || mSettings->standards.cpp < Standards::CPP20)
return;
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (!tok->isName() || !Token::Match(tok, "co_return|co_yield|co_await"))
continue;
Token *end = tok->next();
while (end && end->str() != ";") {
if (Token::Match(end, "[({[]"))
end = end->link();
else if (Token::Match(end, "[)]}]"))
break;
end = end->next();
}
if (Token::simpleMatch(end, ";")) {
tok->insertToken("(");
end->previous()->insertToken(")");
Token::createMutualLinks(tok->next(), end->previous());
}
}
}
static bool sameTokens(const Token *first, const Token *last, const Token *other)
{
while (other && first->str() == other->str()) {

View File

@ -785,6 +785,13 @@ private:
*/
void simplifyNestedNamespace();
/**
* Simplify coroutines - just put parentheses around arguments for
* co_* keywords so they can be handled like function calls in data
* flow.
*/
void simplifyCoroutines();
/**
* Prepare ternary operators with parentheses so that the AST can be created
* */

View File

@ -416,6 +416,8 @@ private:
TEST_CASE(removeExtraTemplateKeywords);
TEST_CASE(removeAlignas);
TEST_CASE(simplifyCoroutines);
}
std::string tokenizeAndStringify(const char code[], bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) {
@ -6507,6 +6509,23 @@ private:
const char expected[] = "unsigned char c [ sizeof ( float ) ] ;";
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
}
void simplifyCoroutines() {
Settings settings;
settings.standards.cpp = Standards::CPP20;
const char code1[] = "generator<int> f() { co_yield start++; }";
const char expected1[] = "generator < int > f ( ) { co_yield ( start ++ ) ; }";
ASSERT_EQUALS(expected1, tokenizeAndStringify(code1, settings));
const char code2[] = "task<> f() { co_await foo(); }";
const char expected2[] = "task < > f ( ) { co_await ( foo ( ) ) ; }";
ASSERT_EQUALS(expected2, tokenizeAndStringify(code2, settings));
const char code3[] = "generator<int> f() { co_return 7; }";
const char expected3[] = "generator < int > f ( ) { co_return ( 7 ) ; }";
ASSERT_EQUALS(expected3, tokenizeAndStringify(code3, settings));
}
};
REGISTER_TEST(TestTokenizer)