r226865 - Sema: code completion for pointer and reference to functions.

Francisco Lopes da Silva oblita at gmail.com
Thu Jan 22 13:14:08 PST 2015


Author: francisco.lopes
Date: Thu Jan 22 15:14:08 2015
New Revision: 226865

URL: http://llvm.org/viewvc/llvm-project?rev=226865&view=rev
Log:
Sema: code completion for pointer and reference to functions.

Added:
    cfe/trunk/test/Index/complete-pointer-and-reference-to-functions.cpp
Modified:
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=226865&r1=226864&r2=226865&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Jan 22 15:14:08 2015
@@ -3896,7 +3896,6 @@ void Sema::CodeCompleteCall(Scope *S, Ex
 
   // FIXME: Provide support for highlighting optional parameters.
   // FIXME: Provide support for variadic template functions.
-  // FIXME: Provide support for pointers and references to functions.
 
   // Ignore type-dependent call expressions entirely.
   if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||
@@ -3928,30 +3927,13 @@ void Sema::CodeCompleteCall(Scope *S, Ex
     AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs,
                           /*SuppressUsedConversions=*/false,
                           /*PartialOverloading=*/true);
-  } else if (auto DC = NakedFn->getType()->getCanonicalTypeInternal()
-                       ->getAsCXXRecordDecl()) {
-    // If it's a CXXRecordDecl, it may overload the function call operator,
-    // so we check if it does and add them as candidates.
-    DeclarationName OpName = Context.DeclarationNames
-                             .getCXXOperatorName(OO_Call);
-    LookupResult R(*this, OpName, Loc, LookupOrdinaryName);
-    LookupQualifiedName(R, DC);
-    R.suppressDiagnostics();
-    SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
-    ArgExprs.append(Args.begin(), Args.end());
-    AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs, CandidateSet,
-                          /*ExplicitArgs=*/nullptr,
-                          /*SuppressUsedConversions=*/false,
-                          /*PartialOverloading=*/true);
   } else {
-    // Lastly we check, as a possibly resolved expression, whether it can be
-    // converted to a function.
     FunctionDecl *FD = nullptr;
     if (auto MCE = dyn_cast<MemberExpr>(NakedFn))
       FD = dyn_cast<FunctionDecl>(MCE->getMemberDecl());
     else if (auto DRE = dyn_cast<DeclRefExpr>(NakedFn))
       FD = dyn_cast<FunctionDecl>(DRE->getDecl());
-    if (FD) {
+    if (FD) { // We check whether it's a resolved function declaration.
       if (!getLangOpts().CPlusPlus || 
           !FD->getType()->getAs<FunctionProtoType>())
         Results.push_back(ResultCandidate(FD));
@@ -3960,6 +3942,34 @@ void Sema::CodeCompleteCall(Scope *S, Ex
                              Args, CandidateSet,
                              /*SuppressUsedConversions=*/false,
                              /*PartialOverloading=*/true);
+
+    } else if (auto DC = NakedFn->getType()->getAsCXXRecordDecl()) {
+      // If expression's type is CXXRecordDecl, it may overload the function
+      // call operator, so we check if it does and add them as candidates.
+      DeclarationName OpName = Context.DeclarationNames
+                               .getCXXOperatorName(OO_Call);
+      LookupResult R(*this, OpName, Loc, LookupOrdinaryName);
+      LookupQualifiedName(R, DC);
+      R.suppressDiagnostics();
+      SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
+      ArgExprs.append(Args.begin(), Args.end());
+      AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs, CandidateSet,
+                            /*ExplicitArgs=*/nullptr,
+                            /*SuppressUsedConversions=*/false,
+                            /*PartialOverloading=*/true);
+    } else {
+      // Lastly we check whether expression's type is function pointer or
+      // function.
+      QualType T = NakedFn->getType();
+      if (!T->getPointeeType().isNull())
+        T = T->getPointeeType();
+
+      if (auto FP = T->getAs<FunctionProtoType>()) {
+        if (!TooManyArguments(FP->getNumParams(), Args.size(),
+                             /*PartialOverloading=*/true))
+          Results.push_back(ResultCandidate(FP));
+      } else if (auto FT = T->getAs<FunctionType>())
+        Results.push_back(ResultCandidate(FT));
     }
   }
 

Added: cfe/trunk/test/Index/complete-pointer-and-reference-to-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-pointer-and-reference-to-functions.cpp?rev=226865&view=auto
==============================================================================
--- cfe/trunk/test/Index/complete-pointer-and-reference-to-functions.cpp (added)
+++ cfe/trunk/test/Index/complete-pointer-and-reference-to-functions.cpp Thu Jan 22 15:14:08 2015
@@ -0,0 +1,34 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+template<class T> void (&foo(T))(T);
+template<class T> void (*bar(T))(T);
+
+int main() {
+  foo(42)(42);
+  bar(42)(42);
+}
+
+// RUN: c-index-test -code-completion-at=%s:8:11 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: OverloadCandidate:{Text void}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
+// CHECK-CC1: Completion contexts:
+// CHECK-CC1-NEXT: Any type
+// CHECK-CC1-NEXT: Any value
+// CHECK-CC1-NEXT: Enum tag
+// CHECK-CC1-NEXT: Union tag
+// CHECK-CC1-NEXT: Struct tag
+// CHECK-CC1-NEXT: Class name
+// CHECK-CC1-NEXT: Nested name specifier
+// CHECK-CC1-NEXT: Objective-C interface
+
+// RUN: c-index-test -code-completion-at=%s:9:11 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: OverloadCandidate:{Text void}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
+// CHECK-CC2: Completion contexts:
+// CHECK-CC2-NEXT: Any type
+// CHECK-CC2-NEXT: Any value
+// CHECK-CC2-NEXT: Enum tag
+// CHECK-CC2-NEXT: Union tag
+// CHECK-CC2-NEXT: Struct tag
+// CHECK-CC2-NEXT: Class name
+// CHECK-CC2-NEXT: Nested name specifier
+// CHECK-CC2-NEXT: Objective-C interface





More information about the cfe-commits mailing list