summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Sema/Sema.h14
-rw-r--r--clang/lib/Parse/ParseDecl.cpp7
-rw-r--r--clang/lib/Parse/ParseExpr.cpp10
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp6
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp3
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp69
-rw-r--r--clang/test/CodeCompletion/call.cpp2
7 files changed, 55 insertions, 56 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 465e8cddb5a..04ba15edb39 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10231,6 +10231,7 @@ public:
struct CodeCompleteExpressionData;
void CodeCompleteExpression(Scope *S,
const CodeCompleteExpressionData &Data);
+ void CodeCompleteExpression(Scope *S, QualType PreferredType);
void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase,
SourceLocation OpLoc, bool IsArrow,
bool IsBaseExprStatement);
@@ -10241,11 +10242,14 @@ public:
const VirtSpecifiers *VS = nullptr);
void CodeCompleteBracketDeclarator(Scope *S);
void CodeCompleteCase(Scope *S);
- void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args,
- SourceLocation OpenParLoc);
- void CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc,
- ArrayRef<Expr *> Args,
- SourceLocation OpenParLoc);
+ /// Reports signatures for a call to CodeCompleteConsumer and returns the
+ /// preferred type for the current argument. Returned type can be null.
+ QualType ProduceCallSignatureHelp(Scope *S, Expr *Fn, ArrayRef<Expr *> Args,
+ SourceLocation OpenParLoc);
+ QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type,
+ SourceLocation Loc,
+ ArrayRef<Expr *> Args,
+ SourceLocation OpenParLoc);
void CodeCompleteInitializer(Scope *S, Decl *D);
void CodeCompleteReturn(Scope *S);
void CodeCompleteAfterIf(Scope *S);
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 5d780de8f55..7a3a0198983 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2302,16 +2302,17 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
llvm::function_ref<void()> ExprListCompleter;
auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
auto ConstructorCompleter = [&, ThisVarDecl] {
- Actions.CodeCompleteConstructor(
+ QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(),
ThisDecl->getLocation(), Exprs, T.getOpenLocation());
+ Actions.CodeCompleteExpression(getCurScope(), PreferredType);
};
if (ThisVarDecl) {
// ParseExpressionList can sometimes succeed even when ThisDecl is not
// VarDecl. This is an error and it is reported in a call to
// Actions.ActOnInitializerError(). However, we call
- // CodeCompleteConstructor only on VarDecls, falling back to default
- // completer in other cases.
+ // ProduceConstructorSignatureHelp only on VarDecls, falling back to
+ // default completer in other cases.
ExprListCompleter = ConstructorCompleter;
}
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 39bf1c63981..d3bb2bbc24e 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1650,8 +1650,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
CommaLocsTy CommaLocs;
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteCall(getCurScope(), LHS.get(), None,
- PT.getOpenLocation());
+ QualType PreferredType = Actions.ProduceCallSignatureHelp(
+ getCurScope(), LHS.get(), None, PT.getOpenLocation());
+ Actions.CodeCompleteExpression(getCurScope(), PreferredType);
cutOffParsing();
return ExprError();
}
@@ -1659,8 +1660,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (OpKind == tok::l_paren || !LHS.isInvalid()) {
if (Tok.isNot(tok::r_paren)) {
if (ParseExpressionList(ArgExprs, CommaLocs, [&] {
- Actions.CodeCompleteCall(getCurScope(), LHS.get(), ArgExprs,
- PT.getOpenLocation());
+ QualType PreferredType = Actions.ProduceCallSignatureHelp(
+ getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation());
+ Actions.CodeCompleteExpression(getCurScope(), PreferredType);
})) {
(void)Actions.CorrectDelayedTyposInExpr(LHS);
LHS = ExprError();
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index fef01a4030f..deafd04506c 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1685,9 +1685,10 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
if (Tok.isNot(tok::r_paren)) {
if (ParseExpressionList(Exprs, CommaLocs, [&] {
- Actions.CodeCompleteConstructor(
+ QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
DS.getEndLoc(), Exprs, T.getOpenLocation());
+ Actions.CodeCompleteExpression(getCurScope(), PreferredType);
})) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
@@ -2819,9 +2820,10 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
if (ParseExpressionList(ConstructorArgs, CommaLocs, [&] {
ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(),
DeclaratorInfo).get();
- Actions.CodeCompleteConstructor(
+ QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen);
+ Actions.CodeCompleteExpression(getCurScope(), PreferredType);
})) {
SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
return ExprError();
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index c53eae3067e..b3c7e3a63d0 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -418,10 +418,11 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
SourceLocation LParLoc = T.getOpenLocation();
if (ParseExpressionList(
Exprs, CommaLocs, [this, OmpPrivParm, LParLoc, &Exprs] {
- Actions.CodeCompleteConstructor(
+ QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
getCurScope(),
OmpPrivParm->getType()->getCanonicalTypeInternal(),
OmpPrivParm->getLocation(), Exprs, LParLoc);
+ Actions.CodeCompleteExpression(getCurScope(), PreferredType);
})) {
Actions.ActOnInitializerError(OmpPrivParm);
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 7ba94c6e0e2..addddd8a849 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -3752,6 +3752,10 @@ void Sema::CodeCompleteExpression(Scope *S,
Results.data(), Results.size());
}
+void Sema::CodeCompleteExpression(Scope *S, QualType PreferredType) {
+ return CodeCompleteExpression(S, CodeCompleteExpressionData(PreferredType));
+}
+
void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
if (E.isInvalid())
CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
@@ -4435,42 +4439,28 @@ static QualType getParamType(Sema &SemaRef,
return ParamType;
}
-static void
-CodeCompleteOverloadResults(Sema &SemaRef, Scope *S,
- MutableArrayRef<ResultCandidate> Candidates,
- unsigned CurrentArg, SourceLocation OpenParLoc,
- bool CompleteExpressionWithCurrentArg = true) {
- QualType ParamType;
- if (CompleteExpressionWithCurrentArg)
- ParamType = getParamType(SemaRef, Candidates, CurrentArg);
-
- if (ParamType.isNull())
- SemaRef.CodeCompleteOrdinaryName(S, Sema::PCC_Expression);
- else
- SemaRef.CodeCompleteExpression(S, ParamType);
-
- if (!Candidates.empty())
- SemaRef.CodeCompleter->ProcessOverloadCandidates(
- SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc);
+static QualType
+ProduceSignatureHelp(Sema &SemaRef, Scope *S,
+ MutableArrayRef<ResultCandidate> Candidates,
+ unsigned CurrentArg, SourceLocation OpenParLoc) {
+ if (Candidates.empty())
+ return QualType();
+ SemaRef.CodeCompleter->ProcessOverloadCandidates(
+ SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc);
+ return getParamType(SemaRef, Candidates, CurrentArg);
}
-void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args,
- SourceLocation OpenParLoc) {
+QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn,
+ ArrayRef<Expr *> Args,
+ SourceLocation OpenParLoc) {
if (!CodeCompleter)
- return;
-
- // When we're code-completing for a call, we fall back to ordinary
- // name code-completion whenever we can't produce specific
- // results. We may want to revisit this strategy in the future,
- // e.g., by merging the two kinds of results.
+ return QualType();
// FIXME: Provide support for variadic template functions.
-
// Ignore type-dependent call expressions entirely.
if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||
Expr::hasAnyTypeDependentArguments(Args)) {
- CodeCompleteOrdinaryName(S, PCC_Expression);
- return;
+ return QualType();
}
// Build an overload candidate set based on the functions we find.
@@ -4551,25 +4541,24 @@ void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args,
Results.push_back(ResultCandidate(FT));
}
}
-
mergeCandidatesWithResults(*this, Results, CandidateSet, Loc);
- CodeCompleteOverloadResults(*this, S, Results, Args.size(), OpenParLoc,
- !CandidateSet.empty());
+ QualType ParamType =
+ ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc);
+ return !CandidateSet.empty() ? ParamType : QualType();
}
-void Sema::CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc,
- ArrayRef<Expr *> Args,
- SourceLocation OpenParLoc) {
+QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type,
+ SourceLocation Loc,
+ ArrayRef<Expr *> Args,
+ SourceLocation OpenParLoc) {
if (!CodeCompleter)
- return;
+ return QualType();
// A complete type is needed to lookup for constructors.
CXXRecordDecl *RD =
isCompleteType(Loc, Type) ? Type->getAsCXXRecordDecl() : nullptr;
- if (!RD) {
- CodeCompleteExpression(S, Type);
- return;
- }
+ if (!RD)
+ return Type;
// FIXME: Provide support for member initializers.
// FIXME: Provide support for variadic template constructors.
@@ -4594,7 +4583,7 @@ void Sema::CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc,
SmallVector<ResultCandidate, 8> Results;
mergeCandidatesWithResults(*this, Results, CandidateSet, Loc);
- CodeCompleteOverloadResults(*this, S, Results, Args.size(), OpenParLoc);
+ return ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc);
}
void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
diff --git a/clang/test/CodeCompletion/call.cpp b/clang/test/CodeCompletion/call.cpp
index 3e062109a9a..c57c339cd13 100644
--- a/clang/test/CodeCompletion/call.cpp
+++ b/clang/test/CodeCompletion/call.cpp
@@ -18,10 +18,10 @@ void f();
void test() {
f(Y(), 0, 0);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
- // CHECK-CC1: COMPLETION: Pattern : dynamic_cast<<#type#>>(<#expression#>)
// CHECK-CC1: f(Y y, <#int ZZ#>)
// CHECK-CC1-NEXT: f(int i, <#int j#>, int k)
// CHECK-CC1-NEXT: f(float x, <#float y#>)
+ // CHECK-CC1: COMPLETION: Pattern : dynamic_cast<<#type#>>(<#expression#>)
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:13 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
// CHECK-CC2-NOT: f(Y y, int ZZ)
// CHECK-CC2: f(int i, int j, <#int k#>)
OpenPOWER on IntegriCloud