about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-03-06 14:17:53 +0200
committerEduard Burtescu <edy.burt@gmail.com>2016-03-17 21:51:52 +0200
commit6c0674e613a708e25d9ae92de4ae4bc5756805c4 (patch)
tree37428d4c59bf9344e88c6b0176641bf466d82449
parentaec63821d04872f9190c3d8606d0a58428005222 (diff)
trans: Remove the foreign module.
-rw-r--r--src/librustc_trans/trans/base.rs13
-rw-r--r--src/librustc_trans/trans/callee.rs3
-rw-r--r--src/librustc_trans/trans/consts.rs65
-rw-r--r--src/librustc_trans/trans/foreign.rs100
-rw-r--r--src/librustc_trans/trans/mod.rs1
-rw-r--r--src/test/compile-fail/dupe-symbols-8.rs23
-rw-r--r--src/test/compile-fail/linkage2.rs2
-rw-r--r--src/test/run-pass/unique-ffi-symbols.rs25
8 files changed, 97 insertions, 135 deletions
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 6d760069cc1..eea53eabec6 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 042f81542d6..578d495e9b8 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 31ad7054996..5969fa6423f 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 92a50ac3181..00000000000
--- 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 <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(),
-        }
-    }
-}
diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs
index ff5ed35b8c0..c5ab0d4e744 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 3c0e545e193..00000000000
--- 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 <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() {}
-    }
-}
diff --git a/src/test/compile-fail/linkage2.rs b/src/test/compile-fail/linkage2.rs
index edbeebe882e..2a127d937ea 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 00000000000..81563f40e94
--- /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 <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));
+}