forked from OSchip/llvm-project
[CodeCompletion] Signature help for braced constructor calls
Implementation is based on the "expected type" as used for designated-initializers in braced init lists. This means it can deduce the type in some cases where it's not written: void foo(Widget); foo({ /*help here*/ }); Only basic constructor calls are in scope of this patch, excluded are: - aggregate initialization (no help is offered for aggregates) - initializer_list initialization (no help is offered for these constructors) Fixes https://github.com/clangd/clangd/issues/306 Differential Revision: https://reviews.llvm.org/D116317
This commit is contained in:
parent
a390c9905d
commit
92417eaf33
|
@ -555,7 +555,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
|
|||
}},
|
||||
{"signatureHelpProvider",
|
||||
llvm::json::Object{
|
||||
{"triggerCharacters", {"(", ",", ")", "<", ">"}},
|
||||
{"triggerCharacters", {"(", ")", "{", "}", "<", ">", ","}},
|
||||
}},
|
||||
{"declarationProvider", true},
|
||||
{"definitionProvider", true},
|
||||
|
|
|
@ -921,7 +921,8 @@ public:
|
|||
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
|
||||
OverloadCandidate *Candidates,
|
||||
unsigned NumCandidates,
|
||||
SourceLocation OpenParLoc) override {
|
||||
SourceLocation OpenParLoc,
|
||||
bool Braced) override {
|
||||
assert(!OpenParLoc.isInvalid());
|
||||
SourceManager &SrcMgr = S.getSourceManager();
|
||||
OpenParLoc = SrcMgr.getFileLoc(OpenParLoc);
|
||||
|
@ -961,8 +962,9 @@ public:
|
|||
paramIndexForArg(Candidate, SigHelp.activeParameter);
|
||||
}
|
||||
|
||||
const auto *CCS = Candidate.CreateSignatureString(
|
||||
CurrentArg, S, *Allocator, CCTUInfo, true);
|
||||
const auto *CCS =
|
||||
Candidate.CreateSignatureString(CurrentArg, S, *Allocator, CCTUInfo,
|
||||
/*IncludeBriefComment=*/true, Braced);
|
||||
assert(CCS && "Expected the CodeCompletionString to be non-null");
|
||||
ScoredSignatures.push_back(processOverloadCandidate(
|
||||
Candidate, *CCS,
|
||||
|
@ -1163,7 +1165,8 @@ public:
|
|||
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
|
||||
OverloadCandidate *Candidates,
|
||||
unsigned NumCandidates,
|
||||
SourceLocation OpenParLoc) override {
|
||||
SourceLocation OpenParLoc,
|
||||
bool Braced) override {
|
||||
assert(CurrentArg <= (unsigned)std::numeric_limits<int>::max() &&
|
||||
"too many arguments");
|
||||
|
||||
|
|
|
@ -107,10 +107,12 @@
|
|||
# CHECK-NEXT: "signatureHelpProvider": {
|
||||
# CHECK-NEXT: "triggerCharacters": [
|
||||
# CHECK-NEXT: "(",
|
||||
# CHECK-NEXT: ",",
|
||||
# CHECK-NEXT: ")",
|
||||
# CHECK-NEXT: "{",
|
||||
# CHECK-NEXT: "}",
|
||||
# CHECK-NEXT: "<",
|
||||
# CHECK-NEXT: ">"
|
||||
# CHECK-NEXT: ","
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "textDocumentSync": {
|
||||
|
|
|
@ -1212,6 +1212,10 @@ struct ExpectedParameter {
|
|||
std::string Text;
|
||||
std::pair<unsigned, unsigned> Offsets;
|
||||
};
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
|
||||
const ExpectedParameter &P) {
|
||||
return OS << P.Text;
|
||||
}
|
||||
MATCHER_P(ParamsAre, P, "") {
|
||||
if (P.size() != arg.parameters.size())
|
||||
return false;
|
||||
|
@ -1260,6 +1264,36 @@ TEST(SignatureHelpTest, Overloads) {
|
|||
EXPECT_EQ(0, Results.activeParameter);
|
||||
}
|
||||
|
||||
TEST(SignatureHelpTest, Constructors) {
|
||||
std::string Top = R"cpp(
|
||||
struct S {
|
||||
S(int);
|
||||
S(const S &) = delete;
|
||||
};
|
||||
)cpp";
|
||||
|
||||
auto CheckParenInit = [&](std::string Init) {
|
||||
EXPECT_THAT(signatures(Top + Init).signatures,
|
||||
UnorderedElementsAre(Sig("S([[int]])")))
|
||||
<< Init;
|
||||
};
|
||||
CheckParenInit("S s(^);");
|
||||
CheckParenInit("auto s = S(^);");
|
||||
CheckParenInit("auto s = new S(^);");
|
||||
|
||||
auto CheckBracedInit = [&](std::string Init) {
|
||||
EXPECT_THAT(signatures(Top + Init).signatures,
|
||||
UnorderedElementsAre(Sig("S{[[int]]}")))
|
||||
<< Init;
|
||||
};
|
||||
CheckBracedInit("S s{^};");
|
||||
CheckBracedInit("S s = {^};");
|
||||
CheckBracedInit("auto s = S{^};");
|
||||
// FIXME: doesn't work: no ExpectedType set in ParseCXXNewExpression.
|
||||
// CheckBracedInit("auto s = new S{^};");
|
||||
CheckBracedInit("int x(S); int i = x({^});");
|
||||
}
|
||||
|
||||
TEST(SignatureHelpTest, OverloadInitListRegression) {
|
||||
auto Results = signatures(R"cpp(
|
||||
struct A {int x;};
|
||||
|
|
|
@ -1081,11 +1081,11 @@ public:
|
|||
|
||||
/// Create a new code-completion string that describes the function
|
||||
/// signature of this overload candidate.
|
||||
CodeCompletionString *CreateSignatureString(unsigned CurrentArg,
|
||||
Sema &S,
|
||||
CodeCompletionAllocator &Allocator,
|
||||
CodeCompletionTUInfo &CCTUInfo,
|
||||
bool IncludeBriefComments) const;
|
||||
CodeCompletionString *
|
||||
CreateSignatureString(unsigned CurrentArg, Sema &S,
|
||||
CodeCompletionAllocator &Allocator,
|
||||
CodeCompletionTUInfo &CCTUInfo,
|
||||
bool IncludeBriefComments, bool Braced) const;
|
||||
};
|
||||
|
||||
CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts)
|
||||
|
@ -1159,7 +1159,8 @@ public:
|
|||
virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
|
||||
OverloadCandidate *Candidates,
|
||||
unsigned NumCandidates,
|
||||
SourceLocation OpenParLoc) {}
|
||||
SourceLocation OpenParLoc,
|
||||
bool Braced) {}
|
||||
//@}
|
||||
|
||||
/// Retrieve the allocator that will be used to allocate
|
||||
|
@ -1210,7 +1211,8 @@ public:
|
|||
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
|
||||
OverloadCandidate *Candidates,
|
||||
unsigned NumCandidates,
|
||||
SourceLocation OpenParLoc) override;
|
||||
SourceLocation OpenParLoc,
|
||||
bool Braced) override;
|
||||
|
||||
bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override;
|
||||
|
||||
|
|
|
@ -12542,13 +12542,12 @@ public:
|
|||
QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type,
|
||||
SourceLocation Loc,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation OpenParLoc);
|
||||
QualType ProduceCtorInitMemberSignatureHelp(Scope *S, Decl *ConstructorDecl,
|
||||
CXXScopeSpec SS,
|
||||
ParsedType TemplateTypeTy,
|
||||
ArrayRef<Expr *> ArgExprs,
|
||||
IdentifierInfo *II,
|
||||
SourceLocation OpenParLoc);
|
||||
SourceLocation OpenParLoc,
|
||||
bool Braced);
|
||||
QualType ProduceCtorInitMemberSignatureHelp(
|
||||
Scope *S, Decl *ConstructorDecl, CXXScopeSpec SS,
|
||||
ParsedType TemplateTypeTy, ArrayRef<Expr *> ArgExprs, IdentifierInfo *II,
|
||||
SourceLocation OpenParLoc, bool Braced);
|
||||
QualType ProduceTemplateArgumentSignatureHelp(
|
||||
TemplateTy, ArrayRef<ParsedTemplateArgument>, SourceLocation LAngleLoc);
|
||||
void CodeCompleteInitializer(Scope *S, Decl *D);
|
||||
|
|
|
@ -1922,9 +1922,10 @@ namespace {
|
|||
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
|
||||
OverloadCandidate *Candidates,
|
||||
unsigned NumCandidates,
|
||||
SourceLocation OpenParLoc) override {
|
||||
SourceLocation OpenParLoc,
|
||||
bool Braced) override {
|
||||
Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
|
||||
OpenParLoc);
|
||||
OpenParLoc, Braced);
|
||||
}
|
||||
|
||||
CodeCompletionAllocator &getAllocator() override {
|
||||
|
|
|
@ -2420,7 +2420,8 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
|
|||
auto RunSignatureHelp = [&]() {
|
||||
QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(),
|
||||
ThisDecl->getLocation(), Exprs, T.getOpenLocation());
|
||||
ThisDecl->getLocation(), Exprs, T.getOpenLocation(),
|
||||
/*Braced=*/false);
|
||||
CalledSignatureHelp = true;
|
||||
return PreferredType;
|
||||
};
|
||||
|
@ -2440,7 +2441,8 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
|
|||
if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
|
||||
Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(),
|
||||
ThisDecl->getLocation(), Exprs, T.getOpenLocation());
|
||||
ThisDecl->getLocation(), Exprs, T.getOpenLocation(),
|
||||
/*Braced=*/false);
|
||||
CalledSignatureHelp = true;
|
||||
}
|
||||
Actions.ActOnInitializerError(ThisDecl);
|
||||
|
|
|
@ -3740,8 +3740,8 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
|
|||
if (TemplateTypeTy.isInvalid())
|
||||
return QualType();
|
||||
QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp(
|
||||
getCurScope(), ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II,
|
||||
T.getOpenLocation());
|
||||
getCurScope(), ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs,
|
||||
II, T.getOpenLocation(), /*Braced=*/false);
|
||||
CalledSignatureHelp = true;
|
||||
return PreferredType;
|
||||
};
|
||||
|
|
|
@ -1878,7 +1878,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
|
|||
if (TypeRep)
|
||||
PreferredType = Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
|
||||
DS.getEndLoc(), Exprs, T.getOpenLocation());
|
||||
DS.getEndLoc(), Exprs, T.getOpenLocation(), /*Braced=*/false);
|
||||
CalledSignatureHelp = true;
|
||||
return PreferredType;
|
||||
};
|
||||
|
@ -3168,7 +3168,8 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
|
|||
if (TypeRep)
|
||||
PreferredType = Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
|
||||
DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen);
|
||||
DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen,
|
||||
/*Braced=*/false);
|
||||
CalledSignatureHelp = true;
|
||||
return PreferredType;
|
||||
};
|
||||
|
|
|
@ -459,12 +459,22 @@ ExprResult Parser::ParseBraceInitializer() {
|
|||
Actions, EnterExpressionEvaluationContext::InitList);
|
||||
|
||||
bool InitExprsOk = true;
|
||||
DesignatorCompletionInfo DesignatorCompletion{
|
||||
InitExprs,
|
||||
PreferredType.get(T.getOpenLocation()),
|
||||
QualType LikelyType = PreferredType.get(T.getOpenLocation());
|
||||
DesignatorCompletionInfo DesignatorCompletion{InitExprs, LikelyType};
|
||||
bool CalledSignatureHelp = false;
|
||||
auto RunSignatureHelp = [&] {
|
||||
QualType PreferredType;
|
||||
if (!LikelyType.isNull())
|
||||
PreferredType = Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), LikelyType->getCanonicalTypeInternal(),
|
||||
T.getOpenLocation(), InitExprs, T.getOpenLocation(), /*Braced=*/true);
|
||||
CalledSignatureHelp = true;
|
||||
return PreferredType;
|
||||
};
|
||||
|
||||
while (1) {
|
||||
PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);
|
||||
|
||||
// Handle Microsoft __if_exists/if_not_exists if necessary.
|
||||
if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
|
||||
Tok.is(tok::kw___if_not_exists))) {
|
||||
|
|
|
@ -471,7 +471,7 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
|
|||
auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
|
||||
QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
|
||||
OmpPrivParm->getLocation(), Exprs, LParLoc);
|
||||
OmpPrivParm->getLocation(), Exprs, LParLoc, /*Braced=*/false);
|
||||
CalledSignatureHelp = true;
|
||||
return PreferredType;
|
||||
};
|
||||
|
|
|
@ -656,7 +656,7 @@ static std::string getOverloadAsString(const CodeCompletionString &CCS) {
|
|||
|
||||
void PrintingCodeCompleteConsumer::ProcessOverloadCandidates(
|
||||
Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates,
|
||||
unsigned NumCandidates, SourceLocation OpenParLoc) {
|
||||
unsigned NumCandidates, SourceLocation OpenParLoc, bool Braced) {
|
||||
OS << "OPENING_PAREN_LOC: ";
|
||||
OpenParLoc.print(OS, SemaRef.getSourceManager());
|
||||
OS << "\n";
|
||||
|
@ -664,7 +664,7 @@ void PrintingCodeCompleteConsumer::ProcessOverloadCandidates(
|
|||
for (unsigned I = 0; I != NumCandidates; ++I) {
|
||||
if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString(
|
||||
CurrentArg, SemaRef, getAllocator(), CCTUInfo,
|
||||
includeBriefComments())) {
|
||||
includeBriefComments(), Braced)) {
|
||||
OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3833,7 +3833,8 @@ static CodeCompletionString *createTemplateSignatureString(
|
|||
CodeCompletionString *
|
||||
CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
|
||||
unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator,
|
||||
CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments) const {
|
||||
CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments,
|
||||
bool Braced) const {
|
||||
PrintingPolicy Policy = getCompletionPrintingPolicy(S);
|
||||
// Show signatures of constructors as they are declared:
|
||||
// vector(int n) rather than vector<string>(int n)
|
||||
|
@ -3857,9 +3858,11 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
|
|||
const FunctionType *FT = getFunctionType();
|
||||
Result.AddResultTypeChunk(Result.getAllocator().CopyString(
|
||||
FT->getReturnType().getAsString(Policy)));
|
||||
Result.AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
Result.AddChunk(Braced ? CodeCompletionString::CK_LeftBrace
|
||||
: CodeCompletionString::CK_LeftParen);
|
||||
Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
|
||||
Result.AddChunk(CodeCompletionString::CK_RightParen);
|
||||
Result.AddChunk(Braced ? CodeCompletionString::CK_RightBrace
|
||||
: CodeCompletionString::CK_RightParen);
|
||||
return Result.TakeString();
|
||||
}
|
||||
|
||||
|
@ -3879,10 +3882,12 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
|
|||
Proto->getReturnType().getAsString(Policy)));
|
||||
}
|
||||
|
||||
Result.AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
Result.AddChunk(Braced ? CodeCompletionString::CK_LeftBrace
|
||||
: CodeCompletionString::CK_LeftParen);
|
||||
AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto, Result,
|
||||
CurrentArg);
|
||||
Result.AddChunk(CodeCompletionString::CK_RightParen);
|
||||
Result.AddChunk(Braced ? CodeCompletionString::CK_RightBrace
|
||||
: CodeCompletionString::CK_RightParen);
|
||||
|
||||
return Result.TakeString();
|
||||
}
|
||||
|
@ -5940,12 +5945,14 @@ static QualType getParamType(Sema &SemaRef,
|
|||
|
||||
static QualType
|
||||
ProduceSignatureHelp(Sema &SemaRef, MutableArrayRef<ResultCandidate> Candidates,
|
||||
unsigned CurrentArg, SourceLocation OpenParLoc) {
|
||||
unsigned CurrentArg, SourceLocation OpenParLoc,
|
||||
bool Braced) {
|
||||
if (Candidates.empty())
|
||||
return QualType();
|
||||
if (SemaRef.getPreprocessor().isCodeCompletionReached())
|
||||
SemaRef.CodeCompleter->ProcessOverloadCandidates(
|
||||
SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc);
|
||||
SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc,
|
||||
Braced);
|
||||
return getParamType(SemaRef, Candidates, CurrentArg);
|
||||
}
|
||||
|
||||
|
@ -6047,15 +6054,16 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn,
|
|||
}
|
||||
}
|
||||
mergeCandidatesWithResults(*this, Results, CandidateSet, Loc, Args.size());
|
||||
QualType ParamType =
|
||||
ProduceSignatureHelp(*this, Results, Args.size(), OpenParLoc);
|
||||
QualType ParamType = ProduceSignatureHelp(*this, Results, Args.size(),
|
||||
OpenParLoc, /*Braced=*/false);
|
||||
return !CandidateSet.empty() ? ParamType : QualType();
|
||||
}
|
||||
|
||||
QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type,
|
||||
SourceLocation Loc,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation OpenParLoc) {
|
||||
SourceLocation OpenParLoc,
|
||||
bool Braced) {
|
||||
if (!CodeCompleter)
|
||||
return QualType();
|
||||
|
||||
|
@ -6064,6 +6072,10 @@ QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type,
|
|||
isCompleteType(Loc, Type) ? Type->getAsCXXRecordDecl() : nullptr;
|
||||
if (!RD)
|
||||
return Type;
|
||||
// FIXME: we don't support signature help for aggregate initialization, so
|
||||
// don't offer a confusing partial list (e.g. the copy constructor).
|
||||
if (Braced && RD->isAggregate())
|
||||
return Type;
|
||||
|
||||
// FIXME: Provide support for member initializers.
|
||||
// FIXME: Provide support for variadic template constructors.
|
||||
|
@ -6072,12 +6084,20 @@ QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type,
|
|||
|
||||
for (NamedDecl *C : LookupConstructors(RD)) {
|
||||
if (auto *FD = dyn_cast<FunctionDecl>(C)) {
|
||||
// FIXME: we can't yet provide correct signature help for initializer
|
||||
// list constructors, so skip them entirely.
|
||||
if (Braced && LangOpts.CPlusPlus && isInitListConstructor(FD))
|
||||
continue;
|
||||
AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), Args,
|
||||
CandidateSet,
|
||||
/*SuppressUserConversions=*/false,
|
||||
/*PartialOverloading=*/true,
|
||||
/*AllowExplicit*/ true);
|
||||
} else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(C)) {
|
||||
if (Braced && LangOpts.CPlusPlus &&
|
||||
isInitListConstructor(FTD->getTemplatedDecl()))
|
||||
continue;
|
||||
|
||||
AddTemplateOverloadCandidate(
|
||||
FTD, DeclAccessPair::make(FTD, C->getAccess()),
|
||||
/*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet,
|
||||
|
@ -6088,12 +6108,13 @@ QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type,
|
|||
|
||||
SmallVector<ResultCandidate, 8> Results;
|
||||
mergeCandidatesWithResults(*this, Results, CandidateSet, Loc, Args.size());
|
||||
return ProduceSignatureHelp(*this, Results, Args.size(), OpenParLoc);
|
||||
return ProduceSignatureHelp(*this, Results, Args.size(), OpenParLoc, Braced);
|
||||
}
|
||||
|
||||
QualType Sema::ProduceCtorInitMemberSignatureHelp(
|
||||
Scope *S, Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy,
|
||||
ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc) {
|
||||
ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc,
|
||||
bool Braced) {
|
||||
if (!CodeCompleter)
|
||||
return QualType();
|
||||
|
||||
|
@ -6106,7 +6127,7 @@ QualType Sema::ProduceCtorInitMemberSignatureHelp(
|
|||
Constructor->getParent(), SS, TemplateTypeTy, II))
|
||||
return ProduceConstructorSignatureHelp(getCurScope(), MemberDecl->getType(),
|
||||
MemberDecl->getLocation(), ArgExprs,
|
||||
OpenParLoc);
|
||||
OpenParLoc, Braced);
|
||||
return QualType();
|
||||
}
|
||||
|
||||
|
@ -6159,7 +6180,8 @@ QualType Sema::ProduceTemplateArgumentSignatureHelp(
|
|||
if (const auto *TD = llvm::dyn_cast<TemplateDecl>(ND))
|
||||
Consider(TD);
|
||||
}
|
||||
return ProduceSignatureHelp(*this, Results, Args.size(), LAngleLoc);
|
||||
return ProduceSignatureHelp(*this, Results, Args.size(), LAngleLoc,
|
||||
/*Braced=*/false);
|
||||
}
|
||||
|
||||
static QualType getDesignatedType(QualType BaseType, const Designation &Desig) {
|
||||
|
|
|
@ -15,3 +15,40 @@ void foo() {
|
|||
// CHECK-CC2: OVERLOAD: Foo(<#const Foo<int *> &#>)
|
||||
// CHECK-CC2: OVERLOAD: Foo(<#Foo<int *> &&#>
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <typename> struct initializer_list {};
|
||||
} // namespace std
|
||||
|
||||
struct Bar {
|
||||
// CHECK-BRACED: OVERLOAD: Bar{<#int#>}
|
||||
Bar(int);
|
||||
// CHECK-BRACED: OVERLOAD: Bar{<#double#>, double}
|
||||
Bar(double, double);
|
||||
// FIXME: no support for init-list constructors yet.
|
||||
// CHECK-BRACED-NOT: OVERLOAD: {{.*}}char
|
||||
Bar(std::initializer_list<char> C);
|
||||
// CHECK-BRACED: OVERLOAD: Bar{<#const Bar &#>}
|
||||
// CHECK-BRACED: OVERLOAD: Bar{<#T *Pointer#>}
|
||||
template <typename T> Bar(T *Pointer);
|
||||
};
|
||||
|
||||
auto b1 = Bar{};
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:36:15 %s | FileCheck -check-prefix=CHECK-BRACED %s
|
||||
Bar b2{};
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:38:8 %s | FileCheck -check-prefix=CHECK-BRACED %s
|
||||
static int consumeBar(Bar) { return 0; }
|
||||
int b3 = consumeBar({});
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:41:22 %s | FileCheck -check-prefix=CHECK-BRACED %s
|
||||
|
||||
struct Aggregate {
|
||||
// FIXME: no support for aggregates yet.
|
||||
// CHECK-AGGREGATE-NOT: OVERLOAD: Aggregate{<#const Aggregate &#>}
|
||||
// CHECK-AGGREGATE-NOT: OVERLOAD: {{.*}}first
|
||||
int first;
|
||||
int second;
|
||||
};
|
||||
|
||||
Aggregate a{};
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:52:13 %s | FileCheck -check-prefix=CHECK-AGGREGATE %s
|
||||
|
||||
|
|
|
@ -656,14 +656,15 @@ namespace {
|
|||
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
|
||||
OverloadCandidate *Candidates,
|
||||
unsigned NumCandidates,
|
||||
SourceLocation OpenParLoc) override {
|
||||
SourceLocation OpenParLoc,
|
||||
bool Braced) override {
|
||||
StoredResults.reserve(StoredResults.size() + NumCandidates);
|
||||
for (unsigned I = 0; I != NumCandidates; ++I) {
|
||||
CodeCompletionString *StoredCompletion
|
||||
= Candidates[I].CreateSignatureString(CurrentArg, S, getAllocator(),
|
||||
CodeCompletionString *StoredCompletion =
|
||||
Candidates[I].CreateSignatureString(CurrentArg, S, getAllocator(),
|
||||
getCodeCompletionTUInfo(),
|
||||
includeBriefComments());
|
||||
|
||||
includeBriefComments(), Braced);
|
||||
|
||||
CXCompletionResult R;
|
||||
R.CursorKind = CXCursor_OverloadCandidate;
|
||||
R.CompletionString = StoredCompletion;
|
||||
|
|
|
@ -995,7 +995,8 @@ public:
|
|||
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
|
||||
OverloadCandidate *Candidates,
|
||||
unsigned NumCandidates,
|
||||
SourceLocation OpenParLoc) override {
|
||||
SourceLocation OpenParLoc,
|
||||
bool Braced) override {
|
||||
// At the moment we don't filter out any overloaded candidates.
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue