Fixed #1244 (tokenize typedef of unnamed struct)

This commit is contained in:
Robert Reif 2010-01-10 08:49:02 +01:00 committed by Daniel Marjamäki
parent 4c641ed80c
commit 19ba151531
2 changed files with 91 additions and 79 deletions

View File

@ -394,74 +394,51 @@ void Tokenizer::simplifyTypedef()
else if (tok->str() != "typedef")
continue;
// pull struct name { ... } out of typedef
if (Token::Match(tok->next(), "struct %type% {"))
{
int structLevel = 1;
Token *tok1 = tok->tokAt(4);
for (; tok1; tok1 = tok1->next())
{
if (tok1->str() == "}")
{
--structLevel;
if (structLevel == 0)
break;
}
if (tok1->str() == "{")
++structLevel;
}
tok1->insertToken(";");
tok1 = tok1->next();
tok1->insertToken("typedef");
tok1 = tok1->next();
Token * tok2 = tok1;
tok1->insertToken("struct");
tok1 = tok1->next();
tok1->insertToken(tok->strAt(2));
tok->deleteThis();
tok = tok2;
}
else if (Token::Match(tok->next(), "enum %type% {") ||
Token::Match(tok->next(), "enum {"))
// pull struct or enum definition out of typedef
// use typedef name for unnamed struct or enum
if (Token::Match(tok->next(), "struct|enum %type% {") ||
Token::Match(tok->next(), "struct|enum {"))
{
Token *tok1;
Token *tok2 = 0;
std::string name;
if (tok->tokAt(2)->str() == "{")
tok1 = tok->tokAt(3);
else
if (tok->tokAt(2)->str() == "{") // unnamed
{
tok1 = tok->tokAt(4);
tok2 = tok->tokAt(2);
}
tok1 = tok->tokAt(2)->link();
for (; tok1; tok1 = tok1->next())
{
if (tok1->str() == "}")
break;
}
if (tok2 == 0)
{
if (Token::Match(tok1->next(), "%type%"))
if (tok1 && tok1->next())
{
tok2 = tok1->next();
tok->tokAt(1)->insertToken(tok2->strAt(0));
// use typedef name if available
if (Token::Match(tok1->next(), "%type%"))
name = tok1->next()->str();
else // create a unique name
{
static long count = 0;
name = "Unnamed" + MathLib::toString<long>(count++);
}
tok->tokAt(1)->insertToken(name.c_str());
}
else
continue;
}
else // has a name
{
tok1 = tok->tokAt(3)->link();
if (!tok1)
continue;
name = tok->tokAt(2)->str();
}
tok1->insertToken(";");
tok1 = tok1->next();
tok1->insertToken("typedef");
tok1 = tok1->next();
Token * tok3 = tok1;
tok1->insertToken("enum");
tok1->insertToken(tok->next()->strAt(0)); // struct or enum
tok1 = tok1->next();
tok1->insertToken(tok2->strAt(0));
tok1->insertToken(name.c_str());
tok->deleteThis();
tok = tok3;
}

View File

@ -145,6 +145,9 @@ private:
TEST_CASE(simplifyTypedef8);
TEST_CASE(simplifyTypedef9);
TEST_CASE(simplifyTypedef10);
TEST_CASE(simplifyTypedef11);
TEST_CASE(simplifyTypedef12);
TEST_CASE(simplifyTypedef13);
TEST_CASE(reverseArraySyntax)
TEST_CASE(simplify_numeric_condition)
@ -2304,49 +2307,81 @@ private:
"typedef unsigned int UINT;\n"
"typedef int * PINT;\n"
"typedef unsigned int * PUINT;\n"
"typedef struct s S, * PS\n;"
"typedef struct t { int a; } T, *TP;"
"typedef enum { a = 0 , b = 1 , c = 2 } abc;"
"typedef enum xyz { x = 0 , y = 1 , z = 2 } XYZ;"
"typedef vector<int> V1;"
"typedef std::vector<int> V2;"
"typedef std::vector<std::vector<int> > V3;"
"INT ti;\n"
"UINT tui;\n"
"PINT tpi;\n"
"PUINT tpui;"
"S s;\n"
"PS ps;\n"
"T t;\n"
"TP tp;\n"
"abc e1;\n"
"XYZ e2;\n"
"V1 v1;\n"
"V2 v2;\n"
"V3 v3;";
"PUINT tpui;";
const char expected[] =
"typedef int INT ; "
"typedef unsigned int UINT ; "
"typedef int * PINT ; "
"typedef unsigned int * PUINT ; "
"typedef struct s S ; typedef struct s * PS ; "
"struct t { int a ; } ; typedef struct t T ; typedef struct t * TP ; "
"enum abc { a = 0 , b = 1 , c = 2 } ; typedef enum abc abc ; "
"enum xyz { x = 0 , y = 1 , z = 2 } ; typedef enum xyz XYZ ; "
"typedef vector < int > V1 ; "
"typedef std :: vector < int > V2 ; "
"typedef std :: vector < std :: vector < int > > V3 ; "
"int ti ; "
"unsigned int tui ; "
"int * tpi ; "
"unsigned int * tpui ; "
"unsigned int * tpui ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef9()
{
const char code[] = "typedef struct s S, * PS\n;"
"typedef struct t { int a; } T, *TP;\n"
"typedef struct { int a; } U;\n"
"typedef struct { int a; } * V;\n"
"S s;\n"
"PS ps;\n"
"T t;\n"
"TP tp;\n"
"U u;\n"
"V v;";
const char expected[] =
"typedef struct s S ; typedef struct s * PS ; "
"struct t { int a ; } ; typedef struct t T ; typedef struct t * TP ; "
"struct U { int a ; } ; typedef struct U U ; "
"struct Unnamed0 { int a ; } ; typedef struct Unnamed0 * V ; "
"struct s s ; "
"struct s * ps ; "
"struct t t ; "
"struct t * tp ; "
"struct U u ; "
"struct Unnamed0 * v ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef10()
{
const char code[] = "typedef enum { a = 0 , b = 1 , c = 2 } abc;\n"
"typedef enum xyz { x = 0 , y = 1 , z = 2 } XYZ;\n"
"abc e1;\n"
"XYZ e2;";
const char expected[] =
"enum abc { a = 0 , b = 1 , c = 2 } ; typedef enum abc abc ; "
"enum xyz { x = 0 , y = 1 , z = 2 } ; typedef enum xyz XYZ ; "
"enum abc e1 ; "
"enum xyz e2 ; "
"enum xyz e2 ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef11()
{
const char code[] = "typedef vector<int> V1;\n"
"typedef std::vector<int> V2;\n"
"typedef std::vector<std::vector<int> > V3;\n"
"V1 v1;\n"
"V2 v2;\n"
"V3 v3;";
const char expected[] =
"typedef vector < int > V1 ; "
"typedef std :: vector < int > V2 ; "
"typedef std :: vector < std :: vector < int > > V3 ; "
"vector < int > v1 ; "
"std :: vector < int > v2 ; "
"std :: vector < std :: vector < int > > v3 ;";
@ -2354,7 +2389,7 @@ private:
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef9()
void simplifyTypedef12()
{
// ticket # 1167
const char code[] = "typedef std::pair<int(*)(void*), void*> Func;"
@ -2373,7 +2408,7 @@ private:
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedef10()
void simplifyTypedef13()
{
// ticket # 1232
const char code[] = "template <typename F, unsigned int N> struct E"