Fixed #1965 (tokenizer::simplifyEnum add support for C++0x enums)
This commit is contained in:
parent
ac8544f3b3
commit
7173e01926
|
@ -6445,21 +6445,53 @@ void Tokenizer::simplifyEnum()
|
||||||
++classLevel;
|
++classLevel;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (Token::Match(tok, "enum {") ||
|
else if (Token::Match(tok, "enum class|struct| {|:") ||
|
||||||
Token::Match(tok, "enum %type% {"))
|
Token::Match(tok, "enum class|struct| %type% {|:"))
|
||||||
{
|
{
|
||||||
Token * tok1;
|
Token *tok1;
|
||||||
Token * start = tok;
|
Token *start = tok;
|
||||||
Token * end;
|
Token *end;
|
||||||
Token * enumType = 0;
|
Token *enumType = 0;
|
||||||
|
Token *typeTokenStart = 0;
|
||||||
|
Token *typeTokenEnd = 0;
|
||||||
|
bool enumClass = false;
|
||||||
|
|
||||||
|
// check for C++0x enum class
|
||||||
|
if (Token::Match(tok->next(), "class|struct"))
|
||||||
|
{
|
||||||
|
tok->deleteNext();
|
||||||
|
enumClass = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for C++0x typed enumeration
|
||||||
|
if (Token::Match(tok->next(), "%type% :"))
|
||||||
|
{
|
||||||
|
// check for forward declaration
|
||||||
|
/** @todo start substitution check at forward declaration */
|
||||||
|
const Token *temp = tok->tokAt(3);
|
||||||
|
while (!Token::Match(temp, "{|;"))
|
||||||
|
temp = temp->next();
|
||||||
|
if (temp->str() == ";")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
typeTokenStart = tok->tokAt(3);
|
||||||
|
typeTokenEnd = typeTokenStart;
|
||||||
|
while (Token::Match(typeTokenEnd->next(), "signed|unsigned|char|short|int|long"))
|
||||||
|
typeTokenEnd = typeTokenEnd->next();
|
||||||
|
}
|
||||||
|
|
||||||
if (tok->tokAt(1)->str() == "{")
|
if (tok->tokAt(1)->str() == "{")
|
||||||
tok1 = tok->tokAt(2);
|
tok1 = tok->tokAt(2);
|
||||||
else
|
else if (tok->tokAt(2)->str() == "{")
|
||||||
{
|
{
|
||||||
enumType = tok->tokAt(1);
|
enumType = tok->tokAt(1);
|
||||||
tok1 = tok->tokAt(3);
|
tok1 = tok->tokAt(3);
|
||||||
}
|
}
|
||||||
|
else if (tok->tokAt(2)->str() == ":")
|
||||||
|
{
|
||||||
|
enumType = tok->tokAt(1);
|
||||||
|
tok1 = typeTokenEnd->tokAt(2);
|
||||||
|
}
|
||||||
|
|
||||||
end = tok1->tokAt(-1)->link();
|
end = tok1->tokAt(-1)->link();
|
||||||
|
|
||||||
|
@ -6672,11 +6704,26 @@ void Tokenizer::simplifyEnum()
|
||||||
// check for a variable definition: enum {} x;
|
// check for a variable definition: enum {} x;
|
||||||
if (end->next()->str() != ";")
|
if (end->next()->str() != ";")
|
||||||
{
|
{
|
||||||
Token * tempTok = end;
|
Token *tempTok = end;
|
||||||
|
|
||||||
tempTok->insertToken(";");
|
tempTok->insertToken(";");
|
||||||
tempTok = tempTok->next();
|
tempTok = tempTok->next();
|
||||||
tempTok->insertToken("int");
|
if (typeTokenStart == 0)
|
||||||
|
tempTok->insertToken("int");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Token *tempTok1 = typeTokenStart;
|
||||||
|
|
||||||
|
tempTok->insertToken(tempTok1->str());
|
||||||
|
|
||||||
|
while (tempTok1 != typeTokenEnd)
|
||||||
|
{
|
||||||
|
tempTok1 = tempTok1->next();
|
||||||
|
|
||||||
|
tempTok->insertToken(tempTok1->str());
|
||||||
|
tempTok = tempTok->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enumType)
|
if (enumType)
|
||||||
|
@ -6727,7 +6774,22 @@ void Tokenizer::simplifyEnum()
|
||||||
{
|
{
|
||||||
if (tok2->str() == "enum")
|
if (tok2->str() == "enum")
|
||||||
tok2->deleteNext();
|
tok2->deleteNext();
|
||||||
tok2->str("int");
|
if (typeTokenStart == 0)
|
||||||
|
tok2->str("int");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Token *tok3 = typeTokenStart;
|
||||||
|
|
||||||
|
tok2->str(tok3->str());
|
||||||
|
|
||||||
|
while (tok3 != typeTokenEnd)
|
||||||
|
{
|
||||||
|
tok3 = tok3->next();
|
||||||
|
|
||||||
|
tok2->insertToken(tok3->str());
|
||||||
|
tok2 = tok2->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hasClass)
|
if (hasClass)
|
||||||
{
|
{
|
||||||
|
|
|
@ -249,6 +249,7 @@ private:
|
||||||
TEST_CASE(enum12);
|
TEST_CASE(enum12);
|
||||||
TEST_CASE(enum13);
|
TEST_CASE(enum13);
|
||||||
TEST_CASE(enum14);
|
TEST_CASE(enum14);
|
||||||
|
TEST_CASE(enum15);
|
||||||
|
|
||||||
// remove "std::" on some standard functions
|
// remove "std::" on some standard functions
|
||||||
TEST_CASE(removestd);
|
TEST_CASE(removestd);
|
||||||
|
@ -5466,6 +5467,44 @@ private:
|
||||||
ASSERT_EQUALS(expected, tok(code, false));
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enum15() // C++0x features
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const char code[] = "enum class Enum1 { a };\n"
|
||||||
|
"Enum1 e1 = a;";
|
||||||
|
const char expected[] = "; int e1 ; e1 = 0 ;";
|
||||||
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "enum Enum1 : char { a };\n"
|
||||||
|
"Enum1 e1 = a;";
|
||||||
|
const char expected[] = "; char e1 ; e1 = 0 ;";
|
||||||
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "enum class Enum1 : unsigned char { a };\n"
|
||||||
|
"Enum1 e1 = a;";
|
||||||
|
const char expected[] = "; unsigned char e1 ; e1 = 0 ;";
|
||||||
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "enum class Enum1 : unsigned int { a };\n"
|
||||||
|
"Enum1 e1 = a;";
|
||||||
|
const char expected[] = "; unsigned int e1 ; e1 = 0 ;";
|
||||||
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "enum class Enum1 : unsigned long long int { a };\n"
|
||||||
|
"Enum1 e1 = a;";
|
||||||
|
const char expected[] = "; unsigned long long e1 ; e1 = 0 ;";
|
||||||
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void removestd()
|
void removestd()
|
||||||
{
|
{
|
||||||
ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);"));
|
ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);"));
|
||||||
|
|
Loading…
Reference in New Issue