[clang] [Clang] Repair the function "rParenEndsCast" to make incorrect judgments in template variable cases (PR #120904)

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 23 00:20:47 PST 2024


https://github.com/dty2 updated https://github.com/llvm/llvm-project/pull/120904

>From 3f72b657741dc1392e3065a862e3489e800f0782 Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Mon, 23 Dec 2024 16:16:47 +0800
Subject: [PATCH] [Clang] Repair the functionrParenEndsCast to make incorrect
 judgments in template variable cases

---
 clang/lib/Format/TokenAnnotator.cpp           | 26 ++++++++++++++++++-
 clang/unittests/Format/TokenAnnotatorTest.cpp | 14 ++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index f2cfa7f49f62f9..3f44b8c18581e1 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -17,6 +17,8 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Debug.h"
 
 #define DEBUG_TYPE "format-token-annotator"
@@ -38,6 +40,10 @@ static bool mustBreakAfterAttributes(const FormatToken &Tok,
 
 namespace {
 
+// TODO: Add new Type modifiers
+llvm::SmallVector<llvm::StringRef> castIdentifiers{"__type_identity_t",
+                                                   "remove_reference_t"};
+
 /// Returns \c true if the line starts with a token that can start a statement
 /// with an initializer.
 static bool startsWithInitStatement(const AnnotatedLine &Line) {
@@ -2474,6 +2480,11 @@ class AnnotatingParser {
           Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
         Current.setType(TT_StringInConcatenation);
       }
+    } else if (Style.isCpp() && Current.is(tok::kw_using)) {
+      if (Current.Next && Current.Next->Next && Current.Next->Next->Next) {
+        if (Current.Next->Next->Next->isTypeName(LangOpts))
+          castIdentifiers.push_back(Current.Next->TokenText);
+      }
     } else if (Current.is(tok::l_paren)) {
       if (lParenStartsCppCast(Current))
         Current.setType(TT_CppCastLParen);
@@ -2831,8 +2842,21 @@ class AnnotatingParser {
         IsQualifiedPointerOrReference(BeforeRParen, LangOpts);
     bool ParensCouldEndDecl =
         AfterRParen->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
-    if (ParensAreType && !ParensCouldEndDecl)
+    if (ParensAreType && !ParensCouldEndDecl) {
+      if (BeforeRParen->is(TT_TemplateCloser)) {
+        if (determineUnaryOperatorByUsage(*AfterRParen))
+          return true;
+        if (AfterRParen->isOneOf(tok::plus, tok::minus, tok::star, tok::exclaim,
+                                 tok::amp)) {
+          auto *Prev = BeforeRParen->MatchingParen->getPreviousNonComment();
+          for (auto &name : castIdentifiers)
+            if (Prev->TokenText == name)
+              return true;
+          return false;
+        }
+      }
       return true;
+    }
 
     // At this point, we heuristically assume that there are no casts at the
     // start of the line. We assume that we have found most cases where there
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index b2fb5227993c3f..e2e94c0588c857 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -752,6 +752,20 @@ TEST_F(TokenAnnotatorTest, UnderstandsCasts) {
   ASSERT_EQ(Tokens.size(), 11u) << Tokens;
   EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
 
+  Tokens = annotate("(std::__type_identity_t<int>)-2;");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("template <typename> using type = int;\n"
+                    "auto = (type<int>)+5;");
+  ASSERT_EQ(Tokens.size(), 21u) << Tokens;
+  EXPECT_TOKEN(Tokens[16], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("template <class t> t c;"
+                    "auto = (c<int>) + 5;");
+  ASSERT_EQ(Tokens.size(), 20u) << Tokens;
+  EXPECT_TOKEN(Tokens[15], tok::r_paren, TT_Unknown);
+
   Tokens = annotate("return (Foo)p;");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen);



More information about the cfe-commits mailing list