Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -6381,63 +6381,63 @@ /// the overload candidate set. void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, ArrayRef Args, - OverloadCandidateSet& CandidateSet, + OverloadCandidateSet &CandidateSet, TemplateArgumentListInfo *ExplicitTemplateArgs, bool SuppressUserConversions, bool PartialOverloading, bool FirstArgumentIsBase) { for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { NamedDecl *D = F.getDecl()->getUnderlyingDecl(); - if (FunctionDecl *FD = dyn_cast(D)) { - ArrayRef FunctionArgs = Args; - if (isa(FD) && !cast(FD)->isStatic()) { - QualType ObjectType; - Expr::Classification ObjectClassification; - if (Args.size() > 0) { - if (Expr *E = Args[0]) { - // Use the explicit base to restrict the lookup: - ObjectType = E->getType(); - ObjectClassification = E->Classify(Context); - } // .. else there is an implit base. - FunctionArgs = Args.slice(1); - } - AddMethodCandidate(cast(FD), F.getPair(), - cast(FD)->getParent(), ObjectType, - ObjectClassification, FunctionArgs, CandidateSet, - SuppressUserConversions, PartialOverloading); - } else { - // Slice the first argument (which is the base) when we access - // static method as non-static - if (Args.size() > 0 && (!Args[0] || (FirstArgumentIsBase && isa(FD) && - !isa(FD)))) { - assert(cast(FD)->isStatic()); - FunctionArgs = Args.slice(1); - } - AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet, - SuppressUserConversions, PartialOverloading); - } - } else { - FunctionTemplateDecl *FunTmpl = cast(D); - if (isa(FunTmpl->getTemplatedDecl()) && - !cast(FunTmpl->getTemplatedDecl())->isStatic()) { - QualType ObjectType; - Expr::Classification ObjectClassification; + ArrayRef FunctionArgs = Args; + + FunctionTemplateDecl *FunTmpl = dyn_cast(D); + const bool IsTemplate = FunTmpl ? true : false; + + FunctionDecl *FD = + IsTemplate ? FunTmpl->getTemplatedDecl() : cast(D); + + if (isa(FD) && !cast(FD)->isStatic()) { + QualType ObjectType; + Expr::Classification ObjectClassification; + if (Args.size() > 0) { if (Expr *E = Args[0]) { // Use the explicit base to restrict the lookup: ObjectType = E->getType(); ObjectClassification = E->Classify(Context); - } // .. else there is an implit base. + } // .. else there is an implicit base. + FunctionArgs = Args.slice(1); + } + if (IsTemplate) { AddMethodTemplateCandidate( FunTmpl, F.getPair(), cast(FunTmpl->getDeclContext()), ExplicitTemplateArgs, ObjectType, ObjectClassification, - Args.slice(1), CandidateSet, SuppressUserConversions, + FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } else { - AddTemplateOverloadCandidate(FunTmpl, F.getPair(), - ExplicitTemplateArgs, Args, - CandidateSet, SuppressUserConversions, - PartialOverloading); + AddMethodCandidate(cast(FD), F.getPair(), + cast(FD)->getParent(), ObjectType, + ObjectClassification, FunctionArgs, CandidateSet, + SuppressUserConversions, PartialOverloading); + } + } else { + // This branch handles both standalone functions and static methods. + + // Slice the first argument (which is the base) when we access + // static method as non-static. + if (Args.size() > 0 && + (!Args[0] || (FirstArgumentIsBase && isa(FD) && + !isa(FD)))) { + assert(cast(FD)->isStatic()); + FunctionArgs = Args.slice(1); + } + if (IsTemplate) { + AddTemplateOverloadCandidate( + FunTmpl, F.getPair(), ExplicitTemplateArgs, FunctionArgs, + CandidateSet, SuppressUserConversions, PartialOverloading); + } else { + AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet, + SuppressUserConversions, PartialOverloading); } } }