diff options
| author | bors <bors@rust-lang.org> | 2019-06-18 21:50:46 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-06-18 21:50:46 +0000 |
| commit | 605ea9d05c48957a291eec11eb7339788c3140ed (patch) | |
| tree | 57b5bcd13ed3c9a67b234200959ca8a454edbebe /src/librustc_codegen_llvm | |
| parent | 04a3dd8a872633ca1e4c217d11f741cc35cb19a5 (diff) | |
| parent | b9ea653aee231114acbe6d4b3c7b1d692772d060 (diff) | |
| download | rust-605ea9d05c48957a291eec11eb7339788c3140ed.tar.gz rust-605ea9d05c48957a291eec11eb7339788c3140ed.zip | |
Auto merge of #59625 - immunant:copy_variadics_typealias, r=eddyb
Refactor C FFI variadics to more closely match their C counterparts, and add Clone implementation We had to make some changes to expose `va_copy` and `va_end` directly to users (mainly for C2Rust, but not exclusively): - redefine the Rust variadic structures to more closely correspond to C: `VaList` now matches `va_list`, and `VaListImpl` matches `__va_list_tag` - add `Clone` for `VaListImpl` - add explicit `as_va_list()` conversion function from `VaListImpl` to `VaList` - add deref coercion from `VaList` to `VaListImpl` - add support for the `asmjs` target All these changes were needed for use cases like: ```Rust let mut ap2 = va_copy(ap); vprintf(fmt, ap2); va_end(&mut ap2); ```
Diffstat (limited to 'src/librustc_codegen_llvm')
| -rw-r--r-- | src/librustc_codegen_llvm/intrinsic.rs | 38 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/va_arg.rs | 12 |
2 files changed, 4 insertions, 46 deletions
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index dc3631e2ee1..7831c200114 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -146,15 +146,8 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.va_end(args[0].immediate()) } "va_copy" => { - let va_list = match (tcx.lang_items().va_list(), &result.layout.ty.sty) { - (Some(did), ty::Adt(def, _)) if def.did == did => args[0].immediate(), - (Some(_), _) => self.load(args[0].immediate(), - tcx.data_layout.pointer_align.abi), - (None, _) => bug!("`va_list` language item must be defined") - }; let intrinsic = self.cx().get_intrinsic(&("llvm.va_copy")); - self.call(intrinsic, &[llresult, va_list], None); - return; + self.call(intrinsic, &[args[0].immediate(), args[1].immediate()], None) } "va_arg" => { match fn_ty.ret.layout.abi { @@ -743,37 +736,12 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.call(expect, &[cond, self.const_bool(expected)], None) } - fn va_start(&mut self, list: &'ll Value) -> &'ll Value { - let target = &self.cx.tcx.sess.target.target; - let arch = &target.arch; - // A pointer to the architecture specific structure is passed to this - // function. For pointer variants (i686, RISC-V, Windows, etc), we - // should do do nothing, as the address to the pointer is needed. For - // architectures with a architecture specific structure (`Aarch64`, - // `X86_64`, etc), this function should load the structure from the - // address provided. - let va_list = match &**arch { - _ if target.options.is_like_windows => list, - "aarch64" if target.target_os == "ios" => list, - "aarch64" | "x86_64" | "powerpc" => - self.load(list, self.tcx().data_layout.pointer_align.abi), - _ => list, - }; + fn va_start(&mut self, va_list: &'ll Value) -> &'ll Value { let intrinsic = self.cx().get_intrinsic("llvm.va_start"); self.call(intrinsic, &[va_list], None) } - fn va_end(&mut self, list: &'ll Value) -> &'ll Value { - let target = &self.cx.tcx.sess.target.target; - let arch = &target.arch; - // See the comment in `va_start` for the purpose of the following. - let va_list = match &**arch { - _ if target.options.is_like_windows => list, - "aarch64" if target.target_os == "ios" => list, - "aarch64" | "x86_64" | "powerpc" => - self.load(list, self.tcx().data_layout.pointer_align.abi), - _ => list, - }; + fn va_end(&mut self, va_list: &'ll Value) -> &'ll Value { let intrinsic = self.cx().get_intrinsic("llvm.va_end"); self.call(intrinsic, &[va_list], None) } diff --git a/src/librustc_codegen_llvm/va_arg.rs b/src/librustc_codegen_llvm/va_arg.rs index 410e00fe0b8..86b0ad761af 100644 --- a/src/librustc_codegen_llvm/va_arg.rs +++ b/src/librustc_codegen_llvm/va_arg.rs @@ -132,16 +132,6 @@ pub(super) fn emit_va_arg( // For all other architecture/OS combinations fall back to using // the LLVM va_arg instruction. // https://llvm.org/docs/LangRef.html#va-arg-instruction - _ => { - let va_list = if (target.arch == "aarch64" || - target.arch == "x86_64" || - target.arch == "powerpc") && - !target.options.is_like_windows { - bx.load(addr.immediate(), bx.tcx().data_layout.pointer_align.abi) - } else { - addr.immediate() - }; - bx.va_arg(va_list, bx.cx.layout_of(target_ty).llvm_type(bx.cx)) - } + _ => bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) } } |
