]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_driver/lib.rs
Auto merge of #43710 - zackmdavis:field_init_shorthand_power_slam, r=Mark-Simulacrum
[rust.git] / src / librustc_driver / lib.rs
index 4c337993468e6803eb82e1e1912254401769573a..a726a792767e20ecf40fab1205640141dec1ae3f 100644 (file)
@@ -49,7 +49,9 @@
 extern crate rustc_mir;
 extern crate rustc_resolve;
 extern crate rustc_save_analysis;
+#[cfg(feature="llvm")]
 extern crate rustc_trans;
+extern crate rustc_trans_utils;
 extern crate rustc_typeck;
 extern crate serialize;
 #[macro_use]
@@ -64,8 +66,6 @@
 use rustc_resolve as resolve;
 use rustc_save_analysis as save;
 use rustc_save_analysis::DumpHandler;
-use rustc_trans::back::link;
-use rustc_trans::back::write::{RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
 use rustc::dep_graph::DepGraph;
 use rustc::session::{self, config, Session, build_session, CompileResult};
 use rustc::session::CompileIncomplete;
@@ -151,6 +151,104 @@ pub fn run<F>(run_compiler: F) -> isize
     0
 }
 
+#[cfg(not(feature="llvm"))]
+pub use no_llvm_metadata_loader::NoLLvmMetadataLoader as MetadataLoader;
+#[cfg(feature="llvm")]
+pub use rustc_trans::LlvmMetadataLoader as MetadataLoader;
+
+#[cfg(not(feature="llvm"))]
+mod no_llvm_metadata_loader {
+    extern crate ar;
+    extern crate owning_ref;
+
+    use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait;
+    use rustc_back::target::Target;
+    use std::io;
+    use std::fs::File;
+    use std::path::Path;
+
+    use self::ar::Archive;
+    use self::owning_ref::{OwningRef, ErasedBoxRef};
+
+    pub struct NoLLvmMetadataLoader;
+
+    impl MetadataLoaderTrait for NoLLvmMetadataLoader {
+        fn get_rlib_metadata(
+            &self,
+            _: &Target,
+            filename: &Path
+        ) -> Result<ErasedBoxRef<[u8]>, String> {
+            let file = File::open(filename).map_err(|e| {
+                format!("metadata file open err: {:?}", e)
+            })?;
+            let mut archive = Archive::new(file);
+
+            while let Some(entry_result) = archive.next_entry() {
+                let mut entry = entry_result.map_err(|e| {
+                    format!("metadata section read err: {:?}", e)
+                })?;
+                if entry.header().identifier() == "rust.metadata.bin" {
+                    let mut buf = Vec::new();
+                    io::copy(&mut entry, &mut buf).unwrap();
+                    let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
+                    return Ok(buf.map_owner_box().erase_owner());
+                }
+            }
+
+            Err("Couldnt find metadata section".to_string())
+        }
+
+        fn get_dylib_metadata(&self,
+                            _target: &Target,
+                            _filename: &Path)
+                            -> Result<ErasedBoxRef<[u8]>, String> {
+            panic!("Dylib metadata loading not supported without LLVM")
+        }
+    }
+}
+
+#[cfg(not(feature="llvm"))]
+mod rustc_trans {
+    use syntax_pos::symbol::Symbol;
+    use rustc::session::Session;
+    use rustc::session::config::{PrintRequest, OutputFilenames};
+    use rustc::ty::{TyCtxt, CrateAnalysis};
+    use rustc::ty::maps::Providers;
+    use rustc_incremental::IncrementalHashesMap;
+
+    use self::back::write::OngoingCrateTranslation;
+
+    pub fn init(_sess: &Session) {}
+    pub fn enable_llvm_debug() {}
+    pub fn provide(_providers: &mut Providers) {}
+    pub fn print_version() {}
+    pub fn print_passes() {}
+    pub fn print(_req: PrintRequest, _sess: &Session) {}
+    pub fn target_features(_sess: &Session) -> Vec<Symbol> { vec![] }
+
+    pub fn trans_crate<'a, 'tcx>(
+        _tcx: TyCtxt<'a, 'tcx, 'tcx>,
+        _analysis: CrateAnalysis,
+        _incr_hashes_map: IncrementalHashesMap,
+        _output_filenames: &OutputFilenames
+    ) -> OngoingCrateTranslation {
+        OngoingCrateTranslation(())
+    }
+
+    pub struct CrateTranslation(());
+
+    pub mod back {
+        pub mod write {
+            pub struct OngoingCrateTranslation(pub (in ::rustc_trans) ());
+
+            pub const RELOC_MODEL_ARGS: [(&'static str, ()); 0] = [];
+            pub const CODE_GEN_MODEL_ARGS: [(&'static str, ()); 0] = [];
+        }
+    }
+
+    __build_diagnostic_array! { librustc_trans, DIAGNOSTICS }
+}
+
 // Parse args and run the compiler. This is the primary entry point for rustc.
 // See comments on CompilerCalls below for details about the callbacks argument.
 // The FileLoader provides a way to load files from sources other than the file system.
@@ -197,7 +295,7 @@ macro_rules! do_or_return {($expr: expr, $sess: expr) => {
     };
 
     let dep_graph = DepGraph::new(sopts.build_dep_graph());
-    let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
+    let cstore = Rc::new(CStore::new(&dep_graph, box ::MetadataLoader));
 
     let loader = file_loader.unwrap_or(box RealFileLoader);
     let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping()));
@@ -422,7 +520,7 @@ fn show_content_with_pager(content: &String) {
 
     match Command::new(pager_name).stdin(Stdio::piped()).spawn() {
         Ok(mut pager) => {
-            if let Some(mut pipe) = pager.stdin.as_mut() {
+            if let Some(pipe) = pager.stdin.as_mut() {
                 if pipe.write_all(content.as_bytes()).is_err() {
                     fallback_to_println = true;
                 }
@@ -477,7 +575,7 @@ fn no_input(&mut self,
                     return None;
                 }
                 let dep_graph = DepGraph::new(sopts.build_dep_graph());
-                let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
+                let cstore = Rc::new(CStore::new(&dep_graph, box ::MetadataLoader));
                 let mut sess = build_session(sopts.clone(),
                     &dep_graph,
                     None,
@@ -518,7 +616,8 @@ fn build_controller(&mut self,
                         -> CompileController<'a> {
         let mut control = CompileController::basic();
 
-        control.keep_ast = sess.opts.debugging_opts.keep_ast || save_analysis(sess);
+        control.keep_ast = sess.opts.debugging_opts.keep_ast;
+        control.continue_parse_after_error = sess.opts.debugging_opts.continue_parse_after_error;
 
         if let Some((ppm, opt_uii)) = parse_pretty(sess, matches) {
             if ppm.needs_ast_map(&opt_uii) {
@@ -574,19 +673,7 @@ fn build_controller(&mut self,
         }
 
         if save_analysis(sess) {
-            control.after_analysis.callback = box |state| {
-                time(state.session.time_passes(), "save analysis", || {
-                    save::process_crate(state.tcx.unwrap(),
-                                        state.expanded_crate.unwrap(),
-                                        state.analysis.unwrap(),
-                                        state.crate_name.unwrap(),
-                                        None,
-                                        DumpHandler::new(state.out_dir,
-                                                         state.crate_name.unwrap()))
-                });
-            };
-            control.after_analysis.run_callback_on_error = true;
-            control.make_glob_map = resolve::MakeGlobMap::Yes;
+            enable_save_analysis(&mut control);
         }
 
         if sess.print_fuel_crate.is_some() {
@@ -603,6 +690,23 @@ fn build_controller(&mut self,
     }
 }
 
+pub fn enable_save_analysis(control: &mut CompileController) {
+    control.keep_ast = true;
+    control.after_analysis.callback = box |state| {
+        time(state.session.time_passes(), "save analysis", || {
+            save::process_crate(state.tcx.unwrap(),
+                                state.expanded_crate.unwrap(),
+                                state.analysis.unwrap(),
+                                state.crate_name.unwrap(),
+                                None,
+                                DumpHandler::new(state.out_dir,
+                                                 state.crate_name.unwrap()))
+        });
+    };
+    control.after_analysis.run_callback_on_error = true;
+    control.make_glob_map = resolve::MakeGlobMap::Yes;
+}
+
 fn save_analysis(sess: &Session) -> bool {
     sess.opts.debugging_opts.save_analysis
 }
@@ -672,14 +776,19 @@ fn print_crate_info(sess: &Session,
                     };
                     let attrs = attrs.as_ref().unwrap();
                     let t_outputs = driver::build_output_filenames(input, odir, ofile, attrs, sess);
-                    let id = link::find_crate_name(Some(sess), attrs, input);
+                    let id = rustc_trans_utils::link::find_crate_name(Some(sess), attrs, input);
                     if *req == PrintRequest::CrateName {
                         println!("{}", id);
                         continue;
                     }
                     let crate_types = driver::collect_crate_types(sess, attrs);
                     for &style in &crate_types {
-                        let fname = link::filename_for_input(sess, style, &id, &t_outputs);
+                        let fname = rustc_trans_utils::link::filename_for_input(
+                            sess,
+                            style,
+                            &id,
+                            &t_outputs
+                        );
                         println!("{}",
                                  fname.file_name()
                                       .unwrap()
@@ -693,7 +802,7 @@ fn print_crate_info(sess: &Session,
                     let mut cfgs = Vec::new();
                     for &(name, ref value) in sess.parse_sess.config.iter() {
                         let gated_cfg = GatedCfg::gate(&ast::MetaItem {
-                            name: name,
+                            name,
                             node: ast::MetaItemKind::Word,
                             span: DUMMY_SP,
                         });
@@ -728,14 +837,14 @@ fn print_crate_info(sess: &Session,
                 }
                 PrintRequest::RelocationModels => {
                     println!("Available relocation models:");
-                    for &(name, _) in RELOC_MODEL_ARGS.iter() {
+                    for &(name, _) in rustc_trans::back::write::RELOC_MODEL_ARGS.iter() {
                         println!("    {}", name);
                     }
                     println!("");
                 }
                 PrintRequest::CodeModels => {
                     println!("Available code models:");
-                    for &(name, _) in CODE_GEN_MODEL_ARGS.iter(){
+                    for &(name, _) in rustc_trans::back::write::CODE_GEN_MODEL_ARGS.iter(){
                         println!("    {}", name);
                     }
                     println!("");
@@ -1215,7 +1324,7 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
     Registry::new(&all_errors)
 }
 
-fn get_args() -> Vec<String> {
+pub fn get_args() -> Vec<String> {
     env::args_os().enumerate()
         .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| {
              early_error(ErrorOutputType::default(),