@@ -954,7 +954,7 @@ void simplecpp::TokenList::constFold()
954954 constFoldQuestionOp (&tok);
955955
956956 // If there is no '(' we are done with the constant folding
957- if (tok->op != ' (' )
957+ if (!tok || tok->op != ' (' )
958958 break ;
959959
960960 if (!tok->next || !tok->next ->next || tok->next ->next ->op != ' )' )
@@ -1164,10 +1164,7 @@ void simplecpp::TokenList::constFoldMulDivRem(Token *tok)
11641164 } else
11651165 continue ;
11661166
1167- tok = tok->previous ;
1168- tok->setstr (toString (result));
1169- deleteToken (tok->next );
1170- deleteToken (tok->next );
1167+ simpleSquash (tok, toString (result));
11711168 }
11721169}
11731170
@@ -1187,10 +1184,7 @@ void simplecpp::TokenList::constFoldAddSub(Token *tok)
11871184 else
11881185 continue ;
11891186
1190- tok = tok->previous ;
1191- tok->setstr (toString (result));
1192- deleteToken (tok->next );
1193- deleteToken (tok->next );
1187+ simpleSquash (tok, toString (result));
11941188 }
11951189}
11961190
@@ -1210,10 +1204,7 @@ void simplecpp::TokenList::constFoldShift(Token *tok)
12101204 else
12111205 continue ;
12121206
1213- tok = tok->previous ;
1214- tok->setstr (toString (result));
1215- deleteToken (tok->next );
1216- deleteToken (tok->next );
1207+ simpleSquash (tok, toString (result));
12171208 }
12181209}
12191210
@@ -1247,10 +1238,7 @@ void simplecpp::TokenList::constFoldComparison(Token *tok)
12471238 else
12481239 continue ;
12491240
1250- tok = tok->previous ;
1251- tok->setstr (toString (result));
1252- deleteToken (tok->next );
1253- deleteToken (tok->next );
1241+ simpleSquash (tok, toString (result));
12541242 }
12551243}
12561244
@@ -1282,12 +1270,51 @@ void simplecpp::TokenList::constFoldBitwise(Token *tok)
12821270 result = (stringToLL (tok->previous ->str ()) ^ stringToLL (tok->next ->str ()));
12831271 else /* if (*op == '|')*/
12841272 result = (stringToLL (tok->previous ->str ()) | stringToLL (tok->next ->str ()));
1285- tok = tok->previous ;
1286- tok->setstr (toString (result));
1287- deleteToken (tok->next );
1288- deleteToken (tok->next );
1273+ simpleSquash (tok, toString (result));
1274+ }
1275+ }
1276+ }
1277+
1278+ void simplecpp::TokenList::simpleSquash (Token *&tok, const std::string & result)
1279+ {
1280+ tok = tok->previous ;
1281+ tok->setstr (result);
1282+ deleteToken (tok->next );
1283+ deleteToken (tok->next );
1284+ }
1285+
1286+ void simplecpp::TokenList::squashTokens (Token *&tok, const std::set<std::string> & breakPoints, bool forwardDirection, const std::string & result)
1287+ {
1288+ const char * const brackets = forwardDirection ? " ()" : " )(" ;
1289+ Token* Token::* const step = forwardDirection ? &Token::next : &Token::previous;
1290+ int skip = 0 ;
1291+ const Token * const tok1 = tok->*step;
1292+ while (tok1 && tok1->*step) {
1293+ if ((tok1->*step)->op == brackets[1 ]){
1294+ if (skip) {
1295+ --skip;
1296+ deleteToken (tok1->*step);
1297+ } else
1298+ break ;
1299+ } else if ((tok1->*step)->op == brackets[0 ]) {
1300+ ++skip;
1301+ deleteToken (tok1->*step);
1302+ } else if (skip) {
1303+ deleteToken (tok1->*step);
1304+ } else if (breakPoints.count ((tok1->*step)->str ()) != 0 ) {
1305+ break ;
1306+ } else {
1307+ deleteToken (tok1->*step);
12891308 }
12901309 }
1310+ simpleSquash (tok, result);
1311+ }
1312+
1313+ static simplecpp::Token * constFoldGetOperand (simplecpp::Token * tok, bool forwardDirection)
1314+ {
1315+ simplecpp::Token* simplecpp::Token::* const step = forwardDirection ? &simplecpp::Token::next : &simplecpp::Token::previous;
1316+ const char bracket = forwardDirection ? ' )' : ' (' ;
1317+ return tok->*step && (tok->*step)->number && (!((tok->*step)->*step) || (((tok->*step)->*step)->op == bracket)) ? tok->*step : nullptr ;
12911318}
12921319
12931320static const std::string AND (" and" );
@@ -1303,21 +1330,24 @@ void simplecpp::TokenList::constFoldLogicalOp(Token *tok)
13031330 }
13041331 if (tok->str () != " &&" && tok->str () != " ||" )
13051332 continue ;
1306- if (!tok-> previous || ! tok-> previous -> number )
1307- continue ;
1308- if (!tok-> next || !tok-> next -> number )
1333+ const Token* const lhs = constFoldGetOperand ( tok, false );
1334+ const Token* const rhs = constFoldGetOperand (tok, true ) ;
1335+ if (!lhs) // if lhs is not a single number we don't need to fold
13091336 continue ;
13101337
1311- int result;
1312- if (tok->str () == " ||" )
1313- result = (stringToLL (tok->previous ->str ()) || stringToLL (tok->next ->str ()));
1314- else /* if (tok->str() == "&&")*/
1315- result = (stringToLL (tok->previous ->str ()) && stringToLL (tok->next ->str ()));
1316-
1317- tok = tok->previous ;
1318- tok->setstr (toString (result));
1319- deleteToken (tok->next );
1320- deleteToken (tok->next );
1338+ std::set<std::string> breakPoints;
1339+ breakPoints.insert (" :" );
1340+ breakPoints.insert (" ?" );
1341+ if (tok->str () == " ||" ){
1342+ if (stringToLL (lhs->str ()) != 0LL || (rhs && stringToLL (rhs->str ()) != 0LL ))
1343+ squashTokens (tok, breakPoints, stringToLL (lhs->str ()) != 0LL , toString (1 ));
1344+ } else /* if (tok->str() == "&&")*/ {
1345+ breakPoints.insert (" ||" );
1346+ if (stringToLL (lhs->str ()) == 0LL || (rhs && stringToLL (rhs->str ()) == 0LL ))
1347+ squashTokens (tok, breakPoints, stringToLL (lhs->str ()) == 0LL , toString (0 ));
1348+ else if (rhs && stringToLL (lhs->str ()) && stringToLL (rhs->str ()))
1349+ simpleSquash (tok, " 1" );
1350+ }
13211351 }
13221352}
13231353
0 commit comments