(index<- )        ./librustc/metadata/cstore.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   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(intrRc<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, cnumast::CrateNum) -> Rc<crate_metadata> {
  99          self.metas.borrow().get(&cnum).clone()
 100      }
 101  
 102      pub fn get_crate_hash(&self, cnumast::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, cnumast::CrateNum, dataRc<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, srcCrateSource) {
 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, cnumast::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, preferLinkagePreference)
 152                             -> Vec<(ast::CrateNum, Option<Path>)> {
 153          let mut ordering = Vec::new();
 154          fn visit(cstore&CStore, cnumast::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, kindNativeLibaryKind) {
 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_idast::NodeId,
 203                                      cnumast::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_idast::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:- 2
163:         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:- 2
42:     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:- 17
62: // 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:- 6
41:     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:- 26
213: 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:- 30
librustc/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:- 12
186:     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:- 12
49: 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: {