@@ -8,20 +8,39 @@ use crate::fmt;
88use crate :: intrinsics:: { va_arg, va_copy} ;
99use crate :: marker:: PhantomCovariantLifetime ;
1010
11- // Most targets explicitly specify the layout of `va_list`, this layout is matched here.
12- // For `va_list`s which are single-element array in C (and therefore experience array-to-pointer
13- // decay when passed as arguments in C), the `VaList` struct is annotated with
14- // `#[rustc_pass_indirectly_in_non_rustic_abis]`. This ensures that the compiler uses the correct
15- // ABI for functions like `extern "C" fn takes_va_list(va: VaList<'_>)` by passing `va` indirectly.
11+ // There are currently three flavors of how a C `va_list` is implemented for
12+ // targets that Rust supports:
13+ //
14+ // - `va_list` is an opaque pointer
15+ // - `va_list` is a struct
16+ // - `va_list` is a single-element array, containing a struct
17+ //
18+ // The opaque pointer approach is the simplest to implement: the pointer just
19+ // points to an array of arguments on the caller's stack.
20+ //
21+ // The struct and single-element array variants are more complex, but
22+ // potentially more efficient because the additional state makes it
23+ // possible to pass variadic arguments via registers.
24+ //
25+ // The Rust `VaList` type is ABI-compatible with the C `va_list`.
26+ // The struct and pointer cases straightforwardly map to their rust equivalents,
27+ // but the single-element array case is special: in C, this type is subject to
28+ // array-to-pointer decay.
29+ //
30+ // The `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute is used to match
31+ // the pointer decay behavior in Rust. This attribute ensures that the compiler
32+ // uses the correct ABI for functions like
33+ // `extern "C" fn takes_va_list(va: VaList<'_>)` by passing `va` indirectly.
1634crate :: cfg_select! {
1735 all(
1836 target_arch = "aarch64" ,
1937 not( target_vendor = "apple" ) ,
2038 not( target_os = "uefi" ) ,
2139 not( windows) ,
2240 ) => {
23- /// AArch64 ABI implementation of a `va_list`. See the
24- /// [AArch64 Procedure Call Standard] for more details.
41+ /// AArch64 ABI implementation of a `va_list`.
42+ ///
43+ /// See the [AArch64 Procedure Call Standard] for more details.
2544 ///
2645 /// [AArch64 Procedure Call Standard]:
2746 /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
@@ -37,6 +56,12 @@ crate::cfg_select! {
3756 }
3857 all( target_arch = "powerpc" , not( target_os = "uefi" ) , not( windows) ) => {
3958 /// PowerPC ABI implementation of a `va_list`.
59+ ///
60+ /// See the [LLVM source] and [GCC header] for more details.
61+ ///
62+ /// [LLVM source]:
63+ /// https://github.com/llvm/llvm-project/blob/af9a4263a1a209953a1d339ef781a954e31268ff/llvm/lib/Target/PowerPC/PPCISelLowering.cpp#L4089-L4111
64+ /// [GCC header]: https://web.mit.edu/darwin/src/modules/gcc/gcc/ginclude/va-ppc.h
4065 #[ repr( C ) ]
4166 #[ derive( Debug ) ]
4267 #[ rustc_pass_indirectly_in_non_rustic_abis]
@@ -50,6 +75,11 @@ crate::cfg_select! {
5075 }
5176 target_arch = "s390x" => {
5277 /// s390x ABI implementation of a `va_list`.
78+ ///
79+ /// See the [S/390x ELF Application Binary Interface Supplement] for more details.
80+ ///
81+ /// [S/390x ELF Application Binary Interface Supplement]:
82+ /// https://docs.google.com/gview?embedded=true&url=https://github.com/IBM/s390x-abi/releases/download/v1.7/lzsabi_s390x.pdf
5383 #[ repr( C ) ]
5484 #[ derive( Debug ) ]
5585 #[ rustc_pass_indirectly_in_non_rustic_abis]
@@ -61,7 +91,12 @@ crate::cfg_select! {
6191 }
6292 }
6393 all( target_arch = "x86_64" , not( target_os = "uefi" ) , not( windows) ) => {
64- /// x86_64 ABI implementation of a `va_list`.
94+ /// x86_64 System V ABI implementation of a `va_list`.
95+ ///
96+ /// See the [System V AMD64 ABI] for more details.
97+ ///
98+ /// [System V AMD64 ABI]:
99+ /// https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf
65100 #[ repr( C ) ]
66101 #[ derive( Debug ) ]
67102 #[ rustc_pass_indirectly_in_non_rustic_abis]
@@ -74,6 +109,11 @@ crate::cfg_select! {
74109 }
75110 target_arch = "xtensa" => {
76111 /// Xtensa ABI implementation of a `va_list`.
112+ ///
113+ /// See the [LLVM source] for more details.
114+ ///
115+ /// [LLVM source]:
116+ /// https://github.com/llvm/llvm-project/blob/af9a4263a1a209953a1d339ef781a954e31268ff/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp#L1211-L1215
77117 #[ repr( C ) ]
78118 #[ derive( Debug ) ]
79119 #[ rustc_pass_indirectly_in_non_rustic_abis]
@@ -88,6 +128,7 @@ crate::cfg_select! {
88128 //
89129 // - apple aarch64 (see https://github.com/rust-lang/rust/pull/56599)
90130 // - windows
131+ // - powerpc64 & powerpc64le
91132 // - uefi
92133 // - any other target for which we don't specify the `VaListInner` above
93134 //
0 commit comments