forked from OSchip/llvm-project
Move the overloading logic of Sema::ActOnCallExpr to a separate function
llvm-svn: 60093
This commit is contained in:
parent
3336b1f06b
commit
99dcbff154
|
@ -447,6 +447,12 @@ public:
|
|||
bool Complain);
|
||||
void FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
|
||||
|
||||
Expr *ResolveOverloadedCallFn(Expr *Fn, OverloadedFunctionDecl *Ovl,
|
||||
SourceLocation LParenLoc,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation *CommaLocs,
|
||||
SourceLocation RParenLoc);
|
||||
|
||||
ExprResult
|
||||
BuildCallToObjectOfClassType(Expr *Object, SourceLocation LParenLoc,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
|
|
|
@ -1294,39 +1294,13 @@ ActOnCallExpr(ExprTy *fn, SourceLocation LParenLoc,
|
|||
}
|
||||
}
|
||||
|
||||
// If we have a set of overloaded functions, perform overload
|
||||
// resolution to pick the function.
|
||||
if (Ovl) {
|
||||
OverloadCandidateSet CandidateSet;
|
||||
AddOverloadCandidates(Ovl, Args, NumArgs, CandidateSet);
|
||||
OverloadCandidateSet::iterator Best;
|
||||
switch (BestViableFunction(CandidateSet, Best)) {
|
||||
case OR_Success:
|
||||
{
|
||||
// Success! Let the remainder of this function build a call to
|
||||
// the function selected by overload resolution.
|
||||
FDecl = Best->Function;
|
||||
Expr *NewFn = new DeclRefExpr(FDecl, FDecl->getType(),
|
||||
Fn->getSourceRange().getBegin());
|
||||
delete Fn;
|
||||
Fn = NewFn;
|
||||
}
|
||||
break;
|
||||
|
||||
case OR_No_Viable_Function:
|
||||
Diag(Fn->getSourceRange().getBegin(),
|
||||
diag::err_ovl_no_viable_function_in_call)
|
||||
<< Ovl->getDeclName() << (unsigned)CandidateSet.size()
|
||||
<< Fn->getSourceRange();
|
||||
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
|
||||
Fn = ResolveOverloadedCallFn(Fn, Ovl, LParenLoc, Args, NumArgs, CommaLocs,
|
||||
RParenLoc);
|
||||
if (!Fn)
|
||||
return true;
|
||||
|
||||
case OR_Ambiguous:
|
||||
Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_ambiguous_call)
|
||||
<< Ovl->getDeclName() << Fn->getSourceRange();
|
||||
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
|
||||
return true;
|
||||
}
|
||||
// Fall through and build the call to Fn.
|
||||
}
|
||||
|
||||
if (getLangOptions().CPlusPlus && Fn->getType()->isRecordType())
|
||||
|
|
|
@ -2963,6 +2963,52 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// ResolveOverloadedCallFn - Given the call expression that calls Fn
|
||||
/// (which eventually refers to the set of overloaded functions in
|
||||
/// Ovl) and the call arguments Args/NumArgs, attempt to resolve the
|
||||
/// function call down to a specific function. If overload resolution
|
||||
/// succeeds, returns an expression that refers to a specific function
|
||||
/// and deletes Fn. Otherwise, emits diagnostics, deletes all of the
|
||||
/// arguments and Fn, and returns NULL.
|
||||
Expr *Sema::ResolveOverloadedCallFn(Expr *Fn, OverloadedFunctionDecl *Ovl,
|
||||
SourceLocation LParenLoc,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation *CommaLocs,
|
||||
SourceLocation RParenLoc) {
|
||||
OverloadCandidateSet CandidateSet;
|
||||
AddOverloadCandidates(Ovl, Args, NumArgs, CandidateSet);
|
||||
OverloadCandidateSet::iterator Best;
|
||||
switch (BestViableFunction(CandidateSet, Best)) {
|
||||
case OR_Success: {
|
||||
Expr *NewFn = new DeclRefExpr(Best->Function, Best->Function->getType(),
|
||||
Fn->getSourceRange().getBegin());
|
||||
Fn->Destroy(Context);
|
||||
return NewFn;
|
||||
}
|
||||
|
||||
case OR_No_Viable_Function:
|
||||
Diag(Fn->getSourceRange().getBegin(),
|
||||
diag::err_ovl_no_viable_function_in_call)
|
||||
<< Ovl->getDeclName() << (unsigned)CandidateSet.size()
|
||||
<< Fn->getSourceRange();
|
||||
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
|
||||
break;
|
||||
|
||||
case OR_Ambiguous:
|
||||
Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_ambiguous_call)
|
||||
<< Ovl->getDeclName() << Fn->getSourceRange();
|
||||
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Overload resolution failed. Destroy all of the subexpressions and
|
||||
// return NULL.
|
||||
Fn->Destroy(Context);
|
||||
for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
|
||||
Args[Arg]->Destroy(Context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// BuildCallToObjectOfClassType - Build a call to an object of class
|
||||
/// type (C++ [over.call.object]), which can end up invoking an
|
||||
/// overloaded function call operator (@c operator()) or performing a
|
||||
|
|
Loading…
Reference in New Issue