@@ -1593,6 +1593,11 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) {
15931593 }
15941594
15951595 if (Mapper::Contains (expr->getCallee ())) {
1596+ if (Mapper::IsLibcPassthrough (GetCalleeOrExpr (expr))) {
1597+ ConvertGenericCallExpr (expr);
1598+ return false ;
1599+ }
1600+
15961601 auto **args = expr->getArgs ();
15971602 auto num_args = expr->getNumArgs ();
15981603 auto ctx = CollectRefBindingTempArgs (expr);
@@ -1667,20 +1672,20 @@ Converter::CallInfo Converter::CollectCallInfo(clang::CallExpr *expr) {
16671672 using Kind = CallArg::Kind;
16681673
16691674 CallInfo info;
1670- info.callee = expr->getCallee ();
1675+ info.expr = expr;
1676+ auto callee = GetCallee (expr);
16711677 unsigned arg_begin = 0 ;
16721678 if (auto op_call = llvm::dyn_cast<clang::CXXOperatorCallExpr>(expr)) {
16731679 if (op_call->getOperator () == clang::OO_Call) {
1674- info.callee = op_call->getArg (0 );
16751680 arg_begin = 1 ;
16761681 }
16771682 }
16781683
1679- const auto *function =
1680- expr-> getCalleeDecl () ? expr-> getCalleeDecl () ->getAsFunction () : nullptr ;
1684+ auto decl = expr-> getCalleeDecl ();
1685+ const auto *function = decl ? decl ->getAsFunction () : nullptr ;
16811686 const clang::FunctionProtoType *proto = nullptr ;
16821687 if (!function) {
1683- auto callee_ty = info. callee ->getType ().getDesugaredType (ctx_);
1688+ auto callee_ty = callee->getType ().getDesugaredType (ctx_);
16841689 if (auto ptr_ty = callee_ty->getAs <clang::PointerType>()) {
16851690 proto = ptr_ty->getPointeeType ()->getAs <clang::FunctionProtoType>();
16861691 }
@@ -1693,6 +1698,7 @@ Converter::CallInfo Converter::CollectCallInfo(clang::CallExpr *expr) {
16931698 function ? function->getNumParams () : proto->getNumParams ();
16941699 info.is_variadic = function ? function->isVariadic () : proto->isVariadic ();
16951700 info.is_fn_ptr_call = !function;
1701+ info.is_libc_passthrough = Mapper::IsLibcPassthrough (GetCalleeOrExpr (expr));
16961702
16971703 for (unsigned i = 0 ; i < num_named_params && i < num_args; ++i) {
16981704 auto *arg = expr->getArg (i + arg_begin);
@@ -1704,7 +1710,8 @@ Converter::CallInfo Converter::CollectCallInfo(clang::CallExpr *expr) {
17041710 : proto->getParamType (i),
17051711 .expr = arg,
17061712 .has_default = function && function->getParamDecl (i)->hasDefaultArg (),
1707- .kind = IsLiteral (arg) ? Kind::Inline : Kind::Hoisted,
1713+ .kind = (IsLiteral (arg) || info.is_libc_passthrough ) ? Kind::Inline
1714+ : Kind::Hoisted,
17081715 };
17091716 bool is_materialize = clang::isa<clang::MaterializeTemporaryExpr>(arg);
17101717 if (is_materialize && ca.param_type ->isLValueReferenceType ()) {
@@ -1778,7 +1785,9 @@ void Converter::EmitArgList(const CallInfo &info) {
17781785 using Kind = CallArg::Kind;
17791786 PushParen call_args (*this );
17801787
1781- for (const auto &ca : info.args ) {
1788+ for (unsigned i = 0 ; i < info.args .size (); i++) {
1789+ const auto &ca = info.args [i];
1790+
17821791 if (ca.has_default ) {
17831792 StrCat (" Some" );
17841793 }
@@ -1794,6 +1803,10 @@ void Converter::EmitArgList(const CallInfo &info) {
17941803 break ;
17951804 case Kind::Inline:
17961805 ConvertParamTy (ca.param_type , ca.expr );
1806+ if (info.is_libc_passthrough ) {
1807+ StrCat (std::format (
1808+ " as {}" , Mapper::GetParamType (GetCalleeOrExpr (info.expr ), i)));
1809+ }
17971810 break ;
17981811 }
17991812 }
@@ -1802,14 +1815,19 @@ void Converter::EmitArgList(const CallInfo &info) {
18021815 }
18031816
18041817 if (info.is_variadic ) {
1805- StrCat (token::kRef );
1806- PushBracket push (*this );
1818+ if (!info.is_libc_passthrough ) {
1819+ StrCat (token::kRef );
1820+ }
1821+ PushBracket push (*this , !info.is_libc_passthrough );
18071822 for (auto *arg : info.variadic_args ) {
18081823 {
18091824 PushParen p (*this );
18101825 ConvertVariadicArg (arg);
18111826 }
1812- StrCat (" .into()" , token::kComma );
1827+ if (!info.is_libc_passthrough ) {
1828+ StrCat (" .into()" );
1829+ }
1830+ StrCat (token::kComma );
18131831 }
18141832 }
18151833}
@@ -1818,10 +1836,14 @@ void Converter::EmitCall(CallInfo &&info) {
18181836 EmitHoistedArgs (info);
18191837
18201838 if (info.is_fn_ptr_call ) {
1821- EmitFnPtrCall (info.callee );
1839+ EmitFnPtrCall (GetCallee (info.expr ));
1840+ } else if (info.is_libc_passthrough ) {
1841+ auto *direct_callee = info.expr ->getDirectCallee ();
1842+ assert (direct_callee);
1843+ StrCat (" libc::" , direct_callee->getName ());
18221844 } else {
18231845 PushExprKind push (*this , ExprKind::Callee);
1824- Convert (info.callee );
1846+ Convert (GetCallee ( info.expr ) );
18251847 }
18261848
18271849 EmitArgList (info);
@@ -4256,6 +4278,8 @@ std::string Converter::ConvertIRFragment(
42564278 .is_index_base = ph->is_index_base ,
42574279 };
42584280 result += ConvertPlaceholder (expr, arg, ph_ctx);
4281+ } else if (std::get_if<TranslationRule::VaArgsFragment>(&frag)) {
4282+ result += ConvertVariadicTail (expr, all_args);
42594283 } else if (auto *mc =
42604284 std::get_if<std::unique_ptr<MethodCallFragment>>(&frag)) {
42614285 result += ConvertMappedMethodCall (expr, **mc, args, num_args, ctx);
@@ -4265,6 +4289,25 @@ std::string Converter::ConvertIRFragment(
42654289 return result;
42664290}
42674291
4292+ std::string
4293+ Converter::ConvertVariadicTail (clang::Expr *expr,
4294+ const std::vector<clang::Expr *> &all_args) {
4295+ const auto *tgt_ir = Mapper::GetExprRule (GetCalleeOrExpr (expr));
4296+ unsigned fixed = tgt_ir ? tgt_ir->params .size () : 0 ;
4297+
4298+ Buffer buf (*this );
4299+ StrCat (" &[" );
4300+ for (unsigned i = fixed; i < all_args.size (); ++i) {
4301+ {
4302+ PushParen p (*this );
4303+ ConvertVariadicArg (all_args[i]);
4304+ }
4305+ StrCat (" .into()" , token::kComma );
4306+ }
4307+ StrCat (" ]" );
4308+ return std::move (buf).str ();
4309+ }
4310+
42684311std::string Converter::AccessLValueObject (clang::MemberExpr *member) {
42694312 auto *object = member->getBase ();
42704313 auto type = object->getType ();
0 commit comments