#![feature(rustc_private)]
extern crate rustc_driver;
extern crate rustc_hir;
extern crate rustc_session;
use log::*;
use std::env;
use rupta::pta::PTACallbacks;
use rupta::util;
use rupta::util::options::AnalysisOptions;
fn main() {
let early_dcx =
rustc_session::EarlyDiagCtxt::new(rustc_session::config::ErrorOutputType::default());
if env::var("RUSTC_LOG").is_ok() {
rustc_driver::init_rustc_env_logger(&early_dcx);
}
if env::var("PTA_LOG").is_ok() {
let e = env_logger::Env::new()
.filter("PTA_LOG")
.write_style("PTA_LOG_STYLE");
env_logger::init_from_env(e);
}
let mut options = AnalysisOptions::default();
let pta_flags = env::var("PTA_FLAGS").unwrap_or_default();
let pta_args: Vec<String> = serde_json::from_str(&pta_flags).unwrap_or_default();
let rustc_args = options.parse_from_args(&pta_args[..], true);
let mut args = env::args_os()
.enumerate()
.map(|(i, arg)| {
arg.into_string().unwrap_or_else(|arg| {
early_dcx.early_fatal(format!("Argument {i} is not valid Unicode: {arg:?}"))
})
})
.collect::<Vec<_>>();
if args.len() > 1 && std::path::Path::new(&args[1]).file_stem() == Some("rustc".as_ref()) {
args.remove(1);
}
let mut rustc_command_line_arguments = options.parse_from_args(&args[1..], false);
info!("PTA Options: {:?}", options);
let result = rustc_driver::catch_fatal_errors(move || {
rustc_command_line_arguments.insert(0, args[0].clone());
rustc_command_line_arguments.extend(rustc_args);
let sysroot: String = "--sysroot".into();
if !rustc_command_line_arguments.iter().any(|arg| arg.starts_with(&sysroot)) {
rustc_command_line_arguments.push(sysroot);
rustc_command_line_arguments.push(util::find_sysroot());
}
let always_encode_mir: String = "always-encode-mir".into();
if !rustc_command_line_arguments.iter().any(|arg| arg.ends_with(&always_encode_mir))
{
rustc_command_line_arguments.push("-Z".into());
rustc_command_line_arguments.push(always_encode_mir);
}
debug!("rustc command line arguments: {:?}", rustc_command_line_arguments);
let mut callbacks = PTACallbacks::new(options);
let compiler = rustc_driver::RunCompiler::new(&rustc_command_line_arguments, &mut callbacks);
compiler.run()
})
.and_then(|result| result);
let exit_code = match result {
Ok(_) => rustc_driver::EXIT_SUCCESS,
Err(_) => rustc_driver::EXIT_FAILURE,
};
std::process::exit(exit_code);
}