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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits