[clang] [clang-format] Fix template parsing regression for unspaced user-defi… (PR #210630)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 31 10:25:54 PDT 2026
================
@@ -595,6 +595,38 @@ bool FormatTokenLexer::tryMergeUserDefinedLiteral() {
if (Tokens.size() < 2)
return false;
+ // --- INTERCEPT STRING/CHARACTER UDLs ALREADY MERGED BY THE RAW LEXER ---
+ // --- INTERCEPT STRING/CHARACTER UDLs ALREADY MERGED BY THE RAW LEXER ---
+ // --- INTERCEPT STRING/CHARACTER UDLs ALREADY MERGED BY THE RAW LEXER ---
+ if (Tokens.back()->isOneOf(tok::string_literal, tok::char_constant, tok::numeric_constant) &&
+ Tokens.end()[-2]->is(tok::kw_operator)) {
+
+ FormatToken *OpToken = Tokens[Tokens.size() - 2];
+ FormatToken *LiteralToken = Tokens.back();
+
+ // Strict guard: Do not merge if this is a member access call (e.g., x.operator""_a())
+ if (Tokens.size() >= 3) {
+ FormatToken *PrevToken = Tokens[Tokens.size() - 3];
+ if (PrevToken->isOneOf(tok::period, tok::arrow) ||
+ PrevToken->TokenText == "." || PrevToken->TokenText == "->") {
----------------
johnnyb2543 wrote:
That sequence of tokens would not occur in valid C++ code but if we run into code like x.operator""_a(), it should still be formatted correctly.
On line 1079 of TokenAnnotatorTest.cpp under TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators), we have
Tokens = annotate("x.operator\"\"_a()");
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
If I did not include the logic in FormatTokenLexer.cpp, then effectively what happens is that the operator token, and the ""_a token get merged. This would reduce the amount of tokens by one and cause this unit test to fail. By the way, this is confirmed looking at lines 1081 through 1082 of TokenAnnotatorTest.cpp:
EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown);
EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
https://github.com/llvm/llvm-project/pull/210630
More information about the cfe-commits
mailing list