Fixed #1671 (simplifyTypedef: support for more typedefs)

This commit is contained in:
Robert Reif 2010-05-23 10:46:39 +02:00 committed by Daniel Marjamäki
parent 048733a15e
commit b20cf06b66
2 changed files with 238 additions and 0 deletions

View File

@ -727,6 +727,8 @@ void Tokenizer::simplifyTypedef()
Token *argEnd = 0; Token *argEnd = 0;
Token *arrayStart = 0; Token *arrayStart = 0;
Token *arrayEnd = 0; Token *arrayEnd = 0;
Token *specStart = 0;
Token *specEnd = 0;
Token *typeDef = tok; Token *typeDef = tok;
int offset = 1; int offset = 1;
bool function = false; bool function = false;
@ -740,6 +742,9 @@ void Tokenizer::simplifyTypedef()
typeStart = tok->next(); typeStart = tok->next();
offset = 1; offset = 1;
if (Token::Match(typeStart, "const"))
offset++;
typeEnd = tok->tokAt(offset++); typeEnd = tok->tokAt(offset++);
bool atEnd = false; bool atEnd = false;
@ -751,6 +756,11 @@ void Tokenizer::simplifyTypedef()
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%") && if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%") &&
tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,|(")) tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,|("))
typeEnd = tok->tokAt(offset++); typeEnd = tok->tokAt(offset++);
else if (Token::Match(tok->tokAt(offset), "const ("))
{
typeEnd = tok->tokAt(offset++);
atEnd = true;
}
else else
atEnd = true; atEnd = true;
} }
@ -881,6 +891,18 @@ void Tokenizer::simplifyTypedef()
// internal error // internal error
continue; continue;
} }
Token *spec = tok;
if (Token::Match(spec, "const|volatile"))
{
specStart = spec;
specEnd = spec;
while (Token::Match(spec->next(), "const|volatile"))
{
specEnd = spec->next();
spec = specEnd;
}
tok = specEnd->next();
}
} }
else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( %var% :: *|&| %type% ) (")) else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( %var% :: *|&| %type% ) ("))
{ {
@ -902,6 +924,18 @@ void Tokenizer::simplifyTypedef()
// internal error // internal error
continue; continue;
} }
Token *spec = tok;
if (Token::Match(spec, "const|volatile"))
{
specStart = spec;
specEnd = spec;
while (Token::Match(spec->next(), "const|volatile"))
{
specEnd = spec->next();
spec = specEnd;
}
tok = specEnd->next();
}
} }
else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( %type% (")) else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( %type% ("))
{ {
@ -1162,6 +1196,18 @@ void Tokenizer::simplifyTypedef()
tok2->insertToken(")"); tok2->insertToken(")");
tok2 = tok2->next(); tok2 = tok2->next();
Token::createMutualLinks(tok2, tok3); Token::createMutualLinks(tok2, tok3);
if (specStart)
{
Token *spec = specStart;
tok2->insertToken(spec->str());
tok2 = tok2->next();
while (spec != specEnd)
{
spec = spec->next();
tok2->insertToken(spec->str());
tok2 = tok2->next();
}
}
} }
if (arrayStart && arrayEnd) if (arrayStart && arrayEnd)

View File

@ -195,6 +195,7 @@ private:
TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685 TEST_CASE(simplifyTypedefFunction2); // ticket #1685
TEST_CASE(simplifyTypedefFunction3);
TEST_CASE(reverseArraySyntax) TEST_CASE(reverseArraySyntax)
TEST_CASE(simplify_numeric_condition) TEST_CASE(simplify_numeric_condition)
@ -4051,6 +4052,197 @@ private:
ASSERT_EQUALS(expected, sizeof_(code)); ASSERT_EQUALS(expected, sizeof_(code));
} }
void simplifyTypedefFunction3()
{
{
const char code[] = "typedef C func1();\n"
"typedef C (* func2)();\n"
"typedef C (& func3)();\n"
"typedef C (C::* func4)();\n"
"typedef C (C::* func5)() const;\n"
"typedef C (C::* func6)() volatile;\n"
"typedef C (C::* func7)() const volatile;\n"
"func1 f1;\n"
"func2 f2;\n"
"func3 f3;\n"
"func4 f4;\n"
"func5 f5;\n"
"func6 f6;\n"
"func7 f7;";
// The expected result..
const std::string expected("; ; ; ; ; ; ; "
"C f1 ( ) ; "
"C * f2 ; " // this gets simplified to a regular pointer
"C ( & f3 ) ( ) ; "
"C ( C :: * f4 ) ( ) ; "
"C ( C :: * f5 ) ( ) const ; "
"C ( C :: * f6 ) ( ) ; " // volatile is removed
"C ( C :: * f7 ) ( ) const ;"); // volatile is removed
ASSERT_EQUALS(expected, sizeof_(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "typedef C const func1();\n"
"typedef C const (* func2)();\n"
"typedef C const (& func3)();\n"
"typedef C const (C::* func4)();\n"
"typedef C const (C::* func5)() const;\n"
"typedef C const (C::* func6)() volatile;\n"
"typedef C const (C::* func7)() const volatile;\n"
"func1 f1;\n"
"func2 f2;\n"
"func3 f3;\n"
"func4 f4;\n"
"func5 f5;\n"
"func6 f6;\n"
"func7 f7;";
// The expected result..
// C const -> const C
const std::string expected("; ; ; ; ; ; ; "
"const C f1 ( ) ; "
"const C * f2 ; " // this gets simplified to a regular pointer
"const C ( & f3 ) ( ) ; "
"const C ( C :: * f4 ) ( ) ; "
"const C ( C :: * f5 ) ( ) const ; "
"const C ( C :: * f6 ) ( ) ; " // volatile is removed
"const C ( C :: * f7 ) ( ) const ;"); // volatile is removed
ASSERT_EQUALS(expected, sizeof_(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "typedef const C func1();\n"
"typedef const C (* func2)();\n"
"typedef const C (& func3)();\n"
"typedef const C (C::* func4)();\n"
"typedef const C (C::* func5)() const;\n"
"typedef const C (C::* func6)() volatile;\n"
"typedef const C (C::* func7)() const volatile;\n"
"func1 f1;\n"
"func2 f2;\n"
"func3 f3;\n"
"func4 f4;\n"
"func5 f5;\n"
"func6 f6;\n"
"func7 f7;";
// The expected result..
const std::string expected("; ; ; ; ; ; ; "
"const C f1 ( ) ; "
"const C * f2 ; " // this gets simplified to a regular pointer
"const C ( & f3 ) ( ) ; "
"const C ( C :: * f4 ) ( ) ; "
"const C ( C :: * f5 ) ( ) const ; "
"const C ( C :: * f6 ) ( ) ; " // volatile is removed
"const C ( C :: * f7 ) ( ) const ;"); // volatile is removed
ASSERT_EQUALS(expected, sizeof_(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "typedef C * func1();\n"
"typedef C * (* func2)();\n"
"typedef C * (& func3)();\n"
"typedef C * (C::* func4)();\n"
"typedef C * (C::* func5)() const;\n"
"typedef C * (C::* func6)() volatile;\n"
"typedef C * (C::* func7)() const volatile;\n"
"func1 f1;\n"
"func2 f2;\n"
"func3 f3;\n"
"func4 f4;\n"
"func5 f5;\n"
"func6 f6;\n"
"func7 f7;";
// The expected result..
const std::string expected("; ; ; ; ; ; ; "
"C * f1 ( ) ; "
"C * * f2 ; " // this gets simplified to a regular pointer
"C * ( & f3 ) ( ) ; "
"C * ( C :: * f4 ) ( ) ; "
"C * ( C :: * f5 ) ( ) const ; "
"C * ( C :: * f6 ) ( ) ; " // volatile is removed
"C * ( C :: * f7 ) ( ) const ;"); // volatile is removed
ASSERT_EQUALS(expected, sizeof_(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "typedef const C * func1();\n"
"typedef const C * (* func2)();\n"
"typedef const C * (& func3)();\n"
"typedef const C * (C::* func4)();\n"
"typedef const C * (C::* func5)() const;\n"
"typedef const C * (C::* func6)() volatile;\n"
"typedef const C * (C::* func7)() const volatile;\n"
"func1 f1;\n"
"func2 f2;\n"
"func3 f3;\n"
"func4 f4;\n"
"func5 f5;\n"
"func6 f6;\n"
"func7 f7;";
// The expected result..
const std::string expected("; ; ; ; ; ; ; "
"const C * f1 ( ) ; "
"const C * * f2 ; " // this gets simplified to a regular pointer
"const C * ( & f3 ) ( ) ; "
"const C * ( C :: * f4 ) ( ) ; "
"const C * ( C :: * f5 ) ( ) const ; "
"const C * ( C :: * f6 ) ( ) ; " // volatile is removed
"const C * ( C :: * f7 ) ( ) const ;"); // volatile is removed
ASSERT_EQUALS(expected, sizeof_(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "typedef C const * func1();\n"
"typedef C const * (* func2)();\n"
"typedef C const * (& func3)();\n"
"typedef C const * (C::* func4)();\n"
"typedef C const * (C::* func5)() const;\n"
"typedef C const * (C::* func6)() volatile;\n"
"typedef C const * (C::* func7)() const volatile;\n"
"func1 f1;\n"
"func2 f2;\n"
"func3 f3;\n"
"func4 f4;\n"
"func5 f5;\n"
"func6 f6;\n"
"func7 f7;";
// The expected result..
// C const -> const C
const std::string expected("; ; ; ; ; ; ; "
"const C * f1 ( ) ; "
"const C * * f2 ; " // this gets simplified to a regular pointer
"const C * ( & f3 ) ( ) ; "
"const C * ( C :: * f4 ) ( ) ; "
"const C * ( C :: * f5 ) ( ) const ; "
"const C * ( C :: * f6 ) ( ) ; " // volatile is removed
"const C * ( C :: * f7 ) ( ) const ;"); // volatile is removed
ASSERT_EQUALS(expected, sizeof_(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("", errout.str());
}
}
void reverseArraySyntax() void reverseArraySyntax()
{ {
ASSERT_EQUALS("a [ 13 ]", tok("13[a]")); ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));