// 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) ||
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));
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));
}
}
--- /dev/null
+// 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