trans: Remove the foreign module.

This commit is contained in:
Eduard Burtescu 2016-03-06 14:17:53 +02:00
parent aec63821d0
commit 6c0674e613
8 changed files with 97 additions and 135 deletions

View file

@ -76,7 +76,6 @@ use trans::datum;
use trans::debuginfo::{self, DebugLoc, ToDebugLoc};
use trans::declare;
use trans::expr;
use trans::foreign;
use trans::glue;
use trans::intrinsic;
use trans::machine;
@ -2311,7 +2310,7 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
return;
}
for fi in &m.items {
let lname = foreign::link_name(fi.name, &fi.attrs).to_string();
let lname = imported_name(fi.name, &fi.attrs).to_string();
ccx.item_symbols().borrow_mut().insert(fi.id, lname);
}
}
@ -2434,6 +2433,16 @@ pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
}
pub fn imported_name(name: ast::Name, attrs: &[ast::Attribute]) -> InternedString {
match attr::first_attr_value_str_by_name(attrs, "link_name") {
Some(ln) => ln.clone(),
None => match weak_lang_items::link_name(attrs) {
Some(name) => name,
None => name.as_str(),
}
}
}
fn contains_null(s: &str) -> bool {
s.bytes().any(|b| b == 0)
}

View file

@ -45,7 +45,6 @@ use trans::declare;
use trans::expr;
use trans::glue;
use trans::inline;
use trans::foreign;
use trans::intrinsic;
use trans::machine::{llalign_of_min, llsize_of_store};
use trans::meth;
@ -529,7 +528,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
Some(hir_map::NodeForeignItem(&hir::ForeignItem {
ref attrs, name, node: hir::ForeignItemFn(..), ..
})) => {
(foreign::link_name(name, attrs).to_string(), &attrs[..], None)
(imported_name(name, attrs).to_string(), &attrs[..], None)
}
None => {

View file

@ -19,7 +19,7 @@ use middle::def::Def;
use middle::def_id::DefId;
use rustc::front::map as hir_map;
use trans::{abi, adt, closure, debuginfo, expr, inline, machine};
use trans::base::{self, exported_name, push_ctxt};
use trans::base::{self, exported_name, imported_name, push_ctxt};
use trans::callee::Callee;
use trans::collector::{self, TransItem};
use trans::common::{type_is_sized, C_nil, const_get_elt};
@ -28,7 +28,6 @@ use trans::common::{C_struct, C_undef, const_to_opt_int, const_to_opt_uint, Vari
use trans::common::{type_is_fat_ptr, Field, C_vector, C_array, C_null};
use trans::datum::{Datum, Lvalue};
use trans::declare;
use trans::foreign;
use trans::monomorphize::{self, Instance};
use trans::type_::Type;
use trans::type_of;
@ -1029,6 +1028,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
}
let g = if let Some(id) = ccx.tcx().map.as_local_node_id(def_id) {
let llty = type_of::type_of(ccx, ty);
match ccx.tcx().map.get(id) {
hir_map::NodeItem(&hir::Item {
ref attrs, span, node: hir::ItemStatic(..), ..
@ -1042,7 +1042,6 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
// Create the global before evaluating the initializer;
// this is necessary to allow recursive statics.
let llty = type_of::type_of(ccx, ty);
let g = declare::define_global(ccx, &sym, llty).unwrap_or_else(|| {
ccx.sess().span_fatal(span,
&format!("symbol `{}` is already defined", sym))
@ -1052,9 +1051,63 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
g
}
hir_map::NodeForeignItem(ni @ &hir::ForeignItem {
node: hir::ForeignItemStatic(..), ..
}) => foreign::register_static(ccx, ni),
hir_map::NodeForeignItem(&hir::ForeignItem {
ref attrs, name, span, node: hir::ForeignItemStatic(..), ..
}) => {
let ident = imported_name(name, attrs);
let g = if let Some(name) =
attr::first_attr_value_str_by_name(&attrs, "linkage") {
// If this is a static with a linkage specified, then we need to handle
// it a little specially. The typesystem prevents things like &T and
// extern "C" fn() from being non-null, so we can't just declare a
// static and call it a day. Some linkages (like weak) will make it such
// that the static actually has a null value.
let linkage = match base::llvm_linkage_by_name(&name) {
Some(linkage) => linkage,
None => {
ccx.sess().span_fatal(span, "invalid linkage specified");
}
};
let llty2 = match ty.sty {
ty::TyRawPtr(ref mt) => type_of::type_of(ccx, mt.ty),
_ => {
ccx.sess().span_fatal(span, "must have type `*const T` or `*mut T`");
}
};
unsafe {
// Declare a symbol `foo` with the desired linkage.
let g1 = declare::declare_global(ccx, &ident, llty2);
llvm::SetLinkage(g1, linkage);
// Declare an internal global `extern_with_linkage_foo` which
// is initialized with the address of `foo`. If `foo` is
// discarded during linking (for example, if `foo` has weak
// linkage and there are no definitions), then
// `extern_with_linkage_foo` will instead be initialized to
// zero.
let mut real_name = "_rust_extern_with_linkage_".to_string();
real_name.push_str(&ident);
let g2 = declare::define_global(ccx, &real_name, llty).unwrap_or_else(||{
ccx.sess().span_fatal(span,
&format!("symbol `{}` is already defined", ident))
});
llvm::SetLinkage(g2, llvm::InternalLinkage);
llvm::LLVMSetInitializer(g2, g1);
g2
}
} else {
// Generate an external declaration.
declare::declare_global(ccx, &ident, llty)
};
for attr in attrs {
if attr.check_name("thread_local") {
llvm::set_thread_local(g, true);
}
}
g
}
item => unreachable!("get_static: expected static, found {:?}", item)
}

View file

@ -1,100 +0,0 @@
// Copyright 2012-2014 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 llvm::{ValueRef};
use llvm;
use middle::weak_lang_items;
use trans::base::{llvm_linkage_by_name};
use trans::common::*;
use trans::declare;
use trans::type_of;
use middle::ty;
use syntax::attr;
use syntax::parse::token::{InternedString};
use syntax::ast;
use syntax::attr::AttrMetaMethods;
use rustc_front::hir;
///////////////////////////////////////////////////////////////////////////
// Calls to external functions
pub fn register_static(ccx: &CrateContext,
foreign_item: &hir::ForeignItem) -> ValueRef {
let ty = ccx.tcx().node_id_to_type(foreign_item.id);
let llty = type_of::type_of(ccx, ty);
let ident = link_name(foreign_item.name, &foreign_item.attrs);
let c = match attr::first_attr_value_str_by_name(&foreign_item.attrs,
"linkage") {
// If this is a static with a linkage specified, then we need to handle
// it a little specially. The typesystem prevents things like &T and
// extern "C" fn() from being non-null, so we can't just declare a
// static and call it a day. Some linkages (like weak) will make it such
// that the static actually has a null value.
Some(name) => {
let linkage = match llvm_linkage_by_name(&name) {
Some(linkage) => linkage,
None => {
ccx.sess().span_fatal(foreign_item.span,
"invalid linkage specified");
}
};
let llty2 = match ty.sty {
ty::TyRawPtr(ref mt) => type_of::type_of(ccx, mt.ty),
_ => {
ccx.sess().span_fatal(foreign_item.span,
"must have type `*T` or `*mut T`");
}
};
unsafe {
// Declare a symbol `foo` with the desired linkage.
let g1 = declare::declare_global(ccx, &ident[..], llty2);
llvm::SetLinkage(g1, linkage);
// Declare an internal global `extern_with_linkage_foo` which
// is initialized with the address of `foo`. If `foo` is
// discarded during linking (for example, if `foo` has weak
// linkage and there are no definitions), then
// `extern_with_linkage_foo` will instead be initialized to
// zero.
let mut real_name = "_rust_extern_with_linkage_".to_string();
real_name.push_str(&ident);
let g2 = declare::define_global(ccx, &real_name[..], llty).unwrap_or_else(||{
ccx.sess().span_fatal(foreign_item.span,
&format!("symbol `{}` is already defined", ident))
});
llvm::SetLinkage(g2, llvm::InternalLinkage);
llvm::LLVMSetInitializer(g2, g1);
g2
}
}
None => // Generate an external declaration.
declare::declare_global(ccx, &ident[..], llty),
}
}
///////////////////////////////////////////////////////////////////////////
// General ABI Support
//
// This code is kind of a confused mess and needs to be reworked given
// the massive simplifications that have occurred.
pub fn link_name(name: ast::Name, attrs: &[ast::Attribute]) -> InternedString {
match attr::first_attr_value_str_by_name(attrs, "link_name") {
Some(ln) => ln.clone(),
None => match weak_lang_items::link_name(attrs) {
Some(name) => name,
None => name.as_str(),
}
}
}

View file

@ -49,7 +49,6 @@ mod debuginfo;
mod declare;
mod disr;
mod expr;
mod foreign;
mod glue;
mod inline;
mod intrinsic;

View file

@ -1,23 +0,0 @@
// Copyright 2015 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.
//
// error-pattern:already defined
#![allow(warnings)]
fn main() {
{
extern fn fail() {}
}
{
extern fn fail() {}
}
}

View file

@ -12,7 +12,7 @@
extern {
#[linkage = "extern_weak"] static foo: i32;
//~^ ERROR: must have type `*T`
//~^ ERROR: must have type `*const T` or `*mut T`
}
fn main() {

View file

@ -0,0 +1,25 @@
// 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.
// We used to have a __rust_abi shim that resulted in duplicated symbols
// whenever the item path wasn't enough to disambiguate between them.
fn main() {
let a = {
extern fn good() -> i32 { return 0; }
good as extern fn() -> i32
};
let b = {
extern fn good() -> i32 { return 5; }
good as extern fn() -> i32
};
assert!(a != b);
assert_eq!((a(), b()), (0, 5));
}