@@ -405,6 +405,9 @@ namespace {
405405// / underlying corrected token stream.
406406class TokenRecorder : public ConsumeTokenReceiver {
407407 ASTContext &Ctx;
408+ // / The lexer that is being used to lex the source file. Used to query whether
409+ // / lexing has been cut off.
410+ Lexer &BaseLexer;
408411 unsigned BufferID;
409412
410413 // Token list ordered by their appearance in the source file.
@@ -425,11 +428,19 @@ class TokenRecorder: public ConsumeTokenReceiver {
425428 void relexComment (CharSourceRange CommentRange,
426429 llvm::SmallVectorImpl<Token> &Scratch) {
427430 auto &SM = Ctx.SourceMgr ;
431+ auto EndOffset = SM.getLocOffsetInBuffer (CommentRange.getEnd (), BufferID);
432+ if (auto LexerCutOffOffset = BaseLexer.lexingCutOffOffset ()) {
433+ if (*LexerCutOffOffset < EndOffset) {
434+ // If lexing was cut off due to a too deep nesting level, adjust the end
435+ // offset to not point past the cut off point.
436+ EndOffset = *LexerCutOffOffset;
437+ }
438+ }
428439 Lexer L (Ctx.LangOpts , SM, BufferID, nullptr , LexerMode::Swift,
429440 HashbangMode::Disallowed, CommentRetentionMode::ReturnAsTokens,
430441 TriviaRetentionMode::WithoutTrivia,
431442 SM.getLocOffsetInBuffer (CommentRange.getStart (), BufferID),
432- SM. getLocOffsetInBuffer (CommentRange. getEnd (), BufferID) );
443+ EndOffset );
433444 while (true ) {
434445 Token Result;
435446 L.lex (Result);
@@ -441,8 +452,8 @@ class TokenRecorder: public ConsumeTokenReceiver {
441452 }
442453
443454public:
444- TokenRecorder (ASTContext &ctx, unsigned BufferID )
445- : Ctx(ctx), BufferID( BufferID) {}
455+ TokenRecorder (ASTContext &ctx, Lexer &BaseLexer )
456+ : Ctx(ctx), BaseLexer(BaseLexer), BufferID(BaseLexer.getBufferID() ) {}
446457
447458 Optional<std::vector<Token>> finalize () override {
448459 auto &SM = Ctx.SourceMgr ;
@@ -516,19 +527,14 @@ class TokenRecorder: public ConsumeTokenReceiver {
516527Parser::Parser (std::unique_ptr<Lexer> Lex, SourceFile &SF,
517528 SILParserStateBase *SIL, PersistentParserState *PersistentState,
518529 std::shared_ptr<SyntaxParseActions> SPActions)
519- : SourceMgr(SF.getASTContext().SourceMgr),
520- Diags(SF.getASTContext().Diags),
521- SF(SF),
522- L(Lex.release()),
523- SIL(SIL),
524- CurDeclContext(&SF),
525- Context(SF.getASTContext()),
526- TokReceiver(SF.shouldCollectTokens() ?
527- new TokenRecorder(SF.getASTContext(), L->getBufferID()) :
528- new ConsumeTokenReceiver()),
529- SyntaxContext(new SyntaxParsingContext(SyntaxContext, SF,
530- L->getBufferID (),
531- std::move(SPActions))) {
530+ : SourceMgr(SF.getASTContext().SourceMgr), Diags(SF.getASTContext().Diags),
531+ SF(SF), L(Lex.release()), SIL(SIL), CurDeclContext(&SF),
532+ Context(SF.getASTContext()),
533+ TokReceiver(SF.shouldCollectTokens()
534+ ? new TokenRecorder(SF.getASTContext(), *L)
535+ : new ConsumeTokenReceiver()),
536+ SyntaxContext(new SyntaxParsingContext(
537+ SyntaxContext, SF, L->getBufferID (), std::move(SPActions))) {
532538 State = PersistentState;
533539 if (!State) {
534540 OwnedState.reset (new PersistentParserState ());
@@ -880,28 +886,25 @@ getStructureMarkerKindForToken(const Token &tok) {
880886 }
881887}
882888
883- Parser::StructureMarkerRAII::StructureMarkerRAII (Parser &parser,
884- const Token &tok)
885- : StructureMarkerRAII(parser, tok.getLoc(),
886- getStructureMarkerKindForToken(tok)) {}
887-
888- bool Parser::StructureMarkerRAII::pushStructureMarker (
889- Parser &parser, SourceLoc loc,
890- StructureMarkerKind kind) {
891-
892- if (parser.StructureMarkers .size () < MaxDepth) {
893- parser.StructureMarkers .push_back ({loc, kind, None});
894- return true ;
895- } else {
889+ Parser::StructureMarkerRAII::StructureMarkerRAII (Parser &parser, SourceLoc loc,
890+ StructureMarkerKind kind)
891+ : StructureMarkerRAII(parser) {
892+ parser.StructureMarkers .push_back ({loc, kind, None});
893+ if (parser.StructureMarkers .size () > MaxDepth) {
896894 parser.diagnose (loc, diag::structure_overflow, MaxDepth);
897895 // We need to cut off parsing or we will stack-overflow.
898896 // But `cutOffParsing` changes the current token to eof, and we may be in
899897 // a place where `consumeToken()` will be expecting e.g. '[',
900898 // since we need that to get to the callsite, so this can cause an assert.
901- parser.cutOffParsing ();
902- return false ;
899+ parser.L ->cutOffLexing ();
903900 }
904901}
902+
903+ Parser::StructureMarkerRAII::StructureMarkerRAII (Parser &parser,
904+ const Token &tok)
905+ : StructureMarkerRAII(parser, tok.getLoc(),
906+ getStructureMarkerKindForToken(tok)) {}
907+
905908// ===----------------------------------------------------------------------===//
906909// Primitive Parsing
907910// ===----------------------------------------------------------------------===//
0 commit comments