Skip to content

Commit 9ef2ac3

Browse files
authored
[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.)
1 parent d7642b2 commit 9ef2ac3

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

clang-tools-extra/clangd/Selection.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,9 @@ const DeclContext &SelectionTree::Node::getDeclContext() const {
11131113
return *DC;
11141114
return *Current->getLexicalDeclContext();
11151115
}
1116+
if (const auto *LE = CurrentNode->ASTNode.get<LambdaExpr>())
1117+
if (CurrentNode != this)
1118+
return *LE->getCallOperator();
11161119
}
11171120
llvm_unreachable("A tree must always be rooted at TranslationUnitDecl.");
11181121
}

clang-tools-extra/clangd/unittests/SelectionTests.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,19 @@ TEST(SelectionTest, DeclContextIsLexical) {
880880
}
881881
}
882882

883+
TEST(SelectionTest, DeclContextLambda) {
884+
llvm::Annotations Test(R"cpp(
885+
void foo();
886+
auto lambda = [] {
887+
return $1^foo();
888+
};
889+
)cpp");
890+
auto AST = TestTU::withCode(Test.code()).build();
891+
auto ST = SelectionTree::createRight(AST.getASTContext(), AST.getTokens(),
892+
Test.point("1"), Test.point("1"));
893+
EXPECT_TRUE(ST.commonAncestor()->getDeclContext().isFunctionOrMethod());
894+
}
895+
883896
} // namespace
884897
} // namespace clangd
885898
} // namespace clang

clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,29 @@ namespace foo { void fun(); }
309309
void foo::fun() {
310310
ff();
311311
})cpp"},
312+
// Inside a lambda.
313+
{
314+
R"cpp(
315+
namespace NS {
316+
void unrelated();
317+
void foo();
318+
}
319+
320+
auto L = [] {
321+
using NS::unrelated;
322+
NS::f^oo();
323+
};)cpp",
324+
R"cpp(
325+
namespace NS {
326+
void unrelated();
327+
void foo();
328+
}
329+
330+
auto L = [] {
331+
using NS::foo;using NS::unrelated;
332+
foo();
333+
};)cpp",
334+
},
312335
// If all other using are fully qualified, add ::
313336
{R"cpp(
314337
#include "test.hpp"

0 commit comments

Comments
 (0)