From f6b89691d2fdb88b97edabbe5f390fb2919c8f0a Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 26 Nov 2008 05:54:23 +0000 Subject: [PATCH] Move the overloading logic of Sema::ActOnCallExpr to a separate function git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60093 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/Sema.h | 6 +++++ lib/Sema/SemaExpr.cpp | 34 ++++------------------------- lib/Sema/SemaOverload.cpp | 46 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 4d0340bba3..cf9b10c0c8 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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, diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index fdd5732cc5..a6e1611dc3 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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()) diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 3321ef19b2..14e0f44c87 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -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 -- 2.40.0