Auto merge of #37973 - vadimcn:dllimport, r=alexcrichton
Implement RFC 1717 Implement the first two points from #37403. r? @alexcrichton
This commit is contained in:
commit
1692c0b587
|
@ -131,6 +131,7 @@ pub struct NativeLibrary {
|
|||
pub kind: NativeLibraryKind,
|
||||
pub name: Symbol,
|
||||
pub cfg: Option<ast::MetaItem>,
|
||||
pub foreign_items: Vec<DefIndex>,
|
||||
}
|
||||
|
||||
/// The data we save and restore about an inlined item or method. This is not
|
||||
|
@ -305,7 +306,8 @@ pub trait CrateStore<'tcx> {
|
|||
fn is_defaulted_trait(&self, did: DefId) -> bool;
|
||||
fn is_default_impl(&self, impl_did: DefId) -> bool;
|
||||
fn is_foreign_item(&self, did: DefId) -> bool;
|
||||
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
|
||||
fn is_dllimport_foreign_item(&self, def: DefId) -> bool;
|
||||
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool;
|
||||
|
||||
// crate metadata
|
||||
fn dylib_dependency_formats(&self, cnum: CrateNum)
|
||||
|
@ -463,7 +465,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
|||
fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") }
|
||||
fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
|
||||
fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
|
||||
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
|
||||
fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false }
|
||||
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false }
|
||||
|
||||
// crate metadata
|
||||
fn dylib_dependency_formats(&self, cnum: CrateNum)
|
||||
|
@ -529,9 +532,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
|||
// This is basically a 1-based range of ints, which is a little
|
||||
// silly - I may fix that.
|
||||
fn crates(&self) -> Vec<CrateNum> { vec![] }
|
||||
fn used_libraries(&self) -> Vec<NativeLibrary> {
|
||||
vec![]
|
||||
}
|
||||
fn used_libraries(&self) -> Vec<NativeLibrary> { vec![] }
|
||||
fn used_link_args(&self) -> Vec<String> { vec![] }
|
||||
|
||||
// utility functions
|
||||
|
|
|
@ -262,7 +262,7 @@ top_level_options!(
|
|||
// much sense: The search path can stay the same while the
|
||||
// things discovered there might have changed on disk.
|
||||
search_paths: SearchPaths [TRACKED],
|
||||
libs: Vec<(String, cstore::NativeLibraryKind)> [TRACKED],
|
||||
libs: Vec<(String, Option<String>, cstore::NativeLibraryKind)> [TRACKED],
|
||||
maybe_sysroot: Option<PathBuf> [TRACKED],
|
||||
|
||||
target_triple: String [TRACKED],
|
||||
|
@ -1449,6 +1449,8 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
|
|||
}
|
||||
|
||||
let libs = matches.opt_strs("l").into_iter().map(|s| {
|
||||
// Parse string of the form "[KIND=]lib[:new_name]",
|
||||
// where KIND is one of "dylib", "framework", "static".
|
||||
let mut parts = s.splitn(2, '=');
|
||||
let kind = parts.next().unwrap();
|
||||
let (name, kind) = match (parts.next(), kind) {
|
||||
|
@ -1462,7 +1464,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
|
|||
s));
|
||||
}
|
||||
};
|
||||
(name.to_string(), kind)
|
||||
let mut name_parts = name.splitn(2, ':');
|
||||
let name = name_parts.next().unwrap();
|
||||
let new_name = name_parts.next();
|
||||
(name.to_string(), new_name.map(|n| n.to_string()), kind)
|
||||
}).collect();
|
||||
|
||||
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
|
||||
|
@ -1728,8 +1733,8 @@ mod dep_tracking {
|
|||
impl_dep_tracking_hash_for_sortable_vec_of!(String);
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!(CrateType);
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!((String, lint::Level));
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!((String, cstore::NativeLibraryKind));
|
||||
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!((String, Option<String>,
|
||||
cstore::NativeLibraryKind));
|
||||
impl DepTrackingHash for SearchPaths {
|
||||
fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) {
|
||||
let mut elems: Vec<_> = self
|
||||
|
@ -1752,6 +1757,21 @@ mod dep_tracking {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
|
||||
where T1: DepTrackingHash,
|
||||
T2: DepTrackingHash,
|
||||
T3: DepTrackingHash
|
||||
{
|
||||
fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
|
||||
Hash::hash(&0, hasher);
|
||||
DepTrackingHash::hash(&self.0, hasher, error_format);
|
||||
Hash::hash(&1, hasher);
|
||||
DepTrackingHash::hash(&self.1, hasher, error_format);
|
||||
Hash::hash(&2, hasher);
|
||||
DepTrackingHash::hash(&self.2, hasher, error_format);
|
||||
}
|
||||
}
|
||||
|
||||
// This is a stable hash because BTreeMap is a sorted container
|
||||
pub fn stable_hash(sub_hashes: BTreeMap<&'static str, &DepTrackingHash>,
|
||||
hasher: &mut DefaultHasher,
|
||||
|
@ -2155,29 +2175,37 @@ mod tests {
|
|||
let mut v1 = super::basic_options();
|
||||
let mut v2 = super::basic_options();
|
||||
let mut v3 = super::basic_options();
|
||||
let mut v4 = super::basic_options();
|
||||
|
||||
// Reference
|
||||
v1.libs = vec![(String::from("a"), cstore::NativeStatic),
|
||||
(String::from("b"), cstore::NativeFramework),
|
||||
(String::from("c"), cstore::NativeUnknown)];
|
||||
v1.libs = vec![(String::from("a"), None, cstore::NativeStatic),
|
||||
(String::from("b"), None, cstore::NativeFramework),
|
||||
(String::from("c"), None, cstore::NativeUnknown)];
|
||||
|
||||
// Change label
|
||||
v2.libs = vec![(String::from("a"), cstore::NativeStatic),
|
||||
(String::from("X"), cstore::NativeFramework),
|
||||
(String::from("c"), cstore::NativeUnknown)];
|
||||
v2.libs = vec![(String::from("a"), None, cstore::NativeStatic),
|
||||
(String::from("X"), None, cstore::NativeFramework),
|
||||
(String::from("c"), None, cstore::NativeUnknown)];
|
||||
|
||||
// Change kind
|
||||
v3.libs = vec![(String::from("a"), cstore::NativeStatic),
|
||||
(String::from("b"), cstore::NativeStatic),
|
||||
(String::from("c"), cstore::NativeUnknown)];
|
||||
v3.libs = vec![(String::from("a"), None, cstore::NativeStatic),
|
||||
(String::from("b"), None, cstore::NativeStatic),
|
||||
(String::from("c"), None, cstore::NativeUnknown)];
|
||||
|
||||
// Change new-name
|
||||
v4.libs = vec![(String::from("a"), None, cstore::NativeStatic),
|
||||
(String::from("b"), Some(String::from("X")), cstore::NativeFramework),
|
||||
(String::from("c"), None, cstore::NativeUnknown)];
|
||||
|
||||
assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash());
|
||||
assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash());
|
||||
assert!(v1.dep_tracking_hash() != v4.dep_tracking_hash());
|
||||
|
||||
// Check clone
|
||||
assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
|
||||
assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
|
||||
assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
|
||||
assert_eq!(v4.dep_tracking_hash(), v4.clone().dep_tracking_hash());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2187,17 +2215,17 @@ mod tests {
|
|||
let mut v3 = super::basic_options();
|
||||
|
||||
// Reference
|
||||
v1.libs = vec![(String::from("a"), cstore::NativeStatic),
|
||||
(String::from("b"), cstore::NativeFramework),
|
||||
(String::from("c"), cstore::NativeUnknown)];
|
||||
v1.libs = vec![(String::from("a"), None, cstore::NativeStatic),
|
||||
(String::from("b"), None, cstore::NativeFramework),
|
||||
(String::from("c"), None, cstore::NativeUnknown)];
|
||||
|
||||
v2.libs = vec![(String::from("b"), cstore::NativeFramework),
|
||||
(String::from("a"), cstore::NativeStatic),
|
||||
(String::from("c"), cstore::NativeUnknown)];
|
||||
v2.libs = vec![(String::from("b"), None, cstore::NativeFramework),
|
||||
(String::from("a"), None, cstore::NativeStatic),
|
||||
(String::from("c"), None, cstore::NativeUnknown)];
|
||||
|
||||
v3.libs = vec![(String::from("c"), cstore::NativeUnknown),
|
||||
(String::from("a"), cstore::NativeStatic),
|
||||
(String::from("b"), cstore::NativeFramework)];
|
||||
v3.libs = vec![(String::from("c"), None, cstore::NativeUnknown),
|
||||
(String::from("a"), None, cstore::NativeStatic),
|
||||
(String::from("b"), None, cstore::NativeFramework)];
|
||||
|
||||
assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash());
|
||||
assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash());
|
||||
|
|
|
@ -471,11 +471,9 @@ pub mod debuginfo {
|
|||
// generates an llvmdeps.rs file next to this one which will be
|
||||
// automatically updated whenever LLVM is updated to include an up-to-date
|
||||
// set of the libraries we need to link to LLVM for.
|
||||
#[link(name = "rustllvm", kind = "static")]
|
||||
#[cfg(not(cargobuild))]
|
||||
extern "C" {}
|
||||
|
||||
#[linked_from = "rustllvm"] // not quite true but good enough
|
||||
#[cfg_attr(not(all(stage0,cargobuild)),
|
||||
link(name = "rustllvm", kind = "static"))] // not quite true but good enough
|
||||
#[cfg_attr(stage0, linked_from = "rustllvm")]
|
||||
extern "C" {
|
||||
// Create and destroy contexts.
|
||||
pub fn LLVMContextCreate() -> ContextRef;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#![feature(concat_idents)]
|
||||
#![feature(libc)]
|
||||
#![feature(link_args)]
|
||||
#![feature(linked_from)]
|
||||
#![cfg_attr(stage0, feature(linked_from))]
|
||||
#![feature(staged_api)]
|
||||
#![cfg_attr(not(stage0), feature(rustc_private))]
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ use rustc_back::PanicStrategy;
|
|||
use rustc::session::search_paths::PathKind;
|
||||
use rustc::middle;
|
||||
use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
|
||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
||||
use rustc::util::nodemap::FxHashSet;
|
||||
use rustc::middle::cstore::NativeLibrary;
|
||||
use rustc::hir::map::Definitions;
|
||||
|
||||
|
@ -52,7 +52,6 @@ pub struct CrateLoader<'a> {
|
|||
pub sess: &'a Session,
|
||||
cstore: &'a CStore,
|
||||
next_crate_num: CrateNum,
|
||||
foreign_item_map: FxHashMap<String, Vec<ast::NodeId>>,
|
||||
local_crate_name: Symbol,
|
||||
}
|
||||
|
||||
|
@ -114,6 +113,13 @@ fn register_native_lib(sess: &Session,
|
|||
cstore.add_used_library(lib);
|
||||
}
|
||||
|
||||
fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool {
|
||||
match lib.cfg {
|
||||
Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, None),
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
|
||||
// Extra info about a crate loaded for plugins or exported macros.
|
||||
struct ExtensionCrate {
|
||||
metadata: PMDSource,
|
||||
|
@ -148,7 +154,6 @@ impl<'a> CrateLoader<'a> {
|
|||
sess: sess,
|
||||
cstore: cstore,
|
||||
next_crate_num: cstore.next_crate_num(),
|
||||
foreign_item_map: FxHashMap(),
|
||||
local_crate_name: Symbol::intern(local_crate_name),
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +297,7 @@ impl<'a> CrateLoader<'a> {
|
|||
|
||||
let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind);
|
||||
|
||||
let cmeta = Rc::new(cstore::CrateMetadata {
|
||||
let mut cmeta = cstore::CrateMetadata {
|
||||
name: name,
|
||||
extern_crate: Cell::new(None),
|
||||
key_map: metadata.load_key_map(crate_root.index),
|
||||
|
@ -310,8 +315,18 @@ impl<'a> CrateLoader<'a> {
|
|||
rlib: rlib,
|
||||
rmeta: rmeta,
|
||||
},
|
||||
});
|
||||
dllimport_foreign_items: FxHashSet(),
|
||||
};
|
||||
|
||||
let dllimports: Vec<_> = cmeta.get_native_libraries().iter()
|
||||
.filter(|lib| relevant_lib(self.sess, lib) &&
|
||||
lib.kind == cstore::NativeLibraryKind::NativeUnknown)
|
||||
.flat_map(|lib| &lib.foreign_items)
|
||||
.map(|id| *id)
|
||||
.collect();
|
||||
cmeta.dllimport_foreign_items.extend(dllimports);
|
||||
|
||||
let cmeta = Rc::new(cmeta);
|
||||
self.cstore.set_crate_data(cnum, cmeta.clone());
|
||||
(cnum, cmeta)
|
||||
}
|
||||
|
@ -640,18 +655,28 @@ impl<'a> CrateLoader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn register_statically_included_foreign_items(&mut self) {
|
||||
fn get_foreign_items_of_kind(&self, kind: cstore::NativeLibraryKind) -> Vec<DefIndex> {
|
||||
let mut items = vec![];
|
||||
let libs = self.cstore.get_used_libraries();
|
||||
for (foreign_lib, list) in self.foreign_item_map.iter() {
|
||||
let is_static = libs.borrow().iter().any(|lib| {
|
||||
lib.name == &**foreign_lib && lib.kind == cstore::NativeStatic
|
||||
});
|
||||
if is_static {
|
||||
for id in list {
|
||||
self.cstore.add_statically_included_foreign_item(*id);
|
||||
}
|
||||
for lib in libs.borrow().iter() {
|
||||
if relevant_lib(self.sess, lib) && lib.kind == kind {
|
||||
items.extend(&lib.foreign_items);
|
||||
}
|
||||
}
|
||||
items
|
||||
}
|
||||
|
||||
fn register_statically_included_foreign_items(&mut self) {
|
||||
for id in self.get_foreign_items_of_kind(cstore::NativeStatic) {
|
||||
self.cstore.add_statically_included_foreign_item(id);
|
||||
}
|
||||
}
|
||||
|
||||
fn register_dllimport_foreign_items(&mut self) {
|
||||
let mut dllimports = self.cstore.dllimport_foreign_items.borrow_mut();
|
||||
for id in self.get_foreign_items_of_kind(cstore::NativeUnknown) {
|
||||
dllimports.insert(id);
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
|
||||
|
@ -861,7 +886,8 @@ impl<'a> CrateLoader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) {
|
||||
fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod,
|
||||
definitions: &Definitions) {
|
||||
if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic {
|
||||
return;
|
||||
}
|
||||
|
@ -912,24 +938,17 @@ impl<'a> CrateLoader<'a> {
|
|||
let cfg = cfg.map(|list| {
|
||||
list[0].meta_item().unwrap().clone()
|
||||
});
|
||||
let foreign_items = fm.items.iter()
|
||||
.map(|it| definitions.opt_def_index(it.id).unwrap())
|
||||
.collect();
|
||||
let lib = NativeLibrary {
|
||||
name: n,
|
||||
kind: kind,
|
||||
cfg: cfg,
|
||||
foreign_items: foreign_items,
|
||||
};
|
||||
register_native_lib(self.sess, self.cstore, Some(m.span), lib);
|
||||
}
|
||||
|
||||
// Finally, process the #[linked_from = "..."] attribute
|
||||
for m in i.attrs.iter().filter(|a| a.check_name("linked_from")) {
|
||||
let lib_name = match m.value_str() {
|
||||
Some(name) => name,
|
||||
None => continue,
|
||||
};
|
||||
let list = self.foreign_item_map.entry(lib_name.to_string())
|
||||
.or_insert(Vec::new());
|
||||
list.extend(fm.items.iter().map(|it| it.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -942,35 +961,76 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
|
|||
dump_crates(&self.cstore);
|
||||
}
|
||||
|
||||
for &(ref name, kind) in &self.sess.opts.libs {
|
||||
let lib = NativeLibrary {
|
||||
name: Symbol::intern(name),
|
||||
kind: kind,
|
||||
cfg: None,
|
||||
};
|
||||
register_native_lib(self.sess, self.cstore, None, lib);
|
||||
// Process libs passed on the command line
|
||||
// First, check for errors
|
||||
let mut renames = FxHashSet();
|
||||
for &(ref name, ref new_name, _) in &self.sess.opts.libs {
|
||||
if let &Some(ref new_name) = new_name {
|
||||
if new_name.is_empty() {
|
||||
self.sess.err(
|
||||
&format!("an empty renaming target was specified for library `{}`",name));
|
||||
} else if !self.cstore.get_used_libraries().borrow().iter()
|
||||
.any(|lib| lib.name == name as &str) {
|
||||
self.sess.err(&format!("renaming of the library `{}` was specified, \
|
||||
however this crate contains no #[link(...)] \
|
||||
attributes referencing this library.", name));
|
||||
} else if renames.contains(name) {
|
||||
self.sess.err(&format!("multiple renamings were specified for library `{}` .",
|
||||
name));
|
||||
} else {
|
||||
renames.insert(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update kind and, optionally, the name of all native libaries
|
||||
// (there may be more than one) with the specified name.
|
||||
for &(ref name, ref new_name, kind) in &self.sess.opts.libs {
|
||||
let mut found = false;
|
||||
for lib in self.cstore.get_used_libraries().borrow_mut().iter_mut() {
|
||||
if lib.name == name as &str {
|
||||
lib.kind = kind;
|
||||
if let &Some(ref new_name) = new_name {
|
||||
lib.name = Symbol::intern(new_name);
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// Add if not found
|
||||
let new_name = new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
|
||||
let lib = NativeLibrary {
|
||||
name: Symbol::intern(new_name.unwrap_or(name)),
|
||||
kind: kind,
|
||||
cfg: None,
|
||||
foreign_items: Vec::new(),
|
||||
};
|
||||
register_native_lib(self.sess, self.cstore, None, lib);
|
||||
}
|
||||
}
|
||||
self.register_statically_included_foreign_items();
|
||||
self.register_dllimport_foreign_items();
|
||||
}
|
||||
|
||||
fn process_item(&mut self, item: &ast::Item, definitions: &Definitions) {
|
||||
match item.node {
|
||||
ast::ItemKind::ExternCrate(_) => {}
|
||||
ast::ItemKind::ForeignMod(ref fm) => return self.process_foreign_mod(item, fm),
|
||||
_ => return,
|
||||
ast::ItemKind::ForeignMod(ref fm) => {
|
||||
self.process_foreign_mod(item, fm, definitions)
|
||||
},
|
||||
ast::ItemKind::ExternCrate(_) => {
|
||||
let info = self.extract_crate_info(item).unwrap();
|
||||
let (cnum, ..) = self.resolve_crate(
|
||||
&None, info.ident, info.name, None, item.span, PathKind::Crate, info.dep_kind,
|
||||
);
|
||||
|
||||
let def_id = definitions.opt_local_def_id(item.id).unwrap();
|
||||
let len = definitions.def_path(def_id.index).data.len();
|
||||
|
||||
let extern_crate =
|
||||
ExternCrate { def_id: def_id, span: item.span, direct: true, path_len: len };
|
||||
self.update_extern_crate(cnum, extern_crate, &mut FxHashSet());
|
||||
self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let info = self.extract_crate_info(item).unwrap();
|
||||
let (cnum, ..) = self.resolve_crate(
|
||||
&None, info.ident, info.name, None, item.span, PathKind::Crate, info.dep_kind,
|
||||
);
|
||||
|
||||
let def_id = definitions.opt_local_def_id(item.id).unwrap();
|
||||
let len = definitions.def_path(def_id.index).data.len();
|
||||
|
||||
let extern_crate =
|
||||
ExternCrate { def_id: def_id, span: item.span, direct: true, path_len: len };
|
||||
self.update_extern_crate(cnum, extern_crate, &mut FxHashSet());
|
||||
self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@ use locator;
|
|||
use schema;
|
||||
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, DefId};
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId};
|
||||
use rustc::hir::map::DefKey;
|
||||
use rustc::hir::svh::Svh;
|
||||
use rustc::middle::cstore::{DepKind, ExternCrate};
|
||||
use rustc_back::PanicStrategy;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc::util::nodemap::{FxHashMap, NodeMap, NodeSet, DefIdMap};
|
||||
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap};
|
||||
|
||||
use std::cell::{RefCell, Cell};
|
||||
use std::rc::Rc;
|
||||
|
@ -31,7 +31,7 @@ use syntax::ext::base::SyntaxExtension;
|
|||
use syntax::symbol::Symbol;
|
||||
use syntax_pos;
|
||||
|
||||
pub use rustc::middle::cstore::{NativeLibrary, LinkagePreference};
|
||||
pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference};
|
||||
pub use rustc::middle::cstore::{NativeStatic, NativeFramework, NativeUnknown};
|
||||
pub use rustc::middle::cstore::{CrateSource, LinkMeta, LibSource};
|
||||
|
||||
|
@ -84,6 +84,8 @@ pub struct CrateMetadata {
|
|||
pub source: CrateSource,
|
||||
|
||||
pub proc_macros: Option<Vec<(ast::Name, Rc<SyntaxExtension>)>>,
|
||||
// Foreign items imported from a dylib (Windows only)
|
||||
pub dllimport_foreign_items: FxHashSet<DefIndex>,
|
||||
}
|
||||
|
||||
pub struct CachedInlinedItem {
|
||||
|
@ -100,7 +102,8 @@ pub struct CStore {
|
|||
extern_mod_crate_map: RefCell<NodeMap<CrateNum>>,
|
||||
used_libraries: RefCell<Vec<NativeLibrary>>,
|
||||
used_link_args: RefCell<Vec<String>>,
|
||||
statically_included_foreign_items: RefCell<NodeSet>,
|
||||
statically_included_foreign_items: RefCell<FxHashSet<DefIndex>>,
|
||||
pub dllimport_foreign_items: RefCell<FxHashSet<DefIndex>>,
|
||||
pub inlined_item_cache: RefCell<DefIdMap<Option<CachedInlinedItem>>>,
|
||||
pub defid_for_inlined_node: RefCell<NodeMap<DefId>>,
|
||||
pub visible_parent_map: RefCell<DefIdMap<DefId>>,
|
||||
|
@ -114,7 +117,8 @@ impl CStore {
|
|||
extern_mod_crate_map: RefCell::new(FxHashMap()),
|
||||
used_libraries: RefCell::new(Vec::new()),
|
||||
used_link_args: RefCell::new(Vec::new()),
|
||||
statically_included_foreign_items: RefCell::new(NodeSet()),
|
||||
statically_included_foreign_items: RefCell::new(FxHashSet()),
|
||||
dllimport_foreign_items: RefCell::new(FxHashSet()),
|
||||
visible_parent_map: RefCell::new(FxHashMap()),
|
||||
inlined_item_cache: RefCell::new(FxHashMap()),
|
||||
defid_for_inlined_node: RefCell::new(FxHashMap()),
|
||||
|
@ -246,12 +250,13 @@ impl CStore {
|
|||
self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
|
||||
}
|
||||
|
||||
pub fn add_statically_included_foreign_item(&self, id: ast::NodeId) {
|
||||
pub fn add_statically_included_foreign_item(&self, id: DefIndex) {
|
||||
self.statically_included_foreign_items.borrow_mut().insert(id);
|
||||
}
|
||||
|
||||
pub fn do_is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool {
|
||||
self.statically_included_foreign_items.borrow().contains(&id)
|
||||
pub fn do_is_statically_included_foreign_item(&self, def_id: DefId) -> bool {
|
||||
assert!(def_id.krate == LOCAL_CRATE);
|
||||
self.statically_included_foreign_items.borrow().contains(&def_id.index)
|
||||
}
|
||||
|
||||
pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
|
||||
|
|
|
@ -19,7 +19,7 @@ use rustc::hir::def::{self, Def};
|
|||
use rustc::middle::lang_items;
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::hir::map as hir_map;
|
||||
|
@ -217,9 +217,17 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
self.get_crate_data(did.krate).is_foreign_item(did.index)
|
||||
}
|
||||
|
||||
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool
|
||||
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool
|
||||
{
|
||||
self.do_is_statically_included_foreign_item(id)
|
||||
self.do_is_statically_included_foreign_item(def_id)
|
||||
}
|
||||
|
||||
fn is_dllimport_foreign_item(&self, def_id: DefId) -> bool {
|
||||
if def_id.krate == LOCAL_CRATE {
|
||||
self.dllimport_foreign_items.borrow().contains(&def_id.index)
|
||||
} else {
|
||||
self.get_crate_data(def_id.krate).is_dllimport_foreign_item(def_id.index)
|
||||
}
|
||||
}
|
||||
|
||||
fn dylib_dependency_formats(&self, cnum: CrateNum)
|
||||
|
|
|
@ -1068,6 +1068,10 @@ impl<'a, 'tcx> CrateMetadata {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_dllimport_foreign_item(&self, id: DefIndex) -> bool {
|
||||
self.dllimport_foreign_items.contains(&id)
|
||||
}
|
||||
|
||||
pub fn is_defaulted_trait(&self, trait_id: DefIndex) -> bool {
|
||||
match self.entry(trait_id).kind {
|
||||
EntryKind::Trait(data) => data.decode(self).has_default_impl,
|
||||
|
|
|
@ -1536,7 +1536,8 @@ pub fn find_exported_symbols(tcx: TyCtxt, reachable: NodeSet) -> NodeSet {
|
|||
// let it through if it's included statically.
|
||||
match tcx.map.get(id) {
|
||||
hir_map::NodeForeignItem(..) => {
|
||||
tcx.sess.cstore.is_statically_included_foreign_item(id)
|
||||
let def_id = tcx.map.local_def_id(id);
|
||||
tcx.sess.cstore.is_statically_included_foreign_item(def_id)
|
||||
}
|
||||
|
||||
// Only consider nodes that actually have exported symbols.
|
||||
|
|
|
@ -637,7 +637,11 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
||||
}
|
||||
}
|
||||
|
||||
if ccx.use_dll_storage_attrs() && ccx.sess().cstore.is_dllimport_foreign_item(def_id) {
|
||||
unsafe {
|
||||
llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
|
||||
}
|
||||
}
|
||||
llfn
|
||||
};
|
||||
|
||||
|
|
|
@ -191,7 +191,12 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
|||
llvm::set_thread_local(g, true);
|
||||
}
|
||||
}
|
||||
if ccx.use_dll_storage_attrs() {
|
||||
if ccx.use_dll_storage_attrs() && !ccx.sess().cstore.is_foreign_item(def_id) {
|
||||
// This item is external but not foreign, i.e. it originates from an external Rust
|
||||
// crate. Since we don't know whether this crate will be linked dynamically or
|
||||
// statically in the final application, we always mark such symbols as 'dllimport'.
|
||||
// If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs to
|
||||
// make things work.
|
||||
unsafe {
|
||||
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
|
||||
}
|
||||
|
@ -199,6 +204,12 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
|||
g
|
||||
};
|
||||
|
||||
if ccx.use_dll_storage_attrs() && ccx.sess().cstore.is_dllimport_foreign_item(def_id) {
|
||||
// For foreign (native) libs we know the exact storage type to use.
|
||||
unsafe {
|
||||
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
|
||||
}
|
||||
}
|
||||
ccx.instances().borrow_mut().insert(instance, g);
|
||||
ccx.statics().borrow_mut().insert(g, def_id);
|
||||
g
|
||||
|
|
|
@ -132,7 +132,6 @@ declare_features! (
|
|||
|
||||
(active, allocator, "1.0.0", Some(27389)),
|
||||
(active, fundamental, "1.0.0", Some(29635)),
|
||||
(active, linked_from, "1.3.0", Some(29629)),
|
||||
(active, main, "1.0.0", Some(29634)),
|
||||
(active, needs_allocator, "1.4.0", Some(27389)),
|
||||
(active, on_unimplemented, "1.0.0", Some(29628)),
|
||||
|
@ -638,12 +637,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
|
|||
is an experimental feature",
|
||||
cfg_fn!(fundamental))),
|
||||
|
||||
("linked_from", Normal, Gated(Stability::Unstable,
|
||||
"linked_from",
|
||||
"the `#[linked_from]` attribute \
|
||||
is an experimental feature",
|
||||
cfg_fn!(linked_from))),
|
||||
|
||||
("proc_macro_derive", Normal, Gated(Stability::Unstable,
|
||||
"proc_macro",
|
||||
"the `#[proc_macro_derive]` attribute \
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// 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.
|
||||
|
||||
// no-prefer-dynamic
|
||||
#![crate_type = "staticlib"]
|
||||
|
||||
// Since codegen tests don't actually perform linking, this library doesn't need to export
|
||||
// any symbols. It's here just to satisfy the compiler looking for a .lib file when processing
|
||||
// #[link(...)] attributes in wrapper.rs.
|
|
@ -0,0 +1,24 @@
|
|||
// 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.
|
||||
|
||||
// no-prefer-dynamic
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "dummy", kind="dylib")]
|
||||
extern "C" {
|
||||
pub fn dylib_func2(x: i32) -> i32;
|
||||
pub static dylib_global2: i32;
|
||||
}
|
||||
|
||||
#[link(name = "dummy", kind="static")]
|
||||
extern "C" {
|
||||
pub fn static_func2(x: i32) -> i32;
|
||||
pub static static_global2: i32;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
// 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.
|
||||
|
||||
// This test is for *-windows-msvc only.
|
||||
// ignore-gnu
|
||||
// ignore-android
|
||||
// ignore-bitrig
|
||||
// ignore-macos
|
||||
// ignore-dragonfly
|
||||
// ignore-freebsd
|
||||
// ignore-haiku
|
||||
// ignore-ios
|
||||
// ignore-linux
|
||||
// ignore-netbsd
|
||||
// ignore-openbsd
|
||||
// ignore-solaris
|
||||
// ignore-emscripten
|
||||
|
||||
// aux-build:dummy.rs
|
||||
// aux-build:wrapper.rs
|
||||
|
||||
extern crate wrapper;
|
||||
|
||||
// Check that external symbols coming from foreign dylibs are adorned with 'dllimport',
|
||||
// whereas symbols coming from foreign staticlibs are not. (RFC-1717)
|
||||
|
||||
// CHECK: @dylib_global1 = external dllimport local_unnamed_addr global i32
|
||||
// CHECK: @dylib_global2 = external dllimport local_unnamed_addr global i32
|
||||
// CHECK: @static_global1 = external local_unnamed_addr global i32
|
||||
// CHECK: @static_global2 = external local_unnamed_addr global i32
|
||||
|
||||
// CHECK: declare dllimport i32 @dylib_func1(i32)
|
||||
// CHECK: declare dllimport i32 @dylib_func2(i32)
|
||||
// CHECK: declare i32 @static_func1(i32)
|
||||
// CHECK: declare i32 @static_func2(i32)
|
||||
|
||||
#[link(name = "dummy", kind="dylib")]
|
||||
extern "C" {
|
||||
pub fn dylib_func1(x: i32) -> i32;
|
||||
pub static dylib_global1: i32;
|
||||
}
|
||||
|
||||
#[link(name = "dummy", kind="static")]
|
||||
extern "C" {
|
||||
pub fn static_func1(x: i32) -> i32;
|
||||
pub static static_global1: i32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
dylib_func1(dylib_global1);
|
||||
wrapper::dylib_func2(wrapper::dylib_global2);
|
||||
|
||||
static_func1(static_global1);
|
||||
wrapper::static_func2(wrapper::static_global2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// 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.
|
||||
|
||||
// compile-flags: -l foo:bar
|
||||
// error-pattern: renaming of the library `foo` was specified
|
||||
|
||||
#![crate_type = "lib"]
|
|
@ -0,0 +1,17 @@
|
|||
// 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.
|
||||
|
||||
// compile-flags: -l foo:bar -l foo:baz
|
||||
// error-pattern: multiple renamings were specified for library
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[link(name = "foo")]
|
||||
extern "C" {}
|
|
@ -0,0 +1,17 @@
|
|||
// 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.
|
||||
|
||||
// compile-flags: -l foo:
|
||||
// error-pattern: an empty renaming target was specified for library
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[link(name = "foo")]
|
||||
extern "C" {}
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
#[link(name = "cfoo")]
|
||||
#[link(name = "cfoo", kind = "static")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "cfoo")]
|
||||
#[link(name = "cfoo", kind = "static")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ extern crate testcrate;
|
|||
|
||||
extern "C" fn bar<T>(ts: testcrate::TestStruct<T>) -> T { ts.y }
|
||||
|
||||
#[link(name = "test")]
|
||||
#[link(name = "test", kind = "static")]
|
||||
extern {
|
||||
fn call(c: extern "C" fn(testcrate::TestStruct<i32>) -> i32) -> i32;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ pub struct TestStruct<T> {
|
|||
|
||||
pub extern "C" fn foo<T>(ts: TestStruct<T>) -> T { ts.y }
|
||||
|
||||
#[link(name = "test")]
|
||||
#[link(name = "test", kind = "static")]
|
||||
extern {
|
||||
pub fn call(c: extern "C" fn(TestStruct<i32>) -> i32) -> i32;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
extern crate foo;
|
||||
|
||||
#[link(name = "bar")]
|
||||
#[link(name = "bar", kind = "static")]
|
||||
extern {
|
||||
fn bar();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "foo")]
|
||||
#[link(name = "foo", kind = "static")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
|
|
@ -8,11 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(linked_from)]
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
#[link(name = "foo", kind = "static")]
|
||||
#[linked_from = "foo"]
|
||||
extern {
|
||||
pub fn foo();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "test")]
|
||||
#[link(name = "test", kind = "static")]
|
||||
extern {
|
||||
fn slice_len(s: &[u8]) -> libc::size_t;
|
||||
fn slice_elem(s: &[u8], idx: libc::size_t) -> u8;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name="foo")]
|
||||
#[link(name="foo", kind = "static")]
|
||||
extern {
|
||||
fn should_return_one() -> libc::c_int;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ mod tests {
|
|||
#[derive(Copy, Clone)]
|
||||
pub struct Floats { a: f64, b: u8, c: f64 }
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern "sysv64" {
|
||||
pub fn rust_int8_to_int32(_: i8) -> i32;
|
||||
pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name="rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ extern crate libc;
|
|||
pub mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
pub mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,9 @@
|
|||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(linked_from)]
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
#[linked_from = "rust_test_helpers"]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_u32(u: u32) -> u32;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_int8_to_int32(_: i8) -> i32;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ extern crate libc;
|
|||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::thread;
|
|||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
|
|
|
@ -15,7 +15,7 @@ extern crate libc;
|
|||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
|
|
|
@ -22,7 +22,7 @@ use std::thread;
|
|||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
|
|
|
@ -16,7 +16,7 @@ pub struct TwoU16s {
|
|||
one: u16, two: u16
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ pub struct TwoU32s {
|
|||
one: u32, two: u32
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ pub struct TwoU64s {
|
|||
one: u64, two: u64
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ pub struct TwoU8s {
|
|||
one: u8, two: u8
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// Test a function that takes/returns a u8.
|
||||
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ struct ManyInts {
|
|||
|
||||
struct Empty;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// Test a function that takes/returns a u32.
|
||||
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// Test a call to a function that takes/returns a u64.
|
||||
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ pub struct TwoU16s {
|
|||
one: u16, two: u16
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ pub struct TwoU32s {
|
|||
one: u32, two: u32
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ pub struct TwoU64s {
|
|||
one: u64, two: u64
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ pub struct TwoU8s {
|
|||
one: u8, two: u8
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ extern crate libc;
|
|||
use std::mem;
|
||||
use std::thread;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
|
||||
data: libc::uintptr_t) -> libc::uintptr_t;
|
||||
|
|
|
@ -16,7 +16,7 @@ pub struct S {
|
|||
z: u64,
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn get_x(x: S) -> u64;
|
||||
pub fn get_y(x: S) -> u64;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
|
|||
mod rustrt {
|
||||
use super::Quad;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn get_c_many_params(_: *const (), _: *const (),
|
||||
_: *const (), _: *const (), f: Quad) -> u64;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_interesting_average(_: i64, ...) -> f64;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// 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.
|
||||
//
|
||||
|
@ -8,9 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[linked_from = "foo"] //~ ERROR experimental feature
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
// no-prefer-dynamic
|
||||
#![crate_type = "staticlib"]
|
||||
|
||||
fn main() {}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn foo(x:i32) -> i32 { x }
|
|
@ -0,0 +1,23 @@
|
|||
// 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.
|
||||
|
||||
// aux-build:clibrary.rs
|
||||
// compile-flags: -lstatic=wronglibrary:clibrary
|
||||
|
||||
#[link(name = "wronglibrary", kind = "dylib")]
|
||||
extern "C" {
|
||||
pub fn foo(x:i32) -> i32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
foo(42);
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ extern crate libc;
|
|||
use std::process::{Command, ExitStatus};
|
||||
use std::env;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_get_null_ptr() -> *mut ::libc::c_char;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
static mut rust_dbg_static_mut: libc::c_int;
|
||||
pub fn rust_dbg_static_mut_check_four();
|
||||
|
|
|
@ -18,7 +18,7 @@ pub struct Floats { a: f64, b: u8, c: f64 }
|
|||
mod rustrt {
|
||||
use super::{Floats, Quad};
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_abi_1(q: Quad) -> Quad;
|
||||
pub fn rust_dbg_abi_2(f: Floats) -> Floats;
|
||||
|
|
|
@ -25,7 +25,7 @@ union LARGE_INTEGER {
|
|||
QuadPart: u64,
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern "C" {
|
||||
fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_interesting_average(_: u64, ...) -> f64;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue