@@ -259,7 +259,7 @@ std::string ConverterRefCount::BoxValue(std::string &&str) const {
259259bool ConverterRefCount::Convert (clang::QualType qual_type) {
260260 // Catch va_list before desugaring
261261 if (IsVaListType (qual_type)) {
262- StrCat (BoxType (" VaList " ));
262+ StrCat (BoxType (" Ptr<VaArg> " ));
263263 return false ;
264264 }
265265
@@ -291,7 +291,7 @@ bool ConverterRefCount::VisitReferenceType(clang::ReferenceType *type) {
291291 PushConversionKind push (*this , ConversionKind::Unboxed);
292292 return Convert (ctx_.getPointerType (pointee_type));
293293 }
294- if (pointee_type->isArrayType ()) {
294+ if (pointee_type->isArrayType () && ! IsVaListType (pointee_type) ) {
295295 // A reference to an array decays straight to a pointer to its first
296296 // element, the same way a by-value array parameter would, instead of
297297 // going through a pointer to the whole boxed array.
@@ -325,7 +325,7 @@ bool ConverterRefCount::VisitPointerType(clang::PointerType *type) {
325325 }
326326
327327 if (IsVaListType (clang::QualType (type, 0 ))) {
328- StrCat (" VaList " );
328+ StrCat (" Ptr<VaArg> " );
329329 return false ;
330330 }
331331
@@ -335,10 +335,11 @@ bool ConverterRefCount::VisitPointerType(clang::PointerType *type) {
335335 }
336336
337337 auto pointee_type = type->getPointeeType ();
338- PushConversionKind push1 (*this , ConversionKind::Ptr,
339- !pointee_type->isArrayType ());
338+ bool pointee_is_array =
339+ pointee_type->isArrayType () && !IsVaListType (pointee_type);
340+ PushConversionKind push1 (*this , ConversionKind::Ptr, !pointee_is_array);
340341 PushConversionKind push2 (*this , ConversionKind::FullRefCount,
341- pointee_type-> isArrayType () );
342+ pointee_is_array );
342343 if (pointee_type->isRecordType () &&
343344 abstract_structs_.contains (GetID (pointee_type->getAsRecordDecl ()))) {
344345 StrCat (" PtrDyn<dyn" );
@@ -791,6 +792,10 @@ void ConverterRefCount::EmitFunctionPreamble(clang::FunctionDecl *decl) {
791792 // name_2)'. We want to get the parameters from the definition if possible,
792793 // i.e. name_2.
793794 PushConversionKind push (*this , ConversionKind::FullRefCount);
795+ if (decl->isVariadic ()) {
796+ StrCat (" let __args: Value<Box<[VaArg]>> = "
797+ " Rc::new(RefCell::new(__args.into()));" );
798+ }
794799 auto params = decl->getDefinition () ? decl->getDefinition ()->parameters ()
795800 : decl->parameters ();
796801 for (auto *param : params) {
@@ -853,7 +858,7 @@ void ConverterRefCount::ConvertVaListVarDecl(clang::VarDecl *decl) {
853858 StrCat (keyword::kLet );
854859 }
855860
856- StrCat (GetNamedDeclAsString (decl), token::kColon , " Value<VaList >" );
861+ StrCat (GetNamedDeclAsString (decl), token::kColon , " Value<Ptr<VaArg> >" );
857862}
858863
859864bool ConverterRefCount::ConvertVarDeclSkipInit (clang::VarDecl *decl) {
@@ -1291,7 +1296,12 @@ void ConverterRefCount::ConvertPrintf(clang::CallExpr *expr) {
12911296}
12921297
12931298bool ConverterRefCount::VisitCallExpr (clang::CallExpr *expr) {
1294- if (IsBuiltinVaStart (expr) || IsBuiltinVaEnd (expr) || IsBuiltinVaCopy (expr)) {
1299+ if (IsBuiltinVaStart (expr)) {
1300+ StrCat (ToString (expr->getArg (0 )->IgnoreImpCasts ()),
1301+ " = __args.as_pointer()" );
1302+ return false ;
1303+ }
1304+ if (IsBuiltinVaEnd (expr) || IsBuiltinVaCopy (expr)) {
12951305 ConvertVAArgCall (expr);
12961306 return false ;
12971307 }
@@ -2471,13 +2481,18 @@ bool ConverterRefCount::VisitVAArgExpr(clang::VAArgExpr *expr) {
24712481 if (auto *cast = clang::dyn_cast<clang::ImplicitCastExpr>(va_list_expr)) {
24722482 va_list_expr = cast->getSubExpr ();
24732483 }
2474- StrCat ( ConvertLValue (va_list_expr) );
2475- StrCat ( " .arg::< " ) ;
2484+ auto str = ConvertLValue (va_list_expr);
2485+ std::string arg_type ;
24762486 {
24772487 PushConversionKind push (*this , ConversionKind::Unboxed);
2478- StrCat (ToString (expr->getType ()));
2488+ arg_type = ToString (expr->getType ());
2489+ }
2490+ if (!pending_deref_.empty ()) {
2491+ StrCat (pending_deref_.take (), " .with_mut(|__v| __v.arg::<" , arg_type,
2492+ " >())" );
2493+ } else {
2494+ StrCat (str, " .arg::<" , arg_type, " >()" );
24792495 }
2480- StrCat (" >()" );
24812496 SetFreshType (expr->getType ());
24822497 return false ;
24832498}
@@ -2529,7 +2544,7 @@ std::string ConverterRefCount::GetDefaultAsString(clang::QualType qual_type) {
25292544
25302545 if (IsVaListType (qual_type)) {
25312546 computed_expr_type_ = ComputedExprType::FreshValue;
2532- return BoxValue (" VaList ::default()" );
2547+ return BoxValue (" Ptr::<VaArg> ::default()" );
25332548 }
25342549
25352550 if (auto arr = GetArrayDefaultAsString (qual_type); !arr.empty ()) {
0 commit comments