rustc_target: move in type definitions from rustc_trans::abi.
This commit is contained in:
parent
bdcd08278a
commit
3bd7efadae
10 changed files with 243 additions and 213 deletions
3
src/Cargo.lock
generated
3
src/Cargo.lock
generated
|
@ -2115,8 +2115,8 @@ dependencies = [
|
|||
name = "rustc_target"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serialize 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
]
|
||||
|
@ -2138,7 +2138,6 @@ dependencies = [
|
|||
name = "rustc_trans"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -9,10 +9,10 @@ path = "lib.rs"
|
|||
crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
log = "0.4"
|
||||
syntax = { path = "../libsyntax" }
|
||||
serialize = { path = "../libserialize" }
|
||||
log = "0.4"
|
||||
rand = "0.4"
|
||||
|
||||
[features]
|
||||
jemalloc = []
|
||||
|
|
214
src/librustc_target/abi/call.rs
Normal file
214
src/librustc_target/abi/call.rs
Normal file
|
@ -0,0 +1,214 @@
|
|||
// Copyright 2017 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.
|
||||
|
||||
use abi::{Align, HasDataLayout, Size};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum PassMode {
|
||||
/// Ignore the argument (useful for empty struct).
|
||||
Ignore,
|
||||
/// Pass the argument directly.
|
||||
Direct(ArgAttributes),
|
||||
/// Pass a pair's elements directly in two arguments.
|
||||
Pair(ArgAttributes, ArgAttributes),
|
||||
/// Pass the argument after casting it, to either
|
||||
/// a single uniform or a pair of registers.
|
||||
Cast(CastTarget),
|
||||
/// Pass the argument indirectly via a hidden pointer.
|
||||
Indirect(ArgAttributes),
|
||||
}
|
||||
|
||||
// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
|
||||
// of this module
|
||||
pub use self::attr_impl::ArgAttribute;
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(unused)]
|
||||
mod attr_impl {
|
||||
// The subset of llvm::Attribute needed for arguments, packed into a bitfield.
|
||||
bitflags! {
|
||||
#[derive(Default)]
|
||||
pub struct ArgAttribute: u16 {
|
||||
const ByVal = 1 << 0;
|
||||
const NoAlias = 1 << 1;
|
||||
const NoCapture = 1 << 2;
|
||||
const NonNull = 1 << 3;
|
||||
const ReadOnly = 1 << 4;
|
||||
const SExt = 1 << 5;
|
||||
const StructRet = 1 << 6;
|
||||
const ZExt = 1 << 7;
|
||||
const InReg = 1 << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A compact representation of LLVM attributes (at least those relevant for this module)
|
||||
/// that can be manipulated without interacting with LLVM's Attribute machinery.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct ArgAttributes {
|
||||
pub regular: ArgAttribute,
|
||||
pub pointee_size: Size,
|
||||
pub pointee_align: Option<Align>
|
||||
}
|
||||
|
||||
impl ArgAttributes {
|
||||
pub fn new() -> Self {
|
||||
ArgAttributes {
|
||||
regular: ArgAttribute::default(),
|
||||
pointee_size: Size::from_bytes(0),
|
||||
pointee_align: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, attr: ArgAttribute) -> &mut Self {
|
||||
self.regular = self.regular | attr;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn contains(&self, attr: ArgAttribute) -> bool {
|
||||
self.regular.contains(attr)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum RegKind {
|
||||
Integer,
|
||||
Float,
|
||||
Vector
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Reg {
|
||||
pub kind: RegKind,
|
||||
pub size: Size,
|
||||
}
|
||||
|
||||
macro_rules! reg_ctor {
|
||||
($name:ident, $kind:ident, $bits:expr) => {
|
||||
pub fn $name() -> Reg {
|
||||
Reg {
|
||||
kind: RegKind::$kind,
|
||||
size: Size::from_bits($bits)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Reg {
|
||||
reg_ctor!(i8, Integer, 8);
|
||||
reg_ctor!(i16, Integer, 16);
|
||||
reg_ctor!(i32, Integer, 32);
|
||||
reg_ctor!(i64, Integer, 64);
|
||||
|
||||
reg_ctor!(f32, Float, 32);
|
||||
reg_ctor!(f64, Float, 64);
|
||||
}
|
||||
|
||||
impl Reg {
|
||||
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
|
||||
let dl = cx.data_layout();
|
||||
match self.kind {
|
||||
RegKind::Integer => {
|
||||
match self.size.bits() {
|
||||
1 => dl.i1_align,
|
||||
2...8 => dl.i8_align,
|
||||
9...16 => dl.i16_align,
|
||||
17...32 => dl.i32_align,
|
||||
33...64 => dl.i64_align,
|
||||
65...128 => dl.i128_align,
|
||||
_ => panic!("unsupported integer: {:?}", self)
|
||||
}
|
||||
}
|
||||
RegKind::Float => {
|
||||
match self.size.bits() {
|
||||
32 => dl.f32_align,
|
||||
64 => dl.f64_align,
|
||||
_ => panic!("unsupported float: {:?}", self)
|
||||
}
|
||||
}
|
||||
RegKind::Vector => dl.vector_align(self.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An argument passed entirely registers with the
|
||||
/// same kind (e.g. HFA / HVA on PPC64 and AArch64).
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct Uniform {
|
||||
pub unit: Reg,
|
||||
|
||||
/// The total size of the argument, which can be:
|
||||
/// * equal to `unit.size` (one scalar/vector)
|
||||
/// * a multiple of `unit.size` (an array of scalar/vectors)
|
||||
/// * if `unit.kind` is `Integer`, the last element
|
||||
/// can be shorter, i.e. `{ i64, i64, i32 }` for
|
||||
/// 64-bit integers with a total size of 20 bytes
|
||||
pub total: Size,
|
||||
}
|
||||
|
||||
impl From<Reg> for Uniform {
|
||||
fn from(unit: Reg) -> Uniform {
|
||||
Uniform {
|
||||
unit,
|
||||
total: unit.size
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Uniform {
|
||||
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
|
||||
self.unit.align(cx)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct CastTarget {
|
||||
pub prefix: [Option<RegKind>; 8],
|
||||
pub prefix_chunk: Size,
|
||||
pub rest: Uniform,
|
||||
}
|
||||
|
||||
impl From<Reg> for CastTarget {
|
||||
fn from(unit: Reg) -> CastTarget {
|
||||
CastTarget::from(Uniform::from(unit))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Uniform> for CastTarget {
|
||||
fn from(uniform: Uniform) -> CastTarget {
|
||||
CastTarget {
|
||||
prefix: [None; 8],
|
||||
prefix_chunk: Size::from_bytes(0),
|
||||
rest: uniform
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CastTarget {
|
||||
pub fn pair(a: Reg, b: Reg) -> CastTarget {
|
||||
CastTarget {
|
||||
prefix: [Some(a.kind), None, None, None, None, None, None, None],
|
||||
prefix_chunk: a.size,
|
||||
rest: Uniform::from(b)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size<C: HasDataLayout>(&self, cx: C) -> Size {
|
||||
(self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64)
|
||||
.abi_align(self.rest.align(cx)) + self.rest.total
|
||||
}
|
||||
|
||||
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
|
||||
self.prefix.iter()
|
||||
.filter_map(|x| x.map(|kind| Reg { kind: kind, size: self.prefix_chunk }.align(cx)))
|
||||
.fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)),
|
||||
|acc, align| acc.max(align))
|
||||
}
|
||||
}
|
|
@ -16,6 +16,8 @@ use spec::Target;
|
|||
use std::cmp;
|
||||
use std::ops::{Add, Sub, Mul, AddAssign, RangeInclusive};
|
||||
|
||||
pub mod call;
|
||||
|
||||
/// Parsed [Data layout](http://llvm.org/docs/LangRef.html#data-layout)
|
||||
/// for a target, which contains everything needed to compute layouts.
|
||||
pub struct TargetDataLayout {
|
||||
|
|
|
@ -31,8 +31,9 @@
|
|||
#![feature(inclusive_range)]
|
||||
#![feature(slice_patterns)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
extern crate syntax;
|
||||
extern crate rand;
|
||||
extern crate serialize;
|
||||
#[macro_use] extern crate log;
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ crate-type = ["dylib"]
|
|||
test = false
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
cc = "1.0.1"
|
||||
flate2 = "1.0"
|
||||
jobserver = "0.1.5"
|
||||
|
|
|
@ -37,53 +37,14 @@ use type_::Type;
|
|||
use type_of::{LayoutLlvmExt, PointerKind};
|
||||
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{self, Align, Size, TyLayout};
|
||||
use rustc::ty::layout::{HasDataLayout, LayoutOf};
|
||||
use rustc::ty::layout::{self, LayoutOf, Size, TyLayout};
|
||||
|
||||
use libc::c_uint;
|
||||
use std::cmp;
|
||||
|
||||
pub use syntax::abi::Abi;
|
||||
pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum PassMode {
|
||||
/// Ignore the argument (useful for empty struct).
|
||||
Ignore,
|
||||
/// Pass the argument directly.
|
||||
Direct(ArgAttributes),
|
||||
/// Pass a pair's elements directly in two arguments.
|
||||
Pair(ArgAttributes, ArgAttributes),
|
||||
/// Pass the argument after casting it, to either
|
||||
/// a single uniform or a pair of registers.
|
||||
Cast(CastTarget),
|
||||
/// Pass the argument indirectly via a hidden pointer.
|
||||
Indirect(ArgAttributes),
|
||||
}
|
||||
|
||||
// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
|
||||
// of this module
|
||||
pub use self::attr_impl::ArgAttribute;
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(unused)]
|
||||
mod attr_impl {
|
||||
// The subset of llvm::Attribute needed for arguments, packed into a bitfield.
|
||||
bitflags! {
|
||||
#[derive(Default)]
|
||||
pub struct ArgAttribute: u16 {
|
||||
const ByVal = 1 << 0;
|
||||
const NoAlias = 1 << 1;
|
||||
const NoCapture = 1 << 2;
|
||||
const NonNull = 1 << 3;
|
||||
const ReadOnly = 1 << 4;
|
||||
const SExt = 1 << 5;
|
||||
const StructRet = 1 << 6;
|
||||
const ZExt = 1 << 7;
|
||||
const InReg = 1 << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use rustc_target::abi::call::*;
|
||||
|
||||
macro_rules! for_each_kind {
|
||||
($flags: ident, $f: ident, $($kind: ident),+) => ({
|
||||
|
@ -91,41 +52,24 @@ macro_rules! for_each_kind {
|
|||
})
|
||||
}
|
||||
|
||||
impl ArgAttribute {
|
||||
trait ArgAttributeExt {
|
||||
fn for_each_kind<F>(&self, f: F) where F: FnMut(llvm::Attribute);
|
||||
}
|
||||
|
||||
impl ArgAttributeExt for ArgAttribute {
|
||||
fn for_each_kind<F>(&self, mut f: F) where F: FnMut(llvm::Attribute) {
|
||||
for_each_kind!(self, f,
|
||||
ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg)
|
||||
}
|
||||
}
|
||||
|
||||
/// A compact representation of LLVM attributes (at least those relevant for this module)
|
||||
/// that can be manipulated without interacting with LLVM's Attribute machinery.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct ArgAttributes {
|
||||
regular: ArgAttribute,
|
||||
pointee_size: Size,
|
||||
pointee_align: Option<Align>
|
||||
pub trait ArgAttributesExt {
|
||||
fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef);
|
||||
fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef);
|
||||
}
|
||||
|
||||
impl ArgAttributes {
|
||||
fn new() -> Self {
|
||||
ArgAttributes {
|
||||
regular: ArgAttribute::default(),
|
||||
pointee_size: Size::from_bytes(0),
|
||||
pointee_align: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, attr: ArgAttribute) -> &mut Self {
|
||||
self.regular = self.regular | attr;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn contains(&self, attr: ArgAttribute) -> bool {
|
||||
self.regular.contains(attr)
|
||||
}
|
||||
|
||||
pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
|
||||
impl ArgAttributesExt for ArgAttributes {
|
||||
fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
|
||||
let mut regular = self.regular;
|
||||
unsafe {
|
||||
let deref = self.pointee_size.bytes();
|
||||
|
@ -150,7 +94,7 @@ impl ArgAttributes {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
|
||||
fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
|
||||
let mut regular = self.regular;
|
||||
unsafe {
|
||||
let deref = self.pointee_size.bytes();
|
||||
|
@ -175,67 +119,13 @@ impl ArgAttributes {
|
|||
}
|
||||
}
|
||||
}
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum RegKind {
|
||||
Integer,
|
||||
Float,
|
||||
Vector
|
||||
|
||||
pub trait LlvmType {
|
||||
fn llvm_type(&self, cx: &CodegenCx) -> Type;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Reg {
|
||||
pub kind: RegKind,
|
||||
pub size: Size,
|
||||
}
|
||||
|
||||
macro_rules! reg_ctor {
|
||||
($name:ident, $kind:ident, $bits:expr) => {
|
||||
pub fn $name() -> Reg {
|
||||
Reg {
|
||||
kind: RegKind::$kind,
|
||||
size: Size::from_bits($bits)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Reg {
|
||||
reg_ctor!(i8, Integer, 8);
|
||||
reg_ctor!(i16, Integer, 16);
|
||||
reg_ctor!(i32, Integer, 32);
|
||||
reg_ctor!(i64, Integer, 64);
|
||||
|
||||
reg_ctor!(f32, Float, 32);
|
||||
reg_ctor!(f64, Float, 64);
|
||||
}
|
||||
|
||||
impl Reg {
|
||||
pub fn align(&self, cx: &CodegenCx) -> Align {
|
||||
let dl = cx.data_layout();
|
||||
match self.kind {
|
||||
RegKind::Integer => {
|
||||
match self.size.bits() {
|
||||
1 => dl.i1_align,
|
||||
2...8 => dl.i8_align,
|
||||
9...16 => dl.i16_align,
|
||||
17...32 => dl.i32_align,
|
||||
33...64 => dl.i64_align,
|
||||
65...128 => dl.i128_align,
|
||||
_ => bug!("unsupported integer: {:?}", self)
|
||||
}
|
||||
}
|
||||
RegKind::Float => {
|
||||
match self.size.bits() {
|
||||
32 => dl.f32_align,
|
||||
64 => dl.f64_align,
|
||||
_ => bug!("unsupported float: {:?}", self)
|
||||
}
|
||||
}
|
||||
RegKind::Vector => dl.vector_align(self.size)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn llvm_type(&self, cx: &CodegenCx) -> Type {
|
||||
impl LlvmType for Reg {
|
||||
fn llvm_type(&self, cx: &CodegenCx) -> Type {
|
||||
match self.kind {
|
||||
RegKind::Integer => Type::ix(cx, self.size.bits()),
|
||||
RegKind::Float => {
|
||||
|
@ -252,36 +142,6 @@ impl Reg {
|
|||
}
|
||||
}
|
||||
|
||||
/// An argument passed entirely registers with the
|
||||
/// same kind (e.g. HFA / HVA on PPC64 and AArch64).
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct Uniform {
|
||||
pub unit: Reg,
|
||||
|
||||
/// The total size of the argument, which can be:
|
||||
/// * equal to `unit.size` (one scalar/vector)
|
||||
/// * a multiple of `unit.size` (an array of scalar/vectors)
|
||||
/// * if `unit.kind` is `Integer`, the last element
|
||||
/// can be shorter, i.e. `{ i64, i64, i32 }` for
|
||||
/// 64-bit integers with a total size of 20 bytes
|
||||
pub total: Size,
|
||||
}
|
||||
|
||||
impl From<Reg> for Uniform {
|
||||
fn from(unit: Reg) -> Uniform {
|
||||
Uniform {
|
||||
unit,
|
||||
total: unit.size
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Uniform {
|
||||
pub fn align(&self, cx: &CodegenCx) -> Align {
|
||||
self.unit.align(cx)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LayoutExt<'tcx> {
|
||||
fn is_aggregate(&self) -> bool;
|
||||
fn homogeneous_aggregate<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option<Reg>;
|
||||
|
@ -381,51 +241,8 @@ impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct CastTarget {
|
||||
pub prefix: [Option<RegKind>; 8],
|
||||
pub prefix_chunk: Size,
|
||||
pub rest: Uniform,
|
||||
}
|
||||
|
||||
impl From<Reg> for CastTarget {
|
||||
fn from(unit: Reg) -> CastTarget {
|
||||
CastTarget::from(Uniform::from(unit))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Uniform> for CastTarget {
|
||||
fn from(uniform: Uniform) -> CastTarget {
|
||||
CastTarget {
|
||||
prefix: [None; 8],
|
||||
prefix_chunk: Size::from_bytes(0),
|
||||
rest: uniform
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CastTarget {
|
||||
pub fn pair(a: Reg, b: Reg) -> CastTarget {
|
||||
CastTarget {
|
||||
prefix: [Some(a.kind), None, None, None, None, None, None, None],
|
||||
prefix_chunk: a.size,
|
||||
rest: Uniform::from(b)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(&self, cx: &CodegenCx) -> Size {
|
||||
(self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64)
|
||||
.abi_align(self.rest.align(cx)) + self.rest.total
|
||||
}
|
||||
|
||||
pub fn align(&self, cx: &CodegenCx) -> Align {
|
||||
self.prefix.iter()
|
||||
.filter_map(|x| x.map(|kind| Reg { kind: kind, size: self.prefix_chunk }.align(cx)))
|
||||
.fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)),
|
||||
|acc, align| acc.max(align))
|
||||
}
|
||||
|
||||
pub fn llvm_type(&self, cx: &CodegenCx) -> Type {
|
||||
impl LlvmType for CastTarget {
|
||||
fn llvm_type(&self, cx: &CodegenCx) -> Type {
|
||||
let rest_ll_unit = self.rest.unit.llvm_type(cx);
|
||||
let rest_count = self.rest.total.bytes() / self.rest.unit.size.bytes();
|
||||
let rem_bytes = self.rest.total.bytes() % self.rest.unit.size.bytes();
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
use intrinsics::{self, Intrinsic};
|
||||
use llvm;
|
||||
use llvm::{ValueRef};
|
||||
use abi::{Abi, FnType, PassMode};
|
||||
use abi::{Abi, FnType, LlvmType, PassMode};
|
||||
use mir::place::PlaceRef;
|
||||
use mir::operand::{OperandRef, OperandValue};
|
||||
use base::*;
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
use rustc::dep_graph::WorkProduct;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
extern crate flate2;
|
||||
extern crate libc;
|
||||
#[macro_use] extern crate rustc;
|
||||
|
|
|
@ -13,7 +13,7 @@ use rustc::middle::lang_items;
|
|||
use rustc::ty::{self, TypeFoldable};
|
||||
use rustc::ty::layout::{self, LayoutOf};
|
||||
use rustc::mir;
|
||||
use abi::{Abi, FnType, ArgType, PassMode};
|
||||
use abi::{Abi, FnType, ArgType, LlvmType, PassMode};
|
||||
use base;
|
||||
use callee;
|
||||
use builder::Builder;
|
||||
|
|
Loading…
Add table
Reference in a new issue