Fixed #3732 - properly simplify struct declarations:

- Don't replace "{ {" if they are part of an initialization
- Properly split struct definition, variable declaration and variable initialization.

Used std::stack instead of std::list
This commit is contained in:
PKEuS 2012-09-08 10:51:31 +02:00
parent a39b58046f
commit 78d49ea4b8
2 changed files with 22 additions and 10 deletions

View File

@ -2250,7 +2250,9 @@ void Tokenizer::simplifyRedundantConsecutiveBraces()
{ {
// Remove redundant consecutive braces, i.e. '.. { { .. } } ..' -> '.. { .. } ..'. // Remove redundant consecutive braces, i.e. '.. { { .. } } ..' -> '.. { .. } ..'.
for (Token *tok = list.front(); tok;) { for (Token *tok = list.front(); tok;) {
if (Token::simpleMatch(tok, "{ {") && Token::simpleMatch(tok->next()->link(), "} }")) { if (Token::simpleMatch(tok, "= {")) {
tok = tok->linkAt(1);
} else if (Token::simpleMatch(tok, "{ {") && Token::simpleMatch(tok->next()->link(), "} }")) {
//remove internal parentheses //remove internal parentheses
tok->next()->link()->deleteThis(); tok->next()->link()->deleteThis();
tok->deleteNext(); tok->deleteNext();
@ -8254,19 +8256,19 @@ void Tokenizer::simplifyStructDecl()
unsigned int count = 0; unsigned int count = 0;
// Skip simplification of unions in class definition // Skip simplification of unions in class definition
std::list<bool> skip; // true = in function, false = not in function std::stack<bool> skip; // true = in function, false = not in function
skip.push_back(false); skip.push(false);
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
Token *restart; Token *restart;
// check for start of scope and determine if it is in a function // check for start of scope and determine if it is in a function
if (tok->str() == "{") if (tok->str() == "{")
skip.push_back(Token::Match(tok->previous(), "const|)")); skip.push(Token::Match(tok->previous(), "const|)"));
// end of scope // end of scope
else if (tok->str() == "}" && !skip.empty()) else if (tok->str() == "}" && !skip.empty())
skip.pop_back(); skip.pop();
// check for named struct/union // check for named struct/union
else if (Token::Match(tok, "class|struct|union %type% :|{")) { else if (Token::Match(tok, "class|struct|union %type% :|{")) {
@ -8278,12 +8280,12 @@ void Tokenizer::simplifyStructDecl()
next = next->next(); next = next->next();
if (!next) if (!next)
continue; continue;
skip.push_back(false); skip.push(false);
tok = next->link(); tok = next->link();
restart = next; restart = next;
// check for named type // check for named type
if (Token::Match(tok->next(), "*|&| %type% ,|;|[")) { if (Token::Match(tok->next(), "*|&| %type% ,|;|[|=")) {
tok->insertToken(";"); tok->insertToken(";");
tok = tok->next(); tok = tok->next();
if (isStatic) { if (isStatic) {
@ -8299,8 +8301,8 @@ void Tokenizer::simplifyStructDecl()
// check for anonymous struct/union // check for anonymous struct/union
else if (Token::Match(tok, "struct|union {")) { else if (Token::Match(tok, "struct|union {")) {
bool inFunction = skip.back(); bool inFunction = skip.top();
skip.push_back(false); skip.push(false);
Token *tok1 = tok; Token *tok1 = tok;
restart = tok->next(); restart = tok->next();
@ -8351,7 +8353,7 @@ void Tokenizer::simplifyStructDecl()
// don't remove unnamed anonymous unions from a class, struct or union // don't remove unnamed anonymous unions from a class, struct or union
if (!(tok1->str() == "union" && !inFunction)) { if (!(tok1->str() == "union" && !inFunction)) {
skip.pop_back(); skip.pop();
tok1->deleteThis(); tok1->deleteThis();
if (tok1->next() == tok) { if (tok1->next() == tok) {
tok1->deleteThis(); tok1->deleteThis();

View File

@ -380,6 +380,7 @@ private:
TEST_CASE(simplifyStructDecl3); TEST_CASE(simplifyStructDecl3);
TEST_CASE(simplifyStructDecl4); TEST_CASE(simplifyStructDecl4);
TEST_CASE(simplifyStructDecl5); // ticket #3533 (segmentation fault) TEST_CASE(simplifyStructDecl5); // ticket #3533 (segmentation fault)
TEST_CASE(simplifyStructDecl6); // ticket #3732
// register int var; => int var; // register int var; => int var;
// inline int foo() {} => int foo() {} // inline int foo() {} => int foo() {}
@ -7568,6 +7569,15 @@ private:
tok(code, false); tok(code, false);
} }
void simplifyStructDecl6() {
ASSERT_EQUALS("struct A { "
"char integers [ X ] ; "
"} ; A arrays ; arrays = { { 0 } } ;",
tok("struct A {\n"
" char integers[X];\n"
"} arrays = {{0}};", false));
}
void removeUnwantedKeywords() { void removeUnwantedKeywords() {
ASSERT_EQUALS("int var ;", tok("register int var ;", true)); ASSERT_EQUALS("int var ;", tok("register int var ;", true));
ASSERT_EQUALS("short var ;", tok("register short int var ;", true)); ASSERT_EQUALS("short var ;", tok("register short int var ;", true));