pub enum VaList {
CharPointer,
VoidPointer,
SysV,
Aapcs,
}Expand description
The type a target’s __builtin_va_list is.
A variable argument list is the one place a psABI dictates a C type rather than how a type
travels, and the four answers below are not four spellings of one thing: sizeof(va_list) is
eight bytes on Apple’s AArch64 and thirty two on Linux’s, and on SysV x86-64 a va_list is an
array, so a va_list passed to a function is passed as a pointer and one assigned to another
is a constraint violation rather than a copy. Code in the wild depends on all of that.
Variants§
CharPointer
char *, which is what a target whose arguments are all passed in one place needs: the
address of the next argument and nothing else. Apple’s AArch64 and both Windows targets.
VoidPointer
void *, which is the RISC-V psABI’s spelling of the same thing.
SysV
struct __va_list_tag { unsigned gp_offset, fp_offset; void *overflow_arg_area, *reg_save_area; } [1], the SysV x86-64 one. Arguments arrive in two register files and
on the stack, so the list is a cursor into each, and the array of one is what makes
passing it to vfprintf pass its address.
Aapcs
struct __va_list { void *__stack, *__gr_top, *__vr_top; int __gr_offs, __vr_offs; },
the AAPCS64 one. The same idea as SysV’s, counting down from the top of each save area
rather than up from the bottom, and not an array.