@@ -182,6 +182,8 @@ pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug {
182
182
fn is_tuple ( this : TyAndLayout < ' a , Self > ) -> bool ;
183
183
fn is_unit ( this : TyAndLayout < ' a , Self > ) -> bool ;
184
184
fn is_transparent ( this : TyAndLayout < ' a , Self > ) -> bool ;
185
+ /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details.
186
+ fn is_pass_indirectly_in_non_rustic_abis_flag_set ( this : TyAndLayout < ' a , Self > ) -> bool ;
185
187
}
186
188
187
189
impl < ' a , Ty > TyAndLayout < ' a , Ty > {
@@ -279,6 +281,30 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
279
281
Ty :: is_transparent ( self )
280
282
}
281
283
284
+ /// If this method returns `true`, then this type should always have a `PassMode` of
285
+ /// `Indirect { on_stack: false, .. }` when being used as the argument type of a function with a
286
+ /// non-Rustic ABI (this is true for structs annotated with the
287
+ /// `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute). Currently this is only used by
288
+ /// `VaList`, so this only needs to be handled on architectures where `VaList` requires it:
289
+ /// specifically there is a `support_architectures` array in the
290
+ /// `check_pass_indirectly_in_non_rustic_abis` function in
291
+ /// `compiler/rustc_passes/src/check_attr.rs` which lists all the architectures this needs to be
292
+ /// handled on. See the comment near the top of `library/core/src/ffi/va_list.rs` for more
293
+ /// details.
294
+ ///
295
+ /// This function handles transparent types automatically.
296
+ pub fn pass_indirectly_in_non_rustic_abis < C > ( mut self , cx : & C ) -> bool
297
+ where
298
+ Ty : TyAbiInterface < ' a , C > + Copy ,
299
+ {
300
+ while self . is_transparent ( )
301
+ && let Some ( ( _, field) ) = self . non_1zst_field ( cx)
302
+ {
303
+ self = field;
304
+ }
305
+ Ty :: is_pass_indirectly_in_non_rustic_abis_flag_set ( self )
306
+ }
307
+
282
308
/// Finds the one field that is not a 1-ZST.
283
309
/// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields.
284
310
pub fn non_1zst_field < C > ( & self , cx : & C ) -> Option < ( FieldIdx , Self ) >
0 commit comments