@@ -122,7 +122,7 @@ arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,
122122
123123  if  (const  auto  *proto = dyn_cast<FunctionProtoType>(fnType)) {
124124    if  (proto->isVariadic ())
125-       cgm. errorNYI ( " call to variadic function "  );
125+       required =  RequiredArgs::getFromProtoWithExtraSlots (proto,  0 );
126126    if  (proto->hasExtParameterInfos ())
127127      cgm.errorNYI (" call to functions with extra parameter info"  );
128128  } else  if  (cgm.getTargetCIRGenInfo ().isNoProtoCallVariadic (
@@ -409,6 +409,18 @@ void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
409409  args.add (emitAnyExprToTemp (e), argType);
410410}
411411
412+ QualType CIRGenFunction::getVarArgType (const  Expr *arg) {
413+   //  System headers on Windows define NULL to 0 instead of 0LL on Win64. MSVC
414+   //  implicitly widens null pointer constants that are arguments to varargs
415+   //  functions to pointer-sized ints.
416+   if  (!getTarget ().getTriple ().isOSWindows ())
417+     return  arg->getType ();
418+ 
419+   assert (!cir::MissingFeatures::msabi ());
420+   cgm.errorNYI (arg->getSourceRange (), " getVarArgType: NYI for Windows target"  );
421+   return  arg->getType ();
422+ }
423+ 
412424// / Similar to emitAnyExpr(), however, the result will always be accessible
413425// / even if no aggregate location is provided.
414426RValue CIRGenFunction::emitAnyExprToTemp (const  Expr *e) {
@@ -429,18 +441,20 @@ void CIRGenFunction::emitCallArgs(
429441  assert (!cir::MissingFeatures::opCallCallConv ());
430442
431443  //  First, if a prototype was provided, use those argument types.
432-   assert (! cir::MissingFeatures::opCallVariadic ()) ;
444+   bool  isVariadic =  false ;
433445  if  (prototype.p ) {
434446    assert (!cir::MissingFeatures::opCallObjCMethod ());
435447
436448    const  auto  *fpt = cast<const  FunctionProtoType *>(prototype.p );
449+     isVariadic = fpt->isVariadic ();
450+     assert (!cir::MissingFeatures::opCallCallConv ());
437451    argTypes.assign (fpt->param_type_begin () + paramsToSkip,
438452                    fpt->param_type_end ());
439453  }
440454
441455  //  If we still have any arguments, emit them using the type of the argument.
442456  for  (const  clang::Expr *a : llvm::drop_begin (argRange, argTypes.size ()))
443-     argTypes.push_back (a->getType ());
457+     argTypes.push_back (isVariadic ?  getVarArgType (a) :  a->getType ());
444458  assert (argTypes.size () == (size_t )(argRange.end () - argRange.begin ()));
445459
446460  //  We must evaluate arguments from right to left in the MS C++ ABI, because
0 commit comments