forked from OSchip/llvm-project
Sema: code completion for pointer and reference to functions.
llvm-svn: 226865
This commit is contained in:
parent
799ef37d02
commit
c6ccc4fe91
|
@ -3896,7 +3896,6 @@ void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args) {
|
|||
|
||||
// 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, Expr *Fn, ArrayRef<Expr *> 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));
|
||||
|
@ -3960,6 +3942,34 @@ void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args) {
|
|||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue