@@ -425,9 +425,38 @@ class Parser {
425425 llvm::Optional<SyntaxParsingContext> SynContext;
426426 bool Backtrack = true ;
427427
428+ // / A token receiver used by the parser in the back tracking scope. This
429+ // / receiver will save any consumed tokens during this back tracking scope.
430+ // / After the scope ends, it either transfers the saved tokens to the old receiver
431+ // / or discard them.
432+ struct DelayedTokenReceiver : ConsumeTokenReceiver {
433+ // / Keep track of the old token receiver in the parser so that we can recover
434+ // / after the backtracking sope ends.
435+ llvm::SaveAndRestore<ConsumeTokenReceiver*> savedConsumer;
436+
437+ // Whether the tokens should be transferred to the original receiver.
438+ // When the back tracking scope will actually back track, this should be false;
439+ // otherwise true.
440+ bool shouldTransfer = false ;
441+ std::vector<Token> delayedTokens;
442+ DelayedTokenReceiver (ConsumeTokenReceiver *&receiver):
443+ savedConsumer (receiver, this ) {}
444+ void receive (Token tok) override {
445+ delayedTokens.push_back (tok);
446+ }
447+ ~DelayedTokenReceiver () {
448+ if (!shouldTransfer)
449+ return ;
450+ for (auto tok: delayedTokens) {
451+ savedConsumer.get ()->receive (tok);
452+ }
453+ }
454+ } TempReceiver;
455+
428456 public:
429457 BacktrackingScope (Parser &P)
430- : P(P), PP(P.getParserPosition()), DT(P.Diags) {
458+ : P(P), PP(P.getParserPosition()), DT(P.Diags),
459+ TempReceiver (P.TokReceiver) {
431460 SynContext.emplace (P.SyntaxContext );
432461 SynContext->setBackTracking ();
433462 }
@@ -440,8 +469,8 @@ class Parser {
440469 SynContext->setTransparent ();
441470 SynContext.reset ();
442471 DT.commit ();
472+ TempReceiver.shouldTransfer = true ;
443473 }
444-
445474 };
446475
447476 // / RAII object that, when it is destructed, restores the parser and lexer to
0 commit comments