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 #![allow(non_camel_case_types)]
12
13 // The crate store - a central repo for information collected about external
14 // crates and libraries
15
16 use back::svh::Svh;
17 use metadata::decoder;
18 use metadata::loader;
19
20 use std::cell::RefCell;
21 use std::c_vec::CVec;
22 use std::rc::Rc;
23 use collections::HashMap;
24 use syntax::ast;
25 use syntax::crateid::CrateId;
26 use syntax::codemap::Span;
27 use syntax::parse::token::IdentInterner;
28
29 // A map from external crate numbers (as decoded from some crate file) to
30 // local crate numbers (as generated during this session). Each external
31 // crate may refer to types in other external crates, and each has their
32 // own crate numbers.
33 pub type cnum_map = HashMap<ast::CrateNum, ast::CrateNum>;
34
35 pub enum MetadataBlob {
36 MetadataVec(CVec<u8>),
37 MetadataArchive(loader::ArchiveMetadata),
38 }
39
40 pub struct crate_metadata {
41 pub name: ~str,
42 pub data: MetadataBlob,
43 pub cnum_map: cnum_map,
44 pub cnum: ast::CrateNum,
45 pub span: Span,
46 }
47
48 #[deriving(Show, Eq, Clone)]
49 pub enum LinkagePreference {
50 RequireDynamic,
51 RequireStatic,
52 }
53
54 #[deriving(Eq, FromPrimitive)]
55 pub enum NativeLibaryKind {
56 NativeStatic, // native static library (.a archive)
57 NativeFramework, // OSX-specific
58 NativeUnknown, // default way to specify a dynamic library
59 }
60
61 // Where a crate came from on the local filesystem. One of these two options
62 // must be non-None.
63 #[deriving(Eq, Clone)]
64 pub struct CrateSource {
65 pub dylib: Option<Path>,
66 pub rlib: Option<Path>,
67 pub cnum: ast::CrateNum,
68 }
69
70 pub struct CStore {
71 metas: RefCell<HashMap<ast::CrateNum, Rc<crate_metadata>>>,
72 extern_mod_crate_map: RefCell<extern_mod_crate_map>,
73 used_crate_sources: RefCell<Vec<CrateSource>>,
74 used_libraries: RefCell<Vec<(~str, NativeLibaryKind)>>,
75 used_link_args: RefCell<Vec<~str>>,
76 pub intr: Rc<IdentInterner>,
77 }
78
79 // Map from NodeId's of local extern crate statements to crate numbers
80 type extern_mod_crate_map = HashMap<ast::NodeId, ast::CrateNum>;
81
82 impl CStore {
83 pub fn new(intr: Rc<IdentInterner>) -> CStore {
84 CStore {
85 metas: RefCell::new(HashMap::new()),
86 extern_mod_crate_map: RefCell::new(HashMap::new()),
87 used_crate_sources: RefCell::new(Vec::new()),
88 used_libraries: RefCell::new(Vec::new()),
89 used_link_args: RefCell::new(Vec::new()),
90 intr: intr
91 }
92 }
93
94 pub fn next_crate_num(&self) -> ast::CrateNum {
95 self.metas.borrow().len() as ast::CrateNum + 1
96 }
97
98 pub fn get_crate_data(&self, cnum: ast::CrateNum) -> Rc<crate_metadata> {
99 self.metas.borrow().get(&cnum).clone()
100 }
101
102 pub fn get_crate_hash(&self, cnum: ast::CrateNum) -> Svh {
103 let cdata = self.get_crate_data(cnum);
104 decoder::get_crate_hash(cdata.data())
105 }
106
107 pub fn set_crate_data(&self, cnum: ast::CrateNum, data: Rc<crate_metadata>) {
108 self.metas.borrow_mut().insert(cnum, data);
109 }
110
111 pub fn iter_crate_data(&self, i: |ast::CrateNum, &crate_metadata|) {
112 for (&k, v) in self.metas.borrow().iter() {
113 i(k, &**v);
114 }
115 }
116
117 pub fn add_used_crate_source(&self, src: CrateSource) {
118 let mut used_crate_sources = self.used_crate_sources.borrow_mut();
119 if !used_crate_sources.contains(&src) {
120 used_crate_sources.push(src);
121 }
122 }
123
124 pub fn get_used_crate_source(&self, cnum: ast::CrateNum)
125 -> Option<CrateSource> {
126 self.used_crate_sources.borrow_mut()
127 .iter().find(|source| source.cnum == cnum)
128 .map(|source| source.clone())
129 }
130
131 pub fn dump_phase_syntax_crates(&self) {
132 }
133
134 pub fn reset(&self) {
135 self.metas.borrow_mut().clear();
136 self.extern_mod_crate_map.borrow_mut().clear();
137 self.used_crate_sources.borrow_mut().clear();
138 self.used_libraries.borrow_mut().clear();
139 self.used_link_args.borrow_mut().clear();
140 }
141
142 // This method is used when generating the command line to pass through to
143 // system linker. The linker expects undefined symbols on the left of the
144 // command line to be defined in libraries on the right, not the other way
145 // around. For more info, see some comments in the add_used_library function
146 // below.
147 //
148 // In order to get this left-to-right dependency ordering, we perform a
149 // topological sort of all crates putting the leaves at the right-most
150 // positions.
151 pub fn get_used_crates(&self, prefer: LinkagePreference)
152 -> Vec<(ast::CrateNum, Option<Path>)> {
153 let mut ordering = Vec::new();
154 fn visit(cstore: &CStore, cnum: ast::CrateNum,
155 ordering: &mut Vec<ast::CrateNum>) {
156 if ordering.as_slice().contains(&cnum) { return }
157 let meta = cstore.get_crate_data(cnum);
158 for (_, &dep) in meta.cnum_map.iter() {
159 visit(cstore, dep, ordering);
160 }
161 ordering.push(cnum);
162 };
163 for (&num, _) in self.metas.borrow().iter() {
164 visit(self, num, &mut ordering);
165 }
166 ordering.as_mut_slice().reverse();
167 let ordering = ordering.as_slice();
168 let mut libs = self.used_crate_sources.borrow()
169 .iter()
170 .map(|src| (src.cnum, match prefer {
171 RequireDynamic => src.dylib.clone(),
172 RequireStatic => src.rlib.clone(),
173 }))
174 .collect::<Vec<(ast::CrateNum, Option<Path>)>>();
175 libs.sort_by(|&(a, _), &(b, _)| {
176 ordering.position_elem(&a).cmp(&ordering.position_elem(&b))
177 });
178 libs
179 }
180
181 pub fn add_used_library(&self, lib: ~str, kind: NativeLibaryKind) {
182 assert!(!lib.is_empty());
183 self.used_libraries.borrow_mut().push((lib, kind));
184 }
185
186 pub fn get_used_libraries<'a>(&'a self)
187 -> &'a RefCell<Vec<(~str, NativeLibaryKind)> > {
188 &self.used_libraries
189 }
190
191 pub fn add_used_link_args(&self, args: &str) {
192 for s in args.split(' ') {
193 self.used_link_args.borrow_mut().push(s.to_owned());
194 }
195 }
196
197 pub fn get_used_link_args<'a>(&'a self) -> &'a RefCell<Vec<~str> > {
198 &self.used_link_args
199 }
200
201 pub fn add_extern_mod_stmt_cnum(&self,
202 emod_id: ast::NodeId,
203 cnum: ast::CrateNum) {
204 self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
205 }
206
207 pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
208 -> Option<ast::CrateNum> {
209 self.extern_mod_crate_map.borrow().find(&emod_id).map(|x| *x)
210 }
211 }
212
213 impl crate_metadata {
214 pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
215 pub fn crate_id(&self) -> CrateId { decoder::get_crate_id(self.data()) }
216 pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
217 }
218
219 impl MetadataBlob {
220 pub fn as_slice<'a>(&'a self) -> &'a [u8] {
221 match *self {
222 MetadataVec(ref vec) => vec.as_slice(),
223 MetadataArchive(ref ar) => ar.as_slice(),
224 }
225 }
226 }
librustc/metadata/cstore.rs:154:8-154:8 -fn- definition:
fn visit(cstore: &CStore, cnum: ast::CrateNum,
ordering: &mut Vec<ast::CrateNum>) {
if ordering.as_slice().contains(&cnum) { return }
references:- 2163: for (&num, _) in self.metas.borrow().iter() {
164: visit(self, num, &mut ordering);
165: }
librustc/metadata/cstore.rs:32:22-32:22 -NK_AS_STR_TODO- definition:
// own crate numbers.
pub type cnum_map = HashMap<ast::CrateNum, ast::CrateNum>;
pub enum MetadataBlob {
references:- 242: pub data: MetadataBlob,
43: pub cnum_map: cnum_map,
44: pub cnum: ast::CrateNum,
librustc/metadata/creader.rs:
352: cdata: &[u8], span : Span)
353: -> cstore::cnum_map {
354: debug!("resolving deps of external crate");
librustc/metadata/cstore.rs:63:23-63:23 -struct- definition:
pub struct CrateSource {
pub dylib: Option<Path>,
pub rlib: Option<Path>,
references:- 1762: // must be non-None.
64: pub struct CrateSource {
--
72: extern_mod_crate_map: RefCell<extern_mod_crate_map>,
73: used_crate_sources: RefCell<Vec<CrateSource>>,
74: used_libraries: RefCell<Vec<(~str, NativeLibaryKind)>>,
--
117: pub fn add_used_crate_source(&self, src: CrateSource) {
118: let mut used_crate_sources = self.used_crate_sources.borrow_mut();
--
124: pub fn get_used_crate_source(&self, cnum: ast::CrateNum)
125: -> Option<CrateSource> {
126: self.used_crate_sources.borrow_mut()
librustc/metadata/creader.rs:
304: let source = cstore::CrateSource {
305: dylib: dylib,
--
321: -> (ast::CrateNum, Rc<cstore::crate_metadata>,
322: cstore::CrateSource) {
323: match existing_match(e, crate_id, hash) {
librustc/metadata/cstore.rs:
62: // must be non-None.
64: pub struct CrateSource {
librustc/metadata/cstore.rs:34:1-34:1 -enum- definition:
pub enum MetadataBlob {
MetadataVec(CVec<u8>),
MetadataArchive(loader::ArchiveMetadata),
references:- 641: pub name: ~str,
42: pub data: MetadataBlob,
43: pub cnum_map: cnum_map,
--
219: impl MetadataBlob {
220: pub fn as_slice<'a>(&'a self) -> &'a [u8] {
librustc/metadata/loader.rs:
342: fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
343: slot: &mut Option<MetadataBlob>) -> Option<Path> {
344: let mut ret = None::<Path>;
--
492: fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, ~str> {
493: if !filename.exists() {
librustc/metadata/cstore.rs:39:1-39:1 -struct- definition:
pub struct crate_metadata {
pub name: ~str,
pub data: MetadataBlob,
references:- 26213: impl crate_metadata {
214: pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
librustc/metadata/creader.rs:
296: let cmeta = Rc::new( cstore::crate_metadata {
297: name: crate_id.name.to_owned(),
librustc/middle/astencode.rs:
732: fn read_vtable_origin(&mut self,
733: tcx: &ty::ctxt, cdata: &cstore::crate_metadata)
734: -> typeck::vtable_origin {
--
1110: tcx: &ty::ctxt,
1111: cdata: &cstore::crate_metadata) -> Vec<ty::t> {
1112: self.read_to_vec(|this| Ok(this.read_ty_noxcx(tcx, cdata)) )
librustc/metadata/decoder.rs:
481: pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Rc<crate_metadata>;
librustc/metadata/creader.rs:
272: lib: loader::Library)
273: -> (ast::CrateNum, Rc<cstore::crate_metadata>,
274: cstore::CrateSource) {
--
320: span: Span)
321: -> (ast::CrateNum, Rc<cstore::crate_metadata>,
322: cstore::CrateSource) {
librustc/middle/astencode.rs:
271: fn read_def_id_noxcx(&mut self,
272: cdata: &cstore::crate_metadata) -> ast::DefId {
273: let did: ast::DefId = Decodable::decode(self).ok().unwrap();
librustc/metadata/cstore.rs:69:1-69:1 -struct- definition:
pub struct CStore {
metas: RefCell<HashMap<ast::CrateNum, Rc<crate_metadata>>>,
extern_mod_crate_map: RefCell<extern_mod_crate_map>,
references:- 30librustc/metadata/csearch.rs:
librustc/driver/session.rs:
librustc/metadata/encoder.rs:
librustc/metadata/creader.rs:
librustc/metadata/csearch.rs:
librustc/metadata/cstore.rs:54:31-54:31 -enum- definition:
pub enum NativeLibaryKind {
NativeStatic, // native static library (.a archive)
NativeFramework, // OSX-specific
references:- 12186: pub fn get_used_libraries<'a>(&'a self)
187: -> &'a RefCell<Vec<(~str, NativeLibaryKind)> > {
188: &self.used_libraries
librustc/metadata/csearch.rs:
247: crate_num: ast::CrateNum)
248: -> Vec<(cstore::NativeLibaryKind, ~str)> {
249: let cdata = cstore.get_crate_data(crate_num);
librustc/metadata/decoder.rs:
1242: pub fn get_native_libraries(cdata: Cmd) -> Vec<(cstore::NativeLibaryKind, ~str)> {
1243: let libraries = reader::get_doc(reader::Doc(cdata.data()),
--
1248: let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name);
1249: let kind: cstore::NativeLibaryKind =
1250: FromPrimitive::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
librustc/metadata/cstore.rs:48:29-48:29 -enum- definition:
pub enum LinkagePreference {
RequireDynamic,
RequireStatic,
references:- 1249: pub enum LinkagePreference {
--
150: // positions.
151: pub fn get_used_crates(&self, prefer: LinkagePreference)
152: -> Vec<(ast::CrateNum, Option<Path>)> {
librustc/middle/dependency_format.rs:
77: /// `kind` (either static or dynamic).
78: pub type DependencyList = Vec<Option<cstore::LinkagePreference>>;
--
198: cnum: ast::CrateNum,
199: link: cstore::LinkagePreference,
200: m: &mut HashMap<ast::CrateNum, cstore::LinkagePreference>) {
201: match m.find(&cnum) {
librustc/metadata/decoder.rs:
1274: pub fn get_dylib_dependency_formats(cdata: Cmd)
1275: -> Vec<(ast::CrateNum, cstore::LinkagePreference)>
1276: {
librustc/metadata/csearch.rs:
294: cnum: ast::CrateNum)
295: -> Vec<(ast::CrateNum, cstore::LinkagePreference)>
296: {