=?utf-8?b?5YWo5Y2T?= <[email protected]>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/[email protected]>


https://github.com/quanzhuo updated 
https://github.com/llvm/llvm-project/pull/163926

>From 4239775554b399c9db5e86a83fd79476734a0e85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=85=A8=E5=8D=93?= <[email protected]>
Date: Fri, 17 Oct 2025 16:24:39 +0800
Subject: [PATCH 1/2] Improve attribute range handling for attributed function
 types in selection

This fix https://github.com/clangd/clangd/issues/2488
---
 clang-tools-extra/clangd/Selection.cpp               | 12 ++++++++++++
 .../clangd/unittests/SelectionTests.cpp              |  9 +++++++++
 2 files changed, 21 insertions(+)

diff --git a/clang-tools-extra/clangd/Selection.cpp 
b/clang-tools-extra/clangd/Selection.cpp
index 06165dfbbcdd2..faa00d20497fa 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -958,6 +958,18 @@ class SelectionVisitor : public 
RecursiveASTVisitor<SelectionVisitor> {
         claimRange(SourceRange(FTL.getLParenLoc(), FTL.getEndLoc()), Result);
         return;
       }
+      if (auto ATL = TL->getAs<AttributedTypeLoc>()) {
+        // For attributed function types like `int foo() [[attr]]`, the
+        // AttributedTypeLoc's range includes the function name. We want to
+        // allow the function name to be associated with the FunctionDecl
+        // rather than the AttributedTypeLoc, so we only claim the attribute
+        // range itself.
+        if (ATL.getModifiedLoc().getAs<FunctionTypeLoc>()) {
+          // Only claim the attribute's source range, not the whole type.
+          claimRange(ATL.getLocalSourceRange(), Result);
+          return;
+        }
+      }
     }
     claimRange(getSourceRange(N), Result);
   }
diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp 
b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index 3df19d8fc174d..103c00ebd5696 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -311,6 +311,15 @@ TEST(SelectionTest, CommonAncestor) {
       {"[[void foo^()]];", "FunctionProtoTypeLoc"},
       {"[[^void foo^()]];", "FunctionDecl"},
       {"[[void ^foo()]];", "FunctionDecl"},
+      // Tricky case: with function attributes, the AttributedTypeLoc's range
+      // includes the function name, but we want the name to be associated with
+      // the FunctionDecl.
+      {"struct X { [[void ^foo() [[clang::lifetimebound]]]]; };",
+       "FunctionDecl"},
+      {"struct X { [[void ^foo() const [[clang::lifetimebound]]]]; };",
+       "FunctionDecl"},
+      {"struct X { [[const int* ^Get() const [[clang::lifetimebound]]]]; };",
+       "FunctionDecl"},
       // Tricky case: two VarDecls share a specifier.
       {"[[int ^a]], b;", "VarDecl"},
       {"[[int a, ^b]];", "VarDecl"},

>From d23f381ab3d3b82ab1c47a45cd85604c3eac62b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=85=A8=E5=8D=93?= <[email protected]>
Date: Sat, 1 Nov 2025 14:59:33 +0800
Subject: [PATCH 2/2] Add test for AttributedTypeLoc

---
 .../clangd/unittests/SelectionTests.cpp            | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp 
b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index 103c00ebd5696..6c978a401fddb 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -313,13 +313,13 @@ TEST(SelectionTest, CommonAncestor) {
       {"[[void ^foo()]];", "FunctionDecl"},
       // Tricky case: with function attributes, the AttributedTypeLoc's range
       // includes the function name, but we want the name to be associated with
-      // the FunctionDecl.
-      {"struct X { [[void ^foo() [[clang::lifetimebound]]]]; };",
-       "FunctionDecl"},
-      {"struct X { [[void ^foo() const [[clang::lifetimebound]]]]; };",
-       "FunctionDecl"},
-      {"struct X { [[const int* ^Get() const [[clang::lifetimebound]]]]; };",
-       "FunctionDecl"},
+      // the CXXMethodDecl.
+      {"struct X { [[const int* ^Get() const <:[clang::lifetimebound]:> "
+       "{return nullptr;}]]; };",
+       "CXXMethodDecl"},
+      {"struct X { const [[int* Foo() const <:[clang::life^timebound]:>]] "
+       "{return nullptr;}; };",
+       "AttributedTypeLoc"},
       // Tricky case: two VarDecls share a specifier.
       {"[[int ^a]], b;", "VarDecl"},
       {"[[int a, ^b]];", "VarDecl"},

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to