(index<- )        ./libsyntax/abi.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Wed Apr  9 17:27:03 2014
   1  // Copyright 2012-2013 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  use std::fmt;
  12  
  13  #[deriving(Eq)]
  14  pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, }
  15  
  16  #[deriving(Eq, TotalEq, Hash, Encodable, Decodable, Clone)]
  17  pub enum Abi {
  18      // NB: This ordering MUST match the AbiDatas array below.
  19      // (This is ensured by the test indices_are_correct().)
  20  
  21      // Single platform ABIs come first (`for_arch()` relies on this)
  22      Cdecl,
  23      Stdcall,
  24      Fastcall,
  25      Aapcs,
  26      Win64,
  27  
  28      // Multiplatform ABIs second
  29      Rust,
  30      C,
  31      System,
  32      RustIntrinsic,
  33  }
  34  
  35  #[allow(non_camel_case_types)]
  36  #[deriving(Eq)]
  37  pub enum Architecture {
  38      // NB. You cannot change the ordering of these
  39      // constants without adjusting IntelBits below.
  40      // (This is ensured by the test indices_are_correct().)
  41      X86,
  42      X86_64,
  43      Arm,
  44      Mips
  45  }
  46  
  47  static IntelBits: u32 = (1 << (X86 as uint)) | (1 << (X86_64 as uint));
  48  static ArmBits: u32 = (1 << (Arm as uint));
  49  
  50  pub struct AbiData {
  51      abi: Abi,
  52  
  53      // Name of this ABI as we like it called.
  54      name: &'static str,
  55  
  56      // Is it specific to a platform? If so, which one?  Also, what is
  57      // the name that LLVM gives it (in case we disagree)
  58      abi_arch: AbiArchitecture
  59  }
  60  
  61  pub enum AbiArchitecture {
  62      RustArch,   // Not a real ABI (e.g., intrinsic)
  63      AllArch,    // An ABI that specifies cross-platform defaults (e.g., "C")
  64      Archs(u32)  // Multiple architectures (bitset)
  65  }
  66  
  67  static AbiDatas: &'static [AbiData] = &[
  68      // Platform-specific ABIs
  69      AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(IntelBits)},
  70      AbiData {abi: Stdcall, name: "stdcall", abi_arch: Archs(IntelBits)},
  71      AbiData {abi: Fastcall, name:"fastcall", abi_arch: Archs(IntelBits)},
  72      AbiData {abi: Aapcs, name: "aapcs", abi_arch: Archs(ArmBits)},
  73      AbiData {abi: Win64, name: "win64",
  74               abi_arch: Archs(1 << (X86_64 as uint))},
  75  
  76      // Cross-platform ABIs
  77      //
  78      // NB: Do not adjust this ordering without
  79      // adjusting the indices below.
  80      AbiData {abi: Rust, name: "Rust", abi_arch: RustArch},
  81      AbiData {abi: C, name: "C", abi_arch: AllArch},
  82      AbiData {abi: System, name: "system", abi_arch: AllArch},
  83      AbiData {abi: RustIntrinsic, name: "rust-intrinsic", abi_arch: RustArch},
  84  ];
  85  
  86  fn each_abi(op: |abi: Abi-> bool) -> bool {
  87      /*!
  88       *
  89       * Iterates through each of the defined ABIs.
  90       */
  91  
  92      AbiDatas.iter().advance(|abi_data| op(abi_data.abi))
  93  }
  94  
  95  pub fn lookup(name: &str) -> Option<Abi> {
  96      /*!
  97       *
  98       * Returns the ABI with the given name (if any).
  99       */
 100  
 101      let mut res = None;
 102  
 103      each_abi(|abi| {
 104          if name == abi.data().name {
 105              res = Some(abi);
 106              false
 107          } else {
 108              true
 109          }
 110      });
 111      res
 112  }
 113  
 114  pub fn all_names() -> Vec<&'static str> {
 115      AbiDatas.iter().map(|d| d.name).collect()
 116  }
 117  
 118  impl Abi {
 119      #[inline]
 120      pub fn index(&self) -> uint {
 121          *self as uint
 122      }
 123  
 124      #[inline]
 125      pub fn data(&self) -> &'static AbiData {
 126          &AbiDatas[self.index()]
 127      }
 128  
 129      pub fn name(&self) -> &'static str {
 130          self.data().name
 131      }
 132  
 133      pub fn for_target(&self, osOs, archArchitecture) -> Option<Abi> {
 134          // If this ABI isn't actually for the specified architecture, then we
 135          // short circuit early
 136          match self.data().abi_arch {
 137              Archs(a) if a & arch.bit() == 0 => return None,
 138              Archs(_) | RustArch | AllArch => {}
 139          }
 140          // Transform this ABI as appropriate for the requested os/arch
 141          // combination.
 142          Some(match (*self, os, arch) {
 143              (System, OsWin32, X86) => Stdcall,
 144              (System, _, _) => C,
 145              (me, _, _) => me,
 146          })
 147      }
 148  }
 149  
 150  impl Architecture {
 151      fn bit(&self) -> u32 {
 152          1 << (*self as u32)
 153      }
 154  }
 155  
 156  impl fmt::Show for Abi {
 157      fn fmt(&self, f&mut fmt::Formatter) -> fmt::Result {
 158          write!(f.buf, "\"{}\"", self.name())
 159      }
 160  }
 161  
 162  #[test]
 163  fn lookup_Rust() {
 164      let abi = lookup("Rust");
 165      assert!(abi.is_some() && abi.unwrap().data().name == "Rust");
 166  }
 167  
 168  #[test]
 169  fn lookup_cdecl() {
 170      let abi = lookup("cdecl");
 171      assert!(abi.is_some() && abi.unwrap().data().name == "cdecl");
 172  }
 173  
 174  #[test]
 175  fn lookup_baz() {
 176      let abi = lookup("baz");
 177      assert!(abi.is_none());
 178  }
 179  
 180  #[test]
 181  fn indices_are_correct() {
 182      for (i, abi_data) in AbiDatas.iter().enumerate() {
 183          assert_eq!(i, abi_data.abi.index());
 184      }
 185  
 186      let bits = 1 << (X86 as u32);
 187      let bits = bits | 1 << (X86_64 as u32);
 188      assert_eq!(IntelBits, bits);
 189  
 190      let bits = 1 << (Arm as u32);
 191      assert_eq!(ArmBits, bits);
 192  }
 193  
 194  #[test]
 195  fn pick_uniplatform() {
 196      assert_eq!(Stdcall.for_target(OsLinux, X86), Some(Stdcall));
 197      assert_eq!(Stdcall.for_target(OsLinux, Arm), None);
 198      assert_eq!(System.for_target(OsLinux, X86), Some(C));
 199      assert_eq!(System.for_target(OsWin32, X86), Some(Stdcall));
 200      assert_eq!(System.for_target(OsWin32, X86_64), Some(C));
 201      assert_eq!(System.for_target(OsWin32, Arm), Some(C));
 202      assert_eq!(Stdcall.for_target(OsWin32, X86), Some(Stdcall));
 203      assert_eq!(Stdcall.for_target(OsWin32, X86_64), Some(Stdcall));
 204  }


libsyntax/abi.rs:16:60-16:60 -enum- definition:
pub enum Abi {
    // NB: This ordering MUST match the AbiDatas array below.
    // (This is ensured by the test indices_are_correct().)
references:- 30
libsyntax/ast.rs:
libsyntax/ast_map.rs:
libsyntax/visit.rs:
libsyntax/parse/parser.rs:
libsyntax/print/pprust.rs:
libsyntax/abi.rs:


libsyntax/abi.rs:36:16-36:16 -enum- definition:
pub enum Architecture {
    // NB. You cannot change the ordering of these
    // constants without adjusting IntelBits below.
references:- 5
133:     pub fn for_target(&self, os: Os, arch: Architecture) -> Option<Abi> {
134:         // If this ABI isn't actually for the specified architecture, then we
--
150: impl Architecture {
151:     fn bit(&self) -> u32 {


libsyntax/abi.rs:13:16-13:16 -enum- definition:
pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, }
pub enum Abi {
    // NB: This ordering MUST match the AbiDatas array below.
references:- 4
14: pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, }
--
133:     pub fn for_target(&self, os: Os, arch: Architecture) -> Option<Abi> {
134:         // If this ABI isn't actually for the specified architecture, then we


libsyntax/abi.rs:49:1-49:1 -struct- definition:
pub struct AbiData {
    abi: Abi,
    // Name of this ABI as we like it called.
references:- 11
79:     // adjusting the indices below.
80:     AbiData {abi: Rust, name: "Rust", abi_arch: RustArch},
81:     AbiData {abi: C, name: "C", abi_arch: AllArch},
82:     AbiData {abi: System, name: "system", abi_arch: AllArch},
83:     AbiData {abi: RustIntrinsic, name: "rust-intrinsic", abi_arch: RustArch},
84: ];
--
124:     #[inline]
125:     pub fn data(&self) -> &'static AbiData {
126:         &AbiDatas[self.index()]