use rustc::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc::middle::cstore::EncodedMetadata;
use rustc::middle::cstore::{self, LinkagePreference};
+use rustc::middle::lang_items;
use rustc::middle::lang_items::StartFnLangItem;
-use rustc::middle::weak_lang_items;
use rustc::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
use rustc::session::config::{self, EntryFnType, Lto};
use rustc::session::Session;
/// Creates the `main` function which will initialize the rust runtime and call
/// users main function.
-pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'a Bx::CodegenCx) {
+pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+ cx: &'a Bx::CodegenCx,
+) -> Option<Bx::Function> {
let (main_def_id, span) = match cx.tcx().entry_fn(LOCAL_CRATE) {
Some((def_id, _)) => (def_id, cx.tcx().def_span(def_id)),
- None => return,
+ None => return None,
};
let instance = Instance::mono(cx.tcx(), main_def_id);
if !cx.codegen_unit().contains_item(&MonoItem::Fn(instance)) {
// We want to create the wrapper in the same codegen unit as Rust's main
// function.
- return;
+ return None;
}
let main_llfn = cx.get_fn_addr(instance);
- let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1);
- match et {
- Some(EntryFnType::Main) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, true),
- Some(EntryFnType::Start) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, false),
- None => {} // Do nothing.
- }
+ return cx.tcx().entry_fn(LOCAL_CRATE).map(|(_, et)| {
+ let use_start_lang_item = EntryFnType::Start != et;
+ create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, use_start_lang_item)
+ });
fn create_entry_fn<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
rust_main: Bx::Value,
rust_main_def_id: DefId,
use_start_lang_item: bool,
- ) {
+ ) -> Bx::Function {
// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
// depending on whether the target needs `argc` and `argv` to be passed in.
let llfty = if cx.sess().target.target.options.main_needs_argc_argv {
let result = bx.call(start_fn, &args, None);
let cast = bx.intcast(result, cx.type_int(), true);
bx.ret(cast);
+
+ llfn
}
}
// No need to look for lang items that are whitelisted and don't
// actually need to exist.
- let missing = missing
- .iter()
- .cloned()
- .filter(|&l| !weak_lang_items::whitelisted(tcx, l))
- .collect();
+ let missing =
+ missing.iter().cloned().filter(|&l| !lang_items::whitelisted(tcx, l)).collect();
info.missing_lang_items.insert(cnum, missing);
}