[clang] fd86789 - [clang-format] Don't allow variable decls to have trailing return arrows
Emilia Dreamer via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 3 05:48:59 PDT 2023
Author: Emilia Dreamer
Date: 2023-04-03T15:54:21+03:00
New Revision: fd86789962964a98157e8159c3d95cdc241942e3
URL: https://github.com/llvm/llvm-project/commit/fd86789962964a98157e8159c3d95cdc241942e3
DIFF: https://github.com/llvm/llvm-project/commit/fd86789962964a98157e8159c3d95cdc241942e3.diff
LOG: [clang-format] Don't allow variable decls to have trailing return arrows
The heuristic for determining if an arrow is a trailing return arrow
looks for the auto keyword, along with parentheses. This isn't
sufficient, since it also triggers on variable declarations with an auto
type, and with an arrow operator.
This patch makes sure a function declaration is being parsed, instead of
any other declaration.
Fixes https://github.com/llvm/llvm-project/issues/61469
Reviewed By: HazardyKnusperkeks, owenpan, MyDeveloperDay
Differential Revision: https://reviews.llvm.org/D147377
Added:
Modified:
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index b1060bde9dedd..5171952dba43c 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -1922,7 +1922,7 @@ class AnnotatingParser {
Style.Language == FormatStyle::LK_Java) {
Current.setType(TT_LambdaArrow);
} else if (Current.is(tok::arrow) && AutoFound &&
- (Line.MustBeDeclaration || Line.InPPDirective) &&
+ (Line.MightBeFunctionDecl || Line.InPPDirective) &&
Current.NestingLevel == 0 &&
!Current.Previous->isOneOf(tok::kw_operator, tok::identifier)) {
// not auto operator->() -> xxx;
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 19b1d96f75ab2..dc2fd4d10c76c 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1477,6 +1477,72 @@ TEST_F(TokenAnnotatorTest, UnderstandsC11GenericSelection) {
EXPECT_TOKEN(Tokens[9], tok::colon, TT_GenericSelectionColon);
}
+TEST_F(TokenAnnotatorTest, UnderstandsTrailingReturnArrow) {
+ auto Tokens = annotate("auto f() -> int;");
+ ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+ EXPECT_TOKEN(Tokens[4], tok::arrow, TT_TrailingReturnArrow);
+
+ Tokens = annotate("auto operator->() -> int;");
+ ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::arrow, TT_OverloadedOperator);
+ EXPECT_TOKEN(Tokens[5], tok::arrow, TT_TrailingReturnArrow);
+
+ Tokens = annotate("auto operator++(int) -> int;");
+ ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[6], tok::arrow, TT_TrailingReturnArrow);
+
+ Tokens = annotate("auto operator=() -> int;");
+ ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+ EXPECT_TOKEN(Tokens[5], tok::arrow, TT_TrailingReturnArrow);
+
+ Tokens = annotate("auto operator=(int) -> int;");
+ ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[6], tok::arrow, TT_TrailingReturnArrow);
+
+ Tokens = annotate("auto foo() -> auto { return Val; }");
+ ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+ EXPECT_TOKEN(Tokens[4], tok::arrow, TT_TrailingReturnArrow);
+
+ Tokens = annotate("struct S { auto bar() const -> int; };");
+ ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+ EXPECT_TOKEN(Tokens[8], tok::arrow, TT_TrailingReturnArrow);
+
+ // Not trailing return arrows
+ Tokens = annotate("auto a = b->c;");
+ ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+ EXPECT_TOKEN(Tokens[4], tok::arrow, TT_Unknown);
+
+ Tokens = annotate("auto a = (b)->c;");
+ ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[6], tok::arrow, TT_Unknown);
+
+ Tokens = annotate("auto a = b()->c;");
+ ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[6], tok::arrow, TT_Unknown);
+
+ Tokens = annotate("auto a = b->c();");
+ ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[4], tok::arrow, TT_Unknown);
+
+ Tokens = annotate("decltype(auto) a = b()->c;");
+ ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+ EXPECT_TOKEN(Tokens[9], tok::arrow, TT_Unknown);
+
+ Tokens = annotate("void f() { auto a = b->c(); }");
+ ASSERT_EQ(Tokens.size(), 16u) << Tokens;
+ EXPECT_TOKEN(Tokens[9], tok::arrow, TT_Unknown);
+
+ Tokens = annotate("void f() { auto a = b()->c; }");
+ ASSERT_EQ(Tokens.size(), 16u) << Tokens;
+ EXPECT_TOKEN(Tokens[11], tok::arrow, TT_Unknown);
+
+ // Mixed
+ Tokens = annotate("auto f() -> int { auto a = b()->c; }");
+ ASSERT_EQ(Tokens.size(), 18u) << Tokens;
+ EXPECT_TOKEN(Tokens[4], tok::arrow, TT_TrailingReturnArrow);
+ EXPECT_TOKEN(Tokens[13], tok::arrow, TT_Unknown);
+}
+
TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
auto Annotate = [this](llvm::StringRef Code) {
return annotate(Code, getLLVMStyle(FormatStyle::LK_Verilog));
More information about the cfe-commits
mailing list