<div dir="ltr">I think it would be good to add comments that explain that, so the next person will not be confused :)<br>Thanks!<br></div><br><div class="gmail_quote">On Fri Jan 23 2015 at 1:28:36 PM Francisco Lopes <<a href="mailto:francisco.mailing.lists@oblita.com">francisco.mailing.lists@oblita.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">You made me recall that not only TooManyArguments must be checked, but also if the prototype is variadic.<br></div><div class="gmail_extra"><br><div class="gmail_quote">2015-01-23 10:25 GMT-02:00 Francisco Lopes <span dir="ltr"><<a href="mailto:francisco.mailing.lists@oblita.com" target="_blank">francisco.mailing.lists@oblita.com</a>></span>:</div></div><div class="gmail_extra"><div class="gmail_quote"><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hi Manuel,<br><br>FunctionType doesn't have getNumParams(). At this point it shouldn't have a prototype, so it should<br></div><div>be a function without one (FunctionNoPrototype), K & R style.<br></div> </div><div class="gmail_extra"><br><div class="gmail_quote">2015-01-23 8:14 GMT-02:00 Manuel Klimek <span dir="ltr"><<a href="mailto:klimek@google.com" target="_blank">klimek@google.com</a>></span>:<div><div><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><br><div class="gmail_quote"><div><div>On Thu Jan 22 2015 at 10:18:15 PM Francisco Lopes da Silva <<a href="mailto:oblita@gmail.com" target="_blank">oblita@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: francisco.lopes<br>
Date: Thu Jan 22 15:14:08 2015<br>
New Revision: 226865<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=226865&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=226865&view=rev</a><br>
Log:<br>
Sema: code completion for pointer and reference to functions.<br>
<br>
Added:<br>
    cfe/trunk/test/Index/complete-<u></u>pointer-and-reference-to-<u></u>functions.cpp<br>
Modified:<br>
    cfe/trunk/lib/Sema/<u></u>SemaCodeComplete.cpp<br>
<br>
Modified: cfe/trunk/lib/Sema/<u></u>SemaCodeComplete.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=226865&r1=226864&r2=226865&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/cfe/trunk/lib/Sema/<u></u>SemaCodeComplete.cpp?rev=<u></u>226865&r1=226864&r2=226865&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- cfe/trunk/lib/Sema/<u></u>SemaCodeComplete.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<u></u>SemaCodeComplete.cpp Thu Jan 22 15:14:08 2015<br>
@@ -3896,7 +3896,6 @@ void Sema::CodeCompleteCall(Scope *S, Ex<br>
<br>
   // FIXME: Provide support for highlighting optional parameters.<br>
   // FIXME: Provide support for variadic template functions.<br>
-  // FIXME: Provide support for pointers and references to functions.<br>
<br>
   // Ignore type-dependent call expressions entirely.<br>
   if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||<br>
@@ -3928,30 +3927,13 @@ void Sema::CodeCompleteCall(Scope *S, Ex<br>
     AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs,<br>
                           /*SuppressUsedConversions=*/<u></u>false,<br>
                           /*PartialOverloading=*/true);<br>
-  } else if (auto DC = NakedFn->getType()-><u></u>getCanonicalTypeInternal()<br>
-                       ->getAsCXXRecordDecl()) {<br>
-    // If it's a CXXRecordDecl, it may overload the function call operator,<br>
-    // so we check if it does and add them as candidates.<br>
-    DeclarationName OpName = Context.DeclarationNames<br>
-                             .getCXXOperatorName(OO_Call);<br>
-    LookupResult R(*this, OpName, Loc, LookupOrdinaryName);<br>
-    LookupQualifiedName(R, DC);<br>
-    R.suppressDiagnostics();<br>
-    SmallVector<Expr *, 12> ArgExprs(1, NakedFn);<br>
-    ArgExprs.append(Args.begin(), Args.end());<br>
-    AddFunctionCandidates(R.<u></u>asUnresolvedSet(), ArgExprs, CandidateSet,<br>
-                          /*ExplicitArgs=*/nullptr,<br>
-                          /*SuppressUsedConversions=*/<u></u>false,<br>
-                          /*PartialOverloading=*/true);<br>
   } else {<br>
-    // Lastly we check, as a possibly resolved expression, whether it can be<br>
-    // converted to a function.<br>
     FunctionDecl *FD = nullptr;<br>
     if (auto MCE = dyn_cast<MemberExpr>(NakedFn))<br>
       FD = dyn_cast<FunctionDecl>(MCE-><u></u>getMemberDecl());<br>
     else if (auto DRE = dyn_cast<DeclRefExpr>(NakedFn)<u></u>)<br>
       FD = dyn_cast<FunctionDecl>(DRE-><u></u>getDecl());<br>
-    if (FD) {<br>
+    if (FD) { // We check whether it's a resolved function declaration.<br>
       if (!getLangOpts().CPlusPlus ||<br>
           !FD->getType()->getAs<<u></u>FunctionProtoType>())<br>
         Results.push_back(<u></u>ResultCandidate(FD));<br>
@@ -3960,6 +3942,34 @@ void Sema::CodeCompleteCall(Scope *S, Ex<br>
                              Args, CandidateSet,<br>
                              /*SuppressUsedConversions=*/<u></u>false,<br>
                              /*PartialOverloading=*/true);<br>
+<br>
+    } else if (auto DC = NakedFn->getType()-><u></u>getAsCXXRecordDecl()) {<br>
+      // If expression's type is CXXRecordDecl, it may overload the function<br>
+      // call operator, so we check if it does and add them as candidates.<br>
+      DeclarationName OpName = Context.DeclarationNames<br>
+                               .getCXXOperatorName(OO_Call);<br>
+      LookupResult R(*this, OpName, Loc, LookupOrdinaryName);<br>
+      LookupQualifiedName(R, DC);<br>
+      R.suppressDiagnostics();<br>
+      SmallVector<Expr *, 12> ArgExprs(1, NakedFn);<br>
+      ArgExprs.append(Args.begin(), Args.end());<br>
+      AddFunctionCandidates(R.<u></u>asUnresolvedSet(), ArgExprs, CandidateSet,<br>
+                            /*ExplicitArgs=*/nullptr,<br>
+                            /*SuppressUsedConversions=*/<u></u>false,<br>
+                            /*PartialOverloading=*/true);<br>
+    } else {<br>
+      // Lastly we check whether expression's type is function pointer or<br>
+      // function.<br>
+      QualType T = NakedFn->getType();<br>
+      if (!T->getPointeeType().isNull()<u></u>)<br>
+        T = T->getPointeeType();<br>
+<br>
+      if (auto FP = T->getAs<FunctionProtoType>()) {<br>
+        if (!TooManyArguments(FP-><u></u>getNumParams(), Args.size(),<br>
+                             /*PartialOverloading=*/true))<br>
+          Results.push_back(<u></u>ResultCandidate(FP));<br>
+      } else if (auto FT = T->getAs<FunctionType>())<br></blockquote><div><br></div></div></div><div>Why don't we have to check for TooManyArguments here?</div><div><div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        Results.push_back(<u></u>ResultCandidate(FT));<br>
     }<br>
   }<br>
<br>
<br>
Added: cfe/trunk/test/Index/complete-<u></u>pointer-and-reference-to-<u></u>functions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-pointer-and-reference-to-functions.cpp?rev=226865&view=auto" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/cfe/trunk/test/Index/<u></u>complete-pointer-and-<u></u>reference-to-functions.cpp?<u></u>rev=226865&view=auto</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- cfe/trunk/test/Index/complete-<u></u>pointer-and-reference-to-<u></u>functions.cpp (added)<br>
+++ cfe/trunk/test/Index/complete-<u></u>pointer-and-reference-to-<u></u>functions.cpp Thu Jan 22 15:14:08 2015<br>
@@ -0,0 +1,34 @@<br>
+// Note: the run lines follow their respective tests, since line/column<br>
+// matter in this test.<br>
+<br>
+template<class T> void (&foo(T))(T);<br>
+template<class T> void (*bar(T))(T);<br>
+<br>
+int main() {<br>
+  foo(42)(42);<br>
+  bar(42)(42);<br>
+}<br>
+<br>
+// RUN: c-index-test -code-completion-at=%s:8:11 %s | FileCheck -check-prefix=CHECK-CC1 %s<br>
+// CHECK-CC1: OverloadCandidate:{Text void}{LeftParen (}{CurrentParameter int}{RightParen )} (1)<br>
+// CHECK-CC1: Completion contexts:<br>
+// CHECK-CC1-NEXT: Any type<br>
+// CHECK-CC1-NEXT: Any value<br>
+// CHECK-CC1-NEXT: Enum tag<br>
+// CHECK-CC1-NEXT: Union tag<br>
+// CHECK-CC1-NEXT: Struct tag<br>
+// CHECK-CC1-NEXT: Class name<br>
+// CHECK-CC1-NEXT: Nested name specifier<br>
+// CHECK-CC1-NEXT: Objective-C interface<br>
+<br>
+// RUN: c-index-test -code-completion-at=%s:9:11 %s | FileCheck -check-prefix=CHECK-CC2 %s<br>
+// CHECK-CC2: OverloadCandidate:{Text void}{LeftParen (}{CurrentParameter int}{RightParen )} (1)<br>
+// CHECK-CC2: Completion contexts:<br>
+// CHECK-CC2-NEXT: Any type<br>
+// CHECK-CC2-NEXT: Any value<br>
+// CHECK-CC2-NEXT: Enum tag<br>
+// CHECK-CC2-NEXT: Union tag<br>
+// CHECK-CC2-NEXT: Struct tag<br>
+// CHECK-CC2-NEXT: Class name<br>
+// CHECK-CC2-NEXT: Nested name specifier<br>
+// CHECK-CC2-NEXT: Objective-C interface<br>
<br>
<br>
______________________________<u></u>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div></div>
<br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div></div></div><br></div>
</blockquote></div></div></blockquote></div>