jackhong12 updated this revision to Diff 438194.
jackhong12 edited the summary of this revision.
jackhong12 added a comment.
Just like mentioned above, UnwrappedLineParser will split the input into
multiple lines. And `MatchingParen` will be reset before annotating(code
<https://github.com/llvm/llvm-project/blob/main/clang/lib/Format/TokenAnnotator.cpp#L1509>).
So when defining a struct, union, or class, the `MatchingParen` of the right
brace will be NULL. If we want to access the left matching brace from the right
brace, we need to add new member data, which saves the address of the left
brace token, in class `FormatToken`.
In my opinion, it will be too complicated. Instead of `MatchingParen`, I
categorize the tokens by checking whether it is a template because `&&` will be
a binary operator only in a template. In the other cases, `&&` is likely a
reference operator.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D127873/new/
https://reviews.llvm.org/D127873
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
@@ -85,6 +85,32 @@
Tokens = annotate("case &x:");
EXPECT_EQ(Tokens.size(), 5u) << Tokens;
EXPECT_TOKEN(Tokens[1], tok::amp, TT_UnaryOperator);
+
+ Tokens = annotate("struct {\n"
+ "} *ptr;");
+ EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
+ Tokens = annotate("union {\n"
+ "} *ptr;");
+ EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
+ Tokens = annotate("class {\n"
+ "} *ptr;");
+ EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
+
+ Tokens = annotate("struct {\n"
+ "} &&ptr = {};");
+ EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
+ Tokens = annotate("union {\n"
+ "} &&ptr = {};");
+ EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
+ Tokens = annotate("class {\n"
+ "} &&ptr = {};");
+ EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
}
TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10431,6 +10431,67 @@
"void F();",
getGoogleStyleWithColumns(68));
+ FormatStyle Style = getLLVMStyle();
+ Style.PointerAlignment = FormatStyle::PAS_Left;
+ verifyFormat("struct {\n"
+ "}* ptr;",
+ Style);
+ verifyFormat("union {\n"
+ "}* ptr;",
+ Style);
+ verifyFormat("class {\n"
+ "}* ptr;",
+ Style);
+ verifyFormat("struct {\n"
+ "}&& ptr = {};",
+ Style);
+ verifyFormat("union {\n"
+ "}&& ptr = {};",
+ Style);
+ verifyFormat("class {\n"
+ "}&& ptr = {};",
+ Style);
+
+ Style.PointerAlignment = FormatStyle::PAS_Middle;
+ verifyFormat("struct {\n"
+ "} * ptr;",
+ Style);
+ verifyFormat("union {\n"
+ "} * ptr;",
+ Style);
+ verifyFormat("class {\n"
+ "} * ptr;",
+ Style);
+ verifyFormat("struct {\n"
+ "} && ptr = {};",
+ Style);
+ verifyFormat("union {\n"
+ "} && ptr = {};",
+ Style);
+ verifyFormat("class {\n"
+ "} && ptr = {};",
+ Style);
+
+ Style.PointerAlignment = FormatStyle::PAS_Right;
+ verifyFormat("struct {\n"
+ "} *ptr;",
+ Style);
+ verifyFormat("union {\n"
+ "} *ptr;",
+ Style);
+ verifyFormat("class {\n"
+ "} *ptr;",
+ Style);
+ verifyFormat("struct {\n"
+ "} &&ptr = {};",
+ Style);
+ verifyFormat("union {\n"
+ "} &&ptr = {};",
+ Style);
+ verifyFormat("class {\n"
+ "} &&ptr = {};",
+ Style);
+
verifyIndependentOfContext("MACRO(int *i);");
verifyIndependentOfContext("MACRO(auto *a);");
verifyIndependentOfContext("MACRO(const A *a);");
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2304,6 +2304,28 @@
if (NextToken->isOneOf(tok::comma, tok::semi))
return TT_PointerOrReference;
+ // After right braces, star tokens are likely to be pointers to struct,
+ // union, or class.
+ // struct {} *ptr;
+ if (PrevToken->is(tok::r_brace) && Tok.is(tok::star))
+ return TT_PointerOrReference;
+
+ // We check whether there is a TemplateCloser(">") to indicate it's a
+ // template or not. If it's a template, "&&" is a binary operator. On the
+ // other hand, if not, "&&" is likely a reference operator.
+ // - reference cases:
+ // struct {} &&ref = {};
+ // - binary operator cases:
+ // enable_if<>{} && ...
+ if (PrevToken->is(tok::r_brace) && Tok.is(tok::ampamp)) {
+ const FormatToken *MatchingLBrace = PrevToken->MatchingParen;
+ if (MatchingLBrace && MatchingLBrace->getPreviousNonComment() &&
+ MatchingLBrace->getPreviousNonComment()->is(TT_TemplateCloser))
+ return TT_BinaryOperator;
+ else
+ return TT_PointerOrReference;
+ }
+
if (PrevToken->Tok.isLiteral() ||
PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
tok::kw_false, tok::r_brace)) {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits