Skip to content

Commit

Permalink
[clang-format] Don't allow variable decls to have trailing return arrows
Browse files Browse the repository at this point in the history
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 #61469

Reviewed By: HazardyKnusperkeks, owenpan, MyDeveloperDay

Differential Revision: https://reviews.llvm.org/D147377
  • Loading branch information
rymiel committed Apr 3, 2023
1 parent b58a697 commit fd86789
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
2 changes: 1 addition & 1 deletion clang/lib/Format/TokenAnnotator.cpp
Expand Up @@ -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;
Expand Down
66 changes: 66 additions & 0 deletions clang/unittests/Format/TokenAnnotatorTest.cpp
Expand Up @@ -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));
Expand Down

0 comments on commit fd86789

Please sign in to comment.