From 6c0674e613a708e25d9ae92de4ae4bc5756805c4 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Sun, 6 Mar 2016 14:17:53 +0200 Subject: [PATCH] trans: Remove the foreign module. --- src/librustc_trans/trans/base.rs | 13 ++- src/librustc_trans/trans/callee.rs | 3 +- src/librustc_trans/trans/consts.rs | 65 +++++++++++++-- src/librustc_trans/trans/foreign.rs | 100 ------------------------ src/librustc_trans/trans/mod.rs | 1 - src/test/compile-fail/dupe-symbols-8.rs | 23 ------ src/test/compile-fail/linkage2.rs | 2 +- src/test/run-pass/unique-ffi-symbols.rs | 25 ++++++ 8 files changed, 97 insertions(+), 135 deletions(-) delete mode 100644 src/librustc_trans/trans/foreign.rs delete mode 100644 src/test/compile-fail/dupe-symbols-8.rs create mode 100644 src/test/run-pass/unique-ffi-symbols.rs diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 6d760069cc1f..eea53eabec6a 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -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) } diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 042f81542d64..578d495e9b8e 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -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 => { diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 31ad70549960..5969fa6423f2 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -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) } diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs deleted file mode 100644 index 92a50ac3181f..000000000000 --- a/src/librustc_trans/trans/foreign.rs +++ /dev/null @@ -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 or the MIT license -// , 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(), - } - } -} diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs index ff5ed35b8c08..c5ab0d4e7442 100644 --- a/src/librustc_trans/trans/mod.rs +++ b/src/librustc_trans/trans/mod.rs @@ -49,7 +49,6 @@ mod debuginfo; mod declare; mod disr; mod expr; -mod foreign; mod glue; mod inline; mod intrinsic; diff --git a/src/test/compile-fail/dupe-symbols-8.rs b/src/test/compile-fail/dupe-symbols-8.rs deleted file mode 100644 index 3c0e545e1933..000000000000 --- a/src/test/compile-fail/dupe-symbols-8.rs +++ /dev/null @@ -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 or the MIT license -// , 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() {} - } -} diff --git a/src/test/compile-fail/linkage2.rs b/src/test/compile-fail/linkage2.rs index edbeebe882e5..2a127d937eaa 100644 --- a/src/test/compile-fail/linkage2.rs +++ b/src/test/compile-fail/linkage2.rs @@ -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() { diff --git a/src/test/run-pass/unique-ffi-symbols.rs b/src/test/run-pass/unique-ffi-symbols.rs new file mode 100644 index 000000000000..81563f40e94b --- /dev/null +++ b/src/test/run-pass/unique-ffi-symbols.rs @@ -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 or the MIT license +// , 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)); +}