Fixed #1671 (simplifyTypedef: support for more typedefs)

This commit is contained in:
Robert Reif 2010-05-25 20:43:44 +02:00 committed by Daniel Marjamäki
parent 4306082fcf
commit 019e1f9dfe
2 changed files with 157 additions and 1 deletions

View File

@ -730,10 +730,14 @@ void Tokenizer::simplifyTypedef()
Token *specStart = 0;
Token *specEnd = 0;
Token *typeDef = tok;
Token *argFuncRetStart = 0;
Token *argFuncRetEnd = 0;
int offset = 1;
bool function = false;
bool functionPtr = false;
bool functionRef = false;
bool functionRetFuncPtr = false;
bool functionPtrRetFuncPtr = false;
Token *functionNamespace = 0;
if (Token::Match(tok->next(), "::") ||
@ -953,9 +957,53 @@ void Tokenizer::simplifyTypedef()
continue;
}
}
// pointer to function returning pointer to function
else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( * ( * %type% ) ("))
{
functionPtrRetFuncPtr = true;
typeName = tok->tokAt(offset + 4);
argStart = tok->tokAt(offset + 6);
argEnd = tok->tokAt(offset + 6)->link();
argFuncRetStart = argEnd->tokAt(2);
argFuncRetEnd = argEnd->tokAt(2)->link();
tok = argFuncRetEnd->next();
}
// function returning pointer to function
else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( * %type% ("))
{
functionRetFuncPtr = true;
typeName = tok->tokAt(offset + 2);
argStart = tok->tokAt(offset + 3);
argEnd = tok->tokAt(offset + 3)->link();
argFuncRetStart = argEnd->tokAt(2);
argFuncRetEnd = argEnd->tokAt(2)->link();
tok = argFuncRetEnd->next();
}
else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( * ( %type% ) ("))
{
functionRetFuncPtr = true;
typeName = tok->tokAt(offset + 3);
argStart = tok->tokAt(offset + 5);
argEnd = tok->tokAt(offset + 5)->link();
argFuncRetStart = argEnd->tokAt(2);
argFuncRetEnd = argEnd->tokAt(2)->link();
tok = argFuncRetEnd->next();
}
// unhandled typedef, skip it and continue
else
{
// unhandled typedef, skip it and continue
continue;
}
@ -1209,6 +1257,93 @@ void Tokenizer::simplifyTypedef()
}
}
}
else if (functionRetFuncPtr || functionPtrRetFuncPtr)
{
tok2->insertToken("(");
tok2 = tok2->next();
Token *tok3 = tok2;
tok2->insertToken("*");
tok2 = tok2->next();
Token * tok4 = 0;
if (functionPtrRetFuncPtr)
{
tok2->insertToken("(");
tok2 = tok2->next();
tok4 = tok2;
tok2->insertToken("*");
tok2 = tok2->next();
}
// skip over variable name
tok2 = tok2->next();
if (tok4 && functionPtrRetFuncPtr)
{
tok2->insertToken(")");
tok2 = tok2->next();
Token::createMutualLinks(tok2, tok4);
}
tok2->insertToken("(");
tok2 = tok2->next();
Token *tok5 = tok2;
Token *nextArgTok;
std::stack<Token *> argLinks;
for (nextArgTok = argStart->next(); nextArgTok != argEnd; nextArgTok = nextArgTok->next())
{
tok2->insertToken(nextArgTok->str());
tok2 = tok2->next();
// Check for links and fix them up
if (tok2->str() == "(" || tok2->str() == "[")
argLinks.push(tok2);
if (tok2->str() == ")" || tok2->str() == "]")
{
Token * link = argLinks.top();
tok2->link(link);
link->link(tok2);
argLinks.pop();
}
}
tok2->insertToken(")");
tok2 = tok2->next();
Token::createMutualLinks(tok2, tok5);
tok2->insertToken(")");
tok2 = tok2->next();
Token::createMutualLinks(tok2, tok3);
tok2->insertToken("(");
tok2 = tok2->next();
Token *tok6 = tok2;
for (nextArgTok = argFuncRetStart->next(); nextArgTok != argFuncRetEnd; nextArgTok = nextArgTok->next())
{
tok2->insertToken(nextArgTok->str());
tok2 = tok2->next();
// Check for links and fix them up
if (tok2->str() == "(" || tok2->str() == "[")
argLinks.push(tok2);
if (tok2->str() == ")" || tok2->str() == "]")
{
Token * link = argLinks.top();
tok2->link(link);
link->link(tok2);
argLinks.pop();
}
}
tok2->insertToken(")");
tok2 = tok2->next();
Token::createMutualLinks(tok2, tok6);
}
if (arrayStart && arrayEnd)
{

View File

@ -196,6 +196,7 @@ private:
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
TEST_CASE(simplifyTypedefFunction3);
TEST_CASE(simplifyTypedefFunction4);
TEST_CASE(reverseArraySyntax)
TEST_CASE(simplify_numeric_condition)
@ -4243,6 +4244,26 @@ private:
}
}
void simplifyTypedefFunction4()
{
const char code[] = "typedef int ( * ( * type1 ) ( bool ) ) ( int , int ) ;\n"
"typedef int ( * ( type2 ) ( bool ) ) ( int , int ) ;\n"
"typedef int ( * type3 ( bool ) ) ( int , int ) ;\n"
"type1 t1;\n"
"type2 t2;\n"
"type3 t3;";
// The expected result..
const std::string expected("; ; ; "
"int ( * ( * t1 ) ( bool ) ) ( int , int ) ; "
"int ( * t2 ( bool ) ) ( int , int ) ; "
"int ( * t3 ( bool ) ) ( int , int ) ;");
ASSERT_EQUALS(expected, tok(code, false));
checkSimplifyTypedef(code);
ASSERT_EQUALS("", errout.str());
}
void reverseArraySyntax()
{
ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));