add class A {} a; -> class A {}; A a; conversion capability to Tokenizer::simplifyStructDecl()

This commit is contained in:
Robert Reif 2011-07-02 09:21:30 -04:00
parent d447e61b09
commit 3f4cc5fa3a
2 changed files with 148 additions and 17 deletions

View File

@ -9323,22 +9323,23 @@ 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; std::list<bool> skip; // true = in function, false = not in function
skip.push_back(false); skip.push_back(false);
for (Token *tok = _tokens; tok; tok = tok->next()) for (Token *tok = _tokens; tok; tok = tok->next())
{ {
Token *restart; Token *restart;
// 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_back(Token::Match(tok->previous(), "const|)"));
// end of scope
else if (tok->str() == "}" && !skip.empty()) else if (tok->str() == "}" && !skip.empty())
skip.pop_back(); skip.pop_back();
else if (!skip.empty() && skip.back() && tok->str() == "union")
continue;
// check for named struct/union // check for named struct/union
if (Token::Match(tok, "struct|union %type% :|{")) else if (Token::Match(tok, "class|struct|union %type% :|{"))
{ {
Token *isStatic = tok->previous() && tok->previous()->str() == "static" ? tok->previous() : NULL; Token *isStatic = tok->previous() && tok->previous()->str() == "static" ? tok->previous() : NULL;
Token *type = tok->next(); Token *type = tok->next();
@ -9348,7 +9349,7 @@ void Tokenizer::simplifyStructDecl()
next = next->next(); next = next->next();
if (!next) if (!next)
continue; continue;
skip.push_back(false);
tok = next->link(); tok = next->link();
restart = next; restart = next;
@ -9372,6 +9373,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();
skip.push_back(false);
Token *tok1 = tok; Token *tok1 = tok;
restart = tok->next(); restart = tok->next();
@ -9391,10 +9394,10 @@ void Tokenizer::simplifyStructDecl()
tok->insertToken(name.c_str()); tok->insertToken(name.c_str());
} }
// unnamed anonymous struct/union so remove it // unnamed anonymous struct/union so possibly remove it
else if (tok->next() && tok->next()->str() == ";") else if (tok->next() && tok->next()->str() == ";")
{ {
if (tok1->str() == "union") if (tok1->str() == "union" && inFunction)
{ {
// Try to create references in the union.. // Try to create references in the union..
Token *tok2 = tok1->tokAt(2); Token *tok2 = tok1->tokAt(2);
@ -9428,18 +9431,22 @@ void Tokenizer::simplifyStructDecl()
} }
} }
tok1->deleteThis(); // don't remove unnamed anonymous unions from a class, struct or union
if (tok1->next() == tok) if (!(tok1->str() == "union" && !inFunction))
{ {
tok1->deleteThis(); tok1->deleteThis();
tok = tok1; if (tok1->next() == tok)
} {
else tok1->deleteThis();
tok1->deleteThis(); tok = tok1;
restart = tok1->previous(); }
tok->deleteThis(); else
if (tok->next()) tok1->deleteThis();
restart = tok1->previous();
tok->deleteThis(); tok->deleteThis();
if (tok->next())
tok->deleteThis();
}
} }
if (!restart) if (!restart)

View File

@ -335,6 +335,7 @@ private:
// struct ABC { } abc; => struct ABC { }; ABC abc; // struct ABC { } abc; => struct ABC { }; ABC abc;
TEST_CASE(simplifyStructDecl1); TEST_CASE(simplifyStructDecl1);
TEST_CASE(simplifyStructDecl2); // ticket #2579 TEST_CASE(simplifyStructDecl2); // ticket #2579
TEST_CASE(simplifyStructDecl3);
// register int var; => int var; // register int var; => int var;
// inline int foo() {} => int foo() {} // inline int foo() {} => int foo() {}
@ -6931,6 +6932,129 @@ private:
ASSERT_EQUALS(expected, tok(code, false)); ASSERT_EQUALS(expected, tok(code, false));
} }
void simplifyStructDecl3()
{
{
const char code[] = "class ABC { } abc;";
const char expected[] = "class ABC { } ; ABC abc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class ABC { } * pabc;";
const char expected[] = "class ABC { } ; ABC * pabc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class ABC { } abc[4];";
const char expected[] = "class ABC { } ; ABC abc [ 4 ] ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class ABC { } abc, def;";
const char expected[] = "class ABC { } ; ABC abc ; ABC def ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class ABC { } abc, * pabc;";
const char expected[] = "class ABC { } ; ABC abc ; ABC * pabc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class ABC { class DEF {} def; } abc;";
const char expected[] = "class ABC { class DEF { } ; DEF def ; } ; ABC abc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { } abc;";
const char expected[] = "class { } abc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { } * pabc;";
const char expected[] = "class { } * pabc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { } abc[4];";
const char expected[] = "class { } abc [ 4 ] ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { } abc, def;";
const char expected[] = "class { } abc , def ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { } abc, * pabc;";
const char expected[] = "class { } abc , * pabc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "struct { class DEF {} def; } abc;";
const char expected[] = "struct Anonymous0 { class DEF { } ; DEF def ; } ; Anonymous0 abc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class ABC { struct {} def; } abc;";
const char expected[] = "class ABC { struct Anonymous0 { } ; Anonymous0 def ; } ; ABC abc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { class {} def; } abc;";
const char expected[] = "class { class { } def ; } abc ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class ABC { struct {} def; };";
const char expected[] = "class ABC { struct Anonymous0 { } ; Anonymous0 def ; } ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class ABC : public XYZ { struct {} def; };";
const char expected[] = "class ABC : public XYZ { struct Anonymous0 { } ; Anonymous0 def ; } ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { int x; }; int y;";
const char expected[] = "class { int x ; } ; int y ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { int x; };";
const char expected[] = "class { int x ; } ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { };";
const char expected[] = "class { } ;";
ASSERT_EQUALS(expected, tok(code, false));
}
{
const char code[] = "class { struct { struct { } ; } ; };";
const char expected[] = "class { } ;";
ASSERT_EQUALS(expected, tok(code, false));
}
}
void removeUnwantedKeywords() void removeUnwantedKeywords()
{ {
ASSERT_EQUALS("int var ;", tok("register int var ;", true)); ASSERT_EQUALS("int var ;", tok("register int var ;", true));