From 7173e01926499d8495767a16241c84bbc2f5ac72 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 21 Aug 2010 07:44:56 +0200 Subject: [PATCH] Fixed #1965 (tokenizer::simplifyEnum add support for C++0x enums) --- lib/tokenize.cpp | 82 ++++++++++++++++++++++++++++++++----- test/testsimplifytokens.cpp | 39 ++++++++++++++++++ 2 files changed, 111 insertions(+), 10 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d4ba41bc2..164f311af 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6445,21 +6445,53 @@ void Tokenizer::simplifyEnum() ++classLevel; continue; } - else if (Token::Match(tok, "enum {") || - Token::Match(tok, "enum %type% {")) + else if (Token::Match(tok, "enum class|struct| {|:") || + Token::Match(tok, "enum class|struct| %type% {|:")) { - Token * tok1; - Token * start = tok; - Token * end; - Token * enumType = 0; + Token *tok1; + Token *start = tok; + Token *end; + 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() == "{") tok1 = tok->tokAt(2); - else + else if (tok->tokAt(2)->str() == "{") { enumType = tok->tokAt(1); tok1 = tok->tokAt(3); } + else if (tok->tokAt(2)->str() == ":") + { + enumType = tok->tokAt(1); + tok1 = typeTokenEnd->tokAt(2); + } end = tok1->tokAt(-1)->link(); @@ -6672,11 +6704,26 @@ void Tokenizer::simplifyEnum() // check for a variable definition: enum {} x; if (end->next()->str() != ";") { - Token * tempTok = end; + Token *tempTok = end; tempTok->insertToken(";"); 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) @@ -6727,7 +6774,22 @@ void Tokenizer::simplifyEnum() { if (tok2->str() == "enum") 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) { diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 247817f79..9786d2663 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -249,6 +249,7 @@ private: TEST_CASE(enum12); TEST_CASE(enum13); TEST_CASE(enum14); + TEST_CASE(enum15); // remove "std::" on some standard functions TEST_CASE(removestd); @@ -5466,6 +5467,44 @@ private: 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() { ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);"));