@@ -2205,34 +2205,17 @@ pub fn set_link_section(ccx: &CrateContext,
22052205 }
22062206}
22072207
2208- pub fn trans_item ( ccx : & CrateContext , item : & hir:: Item ) {
2208+ fn trans_item ( ccx : & CrateContext , item : & hir:: Item ) {
22092209 let _icx = push_ctxt ( "trans_item" ) ;
22102210
2211- let tcx = ccx. tcx ( ) ;
22122211 match item. node {
2213- hir:: ItemFn ( _, _, _, _, _, _) => {
2214- let def_id = tcx. map . local_def_id ( item. id ) ;
2215- // check for the #[rustc_error] annotation, which forces an
2216- // error in trans. This is used to write compile-fail tests
2217- // that actually test that compilation succeeds without
2218- // reporting an error.
2219- if is_entry_fn ( ccx. sess ( ) , item. id ) {
2220- let empty_substs = ccx. empty_substs_for_def_id ( def_id) ;
2221- let llfn = Callee :: def ( ccx, def_id, empty_substs) . reify ( ccx) . val ;
2222- create_entry_wrapper ( ccx, item. span , llfn) ;
2223- if tcx. has_attr ( def_id, "rustc_error" ) {
2224- tcx. sess . span_fatal ( item. span , "compilation successful" ) ;
2225- }
2226- }
2227-
2228- // Function is actually translated in trans_instance
2229- }
22302212 hir:: ItemEnum ( ref enum_definition, ref gens) => {
22312213 if gens. ty_params . is_empty ( ) {
22322214 // sizes only make sense for non-generic types
22332215 enum_variant_size_lint ( ccx, enum_definition, item. span , item. id ) ;
22342216 }
22352217 }
2218+ hir:: ItemFn ( ..) |
22362219 hir:: ItemImpl ( ..) |
22372220 hir:: ItemStatic ( ..) => {
22382221 // Don't do anything here. Translation has been moved to
@@ -2242,22 +2225,40 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
22422225 }
22432226}
22442227
2245- pub fn is_entry_fn ( sess : & Session , node_id : ast:: NodeId ) -> bool {
2246- match * sess. entry_fn . borrow ( ) {
2247- Some ( ( entry_id, _) ) => node_id == entry_id,
2248- None => false ,
2228+ /// Create the `main` function which will initialise the rust runtime and call
2229+ /// users’ main function.
2230+ pub fn maybe_create_entry_wrapper ( ccx : & CrateContext ) {
2231+ let ( main_def_id, span) = match * ccx. sess ( ) . entry_fn . borrow ( ) {
2232+ Some ( ( id, span) ) => {
2233+ ( ccx. tcx ( ) . map . local_def_id ( id) , span)
2234+ }
2235+ None => return ,
2236+ } ;
2237+
2238+ // check for the #[rustc_error] annotation, which forces an
2239+ // error in trans. This is used to write compile-fail tests
2240+ // that actually test that compilation succeeds without
2241+ // reporting an error.
2242+ if ccx. tcx ( ) . has_attr ( main_def_id, "rustc_error" ) {
2243+ ccx. tcx ( ) . sess . span_fatal ( span, "compilation successful" ) ;
2244+ }
2245+
2246+ let instance = Instance :: mono ( ccx. shared ( ) , main_def_id) ;
2247+
2248+ if !ccx. codegen_unit ( ) . items . contains_key ( & TransItem :: Fn ( instance) ) {
2249+ // We want to create the wrapper in the same codegen unit as Rust's main
2250+ // function.
2251+ return ;
22492252 }
2250- }
22512253
2252- /// Create the `main` function which will initialise the rust runtime and call users’ main
2253- /// function.
2254- pub fn create_entry_wrapper ( ccx : & CrateContext , sp : Span , main_llfn : ValueRef ) {
2254+ let main_llfn = Callee :: def ( ccx, main_def_id, instance. substs ) . reify ( ccx) . val ;
2255+
22552256 let et = ccx. sess ( ) . entry_type . get ( ) . unwrap ( ) ;
22562257 match et {
22572258 config:: EntryMain => {
2258- create_entry_fn ( ccx, sp , main_llfn, true ) ;
2259+ create_entry_fn ( ccx, span , main_llfn, true ) ;
22592260 }
2260- config:: EntryStart => create_entry_fn ( ccx, sp , main_llfn, false ) ,
2261+ config:: EntryStart => create_entry_fn ( ccx, span , main_llfn, false ) ,
22612262 config:: EntryNone => { } // Do nothing.
22622263 }
22632264
@@ -2597,13 +2598,11 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
25972598 } ;
25982599 let no_builtins = attr:: contains_name ( & krate. attrs , "no_builtins" ) ;
25992600
2600- let ( codegen_units, symbol_map) =
2601- collect_and_partition_translation_items ( & shared_ccx) ;
2601+ // Run the translation item collector and partition the collected items into
2602+ // codegen units.
2603+ let ( codegen_units, symbol_map) = collect_and_partition_translation_items ( & shared_ccx) ;
26022604 let codegen_unit_count = codegen_units. len ( ) ;
26032605
2604- assert ! ( tcx. sess. opts. cg. codegen_units == codegen_unit_count ||
2605- tcx. sess. opts. debugging_opts. incremental. is_some( ) ) ;
2606-
26072606 let symbol_map = Rc :: new ( symbol_map) ;
26082607
26092608 let crate_context_list = CrateContextList :: new ( & shared_ccx,
@@ -2649,35 +2648,39 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
26492648 for ( trans_item, _) in trans_items {
26502649 trans_item. define ( & ccx) ;
26512650 }
2652- }
2653-
2654- {
2655- let ccx = crate_context_list. get_ccx ( 0 ) ;
2656-
2657- // Translate all items. See `TransModVisitor` for
2658- // details on why we walk in this particular way.
2659- {
2660- let _icx = push_ctxt ( "text" ) ;
2661- intravisit:: walk_mod ( & mut TransItemsWithinModVisitor { ccx : & ccx } , & krate. module ) ;
2662- krate. visit_all_items ( & mut TransModVisitor { ccx : & ccx } ) ;
2663- }
26642651
2665- collector:: print_collection_results ( ccx. shared ( ) ) ;
2652+ // If this codegen unit contains the main function, also create the
2653+ // wrapper here
2654+ maybe_create_entry_wrapper ( & ccx) ;
26662655
2667- symbol_names_test:: report_symbol_names ( & ccx) ;
2668- }
2669-
2670- for ccx in crate_context_list. iter ( ) {
2671- if ccx. sess ( ) . opts . debuginfo != NoDebugInfo {
2672- debuginfo:: finalize ( & ccx) ;
2673- }
2656+ // Run replace-all-uses-with for statics that need it
26742657 for & ( old_g, new_g) in ccx. statics_to_rauw ( ) . borrow ( ) . iter ( ) {
26752658 unsafe {
26762659 let bitcast = llvm:: LLVMConstPointerCast ( new_g, llvm:: LLVMTypeOf ( old_g) ) ;
26772660 llvm:: LLVMReplaceAllUsesWith ( old_g, bitcast) ;
26782661 llvm:: LLVMDeleteGlobal ( old_g) ;
26792662 }
26802663 }
2664+
2665+ // Finalize debuginfo
2666+ if ccx. sess ( ) . opts . debuginfo != NoDebugInfo {
2667+ debuginfo:: finalize ( & ccx) ;
2668+ }
2669+ }
2670+
2671+ collector:: print_collection_results ( & shared_ccx) ;
2672+ symbol_names_test:: report_symbol_names ( & shared_ccx) ;
2673+
2674+ {
2675+ let ccx = crate_context_list. get_ccx ( 0 ) ;
2676+
2677+ // At this point, we only walk the HIR for running
2678+ // enum_variant_size_lint(). This should arguably be moved somewhere
2679+ // else
2680+ {
2681+ intravisit:: walk_mod ( & mut TransItemsWithinModVisitor { ccx : & ccx } , & krate. module ) ;
2682+ krate. visit_all_items ( & mut TransModVisitor { ccx : & ccx } ) ;
2683+ }
26812684 }
26822685
26832686 if shared_ccx. sess ( ) . trans_stats ( ) {
@@ -2703,6 +2706,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27032706 }
27042707 }
27052708 }
2709+
27062710 if shared_ccx. sess ( ) . count_llvm_insns ( ) {
27072711 for ( k, v) in shared_ccx. stats ( ) . llvm_insns . borrow ( ) . iter ( ) {
27082712 println ! ( "{:7} {}" , * v, * k) ;
@@ -2874,6 +2878,9 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
28742878 scx. reachable ( ) )
28752879 } ) ;
28762880
2881+ assert ! ( scx. tcx( ) . sess. opts. cg. codegen_units == codegen_units. len( ) ||
2882+ scx. tcx( ) . sess. opts. debugging_opts. incremental. is_some( ) ) ;
2883+
28772884 if scx. sess ( ) . opts . debugging_opts . print_trans_items . is_some ( ) {
28782885 let mut item_to_cgus = HashMap :: new ( ) ;
28792886
0 commit comments