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)); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits