// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![cfg_attr(not(feature="llvm"), allow(dead_code))]
+
use rustc::hir::{self, map as hir_map};
use rustc::hir::lowering::lower_crate;
use rustc::ich::Fingerprint;
use rustc::session::config::{self, Input, OutputFilenames, OutputType};
use rustc::session::search_paths::PathKind;
use rustc::lint;
-use rustc::middle::{self, dependency_format, stability, reachable};
+use rustc::middle::{self, stability, reachable};
use rustc::middle::privacy::AccessLevels;
use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED, Passes};
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
use rustc_resolve::{MakeGlobMap, Resolver};
use rustc_metadata::creader::CrateLoader;
use rustc_metadata::cstore::{self, CStore};
-#[cfg(feature="llvm")]
-use rustc_trans::back::{link, write};
-#[cfg(feature="llvm")]
+use rustc_trans::back::write;
use rustc_trans as trans;
use rustc_typeck as typeck;
use rustc_privacy;
output: &Option<PathBuf>,
addl_plugins: Option<Vec<String>>,
control: &CompileController) -> CompileResult {
+ use rustc_trans::back::write::OngoingCrateTranslation;
macro_rules! controller_entry_point {
($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{
let state = &mut $make_state;
}}
}
+ if cfg!(not(feature="llvm")) {
+ use rustc::session::config::CrateType;
+ if !sess.opts.debugging_opts.no_trans && sess.opts.output_types.should_trans() {
+ sess.err("LLVM is not supported by this rustc. Please use -Z no-trans to compile")
+ }
+
+ if sess.opts.crate_types.iter().all(|&t|{
+ t != CrateType::CrateTypeRlib && t != CrateType::CrateTypeExecutable
+ }) && !sess.opts.crate_types.is_empty() {
+ sess.err(
+ "LLVM is not supported by this rustc, so non rlib libraries are not supported"
+ );
+ }
+
+ sess.abort_if_errors();
+ }
+
// We need nested scopes here, because the intermediate results can keep
// large chunks of memory alive and we want to free them as soon as
// possible to keep the peak memory usage low
- let (outputs, trans) = {
+ let (outputs, trans): (OutputFilenames, OngoingCrateTranslation) = {
let krate = match phase_1_parse_input(control, sess, input) {
Ok(krate) => krate,
Err(mut parse_error) => {
tcx.print_debug_stats();
}
- #[cfg(feature="llvm")]
let trans = phase_4_translate_to_llvm(tcx, analysis, incremental_hashes_map,
&outputs);
- #[cfg(not(feature="llvm"))]
- let trans = { panic!("LLVM not supported by this rustc."); () };
if log_enabled!(::log::LogLevel::Info) {
println!("Post-trans");
})??
};
- #[cfg(not(feature="llvm"))]
- unreachable!();
+ if cfg!(not(feature="llvm")) {
+ let (_, _) = (outputs, trans);
+ sess.fatal("LLVM is not supported by this rustc");
+ }
#[cfg(feature="llvm")]
{
/// This is a somewhat higher level controller than a Session - the Session
/// controls what happens in each phase, whereas the CompileController controls
/// whether a phase is run at all and whether other code (from outside the
-/// the compiler) is run between phases.
+/// compiler) is run between phases.
///
/// Note that if compilation is set to stop and a callback is provided for a
/// given entry point, the callback is called before compilation is stopped.
pub resolutions: Option<&'a Resolutions>,
pub analysis: Option<&'a ty::CrateAnalysis>,
pub tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
- #[cfg(feature="llvm")]
pub trans: Option<&'a trans::CrateTranslation>,
}
resolutions: None,
analysis: None,
tcx: None,
- #[cfg(feature="llvm")]
trans: None,
}
}
}
}
- #[cfg(feature="llvm")]
fn state_after_llvm(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
mir::provide(&mut local_providers);
reachable::provide(&mut local_providers);
rustc_privacy::provide(&mut local_providers);
- #[cfg(feature="llvm")]
trans::provide(&mut local_providers);
typeck::provide(&mut local_providers);
ty::provide(&mut local_providers);
let mut extern_providers = ty::maps::Providers::default();
cstore::provide(&mut extern_providers);
- #[cfg(feature="llvm")]
trans::provide(&mut extern_providers);
ty::provide_extern(&mut extern_providers);
traits::provide_extern(&mut extern_providers);
// These next passes must be executed together
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
- passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
+ passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::CriticalCallEdges);
passes.push_pass(MIR_OPTIMIZED, mir::transform::elaborate_drops::ElaborateDrops);
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
+ // AddValidation needs to run after ElaborateDrops and before EraseRegions, and it needs
+ // an AllCallEdges pass right before it.
+ passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AllCallEdges);
+ passes.push_pass(MIR_OPTIMIZED, mir::transform::add_validation::AddValidation);
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));
// No lifetime analysis based on borrowing can be done from here on out.
- // AddValidation needs to run after ElaborateDrops and before EraseRegions.
- passes.push_pass(MIR_OPTIMIZED, mir::transform::add_validation::AddValidation);
-
// From here on out, regions are gone.
passes.push_pass(MIR_OPTIMIZED, mir::transform::erase_regions::EraseRegions);
passes.push_pass(MIR_OPTIMIZED, mir::transform::deaggregator::Deaggregator);
passes.push_pass(MIR_OPTIMIZED, mir::transform::copy_prop::CopyPropagation);
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyLocals);
- passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
+ passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::CriticalCallEdges);
passes.push_pass(MIR_OPTIMIZED, mir::transform::dump_mir::Marker("PreTrans"));
TyCtxt::create_and_enter(sess,
/// Run the translation phase to LLVM, after which the AST and analysis can
/// be discarded.
-#[cfg(feature="llvm")]
pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
analysis: ty::CrateAnalysis,
incremental_hashes_map: IncrementalHashesMap,
time(time_passes,
"resolving dependency formats",
- || dependency_format::calculate(tcx));
+ || ::rustc::middle::dependency_format::calculate(tcx));
let translation =
time(time_passes,
pub fn phase_6_link_output(sess: &Session,
trans: &trans::CrateTranslation,
outputs: &OutputFilenames) {
- time(sess.time_passes(),
- "linking",
- || link::link_binary(sess, trans, outputs, &trans.crate_name.as_str()));
+ time(sess.time_passes(), "linking", || {
+ ::rustc_trans::back::link::link_binary(sess, trans, outputs, &trans.crate_name.as_str())
+ });
}
fn escape_dep_filename(filename: &str) -> String {
match *output_type {
OutputType::Exe => {
for output in sess.crate_types.borrow().iter() {
- let p = ::rustc_trans_utils::link::filename_for_input(sess, *output, crate_name, outputs);
+ let p = ::rustc_trans_utils::link::filename_for_input(
+ sess,
+ *output,
+ crate_name,
+ outputs
+ );
out_filenames.push(p);
}
}
base.into_iter()
.filter(|crate_type| {
- let res = !rustc_trans_utils::link::invalid_output_for_target(session, *crate_type);
+ let res = !::rustc_trans_utils::link::invalid_output_for_target(session, *crate_type);
if !res {
session.warn(&format!("dropping unsupported crate type `{}` for target `{}`",