sstwcw updated this revision to Diff 417115.
sstwcw marked an inline comment as done.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D121754/new/
https://reviews.llvm.org/D121754
Files:
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===================================================================
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -78,6 +78,102 @@
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");
+ EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_BinaryOperator);
+ Tokens = annotate("0 + 0");
+ EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::plus, TT_BinaryOperator);
+ Tokens = annotate("x + +0");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::plus, TT_UnaryOperator);
+ Tokens = annotate("x ? -0 : +0");
+ EXPECT_EQ(Tokens.size(), 8u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+ EXPECT_TOKEN(Tokens[5], tok::plus, TT_UnaryOperator);
+ Tokens = annotate("(-0)");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("0, -0");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("for (; -1;) {\n}");
+ EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("x = -1;");
+ EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("x[-1]");
+ EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("x = {-1};");
+ EXPECT_EQ(Tokens.size(), 8u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("case -x:");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("co_await -x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("co_return -x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("co_yield -x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("delete -x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("return -x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("throw -x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("sizeof -x");
+ EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("co_await +x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+ Tokens = annotate("co_return +x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+ Tokens = annotate("co_yield +x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+ Tokens = annotate("delete +x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+ Tokens = annotate("return +x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+ Tokens = annotate("throw +x;");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+ Tokens = annotate("sizeof +x");
+ EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+ Tokens = annotate("(int)-x");
+ EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("(-x)");
+ EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+ Tokens = annotate("!+x");
+ EXPECT_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) {
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -9708,6 +9708,15 @@
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;");
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2147,6 +2147,42 @@
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) {
@@ -2178,12 +2214,7 @@
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))
@@ -2233,23 +2264,14 @@
}
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.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits