[clang-tools-extra] Improve attribute range handling for attributed function types in sel… (PR #163926)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 17 01:35:46 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangd
Author: Quan Zhuo (quanzhuo)
<details>
<summary>Changes</summary>
…ection
This fix https://github.com/clangd/clangd/issues/2488
---
Full diff: https://github.com/llvm/llvm-project/pull/163926.diff
2 Files Affected:
- (modified) clang-tools-extra/clangd/Selection.cpp (+12)
- (modified) clang-tools-extra/clangd/unittests/SelectionTests.cpp (+9)
``````````diff
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"},
``````````
</details>
https://github.com/llvm/llvm-project/pull/163926
More information about the cfe-commits
mailing list