compiler/rustc_abi/src/canon_abi.rs RUST 161 lines View on github.com → Search inside
1use std::fmt;23#[cfg(feature = "nightly")]4use rustc_macros::StableHash;56use crate::ExternAbi;78/// Calling convention to determine codegen9///10/// CanonAbi erases certain distinctions ExternAbi preserves, but remains target-dependent.11/// There are still both target-specific variants and aliasing variants, though much fewer.12/// The reason for this step is the frontend may wish to show an ExternAbi but implement that ABI13/// using a different ABI than the string per se, or describe irrelevant differences, e.g.14/// - extern "system"15/// - extern "cdecl"16/// - extern "C-unwind"17/// In that sense, this erases mere syntactic distinctions to create a canonical *directive*,18/// rather than picking the "actual" ABI.19#[derive(Copy, Clone, Debug)]20#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]21#[cfg_attr(feature = "nightly", derive(StableHash))]22pub enum CanonAbi {23    // NOTE: the use of nested variants for some ABIs is for many targets they don't matter,24    // and this pushes the complexity of their reasoning to target-specific code,25    // allowing a `match` to easily exhaustively ignore these subcategories of variants.26    // Otherwise it is very tempting to avoid matching exhaustively!27    C,28    Rust,29    RustCold,30    RustPreserveNone,31    RustTail,3233    /// An ABI that rustc does not know how to call or define.34    Custom,3536    /// Swift calling convention, exposed via LLVM's `swiftcc`. Cross-platform37    /// and not tied to a specific target architecture.38    Swift,3940    /// ABIs relevant to 32-bit Arm targets41    Arm(ArmCall),42    /// ABI relevant to GPUs: the entry point for a GPU kernel43    GpuKernel,4445    /// ABIs relevant to bare-metal interrupt targets46    // FIXME(workingjubilee): a particular reason for this nesting is we might not need these?47    // interrupt ABIs should have the same properties:48    // - uncallable by Rust calls, as LLVM rejects it in most cases49    // - uses a preserve-all-registers *callee* convention50    // - should always return `-> !` (effectively... it can't use normal `ret`)51    // what differs between targets is52    // - allowed arguments: x86 differs slightly, having 2-3 arguments which are handled magically53    // - may need special prologues/epilogues for some interrupts, without affecting "call ABI"54    Interrupt(InterruptKind),5556    /// ABIs relevant to Windows or x86 targets57    X86(X86Call),58}5960impl CanonAbi {61    pub fn is_rustic_abi(self) -> bool {62        match self {63            CanonAbi::Rust64            | CanonAbi::RustCold65            | CanonAbi::RustPreserveNone66            | CanonAbi::RustTail => true,67            CanonAbi::C68            | CanonAbi::Custom69            | CanonAbi::Swift70            | CanonAbi::Arm(_)71            | CanonAbi::GpuKernel72            | CanonAbi::Interrupt(_)73            | CanonAbi::X86(_) => false,74        }75    }76}7778impl fmt::Display for CanonAbi {79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {80        // convert to the ExternAbi that *shares a string* with this CanonAbi.81        // FIXME: ideally we'd avoid printing `CanonAbi`, and preserve `ExternAbi` everywhere82        // that we need to generate error messages.83        let erased_abi = match self {84            CanonAbi::C => ExternAbi::C { unwind: false },85            CanonAbi::Rust => ExternAbi::Rust,86            CanonAbi::RustCold => ExternAbi::RustCold,87            CanonAbi::RustPreserveNone => ExternAbi::RustPreserveNone,88            CanonAbi::RustTail => ExternAbi::RustTail,89            CanonAbi::Custom => ExternAbi::Custom,90            CanonAbi::Swift => ExternAbi::Swift,91            CanonAbi::Arm(arm_call) => match arm_call {92                ArmCall::Aapcs => ExternAbi::Aapcs { unwind: false },93                ArmCall::CCmseNonSecureCall => ExternAbi::CmseNonSecureCall,94                ArmCall::CCmseNonSecureEntry => ExternAbi::CmseNonSecureEntry,95            },96            CanonAbi::GpuKernel => ExternAbi::GpuKernel,97            CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {98                InterruptKind::Avr => ExternAbi::AvrInterrupt,99                InterruptKind::AvrNonBlocking => ExternAbi::AvrNonBlockingInterrupt,100                InterruptKind::Msp430 => ExternAbi::Msp430Interrupt,101                InterruptKind::RiscvMachine => ExternAbi::RiscvInterruptM,102                InterruptKind::RiscvSupervisor => ExternAbi::RiscvInterruptS,103                InterruptKind::X86 => ExternAbi::X86Interrupt,104            },105            CanonAbi::X86(x86_call) => match x86_call {106                X86Call::Fastcall => ExternAbi::Fastcall { unwind: false },107                X86Call::Stdcall => ExternAbi::Stdcall { unwind: false },108                X86Call::SysV64 => ExternAbi::SysV64 { unwind: false },109                X86Call::Thiscall => ExternAbi::Thiscall { unwind: false },110                X86Call::Vectorcall => ExternAbi::Vectorcall { unwind: false },111                X86Call::Win64 => ExternAbi::Win64 { unwind: false },112            },113        };114        erased_abi.as_str().fmt(f)115    }116}117118/// Callee codegen for interrupts119///120/// This is named differently from the "Call" enums because it is different:121/// these "ABI" differences are not relevant to callers, since there is "no caller".122/// These only affect callee codegen. making their categorization as distinct ABIs a bit peculiar.123#[derive(Copy, Clone, Debug)]124#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]125#[cfg_attr(feature = "nightly", derive(StableHash))]126pub enum InterruptKind {127    Avr,128    AvrNonBlocking,129    Msp430,130    RiscvMachine,131    RiscvSupervisor,132    X86,133}134135/// ABIs defined for x86-{32,64}136///137/// One of SysV64 or Win64 may alias the C ABI, and arguably Win64 is cross-platform now?138#[derive(Clone, Copy, Debug)]139#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]140#[cfg_attr(feature = "nightly", derive(StableHash))]141pub enum X86Call {142    /// "fastcall" has both GNU and Windows variants143    Fastcall,144    /// "stdcall" has both GNU and Windows variants145    Stdcall,146    SysV64,147    Thiscall,148    Vectorcall,149    Win64,150}151152/// ABIs defined for 32-bit Arm153#[derive(Copy, Clone, Debug)]154#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]155#[cfg_attr(feature = "nightly", derive(StableHash))]156pub enum ArmCall {157    Aapcs,158    CCmseNonSecureCall,159    CCmseNonSecureEntry,160}

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.