diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -1377,6 +1377,39 @@ return AllOf(sigHelpLabeled(Label), paramsAre(Parameters)); } +TEST(SignatureHelpTest, SmartPointerFactoryFunctions) { + auto Code = Annotations(R"cpp( + namespace std { + template + T make_unique(Args&&... args); + template + T make_shared(Args&&... args); + } + template + struct QSharedPointer { + template + static T create(Args&&... args); + }; + struct Foo { + Foo(int x, int y) {} + Foo(float x, float y) {} + }; + int main() { + std::make_shared(1, ^); + std::make_unique(1, ^); + QSharedPointer::create(1, ^); + } + )cpp"); + for (auto Point : Code.points()) { + auto Results = signatures(Code.code(), Point); + EXPECT_THAT(Results.signatures, + ElementsAre(sig("Foo([[int x]], [[int y]])"), + sig("Foo([[float x]], [[float y]])"))); + EXPECT_EQ(0, Results.activeSignature); + EXPECT_EQ(1, Results.activeParameter); + } +} + TEST(SignatureHelpTest, Overloads) { auto Results = signatures(R"cpp( void foo(int x, int y); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -6105,6 +6105,38 @@ OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); if (auto ULE = dyn_cast(NakedFn)) { + if (ULE->getNumDecls() > 0) { + std::string QualifiedName; + llvm::raw_string_ostream OS(QualifiedName); + if (const auto *NC = ULE->getNamingClass()) { + NC->printQualifiedName(OS); + OS << "::"; + ULE->decls().begin()->printName(OS); + + if (QualifiedName == "QSharedPointer::create") { + if (const auto *CTSD = dyn_cast( + ULE->getNamingClass())) { + const auto &TemplateArgs = CTSD->getTemplateArgs(); + if (TemplateArgs.size() == 1) { + return ProduceConstructorSignatureHelp( + TemplateArgs[0].getAsType(), OpenParLoc, Args, OpenParLoc, + false); + } + } + } + } else { + ULE->decls().begin()->printQualifiedName(OS); + if (QualifiedName == "std::make_unique" || + QualifiedName == "std::make_shared") { + if (ULE->getNumTemplateArgs() == 1) { + return ProduceConstructorSignatureHelp( + ULE->template_arguments().front().getArgument().getAsType(), OpenParLoc, + Args, OpenParLoc, false); + } + } + } + } + AddOverloadedCallCandidates(ULE, ArgsWithoutDependentTypes, CandidateSet, /*PartialOverloading=*/true); } else if (auto UME = dyn_cast(NakedFn)) {