@@ -947,7 +947,7 @@ void simplecpp::TokenList::constFold()
947
947
constFoldQuestionOp (&tok);
948
948
949
949
// If there is no '(' we are done with the constant folding
950
- if (tok->op != ' (' )
950
+ if (!tok || tok->op != ' (' )
951
951
break ;
952
952
953
953
if (!tok->next || !tok->next ->next || tok->next ->next ->op != ' )' )
@@ -1157,10 +1157,7 @@ void simplecpp::TokenList::constFoldMulDivRem(Token *tok)
1157
1157
} else
1158
1158
continue ;
1159
1159
1160
- tok = tok->previous ;
1161
- tok->setstr (toString (result));
1162
- deleteToken (tok->next );
1163
- deleteToken (tok->next );
1160
+ simpleSquash (tok, toString (result));
1164
1161
}
1165
1162
}
1166
1163
@@ -1180,10 +1177,7 @@ void simplecpp::TokenList::constFoldAddSub(Token *tok)
1180
1177
else
1181
1178
continue ;
1182
1179
1183
- tok = tok->previous ;
1184
- tok->setstr (toString (result));
1185
- deleteToken (tok->next );
1186
- deleteToken (tok->next );
1180
+ simpleSquash (tok, toString (result));
1187
1181
}
1188
1182
}
1189
1183
@@ -1203,10 +1197,7 @@ void simplecpp::TokenList::constFoldShift(Token *tok)
1203
1197
else
1204
1198
continue ;
1205
1199
1206
- tok = tok->previous ;
1207
- tok->setstr (toString (result));
1208
- deleteToken (tok->next );
1209
- deleteToken (tok->next );
1200
+ simpleSquash (tok, toString (result));
1210
1201
}
1211
1202
}
1212
1203
@@ -1240,10 +1231,7 @@ void simplecpp::TokenList::constFoldComparison(Token *tok)
1240
1231
else
1241
1232
continue ;
1242
1233
1243
- tok = tok->previous ;
1244
- tok->setstr (toString (result));
1245
- deleteToken (tok->next );
1246
- deleteToken (tok->next );
1234
+ simpleSquash (tok, toString (result));
1247
1235
}
1248
1236
}
1249
1237
@@ -1275,12 +1263,51 @@ void simplecpp::TokenList::constFoldBitwise(Token *tok)
1275
1263
result = (stringToLL (tok->previous ->str ()) ^ stringToLL (tok->next ->str ()));
1276
1264
else /* if (*op == '|')*/
1277
1265
result = (stringToLL (tok->previous ->str ()) | stringToLL (tok->next ->str ()));
1278
- tok = tok->previous ;
1279
- tok->setstr (toString (result));
1280
- deleteToken (tok->next );
1281
- deleteToken (tok->next );
1266
+ simpleSquash (tok, toString (result));
1267
+ }
1268
+ }
1269
+ }
1270
+
1271
+ void simplecpp::TokenList::simpleSquash (Token *&tok, const std::string & result)
1272
+ {
1273
+ tok = tok->previous ;
1274
+ tok->setstr (result);
1275
+ deleteToken (tok->next );
1276
+ deleteToken (tok->next );
1277
+ }
1278
+
1279
+ void simplecpp::TokenList::squashTokens (Token *&tok, const std::set<std::string> & breakPoints, bool forwardDirection, const std::string & result)
1280
+ {
1281
+ const char * const brackets = forwardDirection ? " ()" : " )(" ;
1282
+ Token* Token::* const step = forwardDirection ? &Token::next : &Token::previous;
1283
+ int skip = 0 ;
1284
+ const Token * const tok1 = tok->*step;
1285
+ while (tok1 && tok1->*step) {
1286
+ if ((tok1->*step)->op == brackets[1 ]){
1287
+ if (skip) {
1288
+ --skip;
1289
+ deleteToken (tok1->*step);
1290
+ } else
1291
+ break ;
1292
+ } else if ((tok1->*step)->op == brackets[0 ]) {
1293
+ ++skip;
1294
+ deleteToken (tok1->*step);
1295
+ } else if (skip) {
1296
+ deleteToken (tok1->*step);
1297
+ } else if (breakPoints.count ((tok1->*step)->str ()) != 0 ) {
1298
+ break ;
1299
+ } else {
1300
+ deleteToken (tok1->*step);
1282
1301
}
1283
1302
}
1303
+ simpleSquash (tok, result);
1304
+ }
1305
+
1306
+ static simplecpp::Token * constFoldGetOperand (simplecpp::Token * tok, bool forwardDirection)
1307
+ {
1308
+ simplecpp::Token* simplecpp::Token::* const step = forwardDirection ? &simplecpp::Token::next : &simplecpp::Token::previous;
1309
+ const char bracket = forwardDirection ? ' )' : ' (' ;
1310
+ return tok->*step && (tok->*step)->number && (!((tok->*step)->*step) || (((tok->*step)->*step)->op == bracket)) ? tok->*step : nullptr ;
1284
1311
}
1285
1312
1286
1313
static const std::string AND (" and" );
@@ -1296,21 +1323,24 @@ void simplecpp::TokenList::constFoldLogicalOp(Token *tok)
1296
1323
}
1297
1324
if (tok->str () != " &&" && tok->str () != " ||" )
1298
1325
continue ;
1299
- if (!tok-> previous || ! tok-> previous -> number )
1300
- continue ;
1301
- if (!tok-> next || !tok-> next -> number )
1326
+ const Token* const lhs = constFoldGetOperand ( tok, false );
1327
+ const Token* const rhs = constFoldGetOperand (tok, true ) ;
1328
+ if (!lhs) // if lhs is not a single number we don't need to fold
1302
1329
continue ;
1303
1330
1304
- int result;
1305
- if (tok->str () == " ||" )
1306
- result = (stringToLL (tok->previous ->str ()) || stringToLL (tok->next ->str ()));
1307
- else /* if (tok->str() == "&&")*/
1308
- result = (stringToLL (tok->previous ->str ()) && stringToLL (tok->next ->str ()));
1309
-
1310
- tok = tok->previous ;
1311
- tok->setstr (toString (result));
1312
- deleteToken (tok->next );
1313
- deleteToken (tok->next );
1331
+ std::set<std::string> breakPoints;
1332
+ breakPoints.insert (" :" );
1333
+ breakPoints.insert (" ?" );
1334
+ if (tok->str () == " ||" ){
1335
+ if (stringToLL (lhs->str ()) != 0LL || (rhs && stringToLL (rhs->str ()) != 0LL ))
1336
+ squashTokens (tok, breakPoints, stringToLL (lhs->str ()) != 0LL , toString (1 ));
1337
+ } else /* if (tok->str() == "&&")*/ {
1338
+ breakPoints.insert (" ||" );
1339
+ if (stringToLL (lhs->str ()) == 0LL || (rhs && stringToLL (rhs->str ()) == 0LL ))
1340
+ squashTokens (tok, breakPoints, stringToLL (lhs->str ()) == 0LL , toString (0 ));
1341
+ else if (rhs && stringToLL (lhs->str ()) && stringToLL (rhs->str ()))
1342
+ simpleSquash (tok, " 1" );
1343
+ }
1314
1344
}
1315
1345
}
1316
1346
@@ -2088,7 +2118,7 @@ namespace simplecpp {
2088
2118
if (expandArg (&temp, defToken, parametertokens))
2089
2119
macroName = temp.cback ()->str ();
2090
2120
if (expandArg (&temp, defToken->next ->next ->next , parametertokens))
2091
- macroName += temp.cback ()->str ();
2121
+ macroName += temp.cback () ? temp. cback () ->str () : " " ;
2092
2122
else
2093
2123
macroName += defToken->next ->next ->next ->str ();
2094
2124
lastToken = defToken->next ->next ->next ;
@@ -2132,7 +2162,8 @@ namespace simplecpp {
2132
2162
for (const Token *partok = parametertokens[argnr]->next ; partok != parametertokens[argnr + 1U ];) {
2133
2163
const MacroMap::const_iterator it = macros.find (partok->str ());
2134
2164
if (it != macros.end () && !partok->isExpandedFrom (&it->second ) && (partok->str () == name () || expandedmacros.find (partok->str ()) == expandedmacros.end ())) {
2135
- const std::set<TokenString> expandedmacros2; // temporary amnesia to allow reexpansion of currently expanding macros during argument evaluation
2165
+ std::set<TokenString> expandedmacros2 (expandedmacros); // temporary amnesia to allow reexpansion of currently expanding macros during argument evaluation
2166
+ expandedmacros2.erase (name ());
2136
2167
partok = it->second .expand (output, loc, partok, macros, expandedmacros2);
2137
2168
} else {
2138
2169
output->push_back (newMacroToken (partok->str (), loc, isReplaced (expandedmacros), partok));
0 commit comments