[clang] [clang-format] Fix parsing of `operator<() {}` (PR #75144)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 11 22:33:06 PST 2023
https://github.com/XDeme created https://github.com/llvm/llvm-project/pull/75144
Fixes llvm/llvm-project#74876.
During the parsing of `operator<(Foo&) {}`, there was no handling for the operator<, so it called `consumeToken()` again starting from `(Foo&)`, causing the `AnnotationParser::Scopes` to have one additional left brace each time it tried to parse it, leaving it unbalanced.
Because of this, in the following code:
```cpp
class Foo {
void operator<(Foo&) {}
Foo& f;
};
```
The `&` in the reference member, was being interpreted as `TT_BinaryOperator` instead of `TT_PointerOrReference`.
>From dddc20d967498c739baedb8d67303a28596f09e0 Mon Sep 17 00:00:00 2001
From: XDeme <fernando.tagawa.gamail.com at gmail.com>
Date: Tue, 12 Dec 2023 03:06:56 -0300
Subject: [PATCH] Fix operator<() parsing
---
clang/lib/Format/TokenAnnotator.cpp | 9 +++++++++
clang/unittests/Format/FormatTest.cpp | 7 +++++++
clang/unittests/Format/TokenAnnotatorTest.cpp | 11 +++++++++++
3 files changed, 27 insertions(+)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index eaccb5881ca30f..957612088c7bb0 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -23,6 +23,9 @@
namespace clang {
namespace format {
+static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current,
+ const AnnotatedLine &Line,
+ FormatToken *&ClosingParen);
static bool mustBreakAfterAttributes(const FormatToken &Tok,
const FormatStyle &Style) {
@@ -164,6 +167,12 @@ class AnnotatingParser {
TT_OverloadedOperatorLParen))) {
return false;
}
+ FormatToken *ClosingParen = nullptr;
+ if (Previous.Previous->is(tok::kw_operator) &&
+ isFunctionDeclarationName(Style.isCpp(), *Previous.Previous, Line,
+ ClosingParen)) {
+ return false;
+ }
}
FormatToken *Left = CurrentToken->Previous;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 24b2fd599dc397..79013a473a7c2e 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -11727,6 +11727,13 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
" void func(type &a) { a & member; }\n"
" anotherType &member;\n"
"}");
+
+ Style.ReferenceAlignment = FormatStyle::RAS_Left;
+ verifyFormat("class Foo {\n"
+ " void operator<(Foo&) {}\n"
+ " Foo& f;\n"
+ "};",
+ Style);
}
TEST_F(FormatTest, UnderstandsAttributes) {
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 65b1f0f4b57659..58a782f909d6aa 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -298,6 +298,17 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
EXPECT_TOKEN(Tokens[2], tok::identifier, TT_TypeName);
EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
+
+ Tokens = annotate("class Foo {\n"
+ "void operator<(Foo&) {}\n"
+ "Foo& f;\n"
+ "};");
+ ASSERT_EQ(Tokens.size(), 19u) << Tokens;
+ EXPECT_TOKEN(Tokens[4], tok::kw_operator, TT_FunctionDeclarationName);
+ EXPECT_TOKEN(Tokens[5], tok::less, TT_OverloadedOperator);
+ EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_OverloadedOperatorLParen);
+ EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_FunctionLBrace);
+ EXPECT_TOKEN(Tokens[13], tok::amp, TT_PointerOrReference);
}
TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
More information about the cfe-commits
mailing list