diff options
| -rw-r--r-- | src/librustc/metadata/creader.rs | 263 | ||||
| -rw-r--r-- | src/librustc_driver/driver.rs | 4 |
2 files changed, 142 insertions, 125 deletions
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 623682a9cd5..578507296fc 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -34,14 +34,21 @@ use syntax::codemap::{self, Span, mk_sp, Pos}; use syntax::parse; use syntax::parse::token::InternedString; use syntax::visit; +use ast_map; use log; +pub struct LocalCrateReader<'a, 'b:'a> { + sess: &'a Session, + creader: CrateReader<'a>, + ast_map: &'a ast_map::Map<'b>, +} + pub struct CrateReader<'a> { sess: &'a Session, next_crate_num: ast::CrateNum, } -impl<'a, 'v> visit::Visitor<'v> for CrateReader<'a> { +impl<'a, 'b, 'v> visit::Visitor<'v> for LocalCrateReader<'a, 'b> { fn visit_item(&mut self, a: &ast::Item) { self.process_item(a); visit::walk_item(self, a); @@ -152,31 +159,6 @@ impl<'a> CrateReader<'a> { } } - // 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(&mut self, krate: &ast::Crate) { - self.process_crate(krate); - visit::walk_crate(self, krate); - - if log_enabled!(log::DEBUG) { - dump_crates(&self.sess.cstore); - } - - for &(ref name, kind) in &self.sess.opts.libs { - register_native_lib(self.sess, None, name.clone(), kind); - } - } - - fn process_crate(&self, c: &ast::Crate) { - for a in c.attrs.iter().filter(|m| m.name() == "link_args") { - match a.value_str() { - Some(ref linkarg) => self.sess.cstore.add_used_link_args(&linkarg), - None => { /* fallthrough */ } - } - } - } - fn extract_crate_info(&self, i: &ast::Item) -> Option<CrateInfo> { match i.node { ast::ItemExternCrate(ref path_opt) => { @@ -201,103 +183,6 @@ impl<'a> CrateReader<'a> { } } - fn process_item(&mut self, i: &ast::Item) { - match i.node { - ast::ItemExternCrate(_) => { - if !should_link(i) { - return; - } - - match self.extract_crate_info(i) { - Some(info) => { - let (cnum, _, _) = self.resolve_crate(&None, - &info.ident, - &info.name, - None, - i.span, - PathKind::Crate); - self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum); - } - None => () - } - } - ast::ItemForeignMod(ref fm) => { - if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic { - return; - } - - // First, add all of the custom link_args attributes - let link_args = i.attrs.iter() - .filter_map(|at| if at.name() == "link_args" { - Some(at) - } else { - None - }) - .collect::<Vec<&ast::Attribute>>(); - for m in &link_args { - match m.value_str() { - Some(linkarg) => self.sess.cstore.add_used_link_args(&linkarg), - None => { /* fallthrough */ } - } - } - - // Next, process all of the #[link(..)]-style arguments - let link_args = i.attrs.iter() - .filter_map(|at| if at.name() == "link" { - Some(at) - } else { - None - }) - .collect::<Vec<&ast::Attribute>>(); - for m in &link_args { - match m.meta_item_list() { - Some(items) => { - let kind = items.iter().find(|k| { - k.name() == "kind" - }).and_then(|a| a.value_str()); - let kind = match kind { - Some(k) => { - if k == "static" { - cstore::NativeStatic - } else if self.sess.target.target.options.is_like_osx - && k == "framework" { - cstore::NativeFramework - } else if k == "framework" { - cstore::NativeFramework - } else if k == "dylib" { - cstore::NativeUnknown - } else { - self.sess.span_err(m.span, - &format!("unknown kind: `{}`", - k)); - cstore::NativeUnknown - } - } - None => cstore::NativeUnknown - }; - let n = items.iter().find(|n| { - n.name() == "name" - }).and_then(|a| a.value_str()); - let n = match n { - Some(n) => n, - None => { - self.sess.span_err(m.span, - "#[link(...)] specified without \ - `name = \"foo\"`"); - InternedString::new("foo") - } - }; - register_native_lib(self.sess, Some(m.span), - n.to_string(), kind); - } - None => {} - } - } - } - _ => { } - } - } - fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind) -> Option<ast::CrateNum> { let mut ret = None; @@ -592,6 +477,138 @@ impl<'a> CrateReader<'a> { } } +impl<'a, 'b> LocalCrateReader<'a, 'b> { + pub fn new(sess: &'a Session, map: &'a ast_map::Map<'b>) -> LocalCrateReader<'a, 'b> { + LocalCrateReader { + sess: sess, + creader: CrateReader::new(sess), + ast_map: map, + } + } + + // 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(&mut self, krate: &ast::Crate) { + self.process_crate(krate); + visit::walk_crate(self, krate); + + if log_enabled!(log::DEBUG) { + dump_crates(&self.sess.cstore); + } + + for &(ref name, kind) in &self.sess.opts.libs { + register_native_lib(self.sess, None, name.clone(), kind); + } + } + + fn process_crate(&self, c: &ast::Crate) { + for a in c.attrs.iter().filter(|m| m.name() == "link_args") { + match a.value_str() { + Some(ref linkarg) => self.sess.cstore.add_used_link_args(&linkarg), + None => { /* fallthrough */ } + } + } + } + + fn process_item(&mut self, i: &ast::Item) { + match i.node { + ast::ItemExternCrate(_) => { + if !should_link(i) { + return; + } + + match self.creader.extract_crate_info(i) { + Some(info) => { + let (cnum, _, _) = self.creader.resolve_crate(&None, + &info.ident, + &info.name, + None, + i.span, + PathKind::Crate); + self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum); + } + None => () + } + } + ast::ItemForeignMod(ref fm) => { + if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic { + return; + } + + // First, add all of the custom link_args attributes + let link_args = i.attrs.iter() + .filter_map(|at| if at.name() == "link_args" { + Some(at) + } else { + None + }) + .collect::<Vec<&ast::Attribute>>(); + for m in &link_args { + match m.value_str() { + Some(linkarg) => self.sess.cstore.add_used_link_args(&linkarg), + None => { /* fallthrough */ } + } + } + + // Next, process all of the #[link(..)]-style arguments + let link_args = i.attrs.iter() + .filter_map(|at| if at.name() == "link" { + Some(at) + } else { + None + }) + .collect::<Vec<&ast::Attribute>>(); + for m in &link_args { + match m.meta_item_list() { + Some(items) => { + let kind = items.iter().find(|k| { + k.name() == "kind" + }).and_then(|a| a.value_str()); + let kind = match kind { + Some(k) => { + if k == "static" { + cstore::NativeStatic + } else if self.sess.target.target.options.is_like_osx + && k == "framework" { + cstore::NativeFramework + } else if k == "framework" { + cstore::NativeFramework + } else if k == "dylib" { + cstore::NativeUnknown + } else { + self.sess.span_err(m.span, + &format!("unknown kind: `{}`", + k)); + cstore::NativeUnknown + } + } + None => cstore::NativeUnknown + }; + let n = items.iter().find(|n| { + n.name() == "name" + }).and_then(|a| a.value_str()); + let n = match n { + Some(n) => n, + None => { + self.sess.span_err(m.span, + "#[link(...)] specified without \ + `name = \"foo\"`"); + InternedString::new("foo") + } + }; + register_native_lib(self.sess, Some(m.span), + n.to_string(), kind); + } + None => {} + } + } + } + _ => { } + } + } +} + /// Imports the codemap from an external crate into the codemap of the crate /// currently being compiled (the "local crate"). /// diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 67301a09e52..80db6426917 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -14,7 +14,7 @@ use rustc::session::search_paths::PathKind; use rustc::ast_map; use rustc::lint; use rustc::metadata; -use rustc::metadata::creader::CrateReader; +use rustc::metadata::creader::LocalCrateReader; use rustc::middle::{stability, ty, reachable}; use rustc::middle::dependency_format; use rustc::middle; @@ -609,7 +609,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session, let krate = ast_map.krate(); time(time_passes, "external crate/lib resolution", (), |_| - CrateReader::new(&sess).read_crates(krate)); + LocalCrateReader::new(&sess, &ast_map).read_crates(krate)); let lang_items = time(time_passes, "language item collection", (), |_| middle::lang_items::collect_language_items(krate, &sess)); |
