Fixed #1251 (tokenize typedef of reference)

This commit is contained in:
Robert Reif 2010-01-18 19:06:50 +01:00 committed by Daniel Marjamäki
parent 5e86403534
commit cd31cd9298
2 changed files with 82 additions and 142 deletions

View File

@ -445,13 +445,14 @@ void Tokenizer::simplifyTypedef()
const char *type1 = 0;
const char *type2 = 0;
const char *type3 = 0;
const char *typeName = 0;
bool pointer = false;
bool toPointer = false;
std::list<std::string> pointers;
Token *start = 0;
Token *end = 0;
Token *num = 0;
Token *typeDef = tok;
int offset = 1;
if (Token::Match(tok->next(), "%type% <") ||
Token::Match(tok->next(), "%type% %type% <") ||
@ -497,92 +498,45 @@ void Tokenizer::simplifyTypedef()
while (end && end->next() && Token::Match(end->next(), ":: %type%"))
end = end->tokAt(2);
if (end && end->next() && end->next()->str() == "*")
tok = end;
}
else if (Token::Match(tok->next(), "%type%"))
{
type1 = tok->strAt(offset++);
if (tok->tokAt(offset) && !Token::Match(tok->tokAt(offset), "*|&") && tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,"))
type2 = tok->strAt(offset++);
if (tok->tokAt(offset) && !Token::Match(tok->tokAt(offset), "*|&") && tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,"))
type3 = tok->strAt(offset++);
}
else
{
// unhandled typedef, skip it and continue
continue;
}
while (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "*|&"))
pointers.push_back(tok->tokAt(offset++)->str());
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%"))
{
typeName = tok->strAt(offset++);
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "[ %num% ]"))
{
pointer = true;
end = end->next();
num = tok->tokAt(offset + 1);
offset += 3;
}
if (end && end->next() && end->next()->str() == "*")
{
toPointer = true;
end = end->next();
}
if (end && end->next() && (Token::Match(end->next(), "%type% ;|,") || Token::Match(end->next(), "%type% [ %num% ] ;|,")))
{
typeName = end->strAt(1);
if (end->tokAt(2)->str() == "[")
{
num = end->tokAt(3);
tok = end->tokAt(5);
}
else
tok = end->tokAt(2);
}
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), ";|,"))
tok = tok->tokAt(offset);
else
{
// unhandled template typedef, skip it and continue
// unhandled typedef, skip it and continue
continue;
}
}
else if (Token::Match(tok->next(), "%type% *| *| %type% [ %num% ] ;|,") ||
Token::Match(tok->next(), "%type% %type% *| *| %type% [ %num% ] ;|,"))
{
// array
int offset = 2;
type1 = tok->strAt(1);
if (tok->tokAt(2)->str() != "*" && tok->tokAt(3)->str() != "[")
{
type2 = tok->strAt(2);
offset++;
}
if (tok->tokAt(offset) && (tok->tokAt(offset)->str() == "*"))
{
pointer = true;
offset++;
}
if (tok->tokAt(offset) && (tok->tokAt(offset)->str() == "*"))
{
toPointer = true;
offset++;
}
typeName = tok->strAt(offset);
num = tok->tokAt(offset + 2);
tok = tok->tokAt(offset + 4);
}
else if (Token::Match(tok->next(), "%type% *| *| %type% ;|,") ||
Token::Match(tok->next(), "%type% %type% *| *| %type% ;|,"))
{
int offset = 2;
type1 = tok->strAt(1);
if (tok->tokAt(2)->str() != "*" && (tok->tokAt(3)->str() != ";" && tok->tokAt(3)->str() != ","))
{
type2 = tok->strAt(2);
offset++;
}
if (tok->tokAt(offset) && (tok->tokAt(offset)->str() == "*"))
{
pointer = true;
offset++;
}
if (tok->tokAt(offset) && (tok->tokAt(offset)->str() == "*"))
{
toPointer = true;
offset++;
}
typeName = tok->strAt(offset++);
tok = tok->tokAt(offset);
}
else
{
// unhandled typedef, skip it and continue
@ -680,16 +634,17 @@ void Tokenizer::simplifyTypedef()
tok2->insertToken(type2);
tok2 = tok2->next();
}
if (type3)
{
tok2->insertToken(type3);
tok2 = tok2->next();
}
}
if (pointer)
while (!pointers.empty())
{
tok2->insertToken("*");
tok2 = tok2->next();
}
if (toPointer)
{
tok2->insertToken("*");
tok2->insertToken(pointers.front().c_str());
pointers.pop_front();
tok2 = tok2->next();
}
if (num)
@ -713,51 +668,29 @@ void Tokenizer::simplifyTypedef()
done = true;
else if (tok->str() == ",")
{
if (Token::Match(tok->next(), "*| *| %type% ;|,") ||
Token::Match(tok->next(), "*| *| %type% [ %num% ] ;|,"))
num = 0;
offset = 1;
while (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "*|&"))
pointers.push_back(tok->tokAt(offset++)->str());
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%"))
{
num = 0;
pointer = (tok->tokAt(1)->str() == "*");
toPointer = (tok->tokAt(2)->str() == "*");
typeName = tok->strAt(offset++);
if (pointer)
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "[ %num% ]"))
{
if (toPointer)
{
typeName = tok->strAt(3);
if (tok->tokAt(4)->str() == "[")
{
num = tok->tokAt(5);
tok = tok->tokAt(7);
}
else
tok = tok->tokAt(4);
}
else
{
typeName = tok->strAt(2);
if (tok->tokAt(3)->str() == "[")
{
num = tok->tokAt(4);
tok = tok->tokAt(6);
}
else
tok = tok->tokAt(3);
}
num = tok->tokAt(offset + 1);
offset += 3;
}
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), ";|,"))
tok = tok->tokAt(offset);
else
{
typeName = tok->strAt(1);
if (tok->tokAt(2)->str() == "[")
{
num = tok->tokAt(3);
tok = tok->tokAt(5);
}
else
tok = tok->tokAt(2);
// we encountered a typedef we don't support yet so just continue
done = true;
ok = false;
}
}
else

View File

@ -2319,12 +2319,24 @@ private:
"typedef unsigned int UINT;\n"
"typedef int * PINT;\n"
"typedef unsigned int * PUINT;\n"
"typedef int & RINT;\n"
"typedef unsigned int & RUINT;\n"
"typedef const int & RCINT;\n"
"typedef const unsigned int & RCUINT;\n"
"INT ti;\n"
"UINT tui;\n"
"PINT tpi;\n"
"PUINT tpui;";
"PUINT tpui;\n"
"RINT tri;\n"
"RUINT trui;\n"
"RCINT trci;\n"
"RCUINT trcui;";
const char expected[] =
"; "
"; "
"; "
"; "
"; "
"; "
"; "
@ -2332,7 +2344,11 @@ private:
"int ti ; "
"unsigned int tui ; "
"int * tpi ; "
"unsigned int * tpui ;";
"unsigned int * tpui ; "
"int & tri ; "
"unsigned int & trui ; "
"const int & trci ; "
"const unsigned int & trcui ;";
ASSERT_EQUALS(expected, tok(code, false));
}
@ -2575,36 +2591,27 @@ private:
}
{
// This doesn't work yet.
// The first name gets substituted successfully.
// The second doesn't so the typedef is left alone.
// The variable declaration simplification code then splits the typedef into two.
const char code[] = "typedef struct {} A, ***B;\n"
const char code[] = "typedef struct {} A, *********B;\n"
"A a;\n"
"B b;";
const char expected[] =
"struct A { } ; typedef struct A A ; typedef struct A * * * B ; "
"struct A a ; "
"B b ;";
const char todo[] =
"struct A { } ; ; "
"struct A a ; "
"struct A * * * b ;";
"struct A * * * * * * * * * b ;";
ASSERT_EQUALS(expected, tok(code, false));
TODO_ASSERT_EQUALS(todo, tok(code, false));
}
{
const char code[] = "typedef struct {} **A, *B, C;\n"
const char code[] = "typedef struct {} **********A, *B, C;\n"
"A a;\n"
"B b;\n"
"C c;";
const char expected[] =
"struct Unnamed2 { } ; ; "
"struct Unnamed2 * * a ; "
"struct Unnamed2 * * * * * * * * * * a ; "
"struct Unnamed2 * b ; "
"struct Unnamed2 c ;";