@@ -1707,7 +1707,7 @@ namespace simplecpp {
17071707 if (output2.cfront () != output2.cback () && macro2tok->str () == this ->name ())
17081708 break ;
17091709 const MacroMap::const_iterator macro = macros.find (macro2tok->str ());
1710- if (macro == macros.end () || !macro->second .functionLike ())
1710+ if (macro == macros.end () || !macro->second .functionLike () || macro2tok-> isExpandedFrom (¯o-> second ) )
17111711 break ;
17121712 TokenList rawtokens2 (inputFiles);
17131713 const Location loc (macro2tok->location );
@@ -2161,39 +2161,37 @@ namespace simplecpp {
21612161 return functionLike () ? parametertokens2.back ()->next : nameTokInst->next ;
21622162 }
21632163
2164- const Token *recursiveExpandToken (TokenList &output, TokenList &temp, const Location &loc, const Token *tok, const MacroMap ¯os, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> ¶metertokens) const {
2165- if (!temp.cback () || !temp.cback ()->name || !tok->next || tok->next ->op != ' (' ) {
2166- output.takeTokens (temp);
2167- return tok->next ;
2168- }
2169-
2170- if (!sameline (tok, tok->next )) {
2171- output.takeTokens (temp);
2172- return tok->next ;
2173- }
2174-
2164+ /* * Returns the macro to expand when the last token of @p temp is the name of a
2165+ * function-like macro and the tokens after @p tok supply its arguments; nullptr otherwise */
2166+ static const Macro *rescanMacro (const TokenList &temp, const Token *tok, const MacroMap ¯os, const std::set<TokenString> &expandedmacros) {
2167+ if (!temp.cback () || !temp.cback ()->name || !sameline (tok, tok->next ) || tok->next ->op != ' (' )
2168+ return nullptr ;
21752169 const MacroMap::const_iterator it = macros.find (temp.cback ()->str ());
2176- if (it == macros.end () || expandedmacros.find (temp.cback ()->str ()) != expandedmacros.end ()) {
2177- output.takeTokens (temp);
2178- return tok->next ;
2179- }
2170+ if (it == macros.end () || expandedmacros.find (temp.cback ()->str ()) != expandedmacros.end ())
2171+ return nullptr ;
2172+ if (!it->second .functionLike () || temp.cback ()->isExpandedFrom (&it->second ))
2173+ return nullptr ;
2174+ return &it->second ;
2175+ }
21802176
2181- const Macro &calledMacro = it->second ;
2182- if (!calledMacro.functionLike ()) {
2177+ const Token *recursiveExpandToken (TokenList &output, TokenList &temp, const Location &loc, const Token *tok, const MacroMap ¯os, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> ¶metertokens) const {
2178+ // Expand while the expansion result ends with the name of a function-like
2179+ // macro whose arguments are supplied by the tokens that follow it. Each round
2180+ // consumes that macro call from the token stream, so tok always advances.
2181+ while (const Macro * const calledMacro = rescanMacro (temp, tok, macros, expandedmacros)) {
2182+ TokenList temp2 (files);
2183+ temp2.push_back (new Token (temp.cback ()->str (), tok->location ));
2184+
2185+ const Token * const tok2 = appendTokens (temp2, loc, tok->next , macros, expandedmacros, parametertokens);
2186+ if (!tok2)
2187+ break ;
21832188 output.takeTokens (temp);
2184- return tok->next ;
2189+ output.deleteToken (output.back ());
2190+ calledMacro->expand (temp, loc, temp2.cfront (), macros, expandedmacros);
2191+ tok = tok2;
21852192 }
2186-
2187- TokenList temp2 (files);
2188- temp2.push_back (new Token (temp.cback ()->str (), tok->location ));
2189-
2190- const Token * const tok2 = appendTokens (temp2, loc, tok->next , macros, expandedmacros, parametertokens);
2191- if (!tok2)
2192- return tok->next ;
21932193 output.takeTokens (temp);
2194- output.deleteToken (output.back ());
2195- calledMacro.expand (output, loc, temp2.cfront (), macros, expandedmacros);
2196- return tok2->next ;
2194+ return tok->next ;
21972195 }
21982196
21992197 const Token *expandToken (TokenList &output, const Location &loc, const Token *tok, const MacroMap ¯os, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> ¶metertokens) const {
0 commit comments