Skip to content

Commit 2db17c8

Browse files
committed
Auto merge of #42058 - froydnj:thiscall-support, r=nikomatsakis
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.
2 parents 4f9c9ed + 9a2e245 commit 2db17c8

File tree

11 files changed

+70
-2
lines changed

11 files changed

+70
-2
lines changed

src/doc/unstable-book/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- [abi_msp430_interrupt](language-features/abi-msp430-interrupt.md)
88
- [abi_ptx](language-features/abi-ptx.md)
99
- [abi_sysv64](language-features/abi-sysv64.md)
10+
- [abi_thiscall](language-features/abi-thiscall.md)
1011
- [abi_unadjusted](language-features/abi-unadjusted.md)
1112
- [abi_vectorcall](language-features/abi-vectorcall.md)
1213
- [abi_x86_interrupt](language-features/abi-x86-interrupt.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# `abi_thiscall`
2+
3+
The tracking issue for this feature is: [#42202]
4+
5+
[#42202]: https://github.com/rust-lang/rust/issues/42202
6+
7+
------------------------
8+
9+
The MSVC ABI on x86 Windows uses the `thiscall` calling convention for C++
10+
instance methods by default; it is identical to the usual (C) calling
11+
convention on x86 Windows except that the first parameter of the method,
12+
the `this` pointer, is passed in the ECX register.

src/librustc/ich/impls_syntax.rs

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ impl_stable_hash_for!(enum ::syntax::abi::Abi {
6363
Stdcall,
6464
Fastcall,
6565
Vectorcall,
66+
Thiscall,
6667
Aapcs,
6768
Win64,
6869
SysV64,

src/librustc_back/target/arm_base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ use syntax::abi::Abi;
1212

1313
// All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm
1414
pub fn abi_blacklist() -> Vec<Abi> {
15-
vec![Abi::Stdcall, Abi::Fastcall, Abi::Vectorcall, Abi::Win64, Abi::SysV64]
15+
vec![Abi::Stdcall, Abi::Fastcall, Abi::Vectorcall, Abi::Thiscall, Abi::Win64, Abi::SysV64]
1616
}

src/librustc_llvm/ffi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub enum CallConv {
4949
X86FastcallCallConv = 65,
5050
ArmAapcsCallConv = 67,
5151
Msp430Intr = 69,
52+
X86_ThisCall = 70,
5253
PtxKernel = 71,
5354
X86_64_SysV = 78,
5455
X86_64_Win64 = 79,

src/librustc_trans/abi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ impl<'a, 'tcx> FnType<'tcx> {
642642
Stdcall => llvm::X86StdcallCallConv,
643643
Fastcall => llvm::X86FastcallCallConv,
644644
Vectorcall => llvm::X86_VectorCall,
645+
Thiscall => llvm::X86_ThisCall,
645646
C => llvm::CCallConv,
646647
Unadjusted => llvm::CCallConv,
647648
Win64 => llvm::X86_64_Win64,

src/libsyntax/abi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub enum Abi {
2020
Stdcall,
2121
Fastcall,
2222
Vectorcall,
23+
Thiscall,
2324
Aapcs,
2425
Win64,
2526
SysV64,
@@ -55,6 +56,7 @@ const AbiDatas: &'static [AbiData] = &[
5556
AbiData {abi: Abi::Stdcall, name: "stdcall", generic: false },
5657
AbiData {abi: Abi::Fastcall, name: "fastcall", generic: false },
5758
AbiData {abi: Abi::Vectorcall, name: "vectorcall", generic: false},
59+
AbiData {abi: Abi::Thiscall, name: "thiscall", generic: false},
5860
AbiData {abi: Abi::Aapcs, name: "aapcs", generic: false },
5961
AbiData {abi: Abi::Win64, name: "win64", generic: false },
6062
AbiData {abi: Abi::SysV64, name: "sysv64", generic: false },

src/libsyntax/feature_gate.rs

+7
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,9 @@ declare_features! (
352352

353353
// Allows use of the :vis macro fragment specifier
354354
(active, macro_vis_matcher, "1.18.0", Some(41022)),
355+
356+
// rustc internal
357+
(active, abi_thiscall, "1.19.0", None),
355358
);
356359

357360
declare_features! (
@@ -1054,6 +1057,10 @@ impl<'a> PostExpansionVisitor<'a> {
10541057
gate_feature_post!(&self, abi_vectorcall, span,
10551058
"vectorcall is experimental and subject to change");
10561059
},
1060+
Abi::Thiscall => {
1061+
gate_feature_post!(&self, abi_thiscall, span,
1062+
"thiscall is experimental and subject to change");
1063+
},
10571064
Abi::RustCall => {
10581065
gate_feature_post!(&self, unboxed_closures, span,
10591066
"rust-call ABI is subject to change");

src/test/compile-fail/feature-gate-abi.rs

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// gate-test-intrinsics
1212
// gate-test-platform_intrinsics
1313
// gate-test-abi_vectorcall
14+
// gate-test-abi_thiscall
1415
// gate-test-abi_ptx
1516
// gate-test-abi_x86_interrupt
1617

@@ -22,6 +23,7 @@ extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change
2223
extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental
2324
extern "ptx-kernel" fn f6() {} //~ ERROR PTX ABIs are experimental and subject to change
2425
extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental
26+
extern "thiscall" fn f8() {} //~ ERROR thiscall is experimental and subject to change
2527

2628
// Methods in trait definition
2729
trait Tr {
@@ -32,6 +34,7 @@ trait Tr {
3234
extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental
3335
extern "ptx-kernel" fn m6(); //~ ERROR PTX ABIs are experimental and subject to change
3436
extern "x86-interrupt" fn m7(); //~ ERROR x86-interrupt ABI is experimental
37+
extern "thiscall" fn m8(); //~ ERROR thiscall is experimental and subject to change
3538

3639
extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change
3740
extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental
@@ -40,6 +43,7 @@ trait Tr {
4043
extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental
4144
extern "ptx-kernel" fn dm6() {} //~ ERROR PTX ABIs are experimental and subject to change
4245
extern "x86-interrupt" fn dm7() {} //~ ERROR x86-interrupt ABI is experimental
46+
extern "thiscall" fn dm8() {} //~ ERROR thiscall is experimental and subject to change
4347
}
4448

4549
struct S;
@@ -53,6 +57,7 @@ impl Tr for S {
5357
extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental
5458
extern "ptx-kernel" fn m6() {} //~ ERROR PTX ABIs are experimental and subject to change
5559
extern "x86-interrupt" fn m7() {} //~ ERROR x86-interrupt ABI is experimental
60+
extern "thiscall" fn m8() {} //~ ERROR thiscall is experimental and subject to change
5661
}
5762

5863
// Methods in inherent impl
@@ -64,6 +69,7 @@ impl S {
6469
extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental
6570
extern "ptx-kernel" fn im6() {} //~ ERROR PTX ABIs are experimental and subject to change
6671
extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
72+
extern "thiscall" fn im8() {} //~ ERROR thiscall is experimental and subject to change
6773
}
6874

6975
// Function pointer types
@@ -74,6 +80,7 @@ type A4 = extern "rust-call" fn(); //~ ERROR rust-call ABI is subject to change
7480
type A5 = extern "msp430-interrupt" fn(); //~ ERROR msp430-interrupt ABI is experimental
7581
type A6 = extern "ptx-kernel" fn (); //~ ERROR PTX ABIs are experimental and subject to change
7682
type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental
83+
type A8 = extern "thiscall" fn(); //~ ERROR thiscall is experimental and subject to change
7784

7885
// Foreign modules
7986
extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
@@ -83,5 +90,6 @@ extern "rust-call" {} //~ ERROR rust-call ABI is subject to change
8390
extern "msp430-interrupt" {} //~ ERROR msp430-interrupt ABI is experimental
8491
extern "ptx-kernel" {} //~ ERROR PTX ABIs are experimental and subject to change
8592
extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental
93+
extern "thiscall" {} //~ ERROR thiscall is experimental and subject to change
8694

8795
fn main() {}

src/test/run-pass/extern-thiscall.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2016 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+
// ignore-arm
12+
// ignore-aarch64
13+
14+
#![feature(abi_thiscall)]
15+
16+
trait A {
17+
extern "thiscall" fn test1(i: i32);
18+
}
19+
20+
struct S;
21+
22+
impl A for S {
23+
extern "thiscall" fn test1(i: i32) {
24+
assert_eq!(i, 1);
25+
}
26+
}
27+
28+
extern "thiscall" fn test2(i: i32) {
29+
assert_eq!(i, 2);
30+
}
31+
32+
fn main() {
33+
<S as A>::test1(1);
34+
test2(2);
35+
}

src/test/ui/codemap_tests/unicode.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
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 `路濫狼á́́`
1+
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 `路濫狼á́́`
22
--> $DIR/unicode.rs:11:8
33
|
44
11 | extern "路濫狼á́́" fn foo() {}

0 commit comments

Comments
 (0)