1
Fork 0

Add option to pass a custom codegen backend from a driver

This commit is contained in:
bjorn3 2020-09-08 13:44:41 +02:00
parent 956e06c6c8
commit 71bc62b9f6
8 changed files with 37 additions and 5 deletions

View file

@ -141,6 +141,9 @@ pub fn run_compiler(
callbacks: &mut (dyn Callbacks + Send),
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
emitter: Option<Box<dyn Write + Send>>,
make_codegen_backend: Option<
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
>,
) -> interface::Result<()> {
let mut args = Vec::new();
for arg in at_args {
@ -162,6 +165,11 @@ pub fn run_compiler(
let sopts = config::build_session_options(&matches);
let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg"));
// We wrap `make_codegen_backend` in another `Option` such that `dummy_config` can take
// ownership of it when necessary, while also allowing the non-dummy config to take ownership
// when `dummy_config` is not used.
let mut make_codegen_backend = Some(make_codegen_backend);
let mut dummy_config = |sopts, cfg, diagnostic_output| {
let mut config = interface::Config {
opts: sopts,
@ -177,6 +185,7 @@ pub fn run_compiler(
lint_caps: Default::default(),
register_lints: None,
override_queries: None,
make_codegen_backend: make_codegen_backend.take().unwrap(),
registry: diagnostics_registry(),
};
callbacks.config(&mut config);
@ -253,6 +262,7 @@ pub fn run_compiler(
lint_caps: Default::default(),
register_lints: None,
override_queries: None,
make_codegen_backend: make_codegen_backend.unwrap(),
registry: diagnostics_registry(),
};
@ -1265,7 +1275,7 @@ pub fn main() -> ! {
})
})
.collect::<Vec<_>>();
run_compiler(&args, &mut callbacks, None, None)
run_compiler(&args, &mut callbacks, None, None, None)
});
// The extra `\t` is necessary to align this label with the others.
print_time_passes_entry(callbacks.time_passes, "\ttotal", start.elapsed());

View file

@ -154,6 +154,10 @@ pub struct Config {
pub override_queries:
Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::Providers)>,
/// This is a callback from the driver that is called to create a codegen backend.
pub make_codegen_backend:
Option<Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>>,
/// Registry of diagnostics codes.
pub registry: Registry,
}
@ -167,6 +171,7 @@ pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R
config.file_loader,
config.input_path.clone(),
config.lint_caps,
config.make_codegen_backend,
registry.clone(),
);

View file

@ -63,9 +63,17 @@ pub fn create_session(
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
input_path: Option<PathBuf>,
lint_caps: FxHashMap<lint::LintId, lint::Level>,
make_codegen_backend: Option<
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
>,
descriptions: Registry,
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>) {
let codegen_backend = get_codegen_backend(&sopts);
let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend {
make_codegen_backend(&sopts)
} else {
get_codegen_backend(&sopts)
};
// target_override is documented to be called before init(), so this is okay
let target_override = codegen_backend.target_override(&sopts);