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