Fixed #1331 (simplify typedef of complex arrays)

This commit is contained in:
Robert Reif 2010-01-30 19:41:22 +01:00 committed by Daniel Marjamäki
parent 48f3921c36
commit 7cbdb9f8a1
2 changed files with 82 additions and 16 deletions

View File

@ -449,7 +449,8 @@ void Tokenizer::simplifyTypedef()
Token *typeEnd = 0; Token *typeEnd = 0;
Token *argStart = 0; Token *argStart = 0;
Token *argEnd = 0; Token *argEnd = 0;
Token *num = 0; Token *arrayStart = 0;
Token *arrayEnd = 0;
Token *typeDef = tok; Token *typeDef = tok;
int offset = 1; int offset = 1;
bool functionPtr = false; bool functionPtr = false;
@ -550,10 +551,27 @@ void Tokenizer::simplifyTypedef()
{ {
typeName = tok->strAt(offset++); typeName = tok->strAt(offset++);
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "[ %num% ]")) if (tok->tokAt(offset) && tok->tokAt(offset)->str() == "[")
{ {
num = tok->tokAt(offset + 1); arrayStart = tok->tokAt(offset);
offset += 3;
bool atEnd = false;
while (!atEnd)
{
while (tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), ";|,"))
offset++;
if (!tok->tokAt(offset + 1))
return; // invalid input
else if (tok->tokAt(offset + 1)->str() == ";")
atEnd = true;
else if (tok->tokAt(offset)->str() == "]")
atEnd = true;
else
offset++;
}
arrayEnd = tok->tokAt(offset++);
} }
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), ";|,")) if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), ";|,"))
@ -751,17 +769,30 @@ void Tokenizer::simplifyTypedef()
Token::createMutualLinks(tok2, tok3); Token::createMutualLinks(tok2, tok3);
} }
if (num) if (arrayStart && arrayEnd)
{ {
tok2 = tok2->next(); tok2 = tok2->next();
tok2->insertToken("["); Token * nextToken;
std::stack<Token *> links;
for (nextToken = arrayStart; nextToken != arrayEnd->next(); nextToken = nextToken->next())
{
tok2->insertToken(nextToken->strAt(0));
tok2 = tok2->next();
// Check for links and fix them up
if (tok2->str() == "(" || tok2->str() == "[")
links.push(tok2);
if (tok2->str() == ")" || tok2->str() == "]")
{
Token * link = links.top();
tok2->link(link);
link->link(tok2);
links.pop();
}
}
tok2 = tok2->next(); tok2 = tok2->next();
Token *tok3 = tok2;
tok2->insertToken(num->strAt(0));
tok2 = tok2->next();
tok2->insertToken("]");
tok2 = tok2->next();
Token::createMutualLinks(tok2, tok3);
} }
simplifyType = false; simplifyType = false;
@ -772,7 +803,8 @@ void Tokenizer::simplifyTypedef()
done = true; done = true;
else if (tok->str() == ",") else if (tok->str() == ",")
{ {
num = 0; arrayStart = 0;
arrayEnd = 0;
offset = 1; offset = 1;
while (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "*|&")) while (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "*|&"))
@ -782,10 +814,23 @@ void Tokenizer::simplifyTypedef()
{ {
typeName = tok->strAt(offset++); typeName = tok->strAt(offset++);
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "[ %num% ]")) if (tok->tokAt(offset) && tok->tokAt(offset)->str() == "[")
{ {
num = tok->tokAt(offset + 1); bool atEnd = false;
offset += 3; while (!atEnd)
{
while (tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), ";|,"))
offset++;
if (!tok->tokAt(offset + 1))
return; // invalid input
else if (tok->tokAt(offset + 1)->str() == ";")
atEnd = true;
else if (tok->tokAt(offset)->str() == "]")
atEnd = true;
else
offset++;
}
} }
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), ";|,")) if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), ";|,"))

View File

@ -165,6 +165,7 @@ private:
TEST_CASE(simplifyTypedef26); TEST_CASE(simplifyTypedef26);
TEST_CASE(simplifyTypedef27); TEST_CASE(simplifyTypedef27);
TEST_CASE(simplifyTypedef28); TEST_CASE(simplifyTypedef28);
TEST_CASE(simplifyTypedef29);
TEST_CASE(reverseArraySyntax) TEST_CASE(reverseArraySyntax)
TEST_CASE(simplify_numeric_condition) TEST_CASE(simplify_numeric_condition)
@ -2970,6 +2971,26 @@ private:
ASSERT_EQUALS(expected, tok(code, false)); ASSERT_EQUALS(expected, tok(code, false));
} }
void simplifyTypedef29()
{
const char code[] = "typedef int array [ice_or<is_int<int>::value, is_int<UDT>::value>::value ? 1 : -1];\n"
"typedef int array1 [N];\n"
"typedef int array2 [N][M];\n"
"array a;\n"
"array1 a1;\n"
"array2 a2;";
const char expected[] =
"; "
"; "
"; "
"int a [ ice_or < is_int < int > :: value , is_int < UDT > :: value > :: value ? 1 : - 1 ] ; "
"int a1 [ N ] ; "
"int a2 [ N ] [ M ] ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void reverseArraySyntax() void reverseArraySyntax()
{ {
ASSERT_EQUALS("a [ 13 ]", tok("13[a]")); ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));