about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/metadata/creader.rs119
-rw-r--r--src/librustc/metadata/cstore.rs12
2 files changed, 61 insertions, 70 deletions
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 8ce4a2f8eed..9c0c73288eb 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -18,6 +18,7 @@ use driver::{driver, session};
 use driver::session::Session;
 use metadata::csearch;
 use metadata::cstore;
+use metadata::cstore::CStore;
 use metadata::decoder;
 use metadata::loader;
 use metadata::loader::Os;
@@ -38,6 +39,13 @@ use syntax::parse::token;
 use syntax::crateid::CrateId;
 use syntax::visit;
 
+struct Env<'a> {
+    sess: &'a Session,
+    os: loader::Os,
+    next_crate_num: ast::CrateNum,
+    intr: Rc<IdentInterner>
+}
+
 // Traverses an AST, reading all the information about use'd crates and extern
 // libraries necessary for later resolving, typechecking, linking, etc.
 pub fn read_crates(sess: &Session,
@@ -47,16 +55,13 @@ pub fn read_crates(sess: &Session,
     let mut e = Env {
         sess: sess,
         os: os,
-        crate_cache: @RefCell::new(Vec::new()),
-        next_crate_num: 1,
+        next_crate_num: sess.cstore.next_crate_num(),
         intr: intr
     };
     visit_crate(&e, krate);
     visit::walk_crate(&mut e, krate, ());
-    dump_crates(e.crate_cache.borrow().as_slice());
-    warn_if_multiple_versions(&mut e,
-                              sess.diagnostic(),
-                              e.crate_cache.borrow().as_slice());
+    dump_crates(&sess.cstore);
+    warn_if_multiple_versions(sess.diagnostic(), &sess.cstore)
 }
 
 impl<'a> visit::Visitor<()> for Env<'a> {
@@ -70,55 +75,36 @@ impl<'a> visit::Visitor<()> for Env<'a> {
     }
 }
 
-#[deriving(Clone)]
-struct cache_entry {
-    cnum: ast::CrateNum,
-    span: Span,
-    hash: Svh,
-    crate_id: CrateId,
-}
-
-fn dump_crates(crate_cache: &[cache_entry]) {
+fn dump_crates(cstore: &CStore) {
     debug!("resolved crates:");
-    for entry in crate_cache.iter() {
-        debug!("cnum: {:?}", entry.cnum);
-        debug!("span: {:?}", entry.span);
-        debug!("hash: {:?}", entry.hash);
-    }
+    cstore.iter_crate_data(|_, data| {
+        debug!("crate_id: {}", data.crate_id());
+        debug!("  cnum: {}", data.cnum);
+        debug!("  hash: {}", data.hash());
+    })
 }
 
-fn warn_if_multiple_versions(e: &mut Env,
-                             diag: &SpanHandler,
-                             crate_cache: &[cache_entry]) {
-    if crate_cache.len() != 0u {
-        let name = crate_cache[crate_cache.len() - 1].crate_id.name.clone();
-
-        let (matches, non_matches) = crate_cache.partitioned(|entry|
-            name == entry.crate_id.name);
+fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
+    let mut map = HashMap::new();
 
-        assert!(!matches.is_empty());
+    cstore.iter_crate_data(|cnum, data| {
+        let crateid = data.crate_id();
+        let key = (crateid.name.clone(), crateid.path.clone());
+        map.find_or_insert_with(key, |_| Vec::new()).push(cnum);
+    });
 
-        if matches.len() != 1u {
-            diag.handler().warn(
-                format!("using multiple versions of crate `{}`", name));
-            for match_ in matches.iter() {
-                diag.span_note(match_.span, "used here");
-                loader::note_crateid_attr(diag, &match_.crate_id);
-            }
+    for ((name, _), dupes) in map.move_iter() {
+        if dupes.len() == 1 { continue }
+        diag.handler().warn(
+            format!("using multiple versions of crate `{}`", name));
+        for dupe in dupes.move_iter() {
+            let data = cstore.get_crate_data(dupe);
+            diag.span_note(data.span, "used here");
+            loader::note_crateid_attr(diag, &data.crate_id());
         }
-
-        warn_if_multiple_versions(e, diag, non_matches);
     }
 }
 
-struct Env<'a> {
-    sess: &'a Session,
-    os: loader::Os,
-    crate_cache: @RefCell<Vec<cache_entry>>,
-    next_crate_num: ast::CrateNum,
-    intr: Rc<IdentInterner>
-}
-
 fn visit_crate(e: &Env, c: &ast::Crate) {
     for a in c.attrs.iter().filter(|m| m.name().equiv(&("link_args"))) {
         match a.value_str() {
@@ -269,14 +255,18 @@ fn visit_item(e: &Env, i: &ast::Item) {
 
 fn existing_match(e: &Env, crate_id: &CrateId,
                   hash: Option<&Svh>) -> Option<ast::CrateNum> {
-    for c in e.crate_cache.borrow().iter() {
-        if !crate_id.matches(&c.crate_id) { continue }
-        match hash {
-            Some(hash) if *hash != c.hash => {}
-            Some(..) | None => return Some(c.cnum)
+    let mut ret = None;
+    e.sess.cstore.iter_crate_data(|cnum, data| {
+        let other_id = data.crate_id();
+        if crate_id.matches(&other_id) {
+            let other_hash = data.hash();
+            match hash {
+                Some(hash) if *hash != other_hash => {}
+                Some(..) | None => { ret = Some(cnum); }
+            }
         }
-    }
-    None
+    });
+    return ret;
 }
 
 fn resolve_crate<'a>(e: &mut Env,
@@ -304,17 +294,8 @@ fn resolve_crate<'a>(e: &mut Env,
                 dylib, rlib, metadata
             } = load_ctxt.load_library_crate(root);
 
-            let crate_id = decoder::get_crate_id(metadata.as_slice());
-            let hash = decoder::get_crate_hash(metadata.as_slice());
-
             // Claim this crate number and cache it
             let cnum = e.next_crate_num;
-            e.crate_cache.borrow_mut().push(cache_entry {
-                cnum: cnum,
-                span: span,
-                hash: hash,
-                crate_id: crate_id,
-            });
             e.next_crate_num += 1;
 
             // Stash paths for top-most crate locally if necessary.
@@ -331,16 +312,15 @@ fn resolve_crate<'a>(e: &mut Env,
             let root = if root.is_some() { root } else { &crate_paths };
 
             // Now resolve the crates referenced by this crate
-            let cnum_map = resolve_crate_deps(e,
-            root,
-            metadata.as_slice(),
-            span);
+            let cnum_map = resolve_crate_deps(e, root, metadata.as_slice(),
+                                              span);
 
             let cmeta = @cstore::crate_metadata {
                 name: load_ctxt.crate_id.name.to_owned(),
                 data: metadata,
                 cnum_map: cnum_map,
-                cnum: cnum
+                cnum: cnum,
+                span: span,
             };
 
             e.sess.cstore.set_crate_data(cnum, cmeta);
@@ -390,8 +370,7 @@ impl<'a> Loader<'a> {
             env: Env {
                 sess: sess,
                 os: os,
-                crate_cache: @RefCell::new(Vec::new()),
-                next_crate_num: 1,
+                next_crate_num: sess.cstore.next_crate_num(),
                 intr: token::get_ident_interner(),
             }
         }
@@ -406,7 +385,7 @@ impl<'a> CrateLoader for Loader<'a> {
         let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap();
         MacroCrate {
             lib: library.dylib,
-            cnum: cnum
+            cnum: cnum,
         }
     }
 
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index e3a3239bdb5..2d46f92e88f 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -22,6 +22,8 @@ use std::c_vec::CVec;
 use std::rc::Rc;
 use collections::HashMap;
 use syntax::ast;
+use syntax::crateid::CrateId;
+use syntax::codemap::Span;
 use syntax::parse::token::IdentInterner;
 
 // A map from external crate numbers (as decoded from some crate file) to
@@ -40,6 +42,7 @@ pub struct crate_metadata {
     pub data: MetadataBlob,
     pub cnum_map: cnum_map,
     pub cnum: ast::CrateNum,
+    pub span: Span,
 }
 
 #[deriving(Eq)]
@@ -88,6 +91,10 @@ impl CStore {
         }
     }
 
+    pub fn next_crate_num(&self) -> ast::CrateNum {
+        self.metas.borrow().len() as ast::CrateNum + 1
+    }
+
     pub fn get_crate_data(&self, cnum: ast::CrateNum) -> @crate_metadata {
         *self.metas.borrow().get(&cnum)
     }
@@ -121,6 +128,9 @@ impl CStore {
             .map(|source| source.clone())
     }
 
+    pub fn dump_phase_syntax_crates(&self) {
+    }
+
     pub fn reset(&self) {
         self.metas.borrow_mut().clear();
         self.extern_mod_crate_map.borrow_mut().clear();
@@ -202,6 +212,8 @@ impl CStore {
 
 impl crate_metadata {
     pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
+    pub fn crate_id(&self) -> CrateId { decoder::get_crate_id(self.data()) }
+    pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
 }
 
 impl MetadataBlob {