From b20cf06b66db233c0351dd76c883cf24de63b560 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 23 May 2010 10:46:39 +0200 Subject: [PATCH] Fixed #1671 (simplifyTypedef: support for more typedefs) --- lib/tokenize.cpp | 46 +++++++++ test/testsimplifytokens.cpp | 192 ++++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index aba7f1652..305eef748 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -727,6 +727,8 @@ void Tokenizer::simplifyTypedef() Token *argEnd = 0; Token *arrayStart = 0; Token *arrayEnd = 0; + Token *specStart = 0; + Token *specEnd = 0; Token *typeDef = tok; int offset = 1; bool function = false; @@ -740,6 +742,9 @@ void Tokenizer::simplifyTypedef() typeStart = tok->next(); offset = 1; + if (Token::Match(typeStart, "const")) + offset++; + typeEnd = tok->tokAt(offset++); bool atEnd = false; @@ -751,6 +756,11 @@ void Tokenizer::simplifyTypedef() if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%") && tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,|(")) typeEnd = tok->tokAt(offset++); + else if (Token::Match(tok->tokAt(offset), "const (")) + { + typeEnd = tok->tokAt(offset++); + atEnd = true; + } else atEnd = true; } @@ -881,6 +891,18 @@ void Tokenizer::simplifyTypedef() // internal error 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% ) (")) { @@ -902,6 +924,18 @@ void Tokenizer::simplifyTypedef() // internal error 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% (")) { @@ -1162,6 +1196,18 @@ void Tokenizer::simplifyTypedef() tok2->insertToken(")"); tok2 = tok2->next(); 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) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index b745c5e6a..40f179300 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -195,6 +195,7 @@ private: TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 + TEST_CASE(simplifyTypedefFunction3); TEST_CASE(reverseArraySyntax) TEST_CASE(simplify_numeric_condition) @@ -4051,6 +4052,197 @@ private: 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() { ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));