summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/CodeComplete.cpp12
-rw-r--r--clang-tools-extra/clangd/Protocol.h7
-rw-r--r--clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp60
3 files changed, 74 insertions, 5 deletions
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index 65c415fbaca..e355a83328d 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -794,7 +794,17 @@ public:
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
- unsigned NumCandidates) override {
+ unsigned NumCandidates,
+ SourceLocation OpenParLoc) override {
+ assert(!OpenParLoc.isInvalid());
+ SourceManager &SrcMgr = S.getSourceManager();
+ OpenParLoc = SrcMgr.getFileLoc(OpenParLoc);
+ if (SrcMgr.isInMainFile(OpenParLoc))
+ SigHelp.argListStart = sourceLocToPosition(SrcMgr, OpenParLoc);
+ else
+ elog("Location oustide main file in signature help: {0}",
+ OpenParLoc.printToString(SrcMgr));
+
std::vector<ScoredSignature> ScoredSignatures;
SigHelp.signatures.reserve(NumCandidates);
ScoredSignatures.reserve(NumCandidates);
diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index d019e82dbf7..2e291bd11f2 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -828,6 +828,13 @@ struct SignatureHelp {
/// The active parameter of the active signature.
int activeParameter = 0;
+
+ /// Position of the start of the argument list, including opening paren. e.g.
+ /// foo("first arg", "second arg",
+ /// ^-argListStart ^-cursor
+ /// This is a clangd-specific extension, it is only available via C++ API and
+ /// not currently serialized for the LSP.
+ Position argListStart;
};
llvm::json::Value toJSON(const SignatureHelp &);
diff --git a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
index b92cf64a6f2..cb0e9a3e515 100644
--- a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
+++ b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
@@ -825,8 +825,7 @@ TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) {
EXPECT_TRUE(Results.Completions.empty());
}
-
-SignatureHelp signatures(StringRef Text,
+SignatureHelp signatures(StringRef Text, Position Point,
std::vector<Symbol> IndexSymbols = {}) {
std::unique_ptr<SymbolIndex> Index;
if (!IndexSymbols.empty())
@@ -840,9 +839,14 @@ SignatureHelp signatures(StringRef Text,
ClangdServer Server(CDB, FS, DiagConsumer, Opts);
auto File = testPath("foo.cpp");
+ runAddDocument(Server, File, Text);
+ return cantFail(runSignatureHelp(Server, File, Point));
+}
+
+SignatureHelp signatures(StringRef Text,
+ std::vector<Symbol> IndexSymbols = {}) {
Annotations Test(Text);
- runAddDocument(Server, File, Test.code());
- return cantFail(runSignatureHelp(Server, File, Test.point()));
+ return signatures(Test.code(), Test.point(), std::move(IndexSymbols));
}
MATCHER_P(ParamsAre, P, "") {
@@ -907,6 +911,54 @@ TEST(SignatureHelpTest, ActiveArg) {
EXPECT_EQ(1, Results.activeParameter);
}
+TEST(SignatureHelpTest, OpeningParen) {
+ llvm::StringLiteral Tests[] = {// Recursive function call.
+ R"cpp(
+ int foo(int a, int b, int c);
+ int main() {
+ foo(foo $p^( foo(10, 10, 10), ^ )));
+ })cpp",
+ // Functional type cast.
+ R"cpp(
+ struct Foo {
+ Foo(int a, int b, int c);
+ };
+ int main() {
+ Foo $p^( 10, ^ );
+ })cpp",
+ // New expression.
+ R"cpp(
+ struct Foo {
+ Foo(int a, int b, int c);
+ };
+ int main() {
+ new Foo $p^( 10, ^ );
+ })cpp",
+ // Macro expansion.
+ R"cpp(
+ int foo(int a, int b, int c);
+ #define FOO foo(
+
+ int main() {
+ // Macro expansions.
+ $p^FOO 10, ^ );
+ })cpp",
+ // Macro arguments.
+ R"cpp(
+ int foo(int a, int b, int c);
+ int main() {
+ #define ID(X) X
+ ID(foo $p^( foo(10), ^ ))
+ })cpp"};
+
+ for (auto Test : Tests) {
+ Annotations Code(Test);
+ EXPECT_EQ(signatures(Code.code(), Code.point()).argListStart,
+ Code.point("p"))
+ << "Test source:" << Test;
+ }
+}
+
class IndexRequestCollector : public SymbolIndex {
public:
bool
OpenPOWER on IntegriCloud