From 496b09a3771f7b607ddbaac9e0824d9ea7bbb3f1 Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Sun, 21 Dec 2008 19:24:21 +0000 Subject: [PATCH] Remove reduntant if sentences that are never executed. --- testtokenize.cpp | 2 +- tokenize.cpp | 122 +++++++++++++++++++++++++++++++++++++++++++++++ tokenize.h | 7 +++ 3 files changed, 130 insertions(+), 1 deletion(-) diff --git a/testtokenize.cpp b/testtokenize.cpp index 27f5bfa27..1c1bc07dc 100644 --- a/testtokenize.cpp +++ b/testtokenize.cpp @@ -217,7 +217,7 @@ private: std::ostringstream ostr; for (const TOKEN *tok = tokenizer.tokens(); tok; tok = tok->next()) ostr << " " << tok->str(); - ASSERT_EQUALS( std::string(" void f ( ) { if ( true ) ; }"), ostr.str() ); + ASSERT_EQUALS( std::string(" void f ( ) { ; }"), ostr.str() ); } void simplify_known_variables() diff --git a/tokenize.cpp b/tokenize.cpp index 63bd42d5f..508ed7fe2 100644 --- a/tokenize.cpp +++ b/tokenize.cpp @@ -1033,10 +1033,132 @@ void Tokenizer::simplifyTokenList() modified |= simplifyCasts(); modified |= simplifyFunctionReturn(); modified |= simplifyKnownVariables(); + modified |= removeReduntantConditions(); } } //--------------------------------------------------------------------------- +bool Tokenizer::removeReduntantConditions() +{ + bool ret = false; + + for ( TOKEN *tok = _tokens; tok; tok = tok->next() ) + { + if (!TOKEN::Match(tok, "if ( %bool% )")) + continue; + + // Find matching else + const TOKEN *elseTag = 0; + if( TOKEN::Match( tok->tokAt( 4 ), "{" ) ) + { + // Find the closing "}" + int indentLevel = 0; + for ( const TOKEN *closing = tok->tokAt( 5 ); closing; closing = closing->next() ) + { + if( TOKEN::Match( closing, "{" ) ) + { + indentLevel++; + continue; + } + + if( TOKEN::Match( closing, "}" ) ) + indentLevel--; + + if( indentLevel >= 0 ) + continue; + + // Closing } is found. + elseTag = closing->next(); + break; + } + } + else + { + // Find the closing ";" + for ( const TOKEN *closing = tok->tokAt( 4 ); closing; closing = closing->next() ) + { + if( TOKEN::Match( closing, ";" ) ) + { + elseTag = closing->next(); + break; + } + } + } + + bool boolValue = false; + if( tok->tokAt( 2 )->str() == "true" ) + boolValue = true; + + if( elseTag && TOKEN::Match( elseTag, "else" ) ) + { + if( TOKEN::Match( elseTag->next(), "if" ) ) + { + // Handle "else if" + if( boolValue == false ) + { + // Convert "if( false ) {aaa;} else if() {bbb;}" => "if() {bbb;}" + TOKEN::eraseTokens( tok, elseTag->tokAt( 1 ) ); + ret = true; + } + else + { + // Keep first if, remove every else if and else after it + + // TODO, implement + } + } + else + { + // Handle else + if( boolValue == false ) + { + // Convert "if( false ) {aaa;} else {bbb;}" => "{bbb;}" or ";{bbb;}" + if( tok->previous() ) + tok = tok->previous(); + else + tok->setstr( ";" ); + + TOKEN::eraseTokens( tok, elseTag->tokAt( 1 ) ); + ret = true; + } + else + { + // Convert "if( true ) {aaa;} else {bbb;}" => "{aaa;}" + + // TODO, implement + } + } + } + else + { + // Handle if without else + if( boolValue == false ) + { + // Remove if and its content + if( tok->previous() ) + tok = tok->previous(); + else + tok->setstr( ";" ); + + TOKEN::eraseTokens( tok, elseTag ); + } + else + { + // convert "if( true ) {aaa;}" => "{aaa;}" + if( tok->previous() ) + tok = tok->previous(); + else + tok->setstr( ";" ); + + TOKEN::eraseTokens( tok, tok->tokAt( 5 ) ); + } + + ret = true; + } + } + + return ret; +} bool Tokenizer::simplifyConditions() { diff --git a/tokenize.h b/tokenize.h index e31af952a..76345146a 100644 --- a/tokenize.h +++ b/tokenize.h @@ -101,6 +101,13 @@ private: */ bool simplifyConditions(); + /** Remove reduntant code, e.g. if( false ) { int a; } should be + * removed, because it is never executed. + * @return true if something is modified + * false if nothing is done. + */ + bool removeReduntantConditions(); + /** Simplify casts * @return true if something is modified * false if nothing is done.