@@ -1749,32 +1749,30 @@ void Lexer::lexStringLiteral(unsigned CustomDelimiterLen) {
1749
1749
// diagnostics about changing them to double quotes.
1750
1750
assert ((QuoteChar == ' "' || QuoteChar == ' \' ' ) && " Unexpected start" );
1751
1751
1752
- bool wasErroneous = false , IsMultilineString = false ;
1753
-
1754
- // Is this the start of a multiline string literal?
1755
- if ((IsMultilineString = advanceIfMultilineDelimiter (CurPtr, Diags))) {
1756
- if (*CurPtr != ' \n ' && *CurPtr != ' \r ' )
1757
- diagnose (CurPtr, diag::lex_illegal_multiline_string_start)
1752
+ bool IsMultilineString = advanceIfMultilineDelimiter (CurPtr, Diags);
1753
+ if (IsMultilineString && *CurPtr != ' \n ' && *CurPtr != ' \r ' )
1754
+ diagnose (CurPtr, diag::lex_illegal_multiline_string_start)
1758
1755
.fixItInsert (Lexer::getSourceLoc (CurPtr), " \n " );
1759
- }
1760
1756
1757
+ bool wasErroneous = false ;
1761
1758
while (true ) {
1759
+ // Handle string interpolation.
1762
1760
const char *TmpPtr = CurPtr + 1 ;
1763
- if (*CurPtr == ' \\ ' && delimiterMatches (CustomDelimiterLen, TmpPtr, nullptr )
1764
- && *TmpPtr == ' (' ) {
1761
+ if (*CurPtr == ' \\ ' &&
1762
+ delimiterMatches (CustomDelimiterLen, TmpPtr, nullptr ) &&
1763
+ *TmpPtr++ == ' (' ) {
1765
1764
// Consume tokens until we hit the corresponding ')'.
1766
- CurPtr = TmpPtr + 1 ;
1767
- const char *EndPtr = skipToEndOfInterpolatedExpression (CurPtr, BufferEnd,
1768
- IsMultilineString);
1769
-
1770
- if (*EndPtr == ' )' ) {
1765
+ CurPtr = skipToEndOfInterpolatedExpression (TmpPtr, BufferEnd,
1766
+ IsMultilineString);
1767
+ if (*CurPtr == ' )' ) {
1771
1768
// Successfully scanned the body of the expression literal.
1772
- CurPtr = EndPtr+1 ;
1773
- } else {
1774
- CurPtr = EndPtr;
1775
- wasErroneous = true ;
1769
+ ++CurPtr;
1770
+ continue ;
1776
1771
}
1777
- continue ;
1772
+
1773
+ // Being diagnosed below.
1774
+ assert ((*CurPtr == ' \r ' || *CurPtr == ' \n ' || CurPtr == BufferEnd) &&
1775
+ " Returned at unexpected position" );
1778
1776
}
1779
1777
1780
1778
// String literals cannot have \n or \r in them (unless multiline).
@@ -1786,59 +1784,57 @@ void Lexer::lexStringLiteral(unsigned CustomDelimiterLen) {
1786
1784
1787
1785
unsigned CharValue = lexCharacter (CurPtr, QuoteChar, true ,
1788
1786
IsMultilineString, CustomDelimiterLen);
1787
+ // This is the end of string, we are done.
1788
+ if (CharValue == ~0U )
1789
+ break ;
1790
+
1791
+ // Remember we had already-diagnosed invalid characters.
1789
1792
wasErroneous |= CharValue == ~1U ;
1793
+ }
1790
1794
1791
- // If this is the end of string, we are done. If it is a normal character
1792
- // or an already-diagnosed error, just munch it.
1793
- if (CharValue == ~0U ) {
1794
-
1795
- if (QuoteChar == ' \' ' ) {
1796
- // Emit diagnostics for single-quote string and suggest replacement
1797
- // with double-quoted equivalent.
1798
- assert (
1799
- !IsMultilineString && CustomDelimiterLen == 0 &&
1800
- " Single quoted string cannot have custom delimitor, nor multiline" );
1801
- assert (*TokStart == ' \' ' && CurPtr[-1 ] == ' \' ' );
1802
-
1803
- StringRef orig (TokStart, CurPtr - TokStart);
1804
- llvm::SmallString<32 > replacement;
1805
- replacement += ' "' ;
1806
- std::string str = orig.slice (1 , orig.size () - 1 ).str ();
1807
- std::string quot = " \" " ;
1808
- size_t pos = 0 ;
1809
- while (pos != str.length ()) {
1810
- if (str.at (pos) == ' \\ ' ) {
1811
- if (str.at (pos + 1 ) == ' \' ' ) {
1812
- // Un-escape escaped single quotes.
1813
- str.replace (pos, 2 , " '" );
1814
- ++pos;
1815
- } else {
1816
- // Skip over escaped characters.
1817
- pos += 2 ;
1818
- }
1819
- } else if (str.at (pos) == ' "' ) {
1820
- str.replace (pos, 1 , " \\\" " );
1821
- // Advance past the newly added ["\""].
1822
- pos += 2 ;
1823
- } else {
1824
- ++pos;
1825
- }
1795
+ if (QuoteChar == ' \' ' ) {
1796
+ // Emit diagnostics for single-quote string and suggest replacement
1797
+ // with double-quoted equivalent.
1798
+ assert (!IsMultilineString && CustomDelimiterLen == 0 &&
1799
+ " Single quoted string cannot have custom delimitor, nor multiline" );
1800
+ assert (*TokStart == ' \' ' && CurPtr[-1 ] == ' \' ' );
1801
+
1802
+ StringRef orig (TokStart, CurPtr - TokStart);
1803
+ llvm::SmallString<32 > replacement;
1804
+ replacement += ' "' ;
1805
+ std::string str = orig.slice (1 , orig.size () - 1 ).str ();
1806
+ std::string quot = " \" " ;
1807
+ size_t pos = 0 ;
1808
+ while (pos != str.length ()) {
1809
+ if (str.at (pos) == ' \\ ' ) {
1810
+ if (str.at (pos + 1 ) == ' \' ' ) {
1811
+ // Un-escape escaped single quotes.
1812
+ str.replace (pos, 2 , " '" );
1813
+ ++pos;
1814
+ } else {
1815
+ // Skip over escaped characters.
1816
+ pos += 2 ;
1826
1817
}
1827
- replacement += StringRef (str);
1828
- replacement += ' "' ;
1829
- diagnose (TokStart, diag::lex_single_quote_string)
1830
- .fixItReplaceChars (getSourceLoc (TokStart), getSourceLoc (CurPtr),
1831
- replacement);
1818
+ } else if (str.at (pos) == ' "' ) {
1819
+ str.replace (pos, 1 , " \\\" " );
1820
+ // Advance past the newly added ["\""].
1821
+ pos += 2 ;
1822
+ } else {
1823
+ ++pos;
1832
1824
}
1833
-
1834
- // Is this the end of multiline/custom-delimited string literal?
1835
- if (wasErroneous)
1836
- return formToken (tok::unknown, TokStart);
1837
-
1838
- return formStringLiteralToken (TokStart, IsMultilineString,
1839
- CustomDelimiterLen);
1840
1825
}
1826
+ replacement += StringRef (str);
1827
+ replacement += ' "' ;
1828
+ diagnose (TokStart, diag::lex_single_quote_string)
1829
+ .fixItReplaceChars (getSourceLoc (TokStart), getSourceLoc (CurPtr),
1830
+ replacement);
1841
1831
}
1832
+
1833
+ if (wasErroneous)
1834
+ return formToken (tok::unknown, TokStart);
1835
+
1836
+ return formStringLiteralToken (TokStart, IsMultilineString,
1837
+ CustomDelimiterLen);
1842
1838
}
1843
1839
1844
1840
0 commit comments