[clang-format] Don't modify template arguments on the LHS of assignment
authorEmilia Dreamer <emilia@rymiel.space>
Tue, 11 Apr 2023 21:33:12 +0000 (00:33 +0300)
committerEmilia Dreamer <emilia@rymiel.space>
Tue, 11 Apr 2023 21:33:17 +0000 (00:33 +0300)
After clang-format has determined that an equals sign starts an
expression, it will also go backwards and modify any star/amp/ampamp
binary operators on the left side of the assignment to be
pointers/references instead.

There already exists logic to skip over contents of parentheses and
square brackets, but this patch also expands that logic to apply to
angle brackets. This is so that binary operators inside of template
arguments would not be touched, primary arguments to non-type template
parameters.

Fixes https://github.com/llvm/llvm-project/issues/62055

Reviewed By: owenpan, MyDeveloperDay, HazardyKnusperkeks

Differential Revision: https://reviews.llvm.org/D148024

clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp

index e7de8fd..18fccca 100644 (file)
@@ -1819,7 +1819,7 @@ private:
              Previous && Previous->Previous &&
              !Previous->Previous->isOneOf(tok::comma, tok::semi);
              Previous = Previous->Previous) {
-          if (Previous->isOneOf(tok::r_square, tok::r_paren)) {
+          if (Previous->isOneOf(tok::r_square, tok::r_paren, tok::greater)) {
             Previous = Previous->MatchingParen;
             if (!Previous)
               break;
index 0fc6442..facd006 100644 (file)
@@ -270,6 +270,18 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
   ASSERT_EQ(Tokens.size(), 19u) << Tokens;
   EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
   EXPECT_TOKEN(Tokens[7], tok::star, TT_PointerOrReference);
+
+  Tokens = annotate("Foo<A && B> a = {};");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_BinaryOperator);
+
+  Tokens = annotate("Foo<A &&> a = {};");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
+
+  Tokens = annotate("template <enable_if_t<foo && !bar>* = nullptr> void f();");
+  ASSERT_EQ(Tokens.size(), 19u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_BinaryOperator);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {