Skip to content

Commit dce5bb9

Browse files
committed
[clang-format] Correctly annotate UDLs as OverloadedOperator
While the opening parenthesis of an user-defined literal operator was correctly annotated as OverloadedOperatorLParen, the "" and its suffix wasn't annotated as OverloadedOperator. Fixes llvm#58035 Differential Revision: https://reviews.llvm.org/D134853
1 parent 01b8140 commit dce5bb9

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,13 +1177,17 @@ class AnnotatingParser {
11771177
if (CurrentToken->isOneOf(tok::star, tok::amp))
11781178
CurrentToken->setType(TT_PointerOrReference);
11791179
consumeToken();
1180-
if (CurrentToken && CurrentToken->is(tok::comma) &&
1180+
if (!CurrentToken)
1181+
continue;
1182+
if (CurrentToken->is(tok::comma) &&
11811183
CurrentToken->Previous->isNot(tok::kw_operator)) {
11821184
break;
11831185
}
1184-
if (CurrentToken && CurrentToken->Previous->isOneOf(
1185-
TT_BinaryOperator, TT_UnaryOperator, tok::comma,
1186-
tok::star, tok::arrow, tok::amp, tok::ampamp)) {
1186+
if (CurrentToken->Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator,
1187+
tok::comma, tok::star, tok::arrow,
1188+
tok::amp, tok::ampamp) ||
1189+
// User defined literal.
1190+
CurrentToken->Previous->TokenText.startswith("\"\"")) {
11871191
CurrentToken->Previous->setType(TT_OverloadedOperator);
11881192
}
11891193
}
@@ -2114,6 +2118,9 @@ class AnnotatingParser {
21142118
if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
21152119
return false;
21162120

2121+
if (Tok.MatchingParen->is(TT_OverloadedOperatorLParen))
2122+
return false;
2123+
21172124
FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
21182125
if (LeftOfParens) {
21192126
// If there is a closing parenthesis left of the current

clang/unittests/Format/FormatTest.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10153,6 +10153,14 @@ TEST_F(FormatTest, UnderstandsOverloadedOperators) {
1015310153
// verifyFormat("void f() { operator*(a & a); }");
1015410154
// verifyFormat("void f() { operator&(a, b * b); }");
1015510155

10156+
verifyFormat("void f() { return operator()(x) * b; }");
10157+
verifyFormat("void f() { return operator[](x) * b; }");
10158+
verifyFormat("void f() { return operator\"\"_a(x) * b; }");
10159+
verifyFormat("void f() { return operator\"\" _a(x) * b; }");
10160+
verifyFormat("void f() { return operator\"\"s(x) * b; }");
10161+
verifyFormat("void f() { return operator\"\" s(x) * b; }");
10162+
verifyFormat("void f() { return operator\"\"if(x) * b; }");
10163+
1015610164
verifyFormat("::operator delete(foo);");
1015710165
verifyFormat("::operator new(n * sizeof(foo));");
1015810166
verifyFormat("foo() { ::operator delete(foo); }");

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,55 @@ TEST_F(TokenAnnotatorTest, UnderstandsFunctionRefQualifiers) {
390390
EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
391391
}
392392

393+
TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators) {
394+
auto Tokens = annotate("x.operator+()");
395+
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
396+
EXPECT_TOKEN(Tokens[3], tok::plus, TT_OverloadedOperator);
397+
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
398+
Tokens = annotate("x.operator=()");
399+
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
400+
EXPECT_TOKEN(Tokens[3], tok::equal, TT_OverloadedOperator);
401+
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
402+
Tokens = annotate("x.operator+=()");
403+
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
404+
EXPECT_TOKEN(Tokens[3], tok::plusequal, TT_OverloadedOperator);
405+
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
406+
Tokens = annotate("x.operator,()");
407+
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
408+
EXPECT_TOKEN(Tokens[3], tok::comma, TT_OverloadedOperator);
409+
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
410+
Tokens = annotate("x.operator()()");
411+
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
412+
EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperator);
413+
EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_OverloadedOperator);
414+
EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
415+
Tokens = annotate("x.operator[]()");
416+
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
417+
// EXPECT_TOKEN(Tokens[3], tok::l_square, TT_OverloadedOperator);
418+
// EXPECT_TOKEN(Tokens[4], tok::r_square, TT_OverloadedOperator);
419+
EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
420+
Tokens = annotate("x.operator\"\"_a()");
421+
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
422+
EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
423+
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
424+
Tokens = annotate("x.operator\"\" _a()");
425+
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
426+
EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
427+
EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
428+
Tokens = annotate("x.operator\"\"if()");
429+
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
430+
EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
431+
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
432+
Tokens = annotate("x.operator\"\"s()");
433+
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
434+
EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
435+
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
436+
Tokens = annotate("x.operator\"\" s()");
437+
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
438+
EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
439+
EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
440+
}
441+
393442
TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
394443
auto Tokens = annotate("template <typename T>\n"
395444
"concept C = (Foo && Bar) && (Bar && Baz);");

0 commit comments

Comments
 (0)