Skip to content

Commit ab690bb

Browse files
committed
Add reusable expandTrailingCalls
1 parent 2fb6739 commit ab690bb

1 file changed

Lines changed: 38 additions & 36 deletions

File tree

simplecpp.cpp

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2174,24 +2174,34 @@ namespace simplecpp {
21742174
return &it->second;
21752175
}
21762176

2177-
const Token *recursiveExpandToken(TokenList &output, TokenList &temp, const Location &loc, const Token *tok, const MacroMap &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) 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.
2177+
/** Expand while the expansion result in @p temp ends with the name of a
2178+
* function-like macro whose arguments are supplied by the tokens after @p tok.
2179+
* Each round consumes that macro call from the token stream, so tok always
2180+
* advances. The @p gatherCall callback copies the "( ... )" tokens that follow
2181+
* @p lpar into its output list and returns the matching ')', or nullptr when no
2182+
* complete call is available. Returns the last consumed token. */
2183+
template<class GatherCall>
2184+
const Token *expandTrailingCalls(TokenList &output, TokenList &temp, const Location &loc, const Token *tok, const MacroMap &macros, const std::set<TokenString> &expandedmacros, GatherCall gatherCall) const {
21812185
while (const Macro * const calledMacro = rescanMacro(temp, tok, macros, expandedmacros)) {
21822186
TokenList temp2(files);
2183-
temp2.push_back(new Token(temp.cback()->str(), tok->location));
2187+
temp2.push_back(new Token(temp.cback()->str(), tok->next->location));
21842188

2185-
const Token * const tok2 = appendTokens(temp2, loc, tok->next, macros, expandedmacros, parametertokens);
2186-
if (!tok2)
2189+
const Token * const closingPar = gatherCall(temp2, tok->next);
2190+
if (!closingPar)
21872191
break;
21882192
output.takeTokens(temp);
21892193
output.deleteToken(output.back());
21902194
calledMacro->expand(temp, loc, temp2.cfront(), macros, expandedmacros);
2191-
tok = tok2;
2195+
tok = closingPar;
21922196
}
21932197
output.takeTokens(temp);
2194-
return tok->next;
2198+
return tok;
2199+
}
2200+
2201+
const Token *recursiveExpandToken(TokenList &output, TokenList &temp, const Location &loc, const Token *tok, const MacroMap &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
2202+
return expandTrailingCalls(output, temp, loc, tok, macros, expandedmacros, [&](TokenList &temp2, const Token *lpar) {
2203+
return appendTokens(temp2, loc, lpar, macros, expandedmacros, parametertokens);
2204+
})->next;
21952205
}
21962206

21972207
const Token *expandToken(TokenList &output, const Location &loc, const Token *tok, const MacroMap &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
@@ -2317,36 +2327,28 @@ namespace simplecpp {
23172327
std::set<TokenString> expandedmacros2(expandedmacros); // temporary amnesia to allow reexpansion of currently expanding macros during argument evaluation
23182328
expandedmacros2.erase(name());
23192329
TokenList temp(files);
2320-
partok = it->second.expand(temp, loc, partok, macros, expandedmacros2);
2321-
// Expand while the expansion result ends with the name of a
2322-
// function-like macro whose arguments are supplied by the
2323-
// remaining argument tokens
2324-
while (partok && partok->previous) {
2325-
const Macro * const calledMacro = rescanMacro(temp, partok->previous, macros, expandedmacros2);
2326-
if (!calledMacro)
2327-
break;
2328-
TokenList temp2(files);
2329-
temp2.push_back(new Token(temp.cback()->str(), partok->location));
2330-
unsigned int par = 0;
2331-
const Token *tok2 = partok;
2332-
for (; tok2 && tok2 != argEnd; tok2 = tok2->next) {
2333-
temp2.push_back(new Token(*tok2));
2334-
if (tok2->op == '(')
2335-
++par;
2336-
else if (tok2->op == ')') {
2337-
--par;
2338-
if (par == 0U)
2339-
break;
2330+
partok = it->second.expand(temp, loc, partok, macros, std::move(expandedmacros2));
2331+
if (partok->op == '(' && temp.cback() && temp.cback()->name) {
2332+
// the expansion result may end with the name of a function-like
2333+
// macro whose arguments are supplied by the remaining argument tokens
2334+
std::set<TokenString> expandedmacros3(expandedmacros);
2335+
expandedmacros3.erase(name());
2336+
partok = expandTrailingCalls(output, temp, loc, partok->previous, macros, expandedmacros3, [&](TokenList &temp2, const Token *lpar) -> const Token * {
2337+
unsigned int par = 0;
2338+
for (const Token *tok2 = lpar; tok2 != argEnd; tok2 = tok2->next) {
2339+
temp2.push_back(new Token(*tok2));
2340+
if (tok2->op == '(')
2341+
++par;
2342+
else if (tok2->op == ')') {
2343+
if (--par == 0U)
2344+
return tok2;
2345+
}
23402346
}
2341-
}
2342-
if (!tok2 || tok2 == argEnd)
2343-
break;
2347+
return nullptr;
2348+
})->next;
2349+
} else {
23442350
output.takeTokens(temp);
2345-
output.deleteToken(output.back());
2346-
calledMacro->expand(temp, loc, temp2.cfront(), macros, expandedmacros2);
2347-
partok = tok2->next;
23482351
}
2349-
output.takeTokens(temp);
23502352
} else {
23512353
output.push_back(newMacroToken(partok->str(), loc, isReplaced(expandedmacros), partok));
23522354
output.back()->macro = partok->macro;

0 commit comments

Comments
 (0)