Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang-format] Fix a regression on annotating template angles #132885

Merged
merged 1 commit into from
Mar 27, 2025

Conversation

owenca
Copy link
Contributor

@owenca owenca commented Mar 25, 2025

Annotate the angles in A<B != A>B as template opener/closer as it's unlikely that they are less/greater-than operators in this context.

Fix #132248

Annotate the angles in `A<B != A>B` as template opener/closer as it's
unlikely that they are less/greater-than operators in this context.

Fix llvm#132248
@llvmbot
Copy link
Member

llvmbot commented Mar 25, 2025

@llvm/pr-subscribers-clang-format

Author: Owen Pan (owenca)

Changes

Annotate the angles in A&lt;B != A&gt;B as template opener/closer as it's unlikely that they are less/greater-than operators in this context.

Fix #132248


Full diff: https://github.com/llvm/llvm-project/pull/132885.diff

2 Files Affected:

  • (modified) clang/lib/Format/TokenAnnotator.cpp (+1-2)
  • (modified) clang/unittests/Format/TokenAnnotatorTest.cpp (+13-2)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 01bf8c3778928..d87b3a6088bd8 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -253,8 +253,7 @@ class AnnotatingParser {
       // FIXME: This is getting out of hand, write a decent parser.
       if (MaybeAngles && InExpr && !Line.startsWith(tok::kw_template) &&
           Prev.is(TT_BinaryOperator) &&
-          (Prev.isOneOf(tok::pipepipe, tok::ampamp) ||
-           Prev.getPrecedence() == prec::Equality)) {
+          Prev.isOneOf(tok::pipepipe, tok::ampamp)) {
         MaybeAngles = false;
       }
       if (Prev.isOneOf(tok::question, tok::colon) && !Style.isProto())
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 1ff785110fc34..7bdae1666a90a 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -720,8 +720,9 @@ TEST_F(TokenAnnotatorTest, UnderstandsNonTemplateAngleBrackets) {
 
   Tokens = annotate("return A < B != A > B;");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
-  EXPECT_TOKEN(Tokens[2], tok::less, TT_BinaryOperator);
-  EXPECT_TOKEN(Tokens[6], tok::greater, TT_BinaryOperator);
+  // FIXME:
+  // EXPECT_TOKEN(Tokens[2], tok::less, TT_BinaryOperator);
+  // EXPECT_TOKEN(Tokens[6], tok::greater, TT_BinaryOperator);
 
   Tokens = annotate("ratio{-1, 2} < ratio{-1, 3} == -1 / 3 > -1 / 2;");
   ASSERT_EQ(Tokens.size(), 27u) << Tokens;
@@ -3827,6 +3828,16 @@ TEST_F(TokenAnnotatorTest, TemplateInstantiation) {
   ASSERT_EQ(Tokens.size(), 24u) << Tokens;
   EXPECT_TOKEN(Tokens[6], tok::less, TT_TemplateOpener);
   EXPECT_TOKEN(Tokens[18], tok::greater, TT_TemplateCloser);
+
+  Tokens = annotate(
+      "std::uint16_t kMTU = std::conditional<\n"
+      "    kTypeKind == KindA,\n"
+      "    std::integral_constant<std::uint16_t, kIoSockMtu>>::type::value;");
+  ASSERT_EQ(Tokens.size(), 30u) << Tokens;
+  EXPECT_TOKEN(Tokens[8], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[16], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[22], tok::greater, TT_TemplateCloser);
+  EXPECT_TOKEN(Tokens[23], tok::greater, TT_TemplateCloser);
 }
 
 TEST_F(TokenAnnotatorTest, VariableTemplate) {

@@ -720,8 +720,9 @@ TEST_F(TokenAnnotatorTest, UnderstandsNonTemplateAngleBrackets) {

Tokens = annotate("return A < B != A > B;");
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
EXPECT_TOKEN(Tokens[2], tok::less, TT_BinaryOperator);
EXPECT_TOKEN(Tokens[6], tok::greater, TT_BinaryOperator);
// FIXME:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a thought, could we check the token after greater? If it is an identifier it can never be a template.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be a template closer e.g. in declarations with implicit instantiated template types? IMO we should rework parseAngle() instead of adding more heuristics for special cases such as A<B != C> D that must be an expression if preceded by return.

@owenca owenca merged commit b8a0558 into llvm:main Mar 27, 2025
13 checks passed
@owenca owenca deleted the 132248 branch March 27, 2025 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[clang-format] incorrect formatting of type trait in assigment
4 participants