kadircet updated this revision to Diff 164477.
kadircet added a comment.

- Rebase and use new signature help.

Currently the problem is, there are again some tests out there that rely on
CodeCompeleteOrdinaryName to be called even when getting overloads at an unknown
parameter type. These tests are:

  Clang :: CodeCompletion/call.cpp
  Clang :: Index/code-completion.cpp
  Clang :: Index/complete-call.cpp
  Clang :: Index/complete-functor-call.cpp
  Clang :: Index/complete-optional-params.cpp
  Clang :: Index/complete-pointer-and-reference-to-functions.cpp

You can run something like this to check for the output(change ../clangd_bugs):

  ninja c-index-test && ./bin/c-index-test 
-code-completion-at=../clangd_bugs/tools/clang/test/Index/complete-call.cpp:53:12
 ../clan
  gd_bugs/tools/clang/test/Index/complete-call.cpp

As you can see current version generates only overloadcandidates, but tests
don't check them with a next loop, because they expect other completions, which
is not problematic but after checks for the items they also look for completion
context, which is not set as desired if CodeCompleteOrdinaryName or
CodeCompleteExpression is not called.

But for the first test case it is more complicated, it checks for code patterns
like dynamic_cast<EXPR>(EXPR); which is not generated if we don't call
CodeCompletionOrdinaryName or Expressions.


Repository:
  rC Clang

https://reviews.llvm.org/D51038

Files:
  include/clang/Parse/Parser.h
  lib/Parse/ParseExpr.cpp
  test/CodeCompletion/function-overloads-inside-param.cpp
  test/CodeCompletion/function-overloads.cpp
  test/Index/complete-block-property-assignment.m

Index: test/Index/complete-block-property-assignment.m
===================================================================
--- test/Index/complete-block-property-assignment.m
+++ test/Index/complete-block-property-assignment.m
@@ -60,13 +60,20 @@
 // 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)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler} (35)
 // 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: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35)
+// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (35)
+// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler} (35)
+// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText onReadonly} (35)
+// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent} (35)
+// CHECK-NO1-NEXT: OverloadCandidate:{ResultType void}{Text func}{LeftParen (}{CurrentParameter int x}{RightParen )} (1)
 @end
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/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: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -1659,12 +1659,27 @@
 
       if (OpKind == tok::l_paren || !LHS.isInvalid()) {
         if (Tok.isNot(tok::r_paren)) {
-          if (ParseExpressionList(ArgExprs, CommaLocs, [&] {
-                QualType PreferredType = Actions.ProduceCallSignatureHelp(
-                    getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation());
-                Actions.CodeCompleteExpression(getCurScope(), PreferredType);
-              })) {
+          auto Completer = [&] {
+            // If inside a nested function call, make sure the call is only
+            // triggered for deepest parsed function.
+            if (CalledOverloadCompletion)
+              return;
+            QualType PreferredType = Actions.ProduceCallSignatureHelp(
+                getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation());
+            // If we were able to deduce current parameter's type then also run
+            // a code completion for that item.
+            if (!PreferredType.isNull())
+              Actions.CodeCompleteExpression(getCurScope(), PreferredType);
+            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: 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;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to