Skip to content

Commit

Permalink
[clangd] Handle lambda scopes inside Node::getDeclContext() (#76329)
Browse files Browse the repository at this point in the history
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.)
  • Loading branch information
zyn0217 committed Jan 11, 2024
1 parent d7642b2 commit 9ef2ac3
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
3 changes: 3 additions & 0 deletions clang-tools-extra/clangd/Selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
}
Expand Down
13 changes: 13 additions & 0 deletions clang-tools-extra/clangd/unittests/SelectionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
23 changes: 23 additions & 0 deletions clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 9ef2ac3

Please sign in to comment.