Skip to content

Commit 9efabbb

Browse files
authored
[clang-format] Fix a bug in lexing C++ UDL ending in $ (llvm#136476)
Fix llvm#61612
1 parent 4f71655 commit 9efabbb

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

clang/lib/Format/FormatTokenLexer.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ void FormatTokenLexer::tryMergePreviousTokens() {
128128
if (Style.isCpp() && tryTransformTryUsageForC())
129129
return;
130130

131+
if ((Style.Language == FormatStyle::LK_Cpp ||
132+
Style.Language == FormatStyle::LK_ObjC) &&
133+
tryMergeUserDefinedLiteral()) {
134+
return;
135+
}
136+
131137
if (Style.isJavaScript() || Style.isCSharp()) {
132138
static const tok::TokenKind NullishCoalescingOperator[] = {tok::question,
133139
tok::question};
@@ -559,6 +565,29 @@ bool FormatTokenLexer::tryMergeGreaterGreater() {
559565
return true;
560566
}
561567

568+
bool FormatTokenLexer::tryMergeUserDefinedLiteral() {
569+
if (Tokens.size() < 2)
570+
return false;
571+
572+
auto *First = Tokens.end() - 2;
573+
auto &Suffix = First[1];
574+
if (Suffix->hasWhitespaceBefore() || Suffix->TokenText != "$")
575+
return false;
576+
577+
auto &Literal = First[0];
578+
if (!Literal->Tok.isLiteral())
579+
return false;
580+
581+
auto &Text = Literal->TokenText;
582+
if (!Text.ends_with("_"))
583+
return false;
584+
585+
Text = StringRef(Text.data(), Text.size() + 1);
586+
++Literal->ColumnWidth;
587+
Tokens.erase(&Suffix);
588+
return true;
589+
}
590+
562591
bool FormatTokenLexer::tryMergeTokens(ArrayRef<tok::TokenKind> Kinds,
563592
TokenType NewType) {
564593
if (Tokens.size() < Kinds.size())

clang/lib/Format/FormatTokenLexer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class FormatTokenLexer {
4848

4949
bool tryMergeLessLess();
5050
bool tryMergeGreaterGreater();
51+
bool tryMergeUserDefinedLiteral();
5152
bool tryMergeNSStringLiteral();
5253
bool tryMergeJSPrivateIdentifier();
5354
bool tryMergeCSharpStringLiteral();

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3985,6 +3985,12 @@ TEST_F(TokenAnnotatorTest, IdentifierPackage) {
39853985
EXPECT_FALSE(Tokens[0]->isObjCAccessSpecifier());
39863986
}
39873987

3988+
TEST_F(TokenAnnotatorTest, UserDefinedLiteral) {
3989+
auto Tokens = annotate("auto dollars = 2_$;");
3990+
ASSERT_EQ(Tokens.size(), 6u) << Tokens;
3991+
EXPECT_EQ(Tokens[3]->TokenText, "2_$");
3992+
}
3993+
39883994
} // namespace
39893995
} // namespace format
39903996
} // namespace clang

0 commit comments

Comments
 (0)