]>
Commit | Line | Data |
---|---|---|
1a4d82fc | 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
223e47cc LB |
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 | ||
223e47cc LB |
11 | // The crate store - a central repo for information collected about external |
12 | // crates and libraries | |
13 | ||
ea8adc8c | 14 | use schema; |
94b46f34 | 15 | use rustc::hir::def_id::{CrateNum, DefIndex}; |
ea8adc8c | 16 | use rustc::hir::map::definitions::DefPathTable; |
7cac9316 | 17 | use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; |
94b46f34 | 18 | use rustc::mir::interpret::AllocDecodingState; |
3157f602 | 19 | use rustc_data_structures::indexed_vec::IndexVec; |
0531ce1d | 20 | use rustc::util::nodemap::{FxHashMap, NodeMap}; |
223e47cc | 21 | |
0531ce1d | 22 | use rustc_data_structures::sync::{Lrc, RwLock, Lock}; |
94b46f34 | 23 | use syntax::ast; |
476ff2be SL |
24 | use syntax::ext::base::SyntaxExtension; |
25 | use syntax::symbol::Symbol; | |
3157f602 | 26 | use syntax_pos; |
92a42be0 | 27 | |
476ff2be | 28 | pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference}; |
8bb4bdeb | 29 | pub use rustc::middle::cstore::NativeLibraryKind::*; |
0531ce1d | 30 | pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule}; |
223e47cc | 31 | |
abe05a73 | 32 | pub use cstore_impl::{provide, provide_extern}; |
8bb4bdeb | 33 | |
223e47cc LB |
34 | // A map from external crate numbers (as decoded from some crate file) to |
35 | // local crate numbers (as generated during this session). Each external | |
36 | // crate may refer to types in other external crates, and each has their | |
37 | // own crate numbers. | |
9e0c209e | 38 | pub type CrateNumMap = IndexVec<CrateNum, CrateNum>; |
223e47cc | 39 | |
0531ce1d XL |
40 | pub use rustc_data_structures::sync::MetadataRef; |
41 | ||
42 | pub struct MetadataBlob(pub MetadataRef); | |
223e47cc | 43 | |
b7449926 XL |
44 | /// Holds information about a syntax_pos::SourceFile imported from another crate. |
45 | /// See `imported_source_files()` for more information. | |
46 | pub struct ImportedSourceFile { | |
47 | /// This SourceFile's byte-offset within the source_map of its original crate | |
3157f602 | 48 | pub original_start_pos: syntax_pos::BytePos, |
b7449926 | 49 | /// The end of this SourceFile within the source_map of its original crate |
3157f602 | 50 | pub original_end_pos: syntax_pos::BytePos, |
b7449926 XL |
51 | /// The imported SourceFile's representation within the local source_map |
52 | pub translated_source_file: Lrc<syntax_pos::SourceFile>, | |
c34b1796 AL |
53 | } |
54 | ||
3157f602 | 55 | pub struct CrateMetadata { |
476ff2be | 56 | pub name: Symbol, |
54a0048b SL |
57 | |
58 | /// Information about the extern crate that caused this crate to | |
59 | /// be loaded. If this is `None`, then the crate was injected | |
60 | /// (e.g., by the allocator) | |
0531ce1d | 61 | pub extern_crate: Lock<Option<ExternCrate>>, |
54a0048b | 62 | |
9e0c209e | 63 | pub blob: MetadataBlob, |
94b46f34 | 64 | pub cnum_map: CrateNumMap, |
9e0c209e | 65 | pub cnum: CrateNum, |
94b46f34 | 66 | pub dependencies: Lock<Vec<CrateNum>>, |
b7449926 | 67 | pub source_map_import_info: RwLock<Vec<ImportedSourceFile>>, |
94b46f34 XL |
68 | |
69 | /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. | |
70 | pub alloc_decoding_state: AllocDecodingState, | |
b039eaaf | 71 | |
9e0c209e | 72 | pub root: schema::CrateRoot, |
e9174d1e | 73 | |
a7813a04 XL |
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. | |
0531ce1d | 79 | pub def_path_table: Lrc<DefPathTable>, |
32a655c1 | 80 | |
ea8adc8c | 81 | pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>, |
a7813a04 | 82 | |
0531ce1d | 83 | pub dep_kind: Lock<DepKind>, |
476ff2be SL |
84 | pub source: CrateSource, |
85 | ||
0531ce1d | 86 | pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>, |
223e47cc LB |
87 | } |
88 | ||
1a4d82fc | 89 | pub struct CStore { |
0531ce1d | 90 | metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>, |
1a4d82fc | 91 | /// Map from NodeId's of local extern crate statements to crate numbers |
0531ce1d | 92 | extern_mod_crate_map: Lock<NodeMap<CrateNum>>, |
8faf50e0 | 93 | pub metadata_loader: Box<dyn MetadataLoader + Sync>, |
1a4d82fc JJ |
94 | } |
95 | ||
b7449926 XL |
96 | pub enum LoadedMacro { |
97 | MacroDef(ast::Item), | |
98 | ProcMacro(Lrc<SyntaxExtension>), | |
99 | } | |
100 | ||
1a4d82fc | 101 | impl CStore { |
8faf50e0 | 102 | pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> CStore { |
1a4d82fc | 103 | CStore { |
94b46f34 XL |
104 | // We add an empty entry for LOCAL_CRATE (which maps to zero) in |
105 | // order to make array indices in `metas` match with the | |
106 | // corresponding `CrateNum`. This first entry will always remain | |
107 | // `None`. | |
108 | metas: RwLock::new(IndexVec::from_elem_n(None, 1)), | |
0531ce1d | 109 | extern_mod_crate_map: Lock::new(FxHashMap()), |
3b2f2976 | 110 | metadata_loader, |
1a4d82fc JJ |
111 | } |
112 | } | |
223e47cc | 113 | |
94b46f34 XL |
114 | pub(super) fn alloc_new_crate_num(&self) -> CrateNum { |
115 | let mut metas = self.metas.borrow_mut(); | |
116 | let cnum = CrateNum::new(metas.len()); | |
117 | metas.push(None); | |
118 | cnum | |
1a4d82fc | 119 | } |
223e47cc | 120 | |
94b46f34 | 121 | pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> { |
2c00a5a8 | 122 | self.metas.borrow()[cnum].clone().unwrap() |
1a4d82fc | 123 | } |
223e47cc | 124 | |
94b46f34 XL |
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); | |
223e47cc | 129 | } |
223e47cc | 130 | |
94b46f34 | 131 | pub(super) fn iter_crate_data<I>(&self, mut i: I) |
0531ce1d | 132 | where I: FnMut(CrateNum, &Lrc<CrateMetadata>) |
1a4d82fc | 133 | { |
2c00a5a8 XL |
134 | for (k, v) in self.metas.borrow().iter_enumerated() { |
135 | if let &Some(ref v) = v { | |
136 | i(k, v); | |
137 | } | |
1a4d82fc JJ |
138 | } |
139 | } | |
223e47cc | 140 | |
94b46f34 | 141 | pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> { |
3157f602 XL |
142 | let mut ordering = Vec::new(); |
143 | self.push_dependencies_in_postorder(&mut ordering, krate); | |
144 | ordering.reverse(); | |
145 | ordering | |
146 | } | |
147 | ||
94b46f34 XL |
148 | pub(super) fn push_dependencies_in_postorder(&self, |
149 | ordering: &mut Vec<CrateNum>, | |
150 | krate: CrateNum) { | |
c30ab7b3 SL |
151 | if ordering.contains(&krate) { |
152 | return; | |
153 | } | |
3157f602 XL |
154 | |
155 | let data = self.get_crate_data(krate); | |
94b46f34 | 156 | for &dep in data.dependencies.borrow().iter() { |
3157f602 XL |
157 | if dep != krate { |
158 | self.push_dependencies_in_postorder(ordering, dep); | |
159 | } | |
160 | } | |
161 | ||
162 | ordering.push(krate); | |
163 | } | |
164 | ||
94b46f34 | 165 | pub(super) fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> { |
1a4d82fc | 166 | let mut ordering = Vec::new(); |
2c00a5a8 XL |
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 | } | |
1a4d82fc | 171 | } |
ea8adc8c | 172 | return ordering |
223e47cc LB |
173 | } |
174 | ||
94b46f34 | 175 | pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) { |
1a4d82fc JJ |
176 | self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum); |
177 | } | |
223e47cc | 178 | |
94b46f34 | 179 | pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { |
92a42be0 SL |
180 | self.extern_mod_crate_map.borrow().get(&emod_id).cloned() |
181 | } | |
1a4d82fc | 182 | } |