[PATCH] D147377: [clang-format] Don't allow variable decls to have trailing return arrows
Emilia Dreamer via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 1 06:43:24 PDT 2023
rymiel created this revision.
rymiel added a project: clang-format.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay.
Herald added projects: All, clang.
Herald added a subscriber: cfe-commits.
rymiel requested review of this revision.
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 unsets the `auto` state when the annotator encounters the
equals sign of a variable declaration.
Fixes https://github.com/llvm/llvm-project/issues/61469
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D147377
Files:
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===================================================================
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1468,6 +1468,72 @@
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));
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1970,6 +1970,12 @@
if (Current.getPrecedence() == prec::Assignment)
Contexts.back().VerilogAssignmentFound = true;
}
+ if (AutoFound && Current.is(tok::equal) && Current.Previous &&
+ Current.Previous->isNot(tok::kw_operator)) {
+ // AutoFound is only used for function declarations with `auto`. This
+ // looks like a variable declaration, so unset it.
+ AutoFound = false;
+ }
Current.setType(TT_BinaryOperator);
} else if (Current.is(tok::comment)) {
if (Current.TokenText.startswith("/*")) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D147377.510221.patch
Type: text/x-patch
Size: 3826 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230401/f06869c2/attachment.bin>
More information about the cfe-commits
mailing list