Author: Micah Weston Date: 2022-11-12T00:58:58-08:00 New Revision: e864ac694540342d5e59f59c525c5082f2594fb8
URL: https://github.com/llvm/llvm-project/commit/e864ac694540342d5e59f59c525c5082f2594fb8 DIFF: https://github.com/llvm/llvm-project/commit/e864ac694540342d5e59f59c525c5082f2594fb8.diff LOG: [clang-format] Treats &/&& as reference when followed by ',' or ')' Ran into an issue where function declarations inside function scopes or uses of sizeof inside a function would treat the && in 'sizeof(Type &&)' as a binary operator. Attempt to fix this by assuming reference when followed by ',' or ')'. Also adds tests for these. Also hit an edge case in another test that treated "and" the same as "&&" since it parses as C++. Changed the "and" to "also" so it is no longer a keyword. Fixes #58923. Differential Revision: https://reviews.llvm.org/D137755 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index e63818cfcd9a..75570552146c 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2356,7 +2356,8 @@ class AnnotatingParser { return TT_BinaryOperator; if (!NextToken || - NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_noexcept) || + NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_noexcept, tok::comma, + tok::r_paren) || NextToken->canBePointerOrReferenceQualifier() || (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) { return TT_PointerOrReference; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index b6c3bda79358..0ff08d4d446d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2132,6 +2132,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("int *a = f1();", Style); verifyFormat("int &b = f2();", Style); verifyFormat("int &&c = f3();", Style); + verifyFormat("int f3() { return sizeof(Foo &); }", Style); + verifyFormat("int f4() { return sizeof(Foo &&); }", Style); + verifyFormat("void f5() { int f6(Foo &, Bar &); }", Style); + verifyFormat("void f5() { int f6(Foo &&, Bar &&); }", Style); verifyFormat("for (auto a = 0, b = 0; const auto &c : {1, 2, 3})", Style); verifyFormat("for (auto a = 0, b = 0; const int &c : {1, 2, 3})", Style); verifyFormat("for (auto a = 0, b = 0; const Foo &c : {1, 2, 3})", Style); @@ -2171,6 +2175,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("int* a = f1();", Style); verifyFormat("int& b = f2();", Style); verifyFormat("int&& c = f3();", Style); + verifyFormat("int f3() { return sizeof(Foo&); }", Style); + verifyFormat("int f4() { return sizeof(Foo&&); }", Style); + verifyFormat("void f5() { int f6(Foo&, Bar&); }", Style); + verifyFormat("void f5() { int f6(Foo&&, Bar&&); }", Style); verifyFormat("for (auto a = 0, b = 0; const auto& c : {1, 2, 3})", Style); verifyFormat("for (auto a = 0, b = 0; const int& c : {1, 2, 3})", Style); verifyFormat("for (auto a = 0, b = 0; const Foo& c : {1, 2, 3})", Style); @@ -2211,6 +2219,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("int *a = f1();", Style); verifyFormat("int& b = f2();", Style); verifyFormat("int&& c = f3();", Style); + verifyFormat("int f3() { return sizeof(Foo&); }", Style); + verifyFormat("int f4() { return sizeof(Foo&&); }", Style); + verifyFormat("void f5() { int f6(Foo&, Bar&); }", Style); + verifyFormat("void f5() { int f6(Foo&&, Bar&&); }", Style); verifyFormat("for (auto a = 0, b = 0; const Foo *c : {1, 2, 3})", Style); verifyFormat("for (int a = 0, b = 0; const Foo *c : {1, 2, 3})", Style); verifyFormat("for (int a = 0, b++; const Foo *c : {1, 2, 3})", Style); @@ -2232,6 +2244,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("int* a = f1();", Style); verifyFormat("int & b = f2();", Style); verifyFormat("int && c = f3();", Style); + verifyFormat("int f3() { return sizeof(Foo &); }", Style); + verifyFormat("int f4() { return sizeof(Foo &&); }", Style); + verifyFormat("void f5() { int f6(Foo &, Bar &); }", Style); + verifyFormat("void f5() { int f6(Foo &&, Bar &&); }", Style); verifyFormat("for (auto a = 0, b = 0; const auto & c : {1, 2, 3})", Style); verifyFormat("for (auto a = 0, b = 0; const int & c : {1, 2, 3})", Style); verifyFormat("for (auto a = 0, b = 0; const Foo & c : {1, 2, 3})", Style); @@ -2268,6 +2284,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("int * a = f1();", Style); verifyFormat("int &b = f2();", Style); verifyFormat("int &&c = f3();", Style); + verifyFormat("int f3() { return sizeof(Foo &); }", Style); + verifyFormat("int f4() { return sizeof(Foo &&); }", Style); + verifyFormat("void f5() { int f6(Foo &, Bar &); }", Style); + verifyFormat("void f5() { int f6(Foo &&, Bar &&); }", Style); verifyFormat("for (auto a = 0, b = 0; const Foo * c : {1, 2, 3})", Style); verifyFormat("for (int a = 0, b = 0; const Foo * c : {1, 2, 3})", Style); verifyFormat("for (int a = 0, b++; const Foo * c : {1, 2, 3})", Style); @@ -9034,7 +9054,7 @@ TEST_F(FormatTest, AlignsStringLiterals) { " \"looooooooooooooooooooooooooooooooooooooooooooooooong literal\");"); verifyFormat("someFunction(\"Always break between multi-line\"\n" " \" string literals\",\n" - " and, other, parameters);"); + " also, other, parameters);"); EXPECT_EQ("fun + \"1243\" /* comment */\n" " \"5678\";", format("fun + \"1243\" /* comment */\n" diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 477e78c9c19e..adacb9761ca3 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -157,6 +157,24 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) { Tokens = annotate("if (Foo* Bar = getObj())"); ASSERT_EQ(Tokens.size(), 11u) << Tokens; EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); + + Tokens = annotate("int f3() { return sizeof(Foo&); }"); + ASSERT_EQ(Tokens.size(), 14u) << Tokens; + EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); + + Tokens = annotate("int f4() { return sizeof(Foo&&); }"); + ASSERT_EQ(Tokens.size(), 14u) << Tokens; + EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_PointerOrReference); + + Tokens = annotate("void f5() { int f6(Foo&, Bar&); }"); + ASSERT_EQ(Tokens.size(), 17u) << Tokens; + EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); + EXPECT_TOKEN(Tokens[12], tok::amp, TT_PointerOrReference); + + Tokens = annotate("void f7() { int f8(Foo&&, Bar&&); }"); + ASSERT_EQ(Tokens.size(), 17u) << Tokens; + EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_PointerOrReference); + EXPECT_TOKEN(Tokens[12], tok::ampamp, TT_PointerOrReference); } TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits