@@ -77,6 +77,7 @@ use trans::debuginfo::{self, DebugLoc, ToDebugLoc};
7777use trans:: declare;
7878use trans:: expr;
7979use trans:: glue;
80+ use trans:: inline;
8081use trans:: intrinsic;
8182use trans:: machine;
8283use trans:: machine:: { llalign_of_min, llsize_of, llsize_of_real} ;
@@ -1392,34 +1393,53 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
13921393 pub fn new ( ccx : & ' blk CrateContext < ' blk , ' tcx > ,
13931394 llfndecl : ValueRef ,
13941395 fn_ty : FnType ,
1395- id : ast :: NodeId ,
1396+ def_id : Option < DefId > ,
13961397 param_substs : & ' tcx Substs < ' tcx > ,
1397- sp : Option < Span > ,
13981398 block_arena : & ' blk TypedArena < common:: BlockS < ' blk , ' tcx > > )
13991399 -> FunctionContext < ' blk , ' tcx > {
14001400 common:: validate_substs ( param_substs) ;
14011401
1402- debug ! ( "FunctionContext::new(path={}, id={}, param_substs={:?})" ,
1403- if id == !0 {
1404- "" . to_string( )
1405- } else {
1402+ let inlined_did = def_id. and_then ( |def_id| inline:: get_local_instance ( ccx, def_id) ) ;
1403+ let inlined_id = inlined_did. and_then ( |id| ccx. tcx ( ) . map . as_local_node_id ( id) ) ;
1404+ let local_id = def_id. and_then ( |id| ccx. tcx ( ) . map . as_local_node_id ( id) ) ;
1405+
1406+ debug ! ( "FunctionContext::new(path={}, def_id={:?}, param_substs={:?})" ,
1407+ inlined_id. map_or( String :: new( ) , |id| {
14061408 ccx. tcx( ) . map. path_to_string( id) . to_string( )
1407- } ,
1408- id ,
1409+ } ) ,
1410+ def_id ,
14091411 param_substs) ;
14101412
1411- let debug_context = debuginfo:: create_function_debug_context ( ccx, id ,
1412- param_substs,
1413- llfndecl ) ;
1414- let ( blk_id , cfg) = build_cfg ( ccx. tcx ( ) , id) ;
1415- let nested_returns = if let Some ( ref cfg) = cfg {
1413+ let debug_context = debuginfo:: create_function_debug_context ( ccx,
1414+ inlined_id . unwrap_or ( ast :: DUMMY_NODE_ID ) , param_substs, llfndecl ) ;
1415+
1416+ let cfg = inlined_id . map ( |id| build_cfg ( ccx. tcx ( ) , id) ) ;
1417+ let nested_returns = if let Some ( ( blk_id , Some ( ref cfg) ) ) = cfg {
14161418 has_nested_returns ( ccx. tcx ( ) , cfg, blk_id)
14171419 } else {
14181420 false
14191421 } ;
14201422
1423+ let check_attrs = |attrs : & [ ast:: Attribute ] | {
1424+ attrs. iter ( ) . any ( |item| item. check_name ( "rustc_mir" ) )
1425+ } ;
1426+
1427+ let use_mir = if let Some ( id) = local_id {
1428+ check_attrs ( ccx. tcx ( ) . map . attrs ( id) )
1429+ } else if let Some ( def_id) = def_id {
1430+ check_attrs ( & ccx. sess ( ) . cstore . item_attrs ( def_id) )
1431+ } else {
1432+ check_attrs ( & [ ] )
1433+ } ;
1434+
1435+ let mir = if use_mir {
1436+ def_id. and_then ( |id| ccx. get_mir ( id) )
1437+ } else {
1438+ None
1439+ } ;
1440+
14211441 FunctionContext {
1422- mir : ccx . mir_map ( ) . map . get ( & id ) ,
1442+ mir : mir ,
14231443 llfn : llfndecl,
14241444 llretslotptr : Cell :: new ( None ) ,
14251445 param_env : ccx. tcx ( ) . empty_parameter_environment ( ) ,
@@ -1431,21 +1451,21 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
14311451 llupvars : RefCell :: new ( NodeMap ( ) ) ,
14321452 lldropflag_hints : RefCell :: new ( DropFlagHintsMap :: new ( ) ) ,
14331453 fn_ty : fn_ty,
1434- id : id,
14351454 param_substs : param_substs,
1436- span : sp ,
1455+ span : inlined_id . and_then ( |id| ccx . tcx ( ) . map . opt_span ( id ) ) ,
14371456 block_arena : block_arena,
14381457 lpad_arena : TypedArena :: new ( ) ,
14391458 ccx : ccx,
14401459 debug_context : debug_context,
14411460 scopes : RefCell :: new ( Vec :: new ( ) ) ,
1442- cfg : cfg,
1461+ cfg : cfg. and_then ( | ( _ , cfg ) | cfg )
14431462 }
14441463 }
14451464
14461465 /// Performs setup on a newly created function, creating the entry
14471466 /// scope block and allocating space for the return pointer.
1448- pub fn init ( & ' blk self , skip_retptr : bool ) -> Block < ' blk , ' tcx > {
1467+ pub fn init ( & ' blk self , skip_retptr : bool , fn_did : Option < DefId > )
1468+ -> Block < ' blk , ' tcx > {
14491469 let entry_bcx = self . new_temp_block ( "entry-block" ) ;
14501470
14511471 // Use a dummy instruction as the insertion point for all allocas.
@@ -1493,15 +1513,15 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
14931513
14941514 // Create the drop-flag hints for every unfragmented path in the function.
14951515 let tcx = self . ccx . tcx ( ) ;
1496- let fn_did = tcx. map . local_def_id ( self . id ) ;
14971516 let tables = tcx. tables . borrow ( ) ;
14981517 let mut hints = self . lldropflag_hints . borrow_mut ( ) ;
14991518 let fragment_infos = tcx. fragment_infos . borrow ( ) ;
15001519
15011520 // Intern table for drop-flag hint datums.
15021521 let mut seen = HashMap :: new ( ) ;
15031522
1504- if let Some ( fragment_infos) = fragment_infos. get ( & fn_did) {
1523+ let fragment_infos = fn_did. and_then ( |did| fragment_infos. get ( & did) ) ;
1524+ if let Some ( fragment_infos) = fragment_infos {
15051525 for & info in fragment_infos {
15061526
15071527 let make_datum = |id| {
@@ -1558,11 +1578,13 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
15581578 fn bind_args ( & ' blk self ,
15591579 args : & [ hir:: Arg ] ,
15601580 abi : Abi ,
1581+ id : ast:: NodeId ,
15611582 closure_env : closure:: ClosureEnv ,
15621583 arg_scope : cleanup:: CustomScopeIndex )
15631584 -> Block < ' blk , ' tcx > {
15641585 let _icx = push_ctxt ( "FunctionContext::bind_args" ) ;
1565- let mut bcx = self . init ( false ) ;
1586+ let fn_did = self . ccx . tcx ( ) . map . local_def_id ( id) ;
1587+ let mut bcx = self . init ( false , Some ( fn_did) ) ;
15661588 let arg_scope_id = cleanup:: CustomScope ( arg_scope) ;
15671589
15681590 let mut idx = 0 ;
@@ -1774,19 +1796,24 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
17741796/// Builds an LLVM function out of a source function.
17751797///
17761798/// If the function closes over its environment a closure will be returned.
1777- pub fn trans_closure < ' a , ' b , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1778- decl : & hir:: FnDecl ,
1779- body : & hir:: Block ,
1780- llfndecl : ValueRef ,
1781- param_substs : & ' tcx Substs < ' tcx > ,
1782- fn_ast_id : ast :: NodeId ,
1783- attributes : & [ ast:: Attribute ] ,
1784- fn_ty : FnType ,
1785- abi : Abi ,
1786- closure_env : closure:: ClosureEnv < ' b > ) {
1799+ pub fn trans_closure < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1800+ decl : & hir:: FnDecl ,
1801+ body : & hir:: Block ,
1802+ llfndecl : ValueRef ,
1803+ param_substs : & ' tcx Substs < ' tcx > ,
1804+ def_id : DefId ,
1805+ inlined_id : ast:: NodeId ,
1806+ fn_ty : FnType ,
1807+ abi : Abi ,
1808+ closure_env : closure:: ClosureEnv ) {
17871809 ccx. stats ( ) . n_closures . set ( ccx. stats ( ) . n_closures . get ( ) + 1 ) ;
17881810
1789- record_translation_item_as_generated ( ccx, fn_ast_id, param_substs) ;
1811+ if collector:: collecting_debug_information ( ccx) {
1812+ ccx. record_translation_item_as_generated ( TransItem :: Fn ( Instance {
1813+ def : def_id,
1814+ params : & param_substs. types
1815+ } ) )
1816+ }
17901817
17911818 let _icx = push_ctxt ( "trans_closure" ) ;
17921819 attributes:: emit_uwtable ( llfndecl, true ) ;
@@ -1795,23 +1822,20 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
17951822
17961823 let ( arena, fcx) : ( TypedArena < _ > , FunctionContext ) ;
17971824 arena = TypedArena :: new ( ) ;
1798- fcx = FunctionContext :: new ( ccx, llfndecl, fn_ty, fn_ast_id,
1799- param_substs, Some ( body. span ) , & arena) ;
1825+ fcx = FunctionContext :: new ( ccx, llfndecl, fn_ty, Some ( def_id) , param_substs, & arena) ;
18001826
1801- if attributes . iter ( ) . any ( |item| item . check_name ( "rustc_mir" ) ) {
1827+ if fcx . mir . is_some ( ) {
18021828 return mir:: trans_mir ( & fcx) ;
18031829 }
18041830
18051831 // cleanup scope for the incoming arguments
1806- let fn_cleanup_debug_loc = debuginfo:: get_cleanup_debug_loc_for_ast_node ( ccx,
1807- fn_ast_id,
1808- body. span ,
1809- true ) ;
1832+ let fn_cleanup_debug_loc = debuginfo:: get_cleanup_debug_loc_for_ast_node (
1833+ ccx, inlined_id, body. span , true ) ;
18101834 let arg_scope = fcx. push_custom_cleanup_scope_with_debug_loc ( fn_cleanup_debug_loc) ;
18111835
18121836 // Set up arguments to the function.
18131837 debug ! ( "trans_closure: function: {:?}" , Value ( fcx. llfn) ) ;
1814- let bcx = fcx. bind_args ( & decl. inputs , abi, closure_env, arg_scope) ;
1838+ let bcx = fcx. bind_args ( & decl. inputs , abi, inlined_id , closure_env, arg_scope) ;
18151839
18161840 // Up until here, IR instructions for this function have explicitly not been annotated with
18171841 // source code location, so we don't step into call setup code. From here on, source location
@@ -1862,28 +1886,6 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
18621886
18631887 // Insert the mandatory first few basic blocks before lltop.
18641888 fcx. finish ( bcx, ret_debug_loc) ;
1865-
1866- fn record_translation_item_as_generated < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1867- node_id : ast:: NodeId ,
1868- param_substs : & ' tcx Substs < ' tcx > ) {
1869- if !collector:: collecting_debug_information ( ccx) {
1870- return ;
1871- }
1872-
1873- let def_id = match ccx. tcx ( ) . node_id_to_type ( node_id) . sty {
1874- ty:: TyClosure ( def_id, _) => def_id,
1875- _ => ccx. external_srcs ( )
1876- . borrow ( )
1877- . get ( & node_id)
1878- . map ( |did| * did)
1879- . unwrap_or_else ( || ccx. tcx ( ) . map . local_def_id ( node_id) ) ,
1880- } ;
1881-
1882- ccx. record_translation_item_as_generated ( TransItem :: Fn ( Instance {
1883- def : def_id,
1884- params : & param_substs. types ,
1885- } ) ) ;
1886- }
18871889}
18881890
18891891/// Creates an LLVM function corresponding to a source language function.
@@ -1892,8 +1894,7 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
18921894 body : & hir:: Block ,
18931895 llfndecl : ValueRef ,
18941896 param_substs : & ' tcx Substs < ' tcx > ,
1895- id : ast:: NodeId ,
1896- attrs : & [ ast:: Attribute ] ) {
1897+ id : ast:: NodeId ) {
18971898 let _s = StatRecorder :: new ( ccx, ccx. tcx ( ) . map . path_to_string ( id) . to_string ( ) ) ;
18981899 debug ! ( "trans_fn(param_substs={:?})" , param_substs) ;
18991900 let _icx = push_ctxt ( "trans_fn" ) ;
@@ -1903,13 +1904,18 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
19031904 let sig = infer:: normalize_associated_type ( ccx. tcx ( ) , & sig) ;
19041905 let abi = fn_ty. fn_abi ( ) ;
19051906 let fn_ty = FnType :: new ( ccx, abi, & sig, & [ ] ) ;
1907+ let def_id = if let Some ( & def_id) = ccx. external_srcs ( ) . borrow ( ) . get ( & id) {
1908+ def_id
1909+ } else {
1910+ ccx. tcx ( ) . map . local_def_id ( id)
1911+ } ;
19061912 trans_closure ( ccx,
19071913 decl,
19081914 body,
19091915 llfndecl,
19101916 param_substs,
1917+ def_id,
19111918 id,
1912- attrs,
19131919 fn_ty,
19141920 abi,
19151921 closure:: ClosureEnv :: NotClosure ) ;
@@ -2001,9 +2007,10 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
20012007
20022008 let ( arena, fcx) : ( TypedArena < _ > , FunctionContext ) ;
20032009 arena = TypedArena :: new ( ) ;
2004- fcx = FunctionContext :: new ( ccx, llfndecl, fn_ty, ctor_id,
2005- param_substs, None , & arena) ;
2006- let bcx = fcx. init ( false ) ;
2010+ fcx = FunctionContext :: new ( ccx, llfndecl, fn_ty,
2011+ Some ( ccx. tcx ( ) . map . local_def_id ( ctor_id) ) ,
2012+ param_substs, & arena) ;
2013+ let bcx = fcx. init ( false , None ) ;
20072014
20082015 assert ! ( !fcx. needs_ret_allocas) ;
20092016
@@ -2239,7 +2246,7 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
22392246 let empty_substs = tcx. mk_substs ( Substs :: trans_empty ( ) ) ;
22402247 let def_id = tcx. map . local_def_id ( item. id ) ;
22412248 let llfn = Callee :: def ( ccx, def_id, empty_substs) . reify ( ccx) . val ;
2242- trans_fn ( ccx, & decl, & body, llfn, empty_substs, item. id , & item . attrs ) ;
2249+ trans_fn ( ccx, & decl, & body, llfn, empty_substs, item. id ) ;
22432250 set_global_section ( ccx, llfn, item) ;
22442251 update_linkage ( ccx,
22452252 llfn,
@@ -2278,8 +2285,7 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
22782285 let empty_substs = tcx. mk_substs ( Substs :: trans_empty ( ) ) ;
22792286 let def_id = tcx. map . local_def_id ( impl_item. id ) ;
22802287 let llfn = Callee :: def ( ccx, def_id, empty_substs) . reify ( ccx) . val ;
2281- trans_fn ( ccx, & sig. decl , body, llfn, empty_substs,
2282- impl_item. id , & impl_item. attrs ) ;
2288+ trans_fn ( ccx, & sig. decl , body, llfn, empty_substs, impl_item. id ) ;
22832289 update_linkage ( ccx, llfn, Some ( impl_item. id ) ,
22842290 if is_origin {
22852291 OriginalTranslation
0 commit comments