[clang-tools-extra] 9ef2ac3 - [clangd] Handle lambda scopes inside Node::getDeclContext() (#76329)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 11 00:59:22 PST 2024
Author: Younan Zhang
Date: 2024-01-11T16:59:18+08:00
New Revision: 9ef2ac3ad1bd5aa9e589f63047e8abeac11ad1b2
URL: https://github.com/llvm/llvm-project/commit/9ef2ac3ad1bd5aa9e589f63047e8abeac11ad1b2
DIFF: https://github.com/llvm/llvm-project/commit/9ef2ac3ad1bd5aa9e589f63047e8abeac11ad1b2.diff
LOG: [clangd] Handle lambda scopes inside Node::getDeclContext() (#76329)
We used to consider the `DeclContext` for selection nodes inside a
lambda as the enclosing scope of the lambda expression, rather than the
lambda itself.
For example,
```cpp
void foo();
auto lambda = [] {
return ^foo();
};
```
where `N` is the selection node for the expression `foo()`,
`N.getDeclContext()` returns the `TranslationUnitDecl` previously, which
IMO is wrong, since the method `operator()` of the lambda is closer.
Incidentally, this fixes a glitch in add-using-declaration tweaks.
(Thanks @HighCommander4 for the test case.)
Added:
Modified:
clang-tools-extra/clangd/Selection.cpp
clang-tools-extra/clangd/unittests/SelectionTests.cpp
clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp
index 8c6d5750ecefdb..277cb8769a1b12 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -1113,6 +1113,9 @@ const DeclContext &SelectionTree::Node::getDeclContext() const {
return *DC;
return *Current->getLexicalDeclContext();
}
+ if (const auto *LE = CurrentNode->ASTNode.get<LambdaExpr>())
+ if (CurrentNode != this)
+ return *LE->getCallOperator();
}
llvm_unreachable("A tree must always be rooted at TranslationUnitDecl.");
}
diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index 4c019a1524f3c3..754e8c287c5148 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -880,6 +880,19 @@ TEST(SelectionTest, DeclContextIsLexical) {
}
}
+TEST(SelectionTest, DeclContextLambda) {
+ llvm::Annotations Test(R"cpp(
+ void foo();
+ auto lambda = [] {
+ return $1^foo();
+ };
+ )cpp");
+ auto AST = TestTU::withCode(Test.code()).build();
+ auto ST = SelectionTree::createRight(AST.getASTContext(), AST.getTokens(),
+ Test.point("1"), Test.point("1"));
+ EXPECT_TRUE(ST.commonAncestor()->getDeclContext().isFunctionOrMethod());
+}
+
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp
index 1fd2487378d705..c2dd8e1bb8eefa 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp
@@ -309,6 +309,29 @@ namespace foo { void fun(); }
void foo::fun() {
ff();
})cpp"},
+ // Inside a lambda.
+ {
+ R"cpp(
+namespace NS {
+void unrelated();
+void foo();
+}
+
+auto L = [] {
+ using NS::unrelated;
+ NS::f^oo();
+};)cpp",
+ R"cpp(
+namespace NS {
+void unrelated();
+void foo();
+}
+
+auto L = [] {
+ using NS::foo;using NS::unrelated;
+ foo();
+};)cpp",
+ },
// If all other using are fully qualified, add ::
{R"cpp(
#include "test.hpp"
More information about the cfe-commits
mailing list