2013-01-25 16:56:56 -06:00
|
|
|
// Copyright 2012 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.
|
|
|
|
|
2014-11-06 02:05:53 -06:00
|
|
|
pub use self::ArgKind::*;
|
|
|
|
|
2014-07-07 19:58:01 -05:00
|
|
|
use llvm::Attribute;
|
2013-06-28 17:32:26 -05:00
|
|
|
use std::option;
|
2014-11-15 19:30:33 -06:00
|
|
|
use trans::context::CrateContext;
|
|
|
|
use trans::cabi_x86;
|
|
|
|
use trans::cabi_x86_64;
|
|
|
|
use trans::cabi_x86_win64;
|
|
|
|
use trans::cabi_arm;
|
|
|
|
use trans::cabi_mips;
|
|
|
|
use trans::type_::Type;
|
2013-01-25 16:56:56 -06:00
|
|
|
|
2014-05-29 19:45:07 -05:00
|
|
|
#[deriving(Clone, PartialEq)]
|
2013-09-25 05:30:44 -05:00
|
|
|
pub enum ArgKind {
|
|
|
|
/// Pass the argument directly using the normal converted
|
|
|
|
/// LLVM type or by coercing to another specified type
|
|
|
|
Direct,
|
|
|
|
/// Pass the argument indirectly via a hidden pointer
|
2014-03-09 00:42:22 -06:00
|
|
|
Indirect,
|
|
|
|
/// Ignore the argument (useful for empty struct)
|
|
|
|
Ignore,
|
2013-09-25 05:30:44 -05:00
|
|
|
}
|
|
|
|
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 19:01:33 -06:00
|
|
|
impl Copy for ArgKind {}
|
|
|
|
|
2013-09-25 05:30:44 -05:00
|
|
|
/// Information about how a specific C type
|
|
|
|
/// should be passed to or returned from a function
|
|
|
|
///
|
|
|
|
/// This is borrowed from clang's ABIInfo.h
|
2013-07-02 14:47:32 -05:00
|
|
|
#[deriving(Clone)]
|
2013-09-25 05:30:44 -05:00
|
|
|
pub struct ArgType {
|
2014-03-28 12:05:27 -05:00
|
|
|
pub kind: ArgKind,
|
2013-09-25 05:30:44 -05:00
|
|
|
/// Original LLVM type
|
2014-03-28 12:05:27 -05:00
|
|
|
pub ty: Type,
|
2013-09-25 05:30:44 -05:00
|
|
|
/// Coerced LLVM Type
|
2014-03-28 12:05:27 -05:00
|
|
|
pub cast: option::Option<Type>,
|
2013-09-25 05:30:44 -05:00
|
|
|
/// Dummy argument, which is emitted before the real argument
|
2014-03-28 12:05:27 -05:00
|
|
|
pub pad: option::Option<Type>,
|
2013-09-25 05:30:44 -05:00
|
|
|
/// LLVM attribute of argument
|
2014-03-28 12:05:27 -05:00
|
|
|
pub attr: option::Option<Attribute>
|
2013-09-25 05:30:44 -05:00
|
|
|
}
|
|
|
|
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 19:01:33 -06:00
|
|
|
impl Copy for ArgType {}
|
|
|
|
|
2013-09-25 05:30:44 -05:00
|
|
|
impl ArgType {
|
|
|
|
pub fn direct(ty: Type, cast: option::Option<Type>,
|
|
|
|
pad: option::Option<Type>,
|
|
|
|
attr: option::Option<Attribute>) -> ArgType {
|
|
|
|
ArgType {
|
|
|
|
kind: Direct,
|
|
|
|
ty: ty,
|
|
|
|
cast: cast,
|
|
|
|
pad: pad,
|
|
|
|
attr: attr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn indirect(ty: Type, attr: option::Option<Attribute>) -> ArgType {
|
|
|
|
ArgType {
|
|
|
|
kind: Indirect,
|
|
|
|
ty: ty,
|
2014-11-28 10:57:41 -06:00
|
|
|
cast: option::Option::None,
|
|
|
|
pad: option::Option::None,
|
2013-09-25 05:30:44 -05:00
|
|
|
attr: attr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:42:22 -06:00
|
|
|
pub fn ignore(ty: Type) -> ArgType {
|
|
|
|
ArgType {
|
|
|
|
kind: Ignore,
|
|
|
|
ty: ty,
|
|
|
|
cast: None,
|
|
|
|
pad: None,
|
|
|
|
attr: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-25 05:30:44 -05:00
|
|
|
pub fn is_indirect(&self) -> bool {
|
|
|
|
return self.kind == Indirect;
|
|
|
|
}
|
2014-03-09 00:42:22 -06:00
|
|
|
|
|
|
|
pub fn is_ignore(&self) -> bool {
|
|
|
|
return self.kind == Ignore;
|
|
|
|
}
|
2013-01-25 16:56:56 -06:00
|
|
|
}
|
|
|
|
|
2013-05-21 14:25:44 -05:00
|
|
|
/// Metadata describing how the arguments to a native function
|
|
|
|
/// should be passed in order to respect the native ABI.
|
|
|
|
///
|
|
|
|
/// I will do my best to describe this structure, but these
|
|
|
|
/// comments are reverse-engineered and may be inaccurate. -NDM
|
2013-01-30 13:46:19 -06:00
|
|
|
pub struct FnType {
|
2013-09-25 05:30:44 -05:00
|
|
|
/// The LLVM types of each argument.
|
2014-03-28 12:05:27 -05:00
|
|
|
pub arg_tys: Vec<ArgType> ,
|
2013-01-25 16:56:56 -06:00
|
|
|
|
2013-05-21 14:25:44 -05:00
|
|
|
/// LLVM return type.
|
2014-03-28 12:05:27 -05:00
|
|
|
pub ret_ty: ArgType,
|
2013-05-21 14:25:44 -05:00
|
|
|
}
|
2013-04-18 17:53:29 -05:00
|
|
|
|
2013-12-19 18:47:15 -06:00
|
|
|
pub fn compute_abi_info(ccx: &CrateContext,
|
2013-05-21 14:25:44 -05:00
|
|
|
atys: &[Type],
|
|
|
|
rty: Type,
|
|
|
|
ret_def: bool) -> FnType {
|
2014-07-23 13:56:36 -05:00
|
|
|
match ccx.sess().target.target.arch.as_slice() {
|
|
|
|
"x86" => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def),
|
|
|
|
"x86_64" => if ccx.sess().target.target.options.is_like_windows {
|
|
|
|
cabi_x86_win64::compute_abi_info(ccx, atys, rty, ret_def)
|
|
|
|
} else {
|
|
|
|
cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def)
|
|
|
|
},
|
|
|
|
"arm" => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def),
|
|
|
|
"mips" => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
|
|
|
|
a => ccx.sess().fatal((format!("unrecognized arch \"{}\" in target specification", a))
|
|
|
|
.as_slice()),
|
2013-01-25 16:56:56 -06:00
|
|
|
}
|
|
|
|
}
|