Tokenizer: Support C++20 default bit-field member initializer

This commit is contained in:
Daniel Marjamäki 2022-02-12 12:19:08 +01:00
parent 06d10b7474
commit 30cec97cc8
2 changed files with 17 additions and 4 deletions

View File

@ -10290,8 +10290,10 @@ void Tokenizer::findGarbageCode() const
unknownMacroError(tok); unknownMacroError(tok);
// Assign/increment/decrement literal // Assign/increment/decrement literal
else if (Token::Match(tok, "!!) %num%|%str%|%char% %assign%|++|--")) else if (Token::Match(tok, "!!) %num%|%str%|%char% %assign%|++|--")) {
syntaxError(tok, tok->next()->str() + " " + tok->strAt(2)); if (!isCPP() || mSettings->standards.cpp < Standards::CPP20 || !Token::Match(tok->previous(), "%name% : %num% ="))
syntaxError(tok, tok->next()->str() + " " + tok->strAt(2));
}
if (tok->isControlFlowKeyword() && Token::Match(tok, "if|while|for|switch")) { // if|while|for|switch (EXPR) { ... } if (tok->isControlFlowKeyword() && Token::Match(tok, "if|while|for|switch")) { // if|while|for|switch (EXPR) { ... }
if (tok->previous() && !Token::Match(tok->previous(), "%name%|:|;|{|}|)")) { if (tok->previous() && !Token::Match(tok->previous(), "%name%|:|;|{|}|)")) {
@ -11566,12 +11568,12 @@ void Tokenizer::simplifyBitfields()
!Token::Match(tok->next(), "case|public|protected|private|class|struct") && !Token::Match(tok->next(), "case|public|protected|private|class|struct") &&
!Token::simpleMatch(tok->tokAt(2), "default :")) { !Token::simpleMatch(tok->tokAt(2), "default :")) {
Token *tok1 = (tok->next()->str() == "const") ? tok->tokAt(3) : tok->tokAt(2); Token *tok1 = (tok->next()->str() == "const") ? tok->tokAt(3) : tok->tokAt(2);
if (Token::Match(tok1, "%name% : %num% ;")) if (Token::Match(tok1, "%name% : %num% [;=]"))
tok1->setBits(MathLib::toLongNumber(tok1->strAt(2))); tok1->setBits(MathLib::toLongNumber(tok1->strAt(2)));
if (tok1 && tok1->tokAt(2) && if (tok1 && tok1->tokAt(2) &&
(Token::Match(tok1->tokAt(2), "%bool%|%num%") || (Token::Match(tok1->tokAt(2), "%bool%|%num%") ||
!Token::Match(tok1->tokAt(2), "public|protected|private| %type% ::|<|,|{|;"))) { !Token::Match(tok1->tokAt(2), "public|protected|private| %type% ::|<|,|{|;"))) {
while (tok1->next() && !Token::Match(tok1->next(), "[;,)]{}]")) { while (tok1->next() && !Token::Match(tok1->next(), "[;,)]{}=]")) {
if (Token::Match(tok1->next(), "[([]")) if (Token::Match(tok1->next(), "[([]"))
Token::eraseTokens(tok1, tok1->next()->link()); Token::eraseTokens(tok1, tok1->next()->link());
tok1->deleteNext(); tok1->deleteNext();

View File

@ -448,6 +448,8 @@ private:
TEST_CASE(simplifyIfSwitchForInit3); TEST_CASE(simplifyIfSwitchForInit3);
TEST_CASE(simplifyIfSwitchForInit4); TEST_CASE(simplifyIfSwitchForInit4);
TEST_CASE(simplifyIfSwitchForInit5); TEST_CASE(simplifyIfSwitchForInit5);
TEST_CASE(cpp20_default_bitfield_initializer);
} }
#define tokenizeAndStringify(...) tokenizeAndStringify_(__FILE__, __LINE__, __VA_ARGS__) #define tokenizeAndStringify(...) tokenizeAndStringify_(__FILE__, __LINE__, __VA_ARGS__)
@ -7213,6 +7215,15 @@ private:
const char code[] = "void f() { if ([] { ; }) {} }"; const char code[] = "void f() { if ([] { ; }) {} }";
ASSERT_EQUALS("void f ( ) { if ( [ ] { ; } ) { } }", tokenizeAndStringify(code, settings)); ASSERT_EQUALS("void f ( ) { if ( [ ] { ; } ) { } }", tokenizeAndStringify(code, settings));
} }
void cpp20_default_bitfield_initializer() {
Settings settings;
const char code[] = "struct S { int a:2 = 0; };";
settings.standards.cpp = Standards::CPP20;
ASSERT_EQUALS("struct S { int a ; a = 0 ; } ;", tokenizeAndStringify(code, settings));
settings.standards.cpp = Standards::CPP17;
ASSERT_THROW(tokenizeAndStringify(code, settings), InternalError);
}
}; };
REGISTER_TEST(TestTokenizer) REGISTER_TEST(TestTokenizer)