From 8dd2ef2130852e406dab6097b1feb248bf16ce91 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 15 Jul 2022 11:36:08 +0200 Subject: [PATCH] [clang-format] distinguish multiplication after brace-init from pointer After https://github.com/llvm/llvm-project/commit/b646f0955574c6ad4c156c9db522e46f597cfda9, the added regression test started being formatted as-if the multiplication `*` was a pointer. This adapts the heuristic to distinguish between these two cases. Reviewed By: jackhong12, curdeius, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D129771 --- clang/lib/Format/TokenAnnotator.cpp | 10 +++++++++- clang/unittests/Format/FormatTest.cpp | 3 +++ clang/unittests/Format/TokenAnnotatorTest.cpp | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 98c012994f45..e0dc7a7f05c9 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2317,7 +2317,15 @@ private: // 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)) + // This by itself is not sufficient to distinguish from multiplication + // following a brace-initialized expression, as in: + // int i = int{42} * 2; + // In the struct case, the part of the struct declaration until the `{` and + // the `}` are put on separate unwrapped lines; in the brace-initialized + // case, the matching `{` is on the same unwrapped line, so check for the + // presence of the matching brace to distinguish between those. + if (PrevToken->is(tok::r_brace) && Tok.is(tok::star) && + !PrevToken->MatchingParen) return TT_PointerOrReference; // For "} &&" diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index ba07584d661a..08cfdbe2cc7a 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -10458,6 +10458,9 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyFormat("class {\n" "}* ptr;", Style); + // Don't confuse a multiplication after a brace-initialized expression with + // a class pointer. + verifyFormat("int i = int{42} * 34;", Style); verifyFormat("struct {\n" "}&& ptr = {};", Style); diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index df1b05226747..a2474d5c10f8 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -111,6 +111,9 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) { "} &&ptr = {};"); EXPECT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference); + Tokens = annotate("int i = int{42} * 2;"); + EXPECT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[7], tok::star, TT_BinaryOperator); } TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {