]> git.lizzy.rs Git - rust.git/blob - src/librustc_metadata/cstore.rs
Rollup merge of #65187 - Wind-River:master_before_merge, r=rkruppe
[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_index::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_pos;
16
17 pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference};
18 pub use rustc::middle::cstore::NativeLibraryKind::*;
19 pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule};
20
21 pub use crate::cstore_impl::{provide, provide_extern};
22
23 // A map from external crate numbers (as decoded from some crate file) to
24 // local crate numbers (as generated during this session). Each external
25 // crate may refer to types in other external crates, and each has their
26 // own crate numbers.
27 pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
28
29 pub use rustc_data_structures::sync::MetadataRef;
30 use syntax_pos::Span;
31 use proc_macro::bridge::client::ProcMacro;
32
33 pub struct MetadataBlob(pub MetadataRef);
34
35 /// Holds information about a syntax_pos::SourceFile imported from another crate.
36 /// See `imported_source_files()` for more information.
37 pub struct ImportedSourceFile {
38     /// This SourceFile's byte-offset within the source_map of its original crate
39     pub original_start_pos: syntax_pos::BytePos,
40     /// The end of this SourceFile within the source_map of its original crate
41     pub original_end_pos: syntax_pos::BytePos,
42     /// The imported SourceFile's representation within the local source_map
43     pub translated_source_file: Lrc<syntax_pos::SourceFile>,
44 }
45
46 pub struct CrateMetadata {
47     /// Information about the extern crate that caused this crate to
48     /// be loaded. If this is `None`, then the crate was injected
49     /// (e.g., by the allocator)
50     pub extern_crate: Lock<Option<ExternCrate>>,
51
52     pub blob: MetadataBlob,
53     pub cnum_map: CrateNumMap,
54     pub cnum: CrateNum,
55     pub dependencies: Lock<Vec<CrateNum>>,
56     pub source_map_import_info: RwLock<Vec<ImportedSourceFile>>,
57
58     /// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
59     pub alloc_decoding_state: AllocDecodingState,
60
61     // NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
62     // lifetime is only used behind `Lazy`, and therefore acts like an
63     // universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
64     // is being used to decode those values.
65     pub root: schema::CrateRoot<'static>,
66
67     /// For each definition in this crate, we encode a key. When the
68     /// crate is loaded, we read all the keys and put them in this
69     /// hashmap, which gives the reverse mapping. This allows us to
70     /// quickly retrace a `DefPath`, which is needed for incremental
71     /// compilation support.
72     pub def_path_table: Lrc<DefPathTable>,
73
74     pub trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>,
75
76     pub dep_kind: Lock<DepKind>,
77     pub source: CrateSource,
78
79     /// Whether or not this crate should be consider a private dependency
80     /// for purposes of the 'exported_private_dependencies' lint
81     pub private_dep: bool,
82
83     pub span: Span,
84
85     pub raw_proc_macros: Option<&'static [ProcMacro]>,
86 }
87
88 pub struct CStore {
89     metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
90     /// Map from NodeId's of local extern crate statements to crate numbers
91     extern_mod_crate_map: Lock<NodeMap<CrateNum>>,
92     pub metadata_loader: Box<dyn MetadataLoader + Sync>,
93 }
94
95 pub enum LoadedMacro {
96     MacroDef(ast::Item),
97     ProcMacro(SyntaxExtension),
98 }
99
100 impl CStore {
101     pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> CStore {
102         CStore {
103             // We add an empty entry for LOCAL_CRATE (which maps to zero) in
104             // order to make array indices in `metas` match with the
105             // corresponding `CrateNum`. This first entry will always remain
106             // `None`.
107             metas: RwLock::new(IndexVec::from_elem_n(None, 1)),
108             extern_mod_crate_map: Default::default(),
109             metadata_loader,
110         }
111     }
112
113     pub(super) fn alloc_new_crate_num(&self) -> CrateNum {
114         let mut metas = self.metas.borrow_mut();
115         let cnum = CrateNum::new(metas.len());
116         metas.push(None);
117         cnum
118     }
119
120     pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
121         self.metas.borrow()[cnum].clone()
122             .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum))
123     }
124
125     pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
126         let mut metas = self.metas.borrow_mut();
127         assert!(metas[cnum].is_none(), "Overwriting crate metadata entry");
128         metas[cnum] = Some(data);
129     }
130
131     pub(super) fn iter_crate_data<I>(&self, mut i: I)
132         where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
133     {
134         for (k, v) in self.metas.borrow().iter_enumerated() {
135             if let &Some(ref v) = v {
136                 i(k, v);
137             }
138         }
139     }
140
141     pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
142         let mut ordering = Vec::new();
143         self.push_dependencies_in_postorder(&mut ordering, krate);
144         ordering.reverse();
145         ordering
146     }
147
148     pub(super) fn push_dependencies_in_postorder(&self,
149                                                  ordering: &mut Vec<CrateNum>,
150                                                  krate: CrateNum) {
151         if ordering.contains(&krate) {
152             return;
153         }
154
155         let data = self.get_crate_data(krate);
156         for &dep in data.dependencies.borrow().iter() {
157             if dep != krate {
158                 self.push_dependencies_in_postorder(ordering, dep);
159             }
160         }
161
162         ordering.push(krate);
163     }
164
165     pub(super) fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
166         let mut ordering = Vec::new();
167         for (num, v) in self.metas.borrow().iter_enumerated() {
168             if let &Some(_) = v {
169                 self.push_dependencies_in_postorder(&mut ordering, num);
170             }
171         }
172         return ordering
173     }
174
175     pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
176         self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
177     }
178
179     pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
180         self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
181     }
182 }