fix #2804 (Underlying type of enumerator produces a syntax error)

This commit is contained in:
Robert Reif 2011-05-27 11:17:39 -04:00
parent 42316f3e0b
commit 311651cc66
2 changed files with 37 additions and 43 deletions

View File

@ -7972,66 +7972,50 @@ void Tokenizer::simplifyEnum()
if (Token::Match(tok->next(), "class|struct"))
tok->deleteNext();
// check for C++0x typed enumeration
if (Token::Match(tok->next(), "%type% :") || tok->next()->str() == ":")
// check for name
if (Token::Match(tok->next(), "%type%"))
{
int offset = 2;
if (tok->next()->str() != ":")
offset = 3;
enumType = tok->next();
tok = tok->next();
}
// check for forward declaration
const Token *temp = tok->tokAt(offset);
while (!Token::Match(temp, "{|;"))
temp = temp->next();
if (temp->str() == ";")
{
/** @todo start substitution check at forward declaration */
// delete forward declaration
tok->deleteThis();
tok->deleteThis();
tok->deleteThis();
tok->deleteThis();
continue;
}
typeTokenStart = tok->tokAt(offset);
// check for C++0x typed enumeration
if (tok->next()->str() == ":")
{
tok = tok->next();
typeTokenStart = tok->next();
tok = tok->next();
typeTokenEnd = typeTokenStart;
while (Token::Match(typeTokenEnd->next(), "signed|unsigned|char|short|int|long|const"))
typeTokenEnd = typeTokenEnd->next();
if (!Token::Match(typeTokenEnd->next(), "{|;"))
while (typeTokenEnd->next()->str() == "::" ||
Token::Match(typeTokenEnd->next(), "%type%"))
{
syntaxError(typeTokenEnd->next());
return;
typeTokenEnd = typeTokenEnd->next();
tok = tok->next();
}
}
// check for forward declaration
else if (Token::Match(tok->next(), "%type% ;"))
if (tok->next()->str() == ";")
{
tok = tok->next();
/** @todo start substitution check at forward declaration */
// delete forward declaration
tok->deleteThis();
tok->deleteThis();
while (start->next() != tok)
start->deleteThis();
start->deleteThis();
continue;
}
if (tok->tokAt(1)->str() == "{")
tok1 = tok->tokAt(2);
else if (tok->tokAt(1)->str() == ":")
tok1 = typeTokenEnd->tokAt(2);
else if (tok->tokAt(2)->str() == "{")
else if (tok->next()->str() != "{")
{
enumType = tok->tokAt(1);
tok1 = tok->tokAt(3);
}
else
{
enumType = tok->tokAt(1);
tok1 = typeTokenEnd->tokAt(2);
syntaxError(tok->next());
return;
}
end = tok1->tokAt(-1)->link();
tok1 = tok->next();
end = tok1->link();
tok1 = tok1->next();
MathLib::bigint lastValue = -1;
Token * lastEnumValueStart = 0;

View File

@ -307,6 +307,7 @@ private:
TEST_CASE(enum20); // ticket #2600
TEST_CASE(enum21); // ticket #2720
TEST_CASE(enum22); // ticket #2745
TEST_CASE(enum23); // ticket #2804
// remove "std::" on some standard functions
TEST_CASE(removestd);
@ -6609,6 +6610,15 @@ private:
"[test.cpp:6] -> [test.cpp:1]: (style) Function parameter 'x' hides enumerator with same name\n", errout.str());
}
void enum23() // ticket #2804
{
const char code[] = "enum Enumerator : std::uint8_t { ITEM1, ITEM2, ITEM3 };\n"
"Enumerator e = ITEM3;\n";
const char expected[] = "; std :: uint8_t e ; e = 2 ;";
ASSERT_EQUALS(expected, tok(code, false));
ASSERT_EQUALS("", errout.str());
}
void removestd()
{
ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);"));