1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use hir::def_id::{DefId, LOCAL_CRATE};
12 use ich::StableHashingContext;
13 use rustc_data_structures::stable_hasher::{StableHasher, HashStable,
18 use ty::subst::Substs;
20 /// The SymbolExportLevel of a symbols specifies from which kinds of crates
21 /// the symbol will be exported. `C` symbols will be exported from any
22 /// kind of crate, including cdylibs which export very few things.
23 /// `Rust` will only be exported if the crate produced is a Rust
25 #[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
26 pub enum SymbolExportLevel {
31 impl_stable_hash_for!(enum self::SymbolExportLevel {
36 impl SymbolExportLevel {
37 pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
38 threshold == SymbolExportLevel::Rust // export everything from Rust dylibs
39 || self == SymbolExportLevel::C
43 #[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
44 pub enum ExportedSymbol<'tcx> {
46 Generic(DefId, &'tcx Substs<'tcx>),
47 NoDefId(ty::SymbolName),
50 impl<'tcx> ExportedSymbol<'tcx> {
51 pub fn symbol_name(&self,
52 tcx: ty::TyCtxt<'_, 'tcx, '_>)
55 ExportedSymbol::NonGeneric(def_id) => {
56 tcx.symbol_name(ty::Instance::mono(tcx, def_id))
58 ExportedSymbol::Generic(def_id, substs) => {
59 tcx.symbol_name(ty::Instance::new(def_id, substs))
61 ExportedSymbol::NoDefId(symbol_name) => {
67 pub fn compare_stable(&self,
68 tcx: ty::TyCtxt<'_, 'tcx, '_>,
69 other: &ExportedSymbol<'tcx>)
72 ExportedSymbol::NonGeneric(self_def_id) => match *other {
73 ExportedSymbol::NonGeneric(other_def_id) => {
74 tcx.def_path_hash(self_def_id).cmp(&tcx.def_path_hash(other_def_id))
76 ExportedSymbol::Generic(..) |
77 ExportedSymbol::NoDefId(_) => {
81 ExportedSymbol::Generic(..) => match *other {
82 ExportedSymbol::NonGeneric(_) => {
83 cmp::Ordering::Greater
85 ExportedSymbol::Generic(..) => {
86 self.symbol_name(tcx).cmp(&other.symbol_name(tcx))
88 ExportedSymbol::NoDefId(_) => {
92 ExportedSymbol::NoDefId(self_symbol_name) => match *other {
93 ExportedSymbol::NonGeneric(_) |
94 ExportedSymbol::Generic(..) => {
95 cmp::Ordering::Greater
97 ExportedSymbol::NoDefId(ref other_symbol_name) => {
98 self_symbol_name.cmp(other_symbol_name)
105 pub fn metadata_symbol_name(tcx: ty::TyCtxt<'_, '_, '_>) -> String {
106 format!("rust_metadata_{}_{}",
107 tcx.original_crate_name(LOCAL_CRATE),
108 tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex())
111 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ExportedSymbol<'gcx> {
112 fn hash_stable<W: StableHasherResult>(&self,
113 hcx: &mut StableHashingContext<'a>,
114 hasher: &mut StableHasher<W>) {
115 mem::discriminant(self).hash_stable(hcx, hasher);
117 ExportedSymbol::NonGeneric(def_id) => {
118 def_id.hash_stable(hcx, hasher);
120 ExportedSymbol::Generic(def_id, substs) => {
121 def_id.hash_stable(hcx, hasher);
122 substs.hash_stable(hcx, hasher);
124 ExportedSymbol::NoDefId(symbol_name) => {
125 symbol_name.hash_stable(hcx, hasher);