@@ -1956,6 +1956,49 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
19561956 closure:: ClosureEnv :: NotClosure ) ;
19571957}
19581958
1959+ pub fn trans_instance < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > , instance : Instance < ' tcx > ) {
1960+ let instance = inline:: maybe_inline_instance ( ccx, instance) ;
1961+
1962+ let fn_node_id = ccx. tcx ( ) . map . as_local_node_id ( instance. def ) . unwrap ( ) ;
1963+
1964+ let _s = StatRecorder :: new ( ccx, ccx. tcx ( ) . node_path_str ( fn_node_id) ) ;
1965+ debug ! ( "trans_instance(instance={:?})" , instance) ;
1966+ let _icx = push_ctxt ( "trans_instance" ) ;
1967+
1968+ let item = ccx. tcx ( ) . map . find ( fn_node_id) . unwrap ( ) ;
1969+
1970+ let fn_ty = ccx. tcx ( ) . lookup_item_type ( instance. def ) . ty ;
1971+ let fn_ty = ccx. tcx ( ) . erase_regions ( & fn_ty) ;
1972+ let fn_ty = monomorphize:: apply_param_substs ( ccx. tcx ( ) , instance. substs , & fn_ty) ;
1973+
1974+ let sig = ccx. tcx ( ) . erase_late_bound_regions ( fn_ty. fn_sig ( ) ) ;
1975+ let sig = ccx. tcx ( ) . normalize_associated_type ( & sig) ;
1976+ let abi = fn_ty. fn_abi ( ) ;
1977+
1978+ let lldecl = match ccx. instances ( ) . borrow ( ) . get ( & instance) {
1979+ Some ( & val) => val,
1980+ None => bug ! ( "Instance `{:?}` not already declared" , instance)
1981+ } ;
1982+
1983+ match item {
1984+ hir_map:: NodeItem ( & hir:: Item {
1985+ node : hir:: ItemFn ( ref decl, _, _, _, _, ref body) , ..
1986+ } ) |
1987+ hir_map:: NodeTraitItem ( & hir:: TraitItem {
1988+ node : hir:: MethodTraitItem (
1989+ hir:: MethodSig { ref decl, .. } , Some ( ref body) ) , ..
1990+ } ) |
1991+ hir_map:: NodeImplItem ( & hir:: ImplItem {
1992+ node : hir:: ImplItemKind :: Method (
1993+ hir:: MethodSig { ref decl, .. } , ref body) , ..
1994+ } ) => {
1995+ trans_closure ( ccx, decl, body, lldecl, instance,
1996+ fn_node_id, & sig, abi, closure:: ClosureEnv :: NotClosure ) ;
1997+ }
1998+ _ => bug ! ( "Instance is a {:?}?" , item)
1999+ }
2000+ }
2001+
19592002pub fn trans_named_tuple_constructor < ' blk , ' tcx > ( mut bcx : Block < ' blk , ' tcx > ,
19602003 ctor_ty : Ty < ' tcx > ,
19612004 disr : Disr ,
@@ -2275,79 +2318,33 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
22752318 let _icx = push_ctxt ( "trans_item" ) ;
22762319
22772320 let tcx = ccx. tcx ( ) ;
2278- let from_external = ccx. external_srcs ( ) . borrow ( ) . contains_key ( & item. id ) ;
2279-
22802321 match item. node {
2281- hir:: ItemFn ( ref decl, _, _, _, ref generics, ref body) => {
2282- if !generics. is_type_parameterized ( ) {
2283- let trans_everywhere = attr:: requests_inline ( & item. attrs ) ;
2284- // Ignore `trans_everywhere` for cross-crate inlined items
2285- // (`from_external`). `trans_item` will be called once for each
2286- // compilation unit that references the item, so it will still get
2287- // translated everywhere it's needed.
2288- for ( ref ccx, is_origin) in ccx. maybe_iter ( !from_external && trans_everywhere) {
2289- let def_id = tcx. map . local_def_id ( item. id ) ;
2290- let empty_substs = ccx. empty_substs_for_def_id ( def_id) ;
2291- let llfn = Callee :: def ( ccx, def_id, empty_substs) . reify ( ccx) . val ;
2292- trans_fn ( ccx, & decl, & body, llfn, empty_substs, item. id ) ;
2293- set_link_section ( ccx, llfn, & item. attrs ) ;
2294- update_linkage ( ccx,
2295- llfn,
2296- Some ( item. id ) ,
2297- if is_origin {
2298- OriginalTranslation
2299- } else {
2300- InlinedCopy
2301- } ) ;
2302-
2303- if is_entry_fn ( ccx. sess ( ) , item. id ) {
2304- create_entry_wrapper ( ccx, item. span , llfn) ;
2305- // check for the #[rustc_error] annotation, which forces an
2306- // error in trans. This is used to write compile-fail tests
2307- // that actually test that compilation succeeds without
2308- // reporting an error.
2309- if tcx. has_attr ( def_id, "rustc_error" ) {
2310- tcx. sess . span_fatal ( item. span , "compilation successful" ) ;
2311- }
2312- }
2322+ hir:: ItemFn ( _, _, _, _, _, _) => {
2323+ let def_id = tcx. map . local_def_id ( item. id ) ;
2324+ // check for the #[rustc_error] annotation, which forces an
2325+ // error in trans. This is used to write compile-fail tests
2326+ // that actually test that compilation succeeds without
2327+ // reporting an error.
2328+ if is_entry_fn ( ccx. sess ( ) , item. id ) {
2329+ let empty_substs = ccx. empty_substs_for_def_id ( def_id) ;
2330+ let llfn = Callee :: def ( ccx, def_id, empty_substs) . reify ( ccx) . val ;
2331+ create_entry_wrapper ( ccx, item. span , llfn) ;
2332+ if tcx. has_attr ( def_id, "rustc_error" ) {
2333+ tcx. sess . span_fatal ( item. span , "compilation successful" ) ;
23132334 }
23142335 }
2315- }
2316- hir:: ItemImpl ( _, _, ref generics, _, _, ref impl_items) => {
2317- // Both here and below with generic methods, be sure to recurse and look for
2318- // items that we need to translate.
2319- if !generics. ty_params . is_empty ( ) {
2320- return ;
2321- }
23222336
2323- for impl_item in impl_items {
2324- if let hir:: ImplItemKind :: Method ( ref sig, ref body) = impl_item. node {
2325- if sig. generics . ty_params . is_empty ( ) {
2326- let trans_everywhere = attr:: requests_inline ( & impl_item. attrs ) ;
2327- for ( ref ccx, is_origin) in ccx. maybe_iter ( trans_everywhere) {
2328- let def_id = tcx. map . local_def_id ( impl_item. id ) ;
2329- let empty_substs = ccx. empty_substs_for_def_id ( def_id) ;
2330- let llfn = Callee :: def ( ccx, def_id, empty_substs) . reify ( ccx) . val ;
2331- trans_fn ( ccx, & sig. decl , body, llfn, empty_substs, impl_item. id ) ;
2332- update_linkage ( ccx, llfn, Some ( impl_item. id ) ,
2333- if is_origin {
2334- OriginalTranslation
2335- } else {
2336- InlinedCopy
2337- } ) ;
2338- }
2339- }
2340- }
2341- }
2337+ // Function is actually translated in trans_instance
23422338 }
23432339 hir:: ItemEnum ( ref enum_definition, ref gens) => {
23442340 if gens. ty_params . is_empty ( ) {
23452341 // sizes only make sense for non-generic types
23462342 enum_variant_size_lint ( ccx, enum_definition, item. span , item. id ) ;
23472343 }
23482344 }
2345+ hir:: ItemImpl ( ..) |
23492346 hir:: ItemStatic ( ..) => {
2350- // Don't do anything here. Translation of statics has been moved to
2347+ // Don't do anything here. Translation has been moved to
23512348 // being "collector-driven".
23522349 }
23532350 _ => { }
@@ -2490,16 +2487,16 @@ fn internalize_symbols(cx: &CrateContextList, reachable: &HashSet<&str>) {
24902487 let linkage = llvm:: LLVMGetLinkage ( val) ;
24912488 // We only care about external declarations (not definitions)
24922489 // and available_externally definitions.
2493- if !( linkage == llvm:: ExternalLinkage as c_uint &&
2494- llvm:: LLVMIsDeclaration ( val) != 0 ) &&
2495- !( linkage == llvm:: AvailableExternallyLinkage as c_uint ) {
2496- continue ;
2490+ let is_available_externally = linkage == llvm:: AvailableExternallyLinkage as c_uint ;
2491+ let is_decl = llvm:: LLVMIsDeclaration ( val) != 0 ;
2492+
2493+ if is_decl || is_available_externally {
2494+ let name = CStr :: from_ptr ( llvm:: LLVMGetValueName ( val) )
2495+ . to_bytes ( )
2496+ . to_vec ( ) ;
2497+ declared. insert ( name) ;
24972498 }
24982499
2499- let name = CStr :: from_ptr ( llvm:: LLVMGetValueName ( val) )
2500- . to_bytes ( )
2501- . to_vec ( ) ;
2502- declared. insert ( name) ;
25032500 }
25042501 }
25052502
@@ -2509,21 +2506,27 @@ fn internalize_symbols(cx: &CrateContextList, reachable: &HashSet<&str>) {
25092506 for ccx in cx. iter ( ) {
25102507 for val in iter_globals ( ccx. llmod ( ) ) . chain ( iter_functions ( ccx. llmod ( ) ) ) {
25112508 let linkage = llvm:: LLVMGetLinkage ( val) ;
2509+
2510+ let is_external = linkage == llvm:: ExternalLinkage as c_uint ;
2511+ let is_weak_odr = linkage == llvm:: WeakODRLinkage as c_uint ;
2512+ let is_decl = llvm:: LLVMIsDeclaration ( val) != 0 ;
2513+
25122514 // We only care about external definitions.
2513- if !( ( linkage == llvm:: ExternalLinkage as c_uint ||
2514- linkage == llvm:: WeakODRLinkage as c_uint ) &&
2515- llvm:: LLVMIsDeclaration ( val) == 0 ) {
2516- continue ;
2517- }
2515+ if ( is_external || is_weak_odr) && !is_decl {
2516+
2517+ let name = CStr :: from_ptr ( llvm:: LLVMGetValueName ( val) )
2518+ . to_bytes ( )
2519+ . to_vec ( ) ;
2520+
2521+ let is_declared = declared. contains ( & name) ;
2522+ let reachable = reachable. contains ( str:: from_utf8 ( & name) . unwrap ( ) ) ;
2523+
2524+ if !is_declared && !reachable {
2525+ llvm:: SetLinkage ( val, llvm:: InternalLinkage ) ;
2526+ llvm:: SetDLLStorageClass ( val, llvm:: DefaultStorageClass ) ;
2527+ llvm:: UnsetComdat ( val) ;
2528+ }
25182529
2519- let name = CStr :: from_ptr ( llvm:: LLVMGetValueName ( val) )
2520- . to_bytes ( )
2521- . to_vec ( ) ;
2522- if !declared. contains ( & name) &&
2523- !reachable. contains ( str:: from_utf8 ( & name) . unwrap ( ) ) {
2524- llvm:: SetLinkage ( val, llvm:: InternalLinkage ) ;
2525- llvm:: SetDLLStorageClass ( val, llvm:: DefaultStorageClass ) ;
2526- llvm:: UnsetComdat ( val) ;
25272530 }
25282531 }
25292532 }
@@ -2752,6 +2755,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27522755 span_bug ! ( item. span, "Mismatch between hir::Item type and TransItem type" )
27532756 }
27542757 }
2758+ TransItem :: Fn ( instance) => {
2759+ trans_instance ( & ccx, instance) ;
2760+ }
27552761 _ => { }
27562762 }
27572763 }
@@ -2988,7 +2994,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
29882994 let mut item_keys: Vec < _ > = items
29892995 . iter ( )
29902996 . map ( |i| {
2991- let mut output = i. to_string ( scx. tcx ( ) ) ;
2997+ let mut output = i. to_string ( scx) ;
29922998 output. push_str ( " @@" ) ;
29932999 let mut empty = Vec :: new ( ) ;
29943000 let mut cgus = item_to_cgus. get_mut ( i) . unwrap_or ( & mut empty) ;
0 commit comments