================ @@ -5548,13 +5504,100 @@ static bool isAtLeastAsSpecializedAs(Sema &S, FunctionTemplateDecl *Sema::getMoreSpecializedTemplate( FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, - unsigned NumCallArguments2, bool Reversed) { + unsigned NumCallArguments2, QualType RawObjType1, QualType RawObjType2, + bool Reversed) { + SmallVector<QualType, 4> Args1; + SmallVector<QualType, 4> Args2; + const FunctionDecl *FD1 = FT1->getTemplatedDecl(); + const FunctionDecl *FD2 = FT2->getTemplatedDecl(); + bool shouldConvert1 = false; + bool shouldConvert2 = false; + QualType ObjType1; + QualType ObjType2; + if (TPOC == TPOC_Call) { + const FunctionProtoType *Proto1 = + FD1->getType()->getAs<FunctionProtoType>(); + const FunctionProtoType *Proto2 = + FD2->getType()->getAs<FunctionProtoType>(); + + // - In the context of a function call, the function parameter types are + // used. + const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1); + const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2); + + if (getLangOpts().CPlusPlus20) { + // C++20 [temp.func.order]p3 + // [...] Each function template M that is a member function is + // considered to have a new first parameter of type + // X(M), described below, inserted in its function parameter list. + // + // Note that we interpret "that is a member function" as + // "that is a member function with no expicit object argument". + // Otherwise the ordering rules for methods with expicit objet arguments + // against anything else make no sense. + shouldConvert1 = Method1 && !Method1->isExplicitObjectMemberFunction(); + shouldConvert2 = Method2 && !Method2->isExplicitObjectMemberFunction(); + } else { + // C++11 [temp.func.order]p3: + // [...] If only one of the function templates is a non-static + // member, that function template is considered to have a new + // first parameter inserted in its function parameter list. + // + // Note that we interpret this to mean "if one of the function + // templates is a non-static member and the other is a non-member"; + // otherwise, the ordering rules for static functions against non-static + // functions don't make any sense. + // + // C++98/03 doesn't have this provision but we've extended DR532 to cover + // it as wording was broken prior to it. + shouldConvert1 = + !Method2 && Method1 && Method1->isImplicitObjectMemberFunction(); + shouldConvert2 = + !Method1 && Method2 && Method2->isImplicitObjectMemberFunction(); + } + if (shouldConvert1) { + bool isR2 = + getLangOpts().CPlusPlus20 && + (shouldConvert1 ---------------- HoBoIs wrote:
Actually I just mixed up `shouldConvert1` and `shouldConvert2` https://github.com/llvm/llvm-project/pull/83279 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits