]> git.lizzy.rs Git - rust.git/blob - src/librustc_metadata/cstore.rs
rustc: Remove `CrateStore::used_crate*`
[rust.git] / src / librustc_metadata / cstore.rs
1 // Copyright 2012-2014 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.
4 //
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.
10
11 // The crate store - a central repo for information collected about external
12 // crates and libraries
13
14 use schema::{self, Tracked};
15
16 use rustc::dep_graph::DepGraph;
17 use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, DefId};
18 use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
19 use rustc::hir::svh::Svh;
20 use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
21 use rustc_back::PanicStrategy;
22 use rustc_data_structures::indexed_vec::IndexVec;
23 use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
24
25 use std::cell::{RefCell, Cell};
26 use std::rc::Rc;
27 use owning_ref::ErasedBoxRef;
28 use syntax::{ast, attr};
29 use syntax::ext::base::SyntaxExtension;
30 use syntax::symbol::Symbol;
31 use syntax_pos;
32
33 pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference};
34 pub use rustc::middle::cstore::NativeLibraryKind::*;
35 pub use rustc::middle::cstore::{CrateSource, LibSource};
36
37 pub use cstore_impl::{provide, provide_local};
38
39 // A map from external crate numbers (as decoded from some crate file) to
40 // local crate numbers (as generated during this session). Each external
41 // crate may refer to types in other external crates, and each has their
42 // own crate numbers.
43 pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
44
45 pub struct MetadataBlob(pub ErasedBoxRef<[u8]>);
46
47 /// Holds information about a syntax_pos::FileMap imported from another crate.
48 /// See `imported_filemaps()` for more information.
49 pub struct ImportedFileMap {
50     /// This FileMap's byte-offset within the codemap of its original crate
51     pub original_start_pos: syntax_pos::BytePos,
52     /// The end of this FileMap within the codemap of its original crate
53     pub original_end_pos: syntax_pos::BytePos,
54     /// The imported FileMap's representation within the local codemap
55     pub translated_filemap: Rc<syntax_pos::FileMap>,
56 }
57
58 pub struct CrateMetadata {
59     pub name: Symbol,
60
61     /// Information about the extern crate that caused this crate to
62     /// be loaded. If this is `None`, then the crate was injected
63     /// (e.g., by the allocator)
64     pub extern_crate: Cell<Option<ExternCrate>>,
65
66     pub blob: MetadataBlob,
67     pub cnum_map: RefCell<CrateNumMap>,
68     pub cnum: CrateNum,
69     pub codemap_import_info: RefCell<Vec<ImportedFileMap>>,
70     pub attribute_cache: RefCell<[Vec<Option<Rc<[ast::Attribute]>>>; 2]>,
71
72     pub root: schema::CrateRoot,
73
74     /// For each public item in this crate, we encode a key.  When the
75     /// crate is loaded, we read all the keys and put them in this
76     /// hashmap, which gives the reverse mapping.  This allows us to
77     /// quickly retrace a `DefPath`, which is needed for incremental
78     /// compilation support.
79     pub def_path_table: Rc<DefPathTable>,
80
81     pub exported_symbols: Tracked<FxHashSet<DefIndex>>,
82
83     pub trait_impls: Tracked<FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>>,
84
85     pub dep_kind: Cell<DepKind>,
86     pub source: CrateSource,
87
88     pub proc_macros: Option<Vec<(ast::Name, Rc<SyntaxExtension>)>>,
89     // Foreign items imported from a dylib (Windows only)
90     pub dllimport_foreign_items: Tracked<FxHashSet<DefIndex>>,
91 }
92
93 pub struct CStore {
94     pub dep_graph: DepGraph,
95     metas: RefCell<FxHashMap<CrateNum, Rc<CrateMetadata>>>,
96     /// Map from NodeId's of local extern crate statements to crate numbers
97     extern_mod_crate_map: RefCell<NodeMap<CrateNum>>,
98     pub metadata_loader: Box<MetadataLoader>,
99 }
100
101 impl CStore {
102     pub fn new(dep_graph: &DepGraph, metadata_loader: Box<MetadataLoader>) -> CStore {
103         CStore {
104             dep_graph: dep_graph.clone(),
105             metas: RefCell::new(FxHashMap()),
106             extern_mod_crate_map: RefCell::new(FxHashMap()),
107             metadata_loader,
108         }
109     }
110
111     pub fn next_crate_num(&self) -> CrateNum {
112         CrateNum::new(self.metas.borrow().len() + 1)
113     }
114
115     pub fn get_crate_data(&self, cnum: CrateNum) -> Rc<CrateMetadata> {
116         self.metas.borrow().get(&cnum).unwrap().clone()
117     }
118
119     pub fn set_crate_data(&self, cnum: CrateNum, data: Rc<CrateMetadata>) {
120         self.metas.borrow_mut().insert(cnum, data);
121     }
122
123     pub fn iter_crate_data<I>(&self, mut i: I)
124         where I: FnMut(CrateNum, &Rc<CrateMetadata>)
125     {
126         for (&k, v) in self.metas.borrow().iter() {
127             i(k, v);
128         }
129     }
130
131     pub fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
132         let mut ordering = Vec::new();
133         self.push_dependencies_in_postorder(&mut ordering, krate);
134         ordering.reverse();
135         ordering
136     }
137
138     pub fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate: CrateNum) {
139         if ordering.contains(&krate) {
140             return;
141         }
142
143         let data = self.get_crate_data(krate);
144         for &dep in data.cnum_map.borrow().iter() {
145             if dep != krate {
146                 self.push_dependencies_in_postorder(ordering, dep);
147             }
148         }
149
150         ordering.push(krate);
151     }
152
153     pub fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
154         let mut ordering = Vec::new();
155         for (&num, _) in self.metas.borrow().iter() {
156             self.push_dependencies_in_postorder(&mut ordering, num);
157         }
158         return ordering
159     }
160
161     pub fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
162         self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
163     }
164
165     pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
166         self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
167     }
168
169     pub fn read_dep_node(&self, def_id: DefId) {
170         use rustc::middle::cstore::CrateStore;
171         let def_path_hash = self.def_path_hash(def_id);
172         let dep_node = def_path_hash.to_dep_node(::rustc::dep_graph::DepKind::MetaData);
173         self.dep_graph.read(dep_node);
174     }
175 }
176
177 impl CrateMetadata {
178     pub fn name(&self) -> Symbol {
179         self.root.name
180     }
181     pub fn hash(&self) -> Svh {
182         self.root.hash
183     }
184     pub fn disambiguator(&self) -> Symbol {
185         self.root.disambiguator
186     }
187
188     pub fn needs_allocator(&self, dep_graph: &DepGraph) -> bool {
189         let attrs = self.get_item_attrs(CRATE_DEF_INDEX, dep_graph);
190         attr::contains_name(&attrs, "needs_allocator")
191     }
192
193     pub fn has_global_allocator(&self, dep_graph: &DepGraph) -> bool {
194         let dep_node = self.metadata_dep_node(GlobalMetaDataKind::Krate);
195         self.root
196             .has_global_allocator
197             .get(dep_graph, dep_node)
198             .clone()
199     }
200
201     pub fn has_default_lib_allocator(&self, dep_graph: &DepGraph) -> bool {
202         let dep_node = self.metadata_dep_node(GlobalMetaDataKind::Krate);
203         self.root
204             .has_default_lib_allocator
205             .get(dep_graph, dep_node)
206             .clone()
207     }
208
209     pub fn is_panic_runtime(&self, dep_graph: &DepGraph) -> bool {
210         let attrs = self.get_item_attrs(CRATE_DEF_INDEX, dep_graph);
211         attr::contains_name(&attrs, "panic_runtime")
212     }
213
214     pub fn needs_panic_runtime(&self, dep_graph: &DepGraph) -> bool {
215         let attrs = self.get_item_attrs(CRATE_DEF_INDEX, dep_graph);
216         attr::contains_name(&attrs, "needs_panic_runtime")
217     }
218
219     pub fn is_compiler_builtins(&self, dep_graph: &DepGraph) -> bool {
220         let attrs = self.get_item_attrs(CRATE_DEF_INDEX, dep_graph);
221         attr::contains_name(&attrs, "compiler_builtins")
222     }
223
224     pub fn is_sanitizer_runtime(&self, dep_graph: &DepGraph) -> bool {
225         let attrs = self.get_item_attrs(CRATE_DEF_INDEX, dep_graph);
226         attr::contains_name(&attrs, "sanitizer_runtime")
227     }
228
229     pub fn is_profiler_runtime(&self, dep_graph: &DepGraph) -> bool {
230         let attrs = self.get_item_attrs(CRATE_DEF_INDEX, dep_graph);
231         attr::contains_name(&attrs, "profiler_runtime")
232     }
233
234     pub fn is_no_builtins(&self, dep_graph: &DepGraph) -> bool {
235         let attrs = self.get_item_attrs(CRATE_DEF_INDEX, dep_graph);
236         attr::contains_name(&attrs, "no_builtins")
237     }
238
239     pub fn panic_strategy(&self, dep_graph: &DepGraph) -> PanicStrategy {
240         let dep_node = self.metadata_dep_node(GlobalMetaDataKind::Krate);
241         self.root
242             .panic_strategy
243             .get(dep_graph, dep_node)
244             .clone()
245     }
246 }