Index: include/clang/Parse/Parser.h =================================================================== --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -214,6 +214,10 @@ /// should not be set directly. bool InMessageExpression; + /// Gets set to true after calling CodeCompleteCall, it is for a workaround to + /// make sure CodeComleteCall is only called at the deepest level. + bool CalledOverloadCompletion = false; + /// The "depth" of the template parameters currently being parsed. unsigned TemplateParameterDepth; Index: lib/Parse/ParseExpr.cpp =================================================================== --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -1658,11 +1658,21 @@ 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()); - })) { + auto Completer = [&] { + if (CalledOverloadCompletion) + return; + Actions.CodeCompleteCall(getCurScope(), LHS.get(), ArgExprs, + PT.getOpenLocation()); + CalledOverloadCompletion = true; + }; + if (ParseExpressionList(ArgExprs, CommaLocs, Completer)) { (void)Actions.CorrectDelayedTyposInExpr(LHS); + // If we got an error when parsing expression list, we don't call + // the CodeCompleteCall handler inside the parser. So call it here + // to make sure we get overload suggestions even when we are in the + // middle of a parameter. + if (PP.isCodeCompletionReached()) + Completer(); LHS = ExprError(); } else if (LHS.isInvalid()) { for (auto &E : ArgExprs) Index: test/CodeCompletion/function-overloads-inside-param.cpp =================================================================== --- /dev/null +++ test/CodeCompletion/function-overloads-inside-param.cpp @@ -0,0 +1,8 @@ +void f(int i, int j = 2, int k = 5); +void f(float x, float y...); + +void test() { + ::f(1 + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:5:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1: f(<#int i#>{#, <#int j = 2#>{#, <#int k = 5#>#}#}) + // CHECK-CC1: f(<#float x#>, <#float y, ...#>) Index: test/CodeCompletion/function-overloads.cpp =================================================================== --- /dev/null +++ test/CodeCompletion/function-overloads.cpp @@ -0,0 +1,8 @@ +void f(int i, int j = 2, int k = 5); +void f(float x, float y...); + +void test() { + ::f( + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:5:7 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1: f(<#int i#>{#, <#int j = 2#>{#, <#int k = 5#>#}#}) + // CHECK-CC1: f(<#float x#>, <#float y, ...#>) Index: test/Index/complete-block-property-assignment.m =================================================================== --- test/Index/complete-block-property-assignment.m +++ test/Index/complete-block-property-assignment.m @@ -60,7 +60,6 @@ // RUN: c-index-test -code-completion-at=%s:51:16 %s | FileCheck -check-prefix=CHECK-NO %s // RUN: c-index-test -code-completion-at=%s:52:23 %s | FileCheck -check-prefix=CHECK-NO %s // RUN: c-index-test -code-completion-at=%s:53:12 %s | FileCheck -check-prefix=CHECK-NO %s -// RUN: c-index-test -code-completion-at=%s:54:15 %s | FileCheck -check-prefix=CHECK-NO %s // RUN: c-index-test -code-completion-at=%s:56:15 %s | FileCheck -check-prefix=CHECK-NO %s // CHECK-NO: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35) // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35) @@ -69,4 +68,7 @@ // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText onReadonly} (35) // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent} (35) +// RUN: c-index-test -code-completion-at=%s:54:15 %s | FileCheck -check-prefix=CHECK-NO1 %s +// CHECK-NO1: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35) +// CHECK-NO1-NEXT: FunctionDecl:{ResultType void}{TypedText func}{LeftParen (}{Placeholder int x}{RightParen )} (50) @end