Fixed #1251 (tokenize typedef of reference)
This commit is contained in:
parent
5e86403534
commit
cd31cd9298
163
lib/tokenize.cpp
163
lib/tokenize.cpp
|
@ -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,91 +498,44 @@ void Tokenizer::simplifyTypedef()
|
|||
while (end && end->next() && Token::Match(end->next(), ":: %type%"))
|
||||
end = end->tokAt(2);
|
||||
|
||||
if (end && end->next() && end->next()->str() == "*")
|
||||
{
|
||||
pointer = true;
|
||||
end = end->next();
|
||||
tok = end;
|
||||
}
|
||||
|
||||
if (end && end->next() && end->next()->str() == "*")
|
||||
else if (Token::Match(tok->next(), "%type%"))
|
||||
{
|
||||
toPointer = true;
|
||||
end = end->next();
|
||||
}
|
||||
type1 = tok->strAt(offset++);
|
||||
|
||||
if (end && end->next() && (Token::Match(end->next(), "%type% ;|,") || Token::Match(end->next(), "%type% [ %num% ] ;|,")))
|
||||
{
|
||||
typeName = end->strAt(1);
|
||||
if (tok->tokAt(offset) && !Token::Match(tok->tokAt(offset), "*|&") && tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,"))
|
||||
type2 = tok->strAt(offset++);
|
||||
|
||||
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->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,"))
|
||||
type3 = tok->strAt(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++;
|
||||
}
|
||||
while (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "*|&"))
|
||||
pointers.push_back(tok->tokAt(offset++)->str());
|
||||
|
||||
if (tok->tokAt(offset) && (tok->tokAt(offset)->str() == "*"))
|
||||
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%"))
|
||||
{
|
||||
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++);
|
||||
|
||||
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "[ %num% ]"))
|
||||
{
|
||||
num = tok->tokAt(offset + 1);
|
||||
offset += 3;
|
||||
}
|
||||
|
||||
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), ";|,"))
|
||||
tok = tok->tokAt(offset);
|
||||
else
|
||||
{
|
||||
// unhandled typedef, skip it and continue
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -680,16 +634,17 @@ void Tokenizer::simplifyTypedef()
|
|||
tok2->insertToken(type2);
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
}
|
||||
|
||||
if (pointer)
|
||||
if (type3)
|
||||
{
|
||||
tok2->insertToken("*");
|
||||
tok2->insertToken(type3);
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
if (toPointer)
|
||||
}
|
||||
|
||||
while (!pointers.empty())
|
||||
{
|
||||
tok2->insertToken("*");
|
||||
tok2->insertToken(pointers.front().c_str());
|
||||
pointers.pop_front();
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
if (num)
|
||||
|
@ -712,52 +667,30 @@ void Tokenizer::simplifyTypedef()
|
|||
if (tok->str() == ";")
|
||||
done = true;
|
||||
else if (tok->str() == ",")
|
||||
{
|
||||
if (Token::Match(tok->next(), "*| *| %type% ;|,") ||
|
||||
Token::Match(tok->next(), "*| *| %type% [ %num% ] ;|,"))
|
||||
{
|
||||
num = 0;
|
||||
pointer = (tok->tokAt(1)->str() == "*");
|
||||
toPointer = (tok->tokAt(2)->str() == "*");
|
||||
offset = 1;
|
||||
|
||||
if (pointer)
|
||||
{
|
||||
if (toPointer)
|
||||
{
|
||||
typeName = tok->strAt(3);
|
||||
while (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "*|&"))
|
||||
pointers.push_back(tok->tokAt(offset++)->str());
|
||||
|
||||
if (tok->tokAt(4)->str() == "[")
|
||||
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%"))
|
||||
{
|
||||
num = tok->tokAt(5);
|
||||
tok = tok->tokAt(7);
|
||||
}
|
||||
else
|
||||
tok = tok->tokAt(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName = tok->strAt(2);
|
||||
typeName = tok->strAt(offset++);
|
||||
|
||||
if (tok->tokAt(3)->str() == "[")
|
||||
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "[ %num% ]"))
|
||||
{
|
||||
num = tok->tokAt(4);
|
||||
tok = tok->tokAt(6);
|
||||
num = tok->tokAt(offset + 1);
|
||||
offset += 3;
|
||||
}
|
||||
else
|
||||
tok = tok->tokAt(3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName = tok->strAt(1);
|
||||
|
||||
if (tok->tokAt(2)->str() == "[")
|
||||
{
|
||||
num = tok->tokAt(3);
|
||||
tok = tok->tokAt(5);
|
||||
}
|
||||
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), ";|,"))
|
||||
tok = tok->tokAt(offset);
|
||||
else
|
||||
tok = tok->tokAt(2);
|
||||
{
|
||||
// we encountered a typedef we don't support yet so just continue
|
||||
done = true;
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -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 ;";
|
||||
|
||||
|
|
Loading…
Reference in New Issue