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
This commit is contained in:
PKEuS 2014-08-26 15:21:19 +02:00
parent 95bf96c980
commit 6a4319f050
3 changed files with 29 additions and 24 deletions

View File

@ -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);
}
}
}

View File

@ -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 } } ;",

View File

@ -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<typename T, typename A = Alloc<T>> struct vector {};\n"
"void z() {\n"