From fac60c39743bc1c941efc30b55ba195910a481d1 Mon Sep 17 00:00:00 2001 From: David Mak Date: Tue, 16 Jul 2024 19:36:08 +0800 Subject: [PATCH] core/codegen: Handle vararg in function generation --- nac3core/src/codegen/mod.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 4f79ddf4..0f2ec564 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -743,7 +743,10 @@ pub fn gen_func_impl< let has_sret = ret_type.map_or(false, |ty| need_sret(ty)); let mut params = args .iter() + .filter(|arg| !arg.is_vararg) .map(|arg| { + debug_assert!(!arg.is_vararg); + get_llvm_abi_type( context, &module, @@ -762,9 +765,12 @@ pub fn gen_func_impl< params.insert(0, ret_type.unwrap().ptr_type(AddressSpace::default()).into()); } + debug_assert!(matches!(args.iter().filter(|arg| arg.is_vararg).count(), 0..=1)); + let vararg_arg = args.iter().find(|arg| arg.is_vararg); + let fn_type = match ret_type { - Some(ret_type) if !has_sret => ret_type.fn_type(¶ms, false), - _ => context.void_type().fn_type(¶ms, false), + Some(ret_type) if !has_sret => ret_type.fn_type(¶ms, vararg_arg.is_some()), + _ => context.void_type().fn_type(¶ms, vararg_arg.is_some()), }; let symbol = &task.symbol_name; @@ -794,7 +800,9 @@ pub fn gen_func_impl< let mut var_assignment = HashMap::new(); let offset = u32::from(has_sret); - for (n, arg) in args.iter().enumerate() { + + // Store non-vararg argument values into local variables + for (n, arg) in args.iter().enumerate().filter(|(_, arg)| !arg.is_vararg) { let param = fn_val.get_nth_param((n as u32) + offset).unwrap(); let local_type = get_llvm_type( context, @@ -827,6 +835,8 @@ pub fn gen_func_impl< var_assignment.insert(arg.name, (alloca, None, 0)); } + // TODO: Save vararg parameters as list + let return_buffer = if has_sret { Some(fn_val.get_nth_param(0).unwrap().into_pointer_value()) } else {