diff --git a/simplecpp.cpp b/simplecpp.cpp index 1ae47f5e..2316c42b 100755 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -947,7 +947,7 @@ void simplecpp::TokenList::constFold() constFoldQuestionOp(&tok); // If there is no '(' we are done with the constant folding - if (!tok || tok->op != '(') + if (tok->op != '(') break; if (!tok->next || !tok->next->next || tok->next->next->op != ')') @@ -1157,7 +1157,10 @@ void simplecpp::TokenList::constFoldMulDivRem(Token *tok) } else continue; - simpleSquash(tok, toString(result)); + tok = tok->previous; + tok->setstr(toString(result)); + deleteToken(tok->next); + deleteToken(tok->next); } } @@ -1177,7 +1180,10 @@ void simplecpp::TokenList::constFoldAddSub(Token *tok) else continue; - simpleSquash(tok, toString(result)); + tok = tok->previous; + tok->setstr(toString(result)); + deleteToken(tok->next); + deleteToken(tok->next); } } @@ -1197,7 +1203,10 @@ void simplecpp::TokenList::constFoldShift(Token *tok) else continue; - simpleSquash(tok, toString(result)); + tok = tok->previous; + tok->setstr(toString(result)); + deleteToken(tok->next); + deleteToken(tok->next); } } @@ -1231,7 +1240,10 @@ void simplecpp::TokenList::constFoldComparison(Token *tok) else continue; - simpleSquash(tok, toString(result)); + tok = tok->previous; + tok->setstr(toString(result)); + deleteToken(tok->next); + deleteToken(tok->next); } } @@ -1263,51 +1275,12 @@ void simplecpp::TokenList::constFoldBitwise(Token *tok) result = (stringToLL(tok->previous->str()) ^ stringToLL(tok->next->str())); else /*if (*op == '|')*/ result = (stringToLL(tok->previous->str()) | stringToLL(tok->next->str())); - simpleSquash(tok, toString(result)); - } - } -} - -void simplecpp::TokenList::simpleSquash(Token *&tok, const std::string & result) -{ - tok = tok->previous; - tok->setstr(result); - deleteToken(tok->next); - deleteToken(tok->next); -} - -void simplecpp::TokenList::squashTokens(Token *&tok, const std::set & breakPoints, bool forwardDirection, const std::string & result) -{ - const char * const brackets = forwardDirection ? "()" : ")("; - Token* Token::* const step = forwardDirection ? &Token::next : &Token::previous; - int skip = 0; - const Token * const tok1 = tok->*step; - while (tok1 && tok1->*step) { - if ((tok1->*step)->op == brackets[1]){ - if (skip) { - --skip; - deleteToken(tok1->*step); - } else - break; - } else if ((tok1->*step)->op == brackets[0]) { - ++skip; - deleteToken(tok1->*step); - } else if (skip) { - deleteToken(tok1->*step); - } else if (breakPoints.count((tok1->*step)->str()) != 0) { - break; - } else { - deleteToken(tok1->*step); + tok = tok->previous; + tok->setstr(toString(result)); + deleteToken(tok->next); + deleteToken(tok->next); } } - simpleSquash(tok, result); -} - -static simplecpp::Token * constFoldGetOperand(simplecpp::Token * tok, bool forwardDirection) -{ - simplecpp::Token* simplecpp::Token::* const step = forwardDirection ? &simplecpp::Token::next : &simplecpp::Token::previous; - const char bracket = forwardDirection ? ')' : '('; - return tok->*step && (tok->*step)->number && (!((tok->*step)->*step) || (((tok->*step)->*step)->op == bracket)) ? tok->*step : nullptr; } static const std::string AND("and"); @@ -1323,24 +1296,21 @@ void simplecpp::TokenList::constFoldLogicalOp(Token *tok) } if (tok->str() != "&&" && tok->str() != "||") continue; - const Token* const lhs = constFoldGetOperand(tok, false); - const Token* const rhs = constFoldGetOperand(tok, true); - if (!lhs) // if lhs is not a single number we don't need to fold + if (!tok->previous || !tok->previous->number) + continue; + if (!tok->next || !tok->next->number) continue; - std::set breakPoints; - breakPoints.insert(":"); - breakPoints.insert("?"); - if (tok->str() == "||"){ - if (stringToLL(lhs->str()) != 0LL || (rhs && stringToLL(rhs->str()) != 0LL)) - squashTokens(tok, breakPoints, stringToLL(lhs->str()) != 0LL, toString(1)); - } else /*if (tok->str() == "&&")*/ { - breakPoints.insert("||"); - if (stringToLL(lhs->str()) == 0LL || (rhs && stringToLL(rhs->str()) == 0LL)) - squashTokens(tok, breakPoints, stringToLL(lhs->str()) == 0LL, toString(0)); - else if (rhs && stringToLL(lhs->str()) && stringToLL(rhs->str())) - simpleSquash(tok, "1"); - } + int result; + if (tok->str() == "||") + result = (stringToLL(tok->previous->str()) || stringToLL(tok->next->str())); + else /*if (tok->str() == "&&")*/ + result = (stringToLL(tok->previous->str()) && stringToLL(tok->next->str())); + + tok = tok->previous; + tok->setstr(toString(result)); + deleteToken(tok->next); + deleteToken(tok->next); } } diff --git a/simplecpp.h b/simplecpp.h index 0be48306..f5c69593 100755 --- a/simplecpp.h +++ b/simplecpp.h @@ -301,8 +301,6 @@ namespace simplecpp { void constFoldLogicalOp(Token *tok); void constFoldQuestionOp(Token **tok1); - void simpleSquash(Token *&tok, const std::string & result); - void squashTokens(Token *&tok, const std::set & breakPoints, bool forwardDirection, const std::string & result); std::string readUntil(Stream &stream, const Location &location, char start, char end, OutputList *outputList); void lineDirective(unsigned int fileIndex, unsigned int line, Location *location); diff --git a/test.cpp b/test.cpp index 82b9e1c7..187b7ec6 100644 --- a/test.cpp +++ b/test.cpp @@ -452,15 +452,6 @@ static void constFold() ASSERT_EQUALS("1", testConstFold("010==8")); ASSERT_EQUALS("exception", testConstFold("!1 ? 2 :")); ASSERT_EQUALS("exception", testConstFold("?2:3")); - ASSERT_EQUALS("0", testConstFold("( 0 ) && 10 < X")); - ASSERT_EQUALS("0", testConstFold("1+2*(3+4) && 7 - 7")); - ASSERT_EQUALS("1", testConstFold("( 1 ) || 10 < X")); - ASSERT_EQUALS("1", testConstFold("1+2*(3+4) || 8 - 7")); - ASSERT_EQUALS("X && 0", testConstFold("X && 0")); - ASSERT_EQUALS("X >= 0 || 0 < Y", testConstFold("X >= 0 || 0 < Y")); - ASSERT_EQUALS("X && 1 && Z", testConstFold("X && (1 || Y) && Z")); - ASSERT_EQUALS("0 || Y", testConstFold("0 && X || Y")); - ASSERT_EQUALS("X > 0 && Y", testConstFold("X > 0 && Y")); } #ifdef __CYGWIN__ @@ -1617,22 +1608,6 @@ static void ifA() ASSERT_EQUALS("\nX", preprocess(code, dui)); } -static void ifXorY() -{ - const char code[] = "#if Z > 0 || 0 < Y\n" - "X\n" - "#endif"; - ASSERT_EQUALS("", preprocess(code)); - - simplecpp::DUI dui; - dui.defines.push_back("Z=1"); - ASSERT_EQUALS("\nX", preprocess(code, dui)); - - dui.defines.clear(); - dui.defines.push_back("Y=15"); - ASSERT_EQUALS("\nX", preprocess(code, dui)); -} - static void ifCharLiteral() { const char code[] = "#if ('A'==0x41)\n" @@ -3151,7 +3126,6 @@ int main(int argc, char **argv) TEST_CASE(ifdef2); TEST_CASE(ifndef); TEST_CASE(ifA); - TEST_CASE(ifXorY); TEST_CASE(ifCharLiteral); TEST_CASE(ifDefined); TEST_CASE(ifDefinedNoPar);