[clang] c261f78 - [clang-format] Refactor determineStarAmpUsage NFC

via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 24 15:32:27 PDT 2022


Author: sstwcw
Date: 2022-04-24T22:30:22Z
New Revision: c261f78d05deee305166e5f8c91e347b8401dfa4

URL: https://github.com/llvm/llvm-project/commit/c261f78d05deee305166e5f8c91e347b8401dfa4
DIFF: https://github.com/llvm/llvm-project/commit/c261f78d05deee305166e5f8c91e347b8401dfa4.diff

LOG: [clang-format] Refactor determineStarAmpUsage NFC

There was some duplicate code in determineStarAmpUsage and
determinePlusMinusCaretUsage

Now a `-` or `+` following `;`, `sizeof`, `co_await`, or `delete` is
regarded as a unary operator.

Now a `*` or `&` following `case` is also a unary operator.

Reviewed By: curdeius, MyDeveloperDay, HazardyKnusperkeks

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

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 cb950f2b2198d..3714b9d3e0fc3 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2146,6 +2146,42 @@ class AnnotatingParser {
     return true;
   }
 
+  /// Returns true if the token is used as a unary operator.
+  bool determineUnaryOperatorByUsage(const FormatToken &Tok) {
+    const FormatToken *PrevToken = Tok.getPreviousNonComment();
+    if (!PrevToken)
+      return true;
+
+    // These keywords are deliberately not included here because they may
+    // precede only one of unary star/amp and plus/minus but not both.  They are
+    // either included in determineStarAmpUsage or determinePlusMinusCaretUsage.
+    //
+    // @ - It may be followed by a unary `-` in Objective-C literals. We don't
+    //   know how they can be followed by a star or amp.
+    if (PrevToken->isOneOf(
+            TT_ConditionalExpr, tok::l_paren, tok::comma, tok::colon, tok::semi,
+            tok::equal, tok::question, tok::l_square, tok::l_brace,
+            tok::kw_case, tok::kw_co_await, tok::kw_co_return, tok::kw_co_yield,
+            tok::kw_delete, tok::kw_return, tok::kw_throw))
+      return true;
+
+    // We put sizeof here instead of only in determineStarAmpUsage. In the cases
+    // where the unary `+` operator is overloaded, it is reasonable to write
+    // things like `sizeof +x`. Like commit 446d6ec996c6c3.
+    if (PrevToken->is(tok::kw_sizeof))
+      return true;
+
+    // A sequence of leading unary operators.
+    if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
+      return true;
+
+    // There can't be two consecutive binary operators.
+    if (PrevToken->is(TT_BinaryOperator))
+      return true;
+
+    return false;
+  }
+
   /// Return the type of the given token assuming it is * or &.
   TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression,
                                   bool InTemplateArgument) {
@@ -2177,12 +2213,7 @@ class AnnotatingParser {
     if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
       return TT_PointerOrReference;
 
-    if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
-                           tok::comma, tok::semi, tok::kw_return, tok::colon,
-                           tok::kw_co_return, tok::kw_co_await,
-                           tok::kw_co_yield, tok::equal, tok::kw_delete,
-                           tok::kw_sizeof, tok::kw_throw, TT_BinaryOperator,
-                           TT_ConditionalExpr, TT_UnaryOperator, TT_CastRParen))
+    if (determineUnaryOperatorByUsage(Tok))
       return TT_UnaryOperator;
 
     if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
@@ -2232,23 +2263,14 @@ class AnnotatingParser {
   }
 
   TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {
-    const FormatToken *PrevToken = Tok.getPreviousNonComment();
-    if (!PrevToken)
+    if (determineUnaryOperatorByUsage(Tok))
       return TT_UnaryOperator;
 
-    if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
-      // This must be a sequence of leading unary operators.
-      return TT_UnaryOperator;
-
-    // Use heuristics to recognize unary operators.
-    if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
-                           tok::question, tok::colon, tok::kw_return,
-                           tok::kw_case, tok::at, tok::l_brace, tok::kw_throw,
-                           tok::kw_co_return, tok::kw_co_yield))
+    const FormatToken *PrevToken = Tok.getPreviousNonComment();
+    if (!PrevToken)
       return TT_UnaryOperator;
 
-    // There can't be two consecutive binary operators.
-    if (PrevToken->is(TT_BinaryOperator))
+    if (PrevToken->is(tok::at))
       return TT_UnaryOperator;
 
     // Fall back to marking the token as binary operator.

diff  --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index a805f8ed15f46..c685fa152281c 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -9754,6 +9754,15 @@ TEST_F(FormatTest, UnderstandsUnaryOperators) {
   verifyFormat("if (!(a->f())) {\n}");
   verifyFormat("if (!+i) {\n}");
   verifyFormat("~&a;");
+  verifyFormat("for (x = 0; -10 < x; --x) {\n}");
+  verifyFormat("sizeof -x");
+  verifyFormat("sizeof +x");
+  verifyFormat("sizeof *x");
+  verifyFormat("sizeof &x");
+  verifyFormat("delete +x;");
+  verifyFormat("co_await +x;");
+  verifyFormat("case *x:");
+  verifyFormat("case &x:");
 
   verifyFormat("a-- > b;");
   verifyFormat("b ? -a : c;");

diff  --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 380ec90330f12..3d2c3a498c724 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -78,6 +78,102 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
   EXPECT_EQ(Tokens.size(), 21u) << Tokens;
   EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_BinaryOperator);
   EXPECT_TOKEN(Tokens[11], tok::star, TT_UnaryOperator);
+
+  Tokens = annotate("case *x:");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::star, TT_UnaryOperator);
+  Tokens = annotate("case &x:");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::amp, TT_UnaryOperator);
+}
+
+TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
+  auto Tokens = annotate("x - 0");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_BinaryOperator);
+  Tokens = annotate("0 + 0");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_BinaryOperator);
+  Tokens = annotate("x + +0");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("x ? -0 : +0");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[5], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("(-0)");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("0, -0");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("for (; -1;) {\n}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x = -1;");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x[-1]");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x = {-1};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("case -x:");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_await -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_return -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_yield -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("delete -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("return -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("throw -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("sizeof -x");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_await +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("co_return +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("co_yield +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("delete +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("return +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("throw +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("sizeof +x");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("(int)-x");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("(-x)");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("!+x");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::exclaim, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsClasses) {


        


More information about the cfe-commits mailing list