@@ -1956,6 +1956,49 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1956
1956
closure:: ClosureEnv :: NotClosure ) ;
1957
1957
}
1958
1958
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
+
1959
2002
pub fn trans_named_tuple_constructor < ' blk , ' tcx > ( mut bcx : Block < ' blk , ' tcx > ,
1960
2003
ctor_ty : Ty < ' tcx > ,
1961
2004
disr : Disr ,
@@ -2275,79 +2318,33 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
2275
2318
let _icx = push_ctxt ( "trans_item" ) ;
2276
2319
2277
2320
let tcx = ccx. tcx ( ) ;
2278
- let from_external = ccx. external_srcs ( ) . borrow ( ) . contains_key ( & item. id ) ;
2279
-
2280
2321
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" ) ;
2313
2334
}
2314
2335
}
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
- }
2322
2336
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
2342
2338
}
2343
2339
hir:: ItemEnum ( ref enum_definition, ref gens) => {
2344
2340
if gens. ty_params . is_empty ( ) {
2345
2341
// sizes only make sense for non-generic types
2346
2342
enum_variant_size_lint ( ccx, enum_definition, item. span , item. id ) ;
2347
2343
}
2348
2344
}
2345
+ hir:: ItemImpl ( ..) |
2349
2346
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
2351
2348
// being "collector-driven".
2352
2349
}
2353
2350
_ => { }
@@ -2490,16 +2487,16 @@ fn internalize_symbols(cx: &CrateContextList, reachable: &HashSet<&str>) {
2490
2487
let linkage = llvm:: LLVMGetLinkage ( val) ;
2491
2488
// We only care about external declarations (not definitions)
2492
2489
// 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) ;
2497
2498
}
2498
2499
2499
- let name = CStr :: from_ptr ( llvm:: LLVMGetValueName ( val) )
2500
- . to_bytes ( )
2501
- . to_vec ( ) ;
2502
- declared. insert ( name) ;
2503
2500
}
2504
2501
}
2505
2502
@@ -2509,21 +2506,27 @@ fn internalize_symbols(cx: &CrateContextList, reachable: &HashSet<&str>) {
2509
2506
for ccx in cx. iter ( ) {
2510
2507
for val in iter_globals ( ccx. llmod ( ) ) . chain ( iter_functions ( ccx. llmod ( ) ) ) {
2511
2508
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
+
2512
2514
// 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
+ }
2518
2529
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) ;
2527
2530
}
2528
2531
}
2529
2532
}
@@ -2752,6 +2755,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
2752
2755
span_bug ! ( item. span, "Mismatch between hir::Item type and TransItem type" )
2753
2756
}
2754
2757
}
2758
+ TransItem :: Fn ( instance) => {
2759
+ trans_instance ( & ccx, instance) ;
2760
+ }
2755
2761
_ => { }
2756
2762
}
2757
2763
}
@@ -2988,7 +2994,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
2988
2994
let mut item_keys: Vec < _ > = items
2989
2995
. iter ( )
2990
2996
. map ( |i| {
2991
- let mut output = i. to_string ( scx. tcx ( ) ) ;
2997
+ let mut output = i. to_string ( scx) ;
2992
2998
output. push_str ( " @@" ) ;
2993
2999
let mut empty = Vec :: new ( ) ;
2994
3000
let mut cgus = item_to_cgus. get_mut ( i) . unwrap_or ( & mut empty) ;
0 commit comments