diff options
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index d719b84c96c..660d60da2a3 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -5677,6 +5677,79 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, } } +ObjCMethodDecl *Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, + SmallVectorImpl<ObjCMethodDecl*>& Methods) { + for (unsigned b = 0, e = Methods.size(); b < e; b++) { + bool Match = true; + ObjCMethodDecl *Method = Methods[b]; + unsigned NumNamedArgs = Sel.getNumArgs(); + // Method might have more arguments than selector indicates. This is due + // to addition of c-style arguments in method. + if (Method->param_size() > NumNamedArgs) + NumNamedArgs = Method->param_size(); + if (Args.size() < NumNamedArgs) + continue; + + for (unsigned i = 0; i < NumNamedArgs; i++) { + // We can't do any type-checking on a type-dependent argument. + if (Args[i]->isTypeDependent()) { + Match = false; + break; + } + + ParmVarDecl *param = Method->parameters()[i]; + Expr *argExpr = Args[i]; + assert(argExpr && "SelectBestMethod(): missing expression"); + + // Strip the unbridged-cast placeholder expression off unless it's + // a consumed argument. + if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) && + !param->hasAttr<CFConsumedAttr>()) + argExpr = stripARCUnbridgedCast(argExpr); + + // If the parameter is __unknown_anytype, move on to the next method. + if (param->getType() == Context.UnknownAnyTy) { + Match = false; + break; + } + + ImplicitConversionSequence ConversionState + = TryCopyInitialization(*this, argExpr, param->getType(), + /*SuppressUserConversions*/false, + /*InOverloadResolution=*/true, + /*AllowObjCWritebackConversion=*/ + getLangOpts().ObjCAutoRefCount, + /*AllowExplicit*/false); + if (ConversionState.isBad()) { + Match = false; + break; + } + } + // Promote additional arguments to variadic methods. + if (Match && Method->isVariadic()) { + for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) { + if (Args[i]->isTypeDependent()) { + Match = false; + break; + } + ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, + nullptr); + if (Arg.isInvalid()) { + Match = false; + break; + } + } + } else + // Check for extra arguments to non-variadic methods. + if (Args.size() != NumNamedArgs) + Match = false; + + if (Match) + return Method; + } + return nullptr; +} + static bool IsNotEnableIfAttr(Attr *A) { return !isa<EnableIfAttr>(A); } EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, |

