Skip to content

Commit da46325

Browse files
committed
Add to va_list lang item
Add the va_list lang item in order to allow VaList in libcore to be correctly generated for the target arch by trans.
1 parent 139b207 commit da46325

File tree

7 files changed

+108
-4
lines changed

7 files changed

+108
-4
lines changed

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ pub mod iter;
189189
pub mod option;
190190
pub mod raw;
191191
pub mod result;
192+
pub mod va_list;
192193

193194
pub mod slice;
194195
pub mod str;

src/libcore/va_list.rs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![unstable(feature = "c_variadic",
12+
reason = "dlrobertson is still working on this",
13+
issue = "27745")]
14+
15+
//! Implementation of a `va_list`
16+
17+
#[cfg(not(stage0))]
18+
#[lang = "va_list"]
19+
/// A wrapper for a `va_list`
20+
//#[derive(Debug)]
21+
#[repr(C)]
22+
#[unstable(feature = "c_variadic",
23+
reason = "dlrobertson is still working on this",
24+
issue = "27745")]
25+
#[derive(Debug)]
26+
pub struct VaList;
27+
28+
#[cfg(not(stage0))]
29+
#[unstable(feature = "c_variadic",
30+
reason = "This is just a test.",
31+
issue = "27745")]
32+
impl VaList {
33+
/// Advance to the next arg.
34+
pub unsafe fn arg<T: Copy>(&mut self) -> T {
35+
let tmp = self as *mut _ as *mut i8;
36+
::intrinsics::va_arg(tmp)
37+
}
38+
39+
/// Copy the `va_list` at the current location.
40+
pub unsafe fn copy<'ret, F, T>(&self, f: F) -> T
41+
where F: FnOnce(&mut VaList) -> T, T: 'ret {
42+
let mut ap: VaList = ::mem::uninitialized::<VaList>();
43+
::intrinsics::va_copy(self as *const _ as *const i8, &mut ap as *mut _ as *mut i8);
44+
let ret = f(&mut ap);
45+
::intrinsics::va_end(&mut ap as *const _ as *mut i8);
46+
ret
47+
}
48+
}

src/librustc/middle/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ language_item_table! {
273273
IndexMutTraitLangItem, "index_mut", index_mut_trait;
274274

275275
UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type;
276+
VaListTypeLangItem, "va_list", va_list;
276277

277278
DerefTraitLangItem, "deref", deref_trait;
278279
DerefMutTraitLangItem, "deref_mut", deref_mut_trait;

src/librustc/ty/context.rs

+29
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use ty::BindingMode;
5353
use ty::CanonicalTy;
5454
use util::nodemap::{DefIdSet, ItemLocalMap};
5555
use util::nodemap::{FxHashMap, FxHashSet};
56+
use rustc_target::spec::VaListKind;
5657
use rustc_data_structures::accumulate_vec::AccumulateVec;
5758
use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5859
StableHasher, StableHasherResult,
@@ -2694,6 +2695,34 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
26942695
self.object_lifetime_defaults_map(id.owner)
26952696
.and_then(|map| map.get(&id.local_id).cloned())
26962697
}
2698+
2699+
pub fn va_list_types(&self) -> Vec<Ty<'tcx>> {
2700+
match self.sess.target.target.options.va_list_kind {
2701+
VaListKind::CharPtr | VaListKind::VoidPtr => {
2702+
vec![self.mk_mut_ptr(self.types.i8)]
2703+
}
2704+
VaListKind::X86_64Abi => {
2705+
vec![self.types.i32,
2706+
self.types.i32,
2707+
self.mk_mut_ptr(self.types.i8),
2708+
self.mk_mut_ptr(self.types.i8)]
2709+
}
2710+
VaListKind::AArch64Abi => {
2711+
vec![self.mk_mut_ptr(self.types.i8),
2712+
self.mk_mut_ptr(self.types.i8),
2713+
self.mk_mut_ptr(self.types.i8),
2714+
self.types.i32,
2715+
self.types.i32]
2716+
}
2717+
VaListKind::PowerPcAbi => {
2718+
vec![self.types.i8,
2719+
self.types.i8,
2720+
self.types.i16,
2721+
self.mk_mut_ptr(self.types.i8),
2722+
self.mk_mut_ptr(self.types.i8)]
2723+
}
2724+
}
2725+
}
26972726
}
26982727

26992728
pub trait InternAs<T: ?Sized, R> {

src/librustc/ty/layout.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,17 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
744744
else { StructKind::AlwaysSized }
745745
};
746746

747-
let mut st = univariant_uninterned(&variants[v], &def.repr, kind)?;
747+
let mut st = match tcx.lang_items().va_list() {
748+
Some(did) if did == def.did => {
749+
let variants = tcx.va_list_types().iter()
750+
.map(|x| self.layout_of(x).unwrap())
751+
.collect::<Vec<_>>();
752+
univariant_uninterned(&variants[..], &def.repr, kind)?
753+
}
754+
_ => {
755+
univariant_uninterned(&variants[v], &def.repr, kind)?
756+
}
757+
};
748758
st.variants = Variants::Single { index: v };
749759
// Exclude 0 from the range of a newtype ABI NonZero<T>.
750760
if Some(def.did) == self.tcx.lang_items().non_zero() {
@@ -1614,6 +1624,13 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
16141624
this.ty.simd_type(tcx)
16151625
}
16161626

1627+
ty::TyAdt(def, ..) if Some(def.did) == tcx.lang_items().va_list() => {
1628+
match this.variants {
1629+
Variants::Single { index } => tcx.va_list_types()[index],
1630+
_ => bug!("VaList must be a struct type with a single variant.")
1631+
}
1632+
}
1633+
16171634
// ADTs.
16181635
ty::TyAdt(def, substs) => {
16191636
match this.variants {

src/librustc_trans/type_of.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,16 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
103103
Type::struct_(cx, &llfields, packed)
104104
}
105105
Some(ref name) => {
106-
let llty = Type::named_struct(cx, name);
107-
*defer = Some((llty, layout));
108-
llty
106+
match layout.ty.sty {
107+
ty::TyAdt(def, _) if Some(def.did) == cx.tcx.lang_items().va_list() => {
108+
Type::va_list(cx, name)
109+
}
110+
_ => {
111+
let llty = Type::named_struct(cx, name);
112+
*defer = Some((llty, layout));
113+
llty
114+
}
115+
}
109116
}
110117
}
111118
}

src/librustdoc/clean/inline.rs

+1
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean:
297297
lang_items.slice_u8_alloc_impl(),
298298
lang_items.const_ptr_impl(),
299299
lang_items.mut_ptr_impl(),
300+
lang_items.va_list(),
300301
];
301302

302303
for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) {

0 commit comments

Comments
 (0)