================ @@ -5406,6 +5408,99 @@ ExprResult Sema::ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, RParenLoc, CurFPFeatureOverrides()); } +ExprResult Sema::BuiltinInvoke(CallExpr *TheCall) { + SourceLocation Loc = TheCall->getBeginLoc(); + auto Args = MutableArrayRef(TheCall->getArgs(), TheCall->getNumArgs()); + assert(llvm::none_of(Args, + [](Expr *Arg) { return Arg->isTypeDependent(); })); + + if (Args.size() == 0) { + Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_few_args_at_least) + << /*callee_type=*/0 << /*min_arg_count=*/1 << /*actual_arg_count=*/0 + << /*is_non_object=*/0 << TheCall->getSourceRange(); + return ExprError(); + } + + auto FuncT = Args[0]->getType(); + + if (auto *MPT = FuncT->getAs<MemberPointerType>()) { + if (Args.size() < 2) { + Diag(TheCall->getBeginLoc(), + diag::err_typecheck_call_too_few_args_at_least) + << /*callee_type=*/0 << /*min_arg_count=*/2 << /*actual_arg_count=*/1 + << /*is_non_object=*/0 << TheCall->getSourceRange(); + return ExprError(); + } + + auto *MemPtrClass = MPT->getQualifier()->getAsType(); + auto ObjectT = Args[1]->getType(); + + if (MPT->isMemberDataPointer() && checkArgCount(TheCall, 2)) + return ExprError(); + + ExprResult ObjectArg = [&]() -> ExprResult { + // (1.1): (t1.*f)(t2, …, tN) when f is a pointer to a member function of a + // class T and is_same_v<T, remove_cvref_t<decltype(t1)>> || + // is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true; + // (1.4): t1.*f when N=1 and f is a pointer to data member of a class T + // and is_same_v<T, remove_cvref_t<decltype(t1)>> || + // is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true; + if (Context.hasSameType(QualType(MemPtrClass, 0), + BuiltinRemoveCVRef(ObjectT, Loc)) || + BuiltinIsBaseOf(Args[1]->getBeginLoc(), QualType(MemPtrClass, 0), + BuiltinRemoveCVRef(ObjectT, Loc))) { + return Args[1]; + } + + // (t1.get().*f)(t2, …, tN) when f is a pointer to a member function of + // a class T and remove_cvref_t<decltype(t1)> is a specialization of + // reference_wrapper; + if (auto *RD = ObjectT->getAsCXXRecordDecl()) { + if (RD->isInStdNamespace() && + RD->getDeclName().getAsString() == "reference_wrapper") { + CXXScopeSpec SS; + IdentifierInfo *GetName = &Context.Idents.get("get"); + UnqualifiedId GetID; + GetID.setIdentifier(GetName, Loc); + + auto MemExpr = ActOnMemberAccessExpr( + getCurScope(), Args[1], Loc, tok::period, SS, + /*TemplateKWLoc=*/SourceLocation(), GetID, nullptr); + ---------------- cor3ntin wrote:
Can you check that this SFINAE properly? https://github.com/llvm/llvm-project/pull/116709 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits