Fixed #1671 (simplifyTypedef: support for more typedefs)
This commit is contained in:
parent
4306082fcf
commit
019e1f9dfe
137
lib/tokenize.cpp
137
lib/tokenize.cpp
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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]"));
|
||||
|
|
Loading…
Reference in New Issue