use crate::queries::Queries; use crate::util; use crate::profile; pub use crate::passes::BoxedResolver; use rustc::lint; use rustc::session::config::{self, Input}; use rustc::session::{DiagnosticOutput, Session}; use rustc::util::common::ErrorReported; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::OnDrop; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_metadata::cstore::CStore; use std::io::Write; use std::path::PathBuf; use std::result; use std::sync::{Arc, Mutex}; use syntax; use syntax::source_map::{FileLoader, SourceMap}; pub type Result = result::Result; /// Represents a compiler session. /// Can be used run `rustc_interface` queries. /// Created by passing `Config` to `run_compiler`. pub struct Compiler { pub(crate) sess: Lrc, codegen_backend: Lrc>, source_map: Lrc, pub(crate) input: Input, pub(crate) input_path: Option, pub(crate) output_dir: Option, pub(crate) output_file: Option, pub(crate) queries: Queries, pub(crate) cstore: Lrc, pub(crate) crate_name: Option, } impl Compiler { pub fn session(&self) -> &Lrc { &self.sess } pub fn codegen_backend(&self) -> &Lrc> { &self.codegen_backend } pub fn cstore(&self) -> &Lrc { &self.cstore } pub fn source_map(&self) -> &Lrc { &self.source_map } pub fn input(&self) -> &Input { &self.input } pub fn output_dir(&self) -> &Option { &self.output_dir } pub fn output_file(&self) -> &Option { &self.output_file } } /// The compiler configuration pub struct Config { /// Command line options pub opts: config::Options, /// cfg! configuration in addition to the default ones pub crate_cfg: FxHashSet<(String, Option)>, pub input: Input, pub input_path: Option, pub output_dir: Option, pub output_file: Option, pub file_loader: Option>, pub diagnostic_output: DiagnosticOutput, /// Set to capture stderr output during compiler execution pub stderr: Option>>>, pub crate_name: Option, pub lint_caps: FxHashMap, } pub fn run_compiler_in_existing_thread_pool(config: Config, f: F) -> R where F: FnOnce(&Compiler) -> R, { let (sess, codegen_backend, source_map) = util::create_session( config.opts, config.crate_cfg, config.diagnostic_output, config.file_loader, config.input_path.clone(), config.lint_caps, ); let cstore = Lrc::new(CStore::new(codegen_backend.metadata_loader())); let compiler = Compiler { sess, codegen_backend, source_map, cstore, input: config.input, input_path: config.input_path, output_dir: config.output_dir, output_file: config.output_file, queries: Default::default(), crate_name: config.crate_name, }; let _sess_abort_error = OnDrop(|| compiler.sess.diagnostic().print_error_count()); if compiler.sess.profile_queries() { profile::begin(&compiler.sess); } let r = f(&compiler); if compiler.sess.profile_queries() { profile::dump(&compiler.sess, "profile_queries".to_string()) } r } pub fn run_compiler(mut config: Config, f: F) -> R where F: FnOnce(&Compiler) -> R + Send, R: Send, { let stderr = config.stderr.take(); util::spawn_thread_pool( config.opts.debugging_opts.threads, &stderr, || run_compiler_in_existing_thread_pool(config, f), ) } pub fn default_thread_pool(f: F) -> R where F: FnOnce() -> R + Send, R: Send, { util::spawn_thread_pool(None, &None, f) }