trans: Remove the foreign module.
This commit is contained in:
parent
aec63821d0
commit
6c0674e613
8 changed files with 97 additions and 135 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -49,7 +49,6 @@ mod debuginfo;
|
|||
mod declare;
|
||||
mod disr;
|
||||
mod expr;
|
||||
mod foreign;
|
||||
mod glue;
|
||||
mod inline;
|
||||
mod intrinsic;
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
}
|
||||
}
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
25
src/test/run-pass/unique-ffi-symbols.rs
Normal file
25
src/test/run-pass/unique-ffi-symbols.rs
Normal 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));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue