add thiscall calling convention support
This support is needed for bindgen to work well on 32-bit Windows, and also enables people to begin experimenting with C++ FFI support on that platform. Fixes #42044.
This commit is contained in:
parent
5b13bff520
commit
9a2e2450f9
@ -7,6 +7,7 @@
|
||||
- [abi_msp430_interrupt](language-features/abi-msp430-interrupt.md)
|
||||
- [abi_ptx](language-features/abi-ptx.md)
|
||||
- [abi_sysv64](language-features/abi-sysv64.md)
|
||||
- [abi_thiscall](language-features/abi-thiscall.md)
|
||||
- [abi_unadjusted](language-features/abi-unadjusted.md)
|
||||
- [abi_vectorcall](language-features/abi-vectorcall.md)
|
||||
- [abi_x86_interrupt](language-features/abi-x86-interrupt.md)
|
||||
|
12
src/doc/unstable-book/src/language-features/abi-thiscall.md
Normal file
12
src/doc/unstable-book/src/language-features/abi-thiscall.md
Normal file
@ -0,0 +1,12 @@
|
||||
# `abi_thiscall`
|
||||
|
||||
The tracking issue for this feature is: [#42202]
|
||||
|
||||
[#42202]: https://github.com/rust-lang/rust/issues/42202
|
||||
|
||||
------------------------
|
||||
|
||||
The MSVC ABI on x86 Windows uses the `thiscall` calling convention for C++
|
||||
instance methods by default; it is identical to the usual (C) calling
|
||||
convention on x86 Windows except that the first parameter of the method,
|
||||
the `this` pointer, is passed in the ECX register.
|
@ -63,6 +63,7 @@ fn hash_stable<W: StableHasherResult>(&self,
|
||||
Stdcall,
|
||||
Fastcall,
|
||||
Vectorcall,
|
||||
Thiscall,
|
||||
Aapcs,
|
||||
Win64,
|
||||
SysV64,
|
||||
|
@ -12,5 +12,5 @@
|
||||
|
||||
// All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm
|
||||
pub fn abi_blacklist() -> Vec<Abi> {
|
||||
vec![Abi::Stdcall, Abi::Fastcall, Abi::Vectorcall, Abi::Win64, Abi::SysV64]
|
||||
vec![Abi::Stdcall, Abi::Fastcall, Abi::Vectorcall, Abi::Thiscall, Abi::Win64, Abi::SysV64]
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ pub enum CallConv {
|
||||
X86FastcallCallConv = 65,
|
||||
ArmAapcsCallConv = 67,
|
||||
Msp430Intr = 69,
|
||||
X86_ThisCall = 70,
|
||||
PtxKernel = 71,
|
||||
X86_64_SysV = 78,
|
||||
X86_64_Win64 = 79,
|
||||
|
@ -642,6 +642,7 @@ pub fn unadjusted(ccx: &CrateContext<'a, 'tcx>,
|
||||
Stdcall => llvm::X86StdcallCallConv,
|
||||
Fastcall => llvm::X86FastcallCallConv,
|
||||
Vectorcall => llvm::X86_VectorCall,
|
||||
Thiscall => llvm::X86_ThisCall,
|
||||
C => llvm::CCallConv,
|
||||
Unadjusted => llvm::CCallConv,
|
||||
Win64 => llvm::X86_64_Win64,
|
||||
|
@ -20,6 +20,7 @@ pub enum Abi {
|
||||
Stdcall,
|
||||
Fastcall,
|
||||
Vectorcall,
|
||||
Thiscall,
|
||||
Aapcs,
|
||||
Win64,
|
||||
SysV64,
|
||||
@ -55,6 +56,7 @@ pub struct AbiData {
|
||||
AbiData {abi: Abi::Stdcall, name: "stdcall", generic: false },
|
||||
AbiData {abi: Abi::Fastcall, name: "fastcall", generic: false },
|
||||
AbiData {abi: Abi::Vectorcall, name: "vectorcall", generic: false},
|
||||
AbiData {abi: Abi::Thiscall, name: "thiscall", generic: false},
|
||||
AbiData {abi: Abi::Aapcs, name: "aapcs", generic: false },
|
||||
AbiData {abi: Abi::Win64, name: "win64", generic: false },
|
||||
AbiData {abi: Abi::SysV64, name: "sysv64", generic: false },
|
||||
|
@ -352,6 +352,9 @@ pub fn new() -> Features {
|
||||
|
||||
// Allows use of the :vis macro fragment specifier
|
||||
(active, macro_vis_matcher, "1.18.0", Some(41022)),
|
||||
|
||||
// rustc internal
|
||||
(active, abi_thiscall, "1.19.0", None),
|
||||
);
|
||||
|
||||
declare_features! (
|
||||
@ -1051,6 +1054,10 @@ fn check_abi(&self, abi: Abi, span: Span) {
|
||||
gate_feature_post!(&self, abi_vectorcall, span,
|
||||
"vectorcall is experimental and subject to change");
|
||||
},
|
||||
Abi::Thiscall => {
|
||||
gate_feature_post!(&self, abi_thiscall, span,
|
||||
"thiscall is experimental and subject to change");
|
||||
},
|
||||
Abi::RustCall => {
|
||||
gate_feature_post!(&self, unboxed_closures, span,
|
||||
"rust-call ABI is subject to change");
|
||||
|
@ -11,6 +11,7 @@
|
||||
// gate-test-intrinsics
|
||||
// gate-test-platform_intrinsics
|
||||
// gate-test-abi_vectorcall
|
||||
// gate-test-abi_thiscall
|
||||
// gate-test-abi_ptx
|
||||
// gate-test-abi_x86_interrupt
|
||||
|
||||
@ -22,6 +23,7 @@ extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change
|
||||
extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental
|
||||
extern "ptx-kernel" fn f6() {} //~ ERROR PTX ABIs are experimental and subject to change
|
||||
extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental
|
||||
extern "thiscall" fn f8() {} //~ ERROR thiscall is experimental and subject to change
|
||||
|
||||
// Methods in trait definition
|
||||
trait Tr {
|
||||
@ -32,6 +34,7 @@ trait Tr {
|
||||
extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental
|
||||
extern "ptx-kernel" fn m6(); //~ ERROR PTX ABIs are experimental and subject to change
|
||||
extern "x86-interrupt" fn m7(); //~ ERROR x86-interrupt ABI is experimental
|
||||
extern "thiscall" fn m8(); //~ ERROR thiscall is experimental and subject to change
|
||||
|
||||
extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change
|
||||
extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental
|
||||
@ -40,6 +43,7 @@ extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change
|
||||
extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental
|
||||
extern "ptx-kernel" fn dm6() {} //~ ERROR PTX ABIs are experimental and subject to change
|
||||
extern "x86-interrupt" fn dm7() {} //~ ERROR x86-interrupt ABI is experimental
|
||||
extern "thiscall" fn dm8() {} //~ ERROR thiscall is experimental and subject to change
|
||||
}
|
||||
|
||||
struct S;
|
||||
@ -53,6 +57,7 @@ extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change
|
||||
extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental
|
||||
extern "ptx-kernel" fn m6() {} //~ ERROR PTX ABIs are experimental and subject to change
|
||||
extern "x86-interrupt" fn m7() {} //~ ERROR x86-interrupt ABI is experimental
|
||||
extern "thiscall" fn m8() {} //~ ERROR thiscall is experimental and subject to change
|
||||
}
|
||||
|
||||
// Methods in inherent impl
|
||||
@ -64,6 +69,7 @@ extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change
|
||||
extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental
|
||||
extern "ptx-kernel" fn im6() {} //~ ERROR PTX ABIs are experimental and subject to change
|
||||
extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
|
||||
extern "thiscall" fn im8() {} //~ ERROR thiscall is experimental and subject to change
|
||||
}
|
||||
|
||||
// Function pointer types
|
||||
@ -74,6 +80,7 @@ extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
|
||||
type A5 = extern "msp430-interrupt" fn(); //~ ERROR msp430-interrupt ABI is experimental
|
||||
type A6 = extern "ptx-kernel" fn (); //~ ERROR PTX ABIs are experimental and subject to change
|
||||
type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental
|
||||
type A8 = extern "thiscall" fn(); //~ ERROR thiscall is experimental and subject to change
|
||||
|
||||
// Foreign modules
|
||||
extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
|
||||
@ -83,5 +90,6 @@ extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
|
||||
extern "msp430-interrupt" {} //~ ERROR msp430-interrupt ABI is experimental
|
||||
extern "ptx-kernel" {} //~ ERROR PTX ABIs are experimental and subject to change
|
||||
extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental
|
||||
extern "thiscall" {} //~ ERROR thiscall is experimental and subject to change
|
||||
|
||||
fn main() {}
|
||||
|
35
src/test/run-pass/extern-thiscall.rs
Normal file
35
src/test/run-pass/extern-thiscall.rs
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-arm
|
||||
// ignore-aarch64
|
||||
|
||||
#![feature(abi_thiscall)]
|
||||
|
||||
trait A {
|
||||
extern "thiscall" fn test1(i: i32);
|
||||
}
|
||||
|
||||
struct S;
|
||||
|
||||
impl A for S {
|
||||
extern "thiscall" fn test1(i: i32) {
|
||||
assert_eq!(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
extern "thiscall" fn test2(i: i32) {
|
||||
assert_eq!(i, 2);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
<S as A>::test1(1);
|
||||
test2(2);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́`
|
||||
error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́`
|
||||
--> $DIR/unicode.rs:11:8
|
||||
|
|
||||
11 | extern "路濫狼á́́" fn foo() {}
|
||||
|
Loading…
Reference in New Issue
Block a user