]> git.lizzy.rs Git - rust.git/blob - src/librustc_metadata/cstore.rs
Rollup merge of #58906 - Nemo157:generator-state-debug-info, r=Zoxc
[rust.git] / src / librustc_metadata / cstore.rs
1 // The crate store - a central repo for information collected about external
2 // crates and libraries
3
4 use crate::schema;
5 use rustc::hir::def_id::{CrateNum, DefIndex};
6 use rustc::hir::map::definitions::DefPathTable;
7 use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
8 use rustc::mir::interpret::AllocDecodingState;
9 use rustc_data_structures::indexed_vec::IndexVec;
10 use rustc::util::nodemap::{FxHashMap, NodeMap};
11
12 use rustc_data_structures::sync::{Lrc, RwLock, Lock};
13 use syntax::ast;
14 use syntax::ext::base::SyntaxExtension;
15 use syntax::symbol::Symbol;
16 use syntax_pos;
17
18 pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference};
19 pub use rustc::middle::cstore::NativeLibraryKind::*;
20 pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule};
21
22 pub use crate::cstore_impl::{provide, provide_extern};
23
24 // A map from external crate numbers (as decoded from some crate file) to
25 // local crate numbers (as generated during this session). Each external
26 // crate may refer to types in other external crates, and each has their
27 // own crate numbers.
28 pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
29
30 pub use rustc_data_structures::sync::MetadataRef;
31
32 pub struct MetadataBlob(pub MetadataRef);
33
34 /// Holds information about a syntax_pos::SourceFile imported from another crate.
35 /// See `imported_source_files()` for more information.
36 pub struct ImportedSourceFile {
37     /// This SourceFile's byte-offset within the source_map of its original crate
38     pub original_start_pos: syntax_pos::BytePos,
39     /// The end of this SourceFile within the source_map of its original crate
40     pub original_end_pos: syntax_pos::BytePos,
41     /// The imported SourceFile's representation within the local source_map
42     pub translated_source_file: Lrc<syntax_pos::SourceFile>,
43 }
44
45 pub struct CrateMetadata {
46     /// Original name of the crate.
47     pub name: Symbol,
48
49     /// Name of the crate as imported. I.e., if imported with
50     /// `extern crate foo as bar;` this will be `bar`.
51     pub imported_name: Symbol,
52
53     /// Information about the extern crate that caused this crate to
54     /// be loaded. If this is `None`, then the crate was injected
55     /// (e.g., by the allocator)
56     pub extern_crate: Lock<Option<ExternCrate>>,
57
58     pub blob: MetadataBlob,
59     pub cnum_map: CrateNumMap,
60     pub cnum: CrateNum,
61     pub dependencies: Lock<Vec<CrateNum>>,
62     pub source_map_import_info: RwLock<Vec<ImportedSourceFile>>,
63
64     /// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
65     pub alloc_decoding_state: AllocDecodingState,
66
67     pub root: schema::CrateRoot,
68
69     /// For each public item in this crate, we encode a key. When the
70     /// crate is loaded, we read all the keys and put them in this
71     /// hashmap, which gives the reverse mapping. This allows us to
72     /// quickly retrace a `DefPath`, which is needed for incremental
73     /// compilation support.
74     pub def_path_table: Lrc<DefPathTable>,
75
76     pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>,
77
78     pub dep_kind: Lock<DepKind>,
79     pub source: CrateSource,
80
81     pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>,
82 }
83
84 pub struct CStore {
85     metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
86     /// Map from NodeId's of local extern crate statements to crate numbers
87     extern_mod_crate_map: Lock<NodeMap<CrateNum>>,
88     pub metadata_loader: Box<dyn MetadataLoader + Sync>,
89 }
90
91 pub enum LoadedMacro {
92     MacroDef(ast::Item),
93     ProcMacro(Lrc<SyntaxExtension>),
94 }
95
96 impl CStore {
97     pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> CStore {
98         CStore {
99             // We add an empty entry for LOCAL_CRATE (which maps to zero) in
100             // order to make array indices in `metas` match with the
101             // corresponding `CrateNum`. This first entry will always remain
102             // `None`.
103             metas: RwLock::new(IndexVec::from_elem_n(None, 1)),
104             extern_mod_crate_map: Default::default(),
105             metadata_loader,
106         }
107     }
108
109     pub(super) fn alloc_new_crate_num(&self) -> CrateNum {
110         let mut metas = self.metas.borrow_mut();
111         let cnum = CrateNum::new(metas.len());
112         metas.push(None);
113         cnum
114     }
115
116     pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
117         self.metas.borrow()[cnum].clone().unwrap()
118     }
119
120     pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
121         let mut metas = self.metas.borrow_mut();
122         assert!(metas[cnum].is_none(), "Overwriting crate metadata entry");
123         metas[cnum] = Some(data);
124     }
125
126     pub(super) fn iter_crate_data<I>(&self, mut i: I)
127         where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
128     {
129         for (k, v) in self.metas.borrow().iter_enumerated() {
130             if let &Some(ref v) = v {
131                 i(k, v);
132             }
133         }
134     }
135
136     pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
137         let mut ordering = Vec::new();
138         self.push_dependencies_in_postorder(&mut ordering, krate);
139         ordering.reverse();
140         ordering
141     }
142
143     pub(super) fn push_dependencies_in_postorder(&self,
144                                                  ordering: &mut Vec<CrateNum>,
145                                                  krate: CrateNum) {
146         if ordering.contains(&krate) {
147             return;
148         }
149
150         let data = self.get_crate_data(krate);
151         for &dep in data.dependencies.borrow().iter() {
152             if dep != krate {
153                 self.push_dependencies_in_postorder(ordering, dep);
154             }
155         }
156
157         ordering.push(krate);
158     }
159
160     pub(super) fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
161         let mut ordering = Vec::new();
162         for (num, v) in self.metas.borrow().iter_enumerated() {
163             if let &Some(_) = v {
164                 self.push_dependencies_in_postorder(&mut ordering, num);
165             }
166         }
167         return ordering
168     }
169
170     pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
171         self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
172     }
173
174     pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
175         self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
176     }
177 }