@@ -1454,67 +1454,61 @@ static const char *skipToEndOfInterpolatedExpression(const char *CurPtr,
1454
1454
if (inStringLiteral () ||
1455
1455
!(CustomDelimiterLen = advanceIfCustomDelimiter (CurPtr, Diags)))
1456
1456
continue ;
1457
+ assert (CurPtr[-1 ] == ' "' &&
1458
+ " advanceIfCustomDelimiter() must stop at after the quote" );
1457
1459
LLVM_FALLTHROUGH;
1458
1460
1459
1461
case ' "' :
1460
1462
case ' \' ' : {
1461
- if (!AllowNewline.back () && inStringLiteral ()) {
1462
- if (OpenDelimiters.back () == CurPtr[-1 ] &&
1463
- delimiterMatches (CustomDelimiter.back (), CurPtr, Diags, true )) {
1464
- // Closing single line string literal.
1465
- OpenDelimiters.pop_back ();
1466
- AllowNewline.pop_back ();
1467
- CustomDelimiter.pop_back ();
1468
- }
1469
- // Otherwise, it's just a quote in string literal. e.g. "foo's".
1470
- continue ;
1471
- }
1472
-
1473
- bool isMultilineQuote = advanceIfMultilineDelimiter (CurPtr, Diags);
1474
-
1475
1463
if (!inStringLiteral ()) {
1476
- // Open string literal
1464
+ // Open string literal.
1477
1465
OpenDelimiters.push_back (CurPtr[-1 ]);
1478
- AllowNewline.push_back (isMultilineQuote );
1466
+ AllowNewline.push_back (advanceIfMultilineDelimiter (CurPtr, Diags) );
1479
1467
CustomDelimiter.push_back (CustomDelimiterLen);
1480
1468
continue ;
1481
1469
}
1482
1470
1483
- // We are in multiline string literal.
1484
- assert (AllowNewline.back () && " other cases must be handled above" );
1485
- if (isMultilineQuote &&
1486
- delimiterMatches (CustomDelimiter.back (), CurPtr, Diags, true )) {
1487
- // Close multiline string literal.
1488
- OpenDelimiters.pop_back ();
1489
- AllowNewline.pop_back ();
1490
- CustomDelimiter.pop_back ();
1491
- }
1471
+ // In string literal.
1472
+
1473
+ // Skip if it's an another kind of quote in string literal. e.g. "foo's".
1474
+ if (OpenDelimiters.back () != CurPtr[-1 ])
1475
+ continue ;
1476
+
1477
+ // Multi-line string can only be closed by '"""'.
1478
+ if (AllowNewline.back () && !advanceIfMultilineDelimiter (CurPtr, Diags))
1479
+ continue ;
1480
+
1481
+ // Check whether we have equivalent number of '#'s.
1482
+ if (!delimiterMatches (CustomDelimiter.back (), CurPtr, Diags, true ))
1483
+ continue ;
1492
1484
1493
- // Otherwise, it's just a normal character in multiline string.
1485
+ // Close string literal.
1486
+ OpenDelimiters.pop_back ();
1487
+ AllowNewline.pop_back ();
1488
+ CustomDelimiter.pop_back ();
1494
1489
continue ;
1495
1490
}
1496
1491
case ' \\ ' :
1492
+ // We ignore invalid escape sequence here. They should be diagnosed in
1493
+ // the real lexer functions.
1497
1494
if (inStringLiteral () &&
1498
1495
delimiterMatches (CustomDelimiter.back (), CurPtr, Diags)) {
1499
- char escapedChar = *CurPtr++;
1500
- switch (escapedChar) {
1496
+ switch (*CurPtr++) {
1501
1497
case ' (' :
1502
1498
// Entering a recursive interpolated expression
1503
1499
OpenDelimiters.push_back (' (' );
1504
1500
continue ;
1505
- case ' \n ' : case ' \r ' :
1506
- if (AllowNewline.back ())
1507
- continue ;
1508
- LLVM_FALLTHROUGH;
1509
- case 0 :
1510
- // Don't jump over newline/EOF due to preceding backslash!
1511
- return CurPtr-1 ;
1501
+ case ' \n ' : case ' \r ' : case 0 :
1502
+ // Don't jump over newline/EOF due to preceding backslash.
1503
+ // Let the outer switch to handle it.
1504
+ --CurPtr;
1505
+ continue ;
1512
1506
default :
1513
1507
continue ;
1514
1508
}
1515
1509
}
1516
1510
continue ;
1517
-
1511
+
1518
1512
// Paren nesting deeper to support "foo = \((a+b)-(c*d)) bar".
1519
1513
case ' (' :
1520
1514
if (!inStringLiteral ()) {
0 commit comments