Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,7 @@ pub trait CrateStore<'tcx> : Any {
fn is_defaulted_trait(&self, did: DefId) -> bool;
fn is_impl(&self, did: DefId) -> bool;
fn is_default_impl(&self, impl_did: DefId) -> bool;
fn is_extern_fn(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool;
fn is_static(&self, did: DefId) -> bool;
fn is_extern_item(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool;
fn is_static_method(&self, did: DefId) -> bool;
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
fn is_typedef(&self, did: DefId) -> bool;
Expand Down Expand Up @@ -357,8 +356,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn is_defaulted_trait(&self, did: DefId) -> bool { unimplemented!() }
fn is_impl(&self, did: DefId) -> bool { unimplemented!() }
fn is_default_impl(&self, impl_did: DefId) -> bool { unimplemented!() }
fn is_extern_fn(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool { unimplemented!() }
fn is_static(&self, did: DefId) -> bool { unimplemented!() }
fn is_extern_item(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool { unimplemented!() }
fn is_static_method(&self, did: DefId) -> bool { unimplemented!() }
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
fn is_typedef(&self, did: DefId) -> bool { unimplemented!() }
Expand Down
20 changes: 11 additions & 9 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,16 +229,18 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
fn propagate_node(&mut self, node: &ast_map::Node,
search_item: ast::NodeId) {
if !self.any_library {
// If we are building an executable, then there's no need to flag
// anything as external except for `extern fn` types. These
// functions may still participate in some form of native interface,
// but all other rust-only interfaces can be private (they will not
// participate in linkage after this product is produced)
// If we are building an executable, only explicitly extern
// types need to be exported.
if let ast_map::NodeItem(item) = *node {
if let hir::ItemFn(_, _, _, abi, _, _) = item.node {
if abi != Abi::Rust {
self.reachable_symbols.insert(search_item);
}
let reachable = if let hir::ItemFn(_, _, _, abi, _, _) = item.node {
abi != Abi::Rust
} else {
false
};
let is_extern = attr::contains_extern_indicator(&self.tcx.sess.diagnostic(),
&item.attrs);
if reachable || is_extern {
self.reachable_symbols.insert(search_item);
}
}
} else {
Expand Down
11 changes: 2 additions & 9 deletions src/librustc_metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,16 +260,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
decoder::is_default_impl(&*cdata, impl_did.index)
}

fn is_extern_fn(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool
{
let cdata = self.get_crate_data(did.krate);
decoder::is_extern_fn(&*cdata, did.index, tcx)
}

fn is_static(&self, did: DefId) -> bool
{
fn is_extern_item(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool {
let cdata = self.get_crate_data(did.krate);
decoder::is_static(&*cdata, did.index)
decoder::is_extern_item(&*cdata, did.index, tcx)
}

fn is_static_method(&self, def: DefId) -> bool
Expand Down
40 changes: 21 additions & 19 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1567,11 +1567,29 @@ pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool {
}
}

pub fn is_static(cdata: Cmd, id: DefIndex) -> bool {
let item_doc = cdata.lookup_item(id);
match item_family(item_doc) {
pub fn is_extern_item(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt) -> bool {
let item_doc = match cdata.get_item(id) {
Some(doc) => doc,
None => return false,
};
let applicable = match item_family(item_doc) {
ImmStatic | MutStatic => true,
Fn => {
let ty::TypeScheme { generics, ty } = get_type(cdata, id, tcx);
let no_generics = generics.types.is_empty();
match ty.sty {
ty::TyBareFn(_, fn_ty) if fn_ty.abi != Abi::Rust => return no_generics,
_ => no_generics,
}
},
_ => false,
};

if applicable {
attr::contains_extern_indicator(tcx.sess.diagnostic(),
&get_attributes(item_doc))
} else {
false
}
}

Expand Down Expand Up @@ -1693,22 +1711,6 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
}).collect()
}

pub fn is_extern_fn(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt) -> bool {
let item_doc = match cdata.get_item(id) {
Some(doc) => doc,
None => return false,
};
if let Fn = item_family(item_doc) {
let ty::TypeScheme { generics, ty } = get_type(cdata, id, tcx);
generics.types.is_empty() && match ty.sty {
ty::TyBareFn(_, fn_ty) => fn_ty.abi != Abi::Rust,
_ => false,
}
} else {
false
}
}

pub fn closure_kind(cdata: Cmd, closure_id: DefIndex) -> ty::ClosureKind {
let closure_doc = cdata.lookup_item(closure_id);
let closure_kind_doc = reader::get_doc(closure_doc, tag_items_closure_kind);
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3281,8 +3281,7 @@ pub fn trans_crate<'tcx>(tcx: &ty::ctxt<'tcx>,
for cnum in sess.cstore.crates() {
let syms = sess.cstore.reachable_ids(cnum);
reachable_symbols.extend(syms.into_iter().filter(|did| {
sess.cstore.is_extern_fn(shared_ccx.tcx(), *did) ||
sess.cstore.is_static(*did)
sess.cstore.is_extern_item(shared_ccx.tcx(), *did)
}).map(|did| {
sess.cstore.item_symbol(did)
}));
Expand Down
5 changes: 5 additions & 0 deletions src/libsyntax/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,11 @@ pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<Inte
})
}

pub fn contains_extern_indicator(diag: &Handler, attrs: &[Attribute]) -> bool {
contains_name(attrs, "no_mangle") ||
find_export_name_attr(diag, attrs).is_some()
}

#[derive(Copy, Clone, PartialEq)]
pub enum InlineAttr {
None,
Expand Down