aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra')
-rw-r--r--clang-tools-extra/clangd/FindSymbols.cpp12
-rw-r--r--clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp93
-rw-r--r--clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp5
3 files changed, 102 insertions, 8 deletions
diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp
index 84bcbc1..7655a39 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -14,6 +14,7 @@
#include "SourceCode.h"
#include "index/Index.h"
#include "support/Logger.h"
+#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Index/IndexSymbol.h"
#include "llvm/ADT/ArrayRef.h"
@@ -391,6 +392,17 @@ private:
D = TD;
}
+ // FriendDecls don't act as DeclContexts, but they might wrap a function
+ // definition that won't be visible through other means in the AST. Hence
+ // unwrap it here instead.
+ if (auto *Friend = llvm::dyn_cast<FriendDecl>(D)) {
+ if (auto *Func =
+ llvm::dyn_cast_or_null<FunctionDecl>(Friend->getFriendDecl())) {
+ if (Func->isThisDeclarationADefinition())
+ D = Func;
+ }
+ }
+
VisitKind Visit = shouldVisit(D);
if (Visit == VisitKind::No)
return;
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 5a5d815..61bd631 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -3267,6 +3267,56 @@ TEST(SignatureHelpTest, VariadicType) {
}
}
+TEST(SignatureHelpTest, SkipExplicitObjectParameter) {
+ Annotations Code(R"cpp(
+ struct A {
+ void foo(this auto&& self, int arg);
+ void bar(this A self, int arg);
+ };
+ int main() {
+ A a {};
+ a.foo($c1^);
+ (&A::bar)($c2^);
+ (&A::foo)($c3^);
+ }
+ )cpp");
+
+ auto TU = TestTU::withCode(Code.code());
+ TU.ExtraArgs = {"-std=c++23"};
+
+ MockFS FS;
+ auto Inputs = TU.inputs(FS);
+
+ auto Preamble = TU.preamble();
+ ASSERT_TRUE(Preamble);
+
+ {
+ const auto Result = signatureHelp(testPath(TU.Filename), Code.point("c1"),
+ *Preamble, Inputs, MarkupKind::PlainText);
+
+ EXPECT_EQ(1U, Result.signatures.size());
+
+ EXPECT_THAT(Result.signatures[0], AllOf(sig("foo([[int arg]]) -> void")));
+ }
+ {
+ const auto Result = signatureHelp(testPath(TU.Filename), Code.point("c2"),
+ *Preamble, Inputs, MarkupKind::PlainText);
+
+ EXPECT_EQ(1U, Result.signatures.size());
+
+ EXPECT_THAT(Result.signatures[0], AllOf(sig("([[A]], [[int]]) -> void")));
+ }
+ {
+ // TODO: llvm/llvm-project/146649
+ const auto Result = signatureHelp(testPath(TU.Filename), Code.point("c3"),
+ *Preamble, Inputs, MarkupKind::PlainText);
+ // TODO: We expect 1 signature here, with this signature
+ EXPECT_EQ(0U, Result.signatures.size());
+ // EXPECT_THAT(Result.signatures[0], AllOf(sig("([[auto&&]], [[int]]) ->
+ // void")));
+ }
+}
+
TEST(CompletionTest, IncludedCompletionKinds) {
Annotations Test(R"cpp(#include "^)cpp");
auto TU = TestTU::withCode(Test.code());
@@ -4369,14 +4419,24 @@ TEST(CompletionTest, SkipExplicitObjectParameter) {
Annotations Code(R"cpp(
struct A {
void foo(this auto&& self, int arg);
+ void bar(this A self, int arg);
};
int main() {
A a {};
- a.^
+ a.$c1^;
+ (&A::fo$c2^;
+ (&A::ba$c3^;
}
)cpp");
+ // TODO: llvm/llvm-project/146649
+ // This is incorrect behavior. Correct Result should be a variant of,
+ // c2: signature = (auto&& self, int arg)
+ // snippet = (${1: auto&& self}, ${2: int arg})
+ // c3: signature = (A self, int arg)
+ // snippet = (${1: A self}, ${2: int arg})
+
auto TU = TestTU::withCode(Code.code());
TU.ExtraArgs = {"-std=c++23"};
@@ -4387,12 +4447,31 @@ TEST(CompletionTest, SkipExplicitObjectParameter) {
MockFS FS;
auto Inputs = TU.inputs(FS);
- auto Result = codeComplete(testPath(TU.Filename), Code.point(),
- Preamble.get(), Inputs, Opts);
-
- EXPECT_THAT(Result.Completions,
- ElementsAre(AllOf(named("foo"), signature("(int arg)"),
- snippetSuffix("(${1:int arg})"))));
+ {
+ auto Result = codeComplete(testPath(TU.Filename), Code.point("c1"),
+ Preamble.get(), Inputs, Opts);
+
+ EXPECT_THAT(Result.Completions,
+ UnorderedElementsAre(AllOf(named("foo"), signature("(int arg)"),
+ snippetSuffix("(${1:int arg})")),
+ AllOf(named("bar"), signature("(int arg)"),
+ snippetSuffix("(${1:int arg})"))));
+ }
+ {
+ auto Result = codeComplete(testPath(TU.Filename), Code.point("c2"),
+ Preamble.get(), Inputs, Opts);
+ EXPECT_THAT(
+ Result.Completions,
+ ElementsAre(AllOf(named("foo"), signature("<class self:auto>(int arg)"),
+ snippetSuffix("<${1:class self:auto}>"))));
+ }
+ {
+ auto Result = codeComplete(testPath(TU.Filename), Code.point("c3"),
+ Preamble.get(), Inputs, Opts);
+ EXPECT_THAT(Result.Completions,
+ ElementsAre(AllOf(named("bar"), signature("(int arg)"),
+ snippetSuffix(""))));
+ }
}
} // namespace
} // namespace clangd
diff --git a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
index 282859c..5b1630e 100644
--- a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
@@ -335,6 +335,7 @@ TEST(DocumentSymbols, BasicSymbols) {
Foo(int a) {}
void $decl[[f]]();
friend void f1();
+ friend void f2() {}
friend class Friend;
Foo& operator=(const Foo&);
~Foo();
@@ -346,7 +347,7 @@ TEST(DocumentSymbols, BasicSymbols) {
};
void f1();
- inline void f2() {}
+ void f2();
static const int KInt = 2;
const char* kStr = "123";
@@ -386,6 +387,8 @@ TEST(DocumentSymbols, BasicSymbols) {
withDetail("(int)"), children()),
AllOf(withName("f"), withKind(SymbolKind::Method),
withDetail("void ()"), children()),
+ AllOf(withName("f2"), withKind(SymbolKind::Function),
+ withDetail("void ()"), children()),
AllOf(withName("operator="), withKind(SymbolKind::Method),
withDetail("Foo &(const Foo &)"), children()),
AllOf(withName("~Foo"), withKind(SymbolKind::Constructor),