From 6a4319f0507f882a25cc5a0ead5687c3f29b1ce0 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Tue, 26 Aug 2014 15:21:19 +0200 Subject: [PATCH] Improved simplifications: - Rearranged their order to solve problems with typedefs. If we simplify chained declarations before typedef parsing, we have less complex expressions to deal with (#4777). - Fixed detection of variables hiding enums --- lib/tokenize.cpp | 33 +++++++++++++++++++-------------- test/testsimplifytokens.cpp | 18 +++++++++--------- test/testtokenize.cpp | 2 +- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 2f1b6809e..78dd4e7da 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3298,6 +3298,15 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) simplifyDebugNew(); + // Remove __asm.. + simplifyAsm(); + + // Change initialisation of variable to assignment + simplifyInitVar(); + + // Split up variable declarations. + simplifyVarDecl(false); + // typedef.. if (m_timerResults) { Timer t("Tokenizer::tokenize::simplifyTypedef", _settings->_showtime, m_timerResults); @@ -3336,9 +3345,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) if (_settings->terminated()) return false; - // Remove __asm.. - simplifyAsm(); - // Put ^{} statements in asm() for (Token *tok = list.front(); tok; tok = tok->next()) { if (Token::simpleMatch(tok, "^ {")) { @@ -3413,19 +3419,13 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) // struct simplification "struct S {} s; => struct S { } ; S s ; simplifyStructDecl(); - // struct initialization (must be used before simplifyVarDecl) + // struct initialization (must be used after simplifyVarDecl) simplifyStructInit(); - // Change initialisation of variable to assignment - simplifyInitVar(); - // The simplifyTemplates have inner loops if (_settings->terminated()) return false; - // Split up variable declarations. - simplifyVarDecl(false); - // specify array size.. needed when arrays are split arraySize(); @@ -7794,8 +7794,8 @@ void Tokenizer::simplifyEnum() break; } else if (tok3->isName() && enumValues.find(tok3->str()) != enumValues.end()) { const Token *prev = tok3->previous(); - if ((prev->isName() && !Token::Match(prev,"return|case|throw")) || - Token::Match(prev, "&|* %type% =")) { + if ((prev->isName() && !Token::Match(prev, "return|case|throw")) || + (Token::Match(prev->previous(), "%type% *|&") && (prev->previous()->isStandardType() || prev->strAt(-1) == "const" || Token::Match(prev->tokAt(-2), ";|{|}")))) { // variable declaration? shadowVars.insert(tok3->str()); if (inScope && _settings->isEnabled("style")) { @@ -8876,7 +8876,11 @@ std::string Tokenizer::simplifyString(const std::string &source) void Tokenizer::simplifyStructInit() { for (Token *tok = list.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "[;{}] struct| %type% %var% = { . %type% =")) { + if (Token::Match(tok, "[;{}] struct| %type% %var% ; %var% = { . %type% =")) { + tok = Token::findsimplematch(tok->tokAt(3), ";"); + if (tok->strAt(-1) != tok->strAt(1)) + continue; + // Goto "." and check if the initializations have an expected format const Token *tok2 = tok; while (tok2->str() != ".") @@ -8896,7 +8900,7 @@ void Tokenizer::simplifyStructInit() continue; // Known expression format => Perform simplification - Token *vartok = tok->tokAt(3); + Token *vartok = tok->next(); if (vartok->str() == "=") vartok = vartok->previous(); vartok->next()->str(";"); @@ -8915,6 +8919,7 @@ void Tokenizer::simplifyStructInit() } tok3->previous()->insertToken(";"); } + vartok->deleteNext(2); } } } diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index f58f561ca..979826f37 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -4342,7 +4342,7 @@ private: "class X { } ; " "int main ( ) " "{ " - "X ( * * Foo ) ( const X & ) = new X ( * ) ( const X & ) [ 2 ] ; " + "X ( * * Foo ) ( const X & ) ; Foo = new X ( * ) ( const X & ) [ 2 ] ; " "}"; ASSERT_EQUALS(expected, tok(code, false)); @@ -4825,7 +4825,7 @@ private: // The expected result.. const std::string expected("class A { public: int i ; } ; " - "const char ( A :: * t1 ) = & A :: i ;"); + "const char ( A :: * t1 ) ; t1 = & A :: i ;"); ASSERT_EQUALS(expected, tok(code)); } @@ -5048,7 +5048,7 @@ private: "}"; // The expected tokens.. - const std::string expected2("void f ( ) { char a [ 256 ] = { 0 } ; char b [ 256 ] = { 0 } ; }"); + const std::string expected2("void f ( ) { char a [ 256 ] ; a = { 0 } ; char b [ 256 ] ; b = { 0 } ; }"); ASSERT_EQUALS(expected2, tok(code2, false)); // Check for output.. @@ -5062,7 +5062,7 @@ private: "}"; // The expected tokens.. - const std::string expected3("void f ( ) { char a [ 256 ] = \"\" ; char b [ 256 ] = \"\" ; }"); + const std::string expected3("void f ( ) { char a [ 256 ] ; a = \"\" ; char b [ 256 ] ; b = \"\" ; }"); ASSERT_EQUALS(expected3, tok(code3, false)); // Check for output.. @@ -5076,7 +5076,7 @@ private: "}"; // The expected tokens.. - const std::string expected4("void f ( ) { char a [ 256 ] = \"1234\" ; char b [ 256 ] = \"5678\" ; }"); + const std::string expected4("void f ( ) { char a [ 256 ] ; a = \"1234\" ; char b [ 256 ] ; b = \"5678\" ; }"); ASSERT_EQUALS(expected4, tok(code4, false)); // Check for output.. @@ -5254,7 +5254,7 @@ private: "typedef state_func_t (*state_t)(void);\n" "state_t current_state = death;\n" "static char get_runlevel(const state_t);\n"; - const std::string expected = "long ( * ( * current_state ) ( void ) ) ( void ) = death ; " + const std::string expected = "long ( * ( * current_state ) ( void ) ) ( void ) ; current_state = death ; " "static char get_runlevel ( const long ( * ( * ) ( void ) ) ( void ) ) ;"; ASSERT_EQUALS(expected, tok(code)); ASSERT_EQUALS("", errout.str()); @@ -7286,9 +7286,9 @@ private: } void initstruct() { - ASSERT_EQUALS("; struct A a ; a . buf = 3 ;", tok("; struct A a = { .buf = 3 };")); - ASSERT_EQUALS("; struct A a ; a . buf = x ;", tok("; struct A a = { .buf = x };")); - ASSERT_EQUALS("; struct A a ; a . buf = & key ;", tok("; struct A a = { .buf = &key };")); + ASSERT_EQUALS("; struct A a ; a . buf = 3 ;", tok("; struct A a ; a = { .buf = 3 };")); + ASSERT_EQUALS("; struct A a ; a . buf = x ;", tok("; struct A a ; a = { .buf = x };")); + ASSERT_EQUALS("; struct A a ; a . buf = & key ;", tok("; struct A a ; a = { .buf = &key };")); ASSERT_EQUALS("; struct ABC abc ; abc . a = 3 ; abc . b = x ; abc . c = & key ;", tok("; struct ABC abc = { .a = 3, .b = x, .c = &key };")); TODO_ASSERT_EQUALS("; struct A a ; a . buf = { 0 } ;", "; struct A a ; a = { . buf = { 0 } } ;", diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 5580a358b..da0efcbe0 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -906,7 +906,7 @@ private: ASSERT_EQUALS(code, tokenizeAndStringify(code)); } - // ##5780 Various crashes on valid template code in Tokenizer::setVarId() + // #5780 Various crashes on valid template code in Tokenizer::setVarId() void tokenize33() { const char * code = "template> struct vector {};\n" "void z() {\n"