Fixed #1326 (remove simplified enum definitions)

This commit is contained in:
Robert Reif 2010-01-29 15:57:26 +01:00 committed by Daniel Marjamäki
parent 9d11492845
commit fc54ed1eef
2 changed files with 125 additions and 8 deletions

View File

@ -924,6 +924,7 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
// typedef..
simplifyTypedef();
// enum..
simplifyEnum();
// Remove __asm..
@ -4702,12 +4703,17 @@ void Tokenizer::simplifyEnum()
Token::Match(tok, "enum %type% {"))
{
Token * tok1;
Token * start = tok;
Token * end;
Token * enumType = 0;
if (tok->tokAt(1)->str() == "{")
tok1 = tok->tokAt(2);
else
{
enumType = tok->tokAt(1);
tok1 = tok->tokAt(3);
}
end = tok1->tokAt(-1)->link();
@ -4743,6 +4749,7 @@ void Tokenizer::simplifyEnum()
bool exitThisScope = false;
int exitScope = 0;
bool simplifyEnum = false;
bool hasClass = false;
for (Token *tok2 = end->next(); tok2; tok2 = tok2->next())
{
if (tok2->str() == "}")
@ -4762,6 +4769,7 @@ void Tokenizer::simplifyEnum()
else if (!pattern.empty() && Token::Match(tok2, pattern.c_str()))
{
simplifyEnum = true;
hasClass = true;
}
else if (inScope && !exitThisScope && tok2->str() == enumName->str())
{
@ -4770,18 +4778,99 @@ void Tokenizer::simplifyEnum()
// Don't replace this enum if it's preceded by "::"
}
else
{
simplifyEnum = true;
hasClass = false;
}
}
if (simplifyEnum)
{
tok2->str(enumValue->strAt(0));
if (hasClass)
{
tok2->deleteNext();
tok2->deleteNext();
}
simplifyEnum = false;
}
}
}
}
if (enumType)
{
const std::string pattern(className.empty() ? "" : (className + " :: " + enumType->str()).c_str());
int level = 0;
bool inScope = true;
bool exitThisScope = false;
int exitScope = 0;
bool simplifyEnum = false;
bool hasClass = false;
for (Token *tok2 = end->next(); tok2; tok2 = tok2->next())
{
if (tok2->str() == "}")
{
--level;
if (level < 0)
inScope = false;
if (exitThisScope)
{
if (level < exitScope)
exitThisScope = false;
}
}
else if (tok2->str() == "{")
++level;
else if (!pattern.empty() && ((Token::Match(tok2, "enum") && Token::Match(tok2->next(), pattern.c_str())) || Token::Match(tok2, pattern.c_str())))
{
simplifyEnum = true;
hasClass = true;
}
else if (inScope && !exitThisScope && (tok2->str() == enumType->str() || (tok2->str() == "enum" && tok2->next()->str() == enumType->str())))
{
if (Token::simpleMatch(tok2->previous(), "::"))
{
// Don't replace this enum if it's preceded by "::"
}
else
{
simplifyEnum = true;
hasClass = false;
}
}
if (simplifyEnum)
{
if (tok2->str() == "enum")
tok2->deleteNext();
tok2->str("int");
if (hasClass)
{
tok2->deleteNext();
tok2->deleteNext();
}
simplifyEnum = false;
}
}
}
tok1 = start;
while (tok1->next() && tok1->next() != end->next())
tok1->deleteNext();
if (start != _tokens)
{
tok1 = start->previous();
tok1->deleteNext();
}
else
_tokens->deleteThis();
}
}
}

View File

@ -178,6 +178,7 @@ private:
TEST_CASE(enum1);
TEST_CASE(enum2);
TEST_CASE(enum3);
TEST_CASE(enum4);
// remove "std::" on some standard functions
TEST_CASE(removestd);
@ -2474,10 +2475,10 @@ private:
"XYZ e2;";
const char expected[] =
"enum abc { a = 0 , b = 1 , c = 2 } ; ; "
"enum xyz { x = 0 , y = 1 , z = 2 } ; ; "
"enum abc e1 ; "
"enum xyz e2 ;";
"; ; "
"; ; "
"int e1 ; "
"int e2 ;";
ASSERT_EQUALS(expected, tok(code, false));
}
@ -3145,8 +3146,8 @@ private:
void enum1()
{
const char code[] = "enum A { a, b, c };";
const char expected[] = "enum A { a = 0 , b = 1 , c = 2 } ;";
const char code[] = "enum A { a, b, c }; A c1 = c;";
const char expected[] = "; int c1 ; c1 = 2 ;";
ASSERT_EQUALS(expected, tok(code, false));
}
@ -3154,7 +3155,7 @@ private:
void enum2()
{
const char code[] = "enum A { a, }; int array[a];";
const char expected[] = "enum A { a = 0 , } ; int array [ 0 ] ;";
const char expected[] = "; int array [ 0 ] ;";
ASSERT_EQUALS(expected, tok(code, false));
}
@ -3162,7 +3163,34 @@ private:
void enum3()
{
const char code[] = "enum { a, }; int array[a];";
const char expected[] = "enum { a = 0 , } ; int array [ 0 ] ;";
const char expected[] = "; int array [ 0 ] ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void enum4()
{
const char code[] = "class A {\n"
"public:\n"
" enum EA { a1, a2, a3 };\n"
" EA get() const;\n"
" void put(EA a) { ea = a; ea = a1; }\n"
"private:\n"
" EA ea;\n"
"};\n"
"A::EA A::get() const { return ea; }\n"
"A::EA e = A::a1;";
const char expected[] = "class A { "
"public: "
"; "
"int get ( ) const ; "
"void put ( int a ) { ea = a ; ea = 0 ; } "
"private: "
"int ea ; "
"} ; "
"int A :: get ( ) const { return ea ; } "
"int e ; e = 0 ;";
ASSERT_EQUALS(expected, tok(code, false));
}