@@ -183,9 +183,12 @@ Lexer::Lexer(const PrincipalTag &, const LangOptions &LangOpts,
183
183
HashbangMode HashbangAllowed, CommentRetentionMode RetainComments,
184
184
TriviaRetentionMode TriviaRetention)
185
185
: LangOpts(LangOpts), SourceMgr(SourceMgr), BufferID(BufferID),
186
- Diags(Diags), LexMode(LexMode),
186
+ LexMode(LexMode),
187
187
IsHashbangAllowed(HashbangAllowed == HashbangMode::Allowed),
188
- RetainComments(RetainComments), TriviaRetention(TriviaRetention) {}
188
+ RetainComments(RetainComments), TriviaRetention(TriviaRetention) {
189
+ if (Diags)
190
+ DiagQueue.emplace (*Diags, /* emitOnDestruction*/ false );
191
+ }
189
192
190
193
void Lexer::initialize (unsigned Offset, unsigned EndOffset) {
191
194
assert (Offset <= EndOffset);
@@ -245,7 +248,7 @@ Lexer::Lexer(const LangOptions &Options, const SourceManager &SourceMgr,
245
248
246
249
Lexer::Lexer (Lexer &Parent, State BeginState, State EndState)
247
250
: Lexer(PrincipalTag(), Parent.LangOpts, Parent.SourceMgr, Parent.BufferID,
248
- Parent.Diags , Parent.LexMode,
251
+ Parent.getUnderlyingDiags() , Parent.LexMode,
249
252
Parent.IsHashbangAllowed
250
253
? HashbangMode::Allowed
251
254
: HashbangMode::Disallowed,
@@ -261,7 +264,7 @@ Lexer::Lexer(Lexer &Parent, State BeginState, State EndState)
261
264
}
262
265
263
266
InFlightDiagnostic Lexer::diagnose (const char *Loc, Diagnostic Diag) {
264
- if (Diags)
267
+ if (auto * Diags = getTokenDiags () )
265
268
return Diags->diagnose (getSourceLoc (Loc), Diag);
266
269
267
270
return InFlightDiagnostic ();
@@ -272,7 +275,7 @@ Token Lexer::getTokenAt(SourceLoc Loc) {
272
275
SourceMgr.findBufferContainingLoc (Loc)) &&
273
276
" location from the wrong buffer" );
274
277
275
- Lexer L (LangOpts, SourceMgr, BufferID, Diags , LexMode,
278
+ Lexer L (LangOpts, SourceMgr, BufferID, getUnderlyingDiags () , LexMode,
276
279
HashbangMode::Allowed, CommentRetentionMode::None,
277
280
TriviaRetentionMode::WithoutTrivia);
278
281
L.restoreState (State (Loc));
@@ -330,6 +333,7 @@ void Lexer::formStringLiteralToken(const char *TokStart,
330
333
return ;
331
334
NextToken.setStringLiteral (IsMultilineString, CustomDelimiterLen);
332
335
336
+ auto *Diags = getTokenDiags ();
333
337
if (IsMultilineString && Diags)
334
338
validateMultilineIndents (NextToken, Diags);
335
339
}
@@ -416,7 +420,8 @@ static bool advanceToEndOfLine(const char *&CurPtr, const char *BufferEnd,
416
420
}
417
421
418
422
void Lexer::skipToEndOfLine (bool EatNewline) {
419
- bool isEOL = advanceToEndOfLine (CurPtr, BufferEnd, CodeCompletionPtr, Diags);
423
+ bool isEOL =
424
+ advanceToEndOfLine (CurPtr, BufferEnd, CodeCompletionPtr, getTokenDiags ());
420
425
if (EatNewline && isEOL) {
421
426
++CurPtr;
422
427
NextToken.setAtStartOfLine (true );
@@ -514,8 +519,8 @@ static bool skipToEndOfSlashStarComment(const char *&CurPtr,
514
519
// / skipSlashStarComment - /**/ comments are skipped (treated as whitespace).
515
520
// / Note that (unlike in C) block comments can be nested.
516
521
void Lexer::skipSlashStarComment () {
517
- bool isMultiline =
518
- skipToEndOfSlashStarComment ( CurPtr, BufferEnd, CodeCompletionPtr, Diags );
522
+ bool isMultiline = skipToEndOfSlashStarComment (
523
+ CurPtr, BufferEnd, CodeCompletionPtr, getTokenDiags () );
519
524
if (isMultiline)
520
525
NextToken.setAtStartOfLine (true );
521
526
}
@@ -1360,7 +1365,7 @@ unsigned Lexer::lexCharacter(const char *&CurPtr, char StopQuote,
1360
1365
if (!IsMultilineString && !CustomDelimiterLen)
1361
1366
return ~0U ;
1362
1367
1363
- DiagnosticEngine *D = EmitDiagnostics ? Diags : nullptr ;
1368
+ DiagnosticEngine *D = EmitDiagnostics ? getTokenDiags () : nullptr ;
1364
1369
auto TmpPtr = CurPtr;
1365
1370
if (IsMultilineString &&
1366
1371
!advanceIfMultilineDelimiter (CustomDelimiterLen, TmpPtr, D))
@@ -1385,7 +1390,7 @@ unsigned Lexer::lexCharacter(const char *&CurPtr, char StopQuote,
1385
1390
return CurPtr[-1 ];
1386
1391
case ' \\ ' : // Escapes.
1387
1392
if (!delimiterMatches (CustomDelimiterLen, CurPtr,
1388
- EmitDiagnostics ? Diags : nullptr ))
1393
+ EmitDiagnostics ? getTokenDiags () : nullptr ))
1389
1394
return ' \\ ' ;
1390
1395
break ;
1391
1396
}
@@ -1799,7 +1804,7 @@ static void validateMultilineIndents(const Token &Str,
1799
1804
void Lexer::diagnoseSingleQuoteStringLiteral (const char *TokStart,
1800
1805
const char *TokEnd) {
1801
1806
assert (*TokStart == ' \' ' && TokEnd[-1 ] == ' \' ' );
1802
- if (!Diags ) // or assert?
1807
+ if (!getTokenDiags () ) // or assert?
1803
1808
return ;
1804
1809
1805
1810
auto startLoc = Lexer::getSourceLoc (TokStart);
@@ -1836,7 +1841,7 @@ void Lexer::diagnoseSingleQuoteStringLiteral(const char *TokStart,
1836
1841
replacement.append (OutputPtr, Ptr - 1 );
1837
1842
replacement.push_back (' "' );
1838
1843
1839
- Diags ->diagnose (startLoc, diag::lex_single_quote_string)
1844
+ getTokenDiags () ->diagnose (startLoc, diag::lex_single_quote_string)
1840
1845
.fixItReplaceChars (startLoc, endLoc, replacement);
1841
1846
}
1842
1847
@@ -1852,8 +1857,8 @@ void Lexer::lexStringLiteral(unsigned CustomDelimiterLen) {
1852
1857
// diagnostics about changing them to double quotes.
1853
1858
assert ((QuoteChar == ' "' || QuoteChar == ' \' ' ) && " Unexpected start" );
1854
1859
1855
- bool IsMultilineString = advanceIfMultilineDelimiter (CustomDelimiterLen,
1856
- CurPtr, Diags , true );
1860
+ bool IsMultilineString = advanceIfMultilineDelimiter (
1861
+ CustomDelimiterLen, CurPtr, getTokenDiags () , true );
1857
1862
if (IsMultilineString && *CurPtr != ' \n ' && *CurPtr != ' \r ' )
1858
1863
diagnose (CurPtr, diag::lex_illegal_multiline_string_start)
1859
1864
.fixItInsert (Lexer::getSourceLoc (CurPtr), " \n " );
@@ -2380,6 +2385,11 @@ void Lexer::lexImpl() {
2380
2385
assert (CurPtr >= BufferStart &&
2381
2386
CurPtr <= BufferEnd && " Current pointer out of range!" );
2382
2387
2388
+ // If we're re-lexing, clear out any previous diagnostics that weren't
2389
+ // emitted.
2390
+ if (DiagQueue)
2391
+ DiagQueue->clear ();
2392
+
2383
2393
const char *LeadingTriviaStart = CurPtr;
2384
2394
if (CurPtr == BufferStart) {
2385
2395
if (BufferStart < ContentStart) {
@@ -2467,8 +2477,9 @@ void Lexer::lexImpl() {
2467
2477
case ' :' : return formToken (tok::colon, TokStart);
2468
2478
case ' \\ ' : return formToken (tok::backslash, TokStart);
2469
2479
2470
- case ' #' :
2480
+ case ' #' : {
2471
2481
// Try lex a raw string literal.
2482
+ auto *Diags = getTokenDiags ();
2472
2483
if (unsigned CustomDelimiterLen = advanceIfCustomDelimiter (CurPtr, Diags))
2473
2484
return lexStringLiteral (CustomDelimiterLen);
2474
2485
@@ -2479,8 +2490,8 @@ void Lexer::lexImpl() {
2479
2490
2480
2491
// Otherwise try lex a magic pound literal.
2481
2492
return lexHash ();
2482
-
2483
- // Operator characters.
2493
+ }
2494
+ // Operator characters.
2484
2495
case ' /' :
2485
2496
if (CurPtr[0 ] == ' /' ) { // "//"
2486
2497
skipSlashSlashComment (/* EatNewline=*/ true );
@@ -2656,7 +2667,7 @@ StringRef Lexer::lexTrivia(bool IsForTrailingTrivia,
2656
2667
case 0 :
2657
2668
switch (getNulCharacterKind (CurPtr - 1 )) {
2658
2669
case NulCharacterKind::Embedded: {
2659
- diagnoseEmbeddedNul (Diags , CurPtr - 1 );
2670
+ diagnoseEmbeddedNul (getTokenDiags () , CurPtr - 1 );
2660
2671
goto Restart;
2661
2672
}
2662
2673
case NulCharacterKind::CodeCompletion:
0 commit comments