about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/SUMMARY.md1
-rw-r--r--src/doc/unstable-book/src/language-features/abi-thiscall.md12
-rw-r--r--src/librustc/ich/impls_syntax.rs1
-rw-r--r--src/librustc_back/target/arm_base.rs2
-rw-r--r--src/librustc_llvm/ffi.rs1
-rw-r--r--src/librustc_trans/abi.rs1
-rw-r--r--src/libsyntax/abi.rs2
-rw-r--r--src/libsyntax/feature_gate.rs7
-rw-r--r--src/test/compile-fail/feature-gate-abi.rs8
-rw-r--r--src/test/run-pass/extern-thiscall.rs35
-rw-r--r--src/test/ui/codemap_tests/unicode.stderr2
11 files changed, 70 insertions, 2 deletions
diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md
index 456a683dc33..754ceadbccd 100644
--- a/src/doc/unstable-book/src/SUMMARY.md
+++ b/src/doc/unstable-book/src/SUMMARY.md
@@ -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)
diff --git a/src/doc/unstable-book/src/language-features/abi-thiscall.md b/src/doc/unstable-book/src/language-features/abi-thiscall.md
new file mode 100644
index 00000000000..73bc6eacf42
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/abi-thiscall.md
@@ -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.
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 7138db01339..d0bdf266332 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -63,6 +63,7 @@ impl_stable_hash_for!(enum ::syntax::abi::Abi {
     Stdcall,
     Fastcall,
     Vectorcall,
+    Thiscall,
     Aapcs,
     Win64,
     SysV64,
diff --git a/src/librustc_back/target/arm_base.rs b/src/librustc_back/target/arm_base.rs
index ad132c27cb8..416e5a0e13a 100644
--- a/src/librustc_back/target/arm_base.rs
+++ b/src/librustc_back/target/arm_base.rs
@@ -12,5 +12,5 @@ use syntax::abi::Abi;
 
 // 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]
 }
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index 5cb5a62c93b..d7b575d90a6 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -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,
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index a6b0eb473eb..9b94a3b2f23 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -642,6 +642,7 @@ impl<'a, 'tcx> FnType<'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,
diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs
index 30641515a41..ed2eb209906 100644
--- a/src/libsyntax/abi.rs
+++ b/src/libsyntax/abi.rs
@@ -20,6 +20,7 @@ pub enum Abi {
     Stdcall,
     Fastcall,
     Vectorcall,
+    Thiscall,
     Aapcs,
     Win64,
     SysV64,
@@ -55,6 +56,7 @@ const AbiDatas: &'static [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 },
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index e1b7d4681ad..f9fe072ef87 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -352,6 +352,9 @@ declare_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 @@ impl<'a> PostExpansionVisitor<'a> {
                 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");
diff --git a/src/test/compile-fail/feature-gate-abi.rs b/src/test/compile-fail/feature-gate-abi.rs
index b77c9fab716..45c715f51fe 100644
--- a/src/test/compile-fail/feature-gate-abi.rs
+++ b/src/test/compile-fail/feature-gate-abi.rs
@@ -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 @@ trait Tr {
     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 @@ impl Tr for S {
     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 @@ impl S {
     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 @@ type A4 = extern "rust-call" fn(); //~ ERROR rust-call ABI is subject to change
 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 "rust-call" {} //~ ERROR rust-call ABI is subject to change
 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() {}
diff --git a/src/test/run-pass/extern-thiscall.rs b/src/test/run-pass/extern-thiscall.rs
new file mode 100644
index 00000000000..a669f29d098
--- /dev/null
+++ b/src/test/run-pass/extern-thiscall.rs
@@ -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);
+}
diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr
index eef87935115..0828fd28b58 100644
--- a/src/test/ui/codemap_tests/unicode.stderr
+++ b/src/test/ui/codemap_tests/unicode.stderr
@@ -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() {}