Skip to content

Commit e6e55c2

Browse files
committed
[Lexer] Code tweaks in lexStringLiteral()
NFC. Reorder code to improve readability.
1 parent 1a4d375 commit e6e55c2

File tree

1 file changed

+62
-66
lines changed

1 file changed

+62
-66
lines changed

lib/Parse/Lexer.cpp

Lines changed: 62 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,32 +1749,30 @@ void Lexer::lexStringLiteral(unsigned CustomDelimiterLen) {
17491749
// diagnostics about changing them to double quotes.
17501750
assert((QuoteChar == '"' || QuoteChar == '\'') && "Unexpected start");
17511751

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)
17581755
.fixItInsert(Lexer::getSourceLoc(CurPtr), "\n");
1759-
}
17601756

1757+
bool wasErroneous = false;
17611758
while (true) {
1759+
// Handle string interpolation.
17621760
const char *TmpPtr = CurPtr + 1;
1763-
if (*CurPtr == '\\' && delimiterMatches(CustomDelimiterLen, TmpPtr, nullptr)
1764-
&& *TmpPtr == '(') {
1761+
if (*CurPtr == '\\' &&
1762+
delimiterMatches(CustomDelimiterLen, TmpPtr, nullptr) &&
1763+
*TmpPtr++ == '(') {
17651764
// 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 == ')') {
17711768
// Successfully scanned the body of the expression literal.
1772-
CurPtr = EndPtr+1;
1773-
} else {
1774-
CurPtr = EndPtr;
1775-
wasErroneous = true;
1769+
++CurPtr;
1770+
continue;
17761771
}
1777-
continue;
1772+
1773+
// Being diagnosed below.
1774+
assert((*CurPtr == '\r' || *CurPtr == '\n' || CurPtr == BufferEnd) &&
1775+
"Returned at unexpected position");
17781776
}
17791777

17801778
// String literals cannot have \n or \r in them (unless multiline).
@@ -1786,59 +1784,57 @@ void Lexer::lexStringLiteral(unsigned CustomDelimiterLen) {
17861784

17871785
unsigned CharValue = lexCharacter(CurPtr, QuoteChar, true,
17881786
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.
17891792
wasErroneous |= CharValue == ~1U;
1793+
}
17901794

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;
18261817
}
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;
18321824
}
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);
18401825
}
1826+
replacement += StringRef(str);
1827+
replacement += '"';
1828+
diagnose(TokStart, diag::lex_single_quote_string)
1829+
.fixItReplaceChars(getSourceLoc(TokStart), getSourceLoc(CurPtr),
1830+
replacement);
18411831
}
1832+
1833+
if (wasErroneous)
1834+
return formToken(tok::unknown, TokStart);
1835+
1836+
return formStringLiteralToken(TokStart, IsMultilineString,
1837+
CustomDelimiterLen);
18421838
}
18431839

18441840

0 commit comments

Comments
 (0)