@@ -26,6 +26,7 @@ use middle::lang_items::LangItem;
2626use middle:: subst:: { self , Substs } ;
2727use trans:: base;
2828use trans:: build;
29+ use trans:: builder:: Builder ;
2930use trans:: callee;
3031use trans:: cleanup;
3132use trans:: consts;
@@ -45,6 +46,7 @@ use util::nodemap::{FnvHashMap, NodeMap};
4546
4647use arena:: TypedArena ;
4748use libc:: { c_uint, c_char} ;
49+ use std:: ops:: Deref ;
4850use std:: ffi:: CString ;
4951use std:: cell:: { Cell , RefCell } ;
5052use std:: vec:: Vec ;
@@ -365,6 +367,9 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
365367 // The arena that blocks are allocated from.
366368 pub block_arena : & ' a TypedArena < BlockS < ' a , ' tcx > > ,
367369
370+ // The arena that landing pads are allocated from.
371+ pub lpad_arena : TypedArena < LandingPad > ,
372+
368373 // This function's enclosing crate context.
369374 pub ccx : & ' a CrateContext < ' a , ' tcx > ,
370375
@@ -582,7 +587,7 @@ pub struct BlockS<'blk, 'tcx: 'blk> {
582587
583588 // If this block part of a landing pad, then this is `Some` indicating what
584589 // kind of landing pad its in, otherwise this is none.
585- pub lpad : RefCell < Option < LandingPad > > ,
590+ pub lpad : Cell < Option < & ' blk LandingPad > > ,
586591
587592 // AST node-id associated with this block, if any. Used for
588593 // debugging purposes only.
@@ -604,7 +609,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
604609 llbb : llbb,
605610 terminated : Cell :: new ( false ) ,
606611 unreachable : Cell :: new ( false ) ,
607- lpad : RefCell :: new ( None ) ,
612+ lpad : Cell :: new ( None ) ,
608613 opt_node_id : opt_node_id,
609614 fcx : fcx
610615 } )
@@ -613,11 +618,18 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
613618 pub fn ccx ( & self ) -> & ' blk CrateContext < ' blk , ' tcx > {
614619 self . fcx . ccx
615620 }
621+ pub fn fcx ( & self ) -> & ' blk FunctionContext < ' blk , ' tcx > {
622+ self . fcx
623+ }
616624 pub fn tcx ( & self ) -> & ' blk ty:: ctxt < ' tcx > {
617625 self . fcx . ccx . tcx ( )
618626 }
619627 pub fn sess ( & self ) -> & ' blk Session { self . fcx . ccx . sess ( ) }
620628
629+ pub fn lpad ( & self ) -> Option < & ' blk LandingPad > {
630+ self . lpad . get ( )
631+ }
632+
621633 pub fn mir ( & self ) -> & ' blk Mir < ' tcx > {
622634 self . fcx . mir ( )
623635 }
@@ -659,6 +671,109 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
659671 self . fcx . param_substs ,
660672 value)
661673 }
674+
675+ pub fn build ( & ' blk self ) -> BlockAndBuilder < ' blk , ' tcx > {
676+ BlockAndBuilder :: new ( self , OwnedBuilder :: new_with_ccx ( self . ccx ( ) ) )
677+ }
678+ }
679+
680+ pub struct OwnedBuilder < ' blk , ' tcx : ' blk > {
681+ builder : Builder < ' blk , ' tcx >
682+ }
683+
684+ impl < ' blk , ' tcx > OwnedBuilder < ' blk , ' tcx > {
685+ pub fn new_with_ccx ( ccx : & ' blk CrateContext < ' blk , ' tcx > ) -> Self {
686+ // Create a fresh builder from the crate context.
687+ let llbuilder = unsafe {
688+ llvm:: LLVMCreateBuilderInContext ( ccx. llcx ( ) )
689+ } ;
690+ OwnedBuilder {
691+ builder : Builder {
692+ llbuilder : llbuilder,
693+ ccx : ccx,
694+ }
695+ }
696+ }
697+ }
698+
699+ impl < ' blk , ' tcx > Drop for OwnedBuilder < ' blk , ' tcx > {
700+ fn drop ( & mut self ) {
701+ unsafe {
702+ llvm:: LLVMDisposeBuilder ( self . builder . llbuilder ) ;
703+ }
704+ }
705+ }
706+
707+ pub struct BlockAndBuilder < ' blk , ' tcx : ' blk > {
708+ bcx : Block < ' blk , ' tcx > ,
709+ owned_builder : OwnedBuilder < ' blk , ' tcx > ,
710+ }
711+
712+ impl < ' blk , ' tcx > BlockAndBuilder < ' blk , ' tcx > {
713+ pub fn new ( bcx : Block < ' blk , ' tcx > , owned_builder : OwnedBuilder < ' blk , ' tcx > ) -> Self {
714+ // Set the builder's position to this block's end.
715+ owned_builder. builder . position_at_end ( bcx. llbb ) ;
716+ BlockAndBuilder {
717+ bcx : bcx,
718+ owned_builder : owned_builder,
719+ }
720+ }
721+
722+ pub fn with_block < F , R > ( & self , f : F ) -> R
723+ where F : FnOnce ( Block < ' blk , ' tcx > ) -> R
724+ {
725+ let result = f ( self . bcx ) ;
726+ self . position_at_end ( self . bcx . llbb ) ;
727+ result
728+ }
729+
730+ pub fn map_block < F > ( self , f : F ) -> Self
731+ where F : FnOnce ( Block < ' blk , ' tcx > ) -> Block < ' blk , ' tcx >
732+ {
733+ let BlockAndBuilder { bcx, owned_builder } = self ;
734+ let bcx = f ( bcx) ;
735+ BlockAndBuilder :: new ( bcx, owned_builder)
736+ }
737+
738+ // Methods delegated to bcx
739+
740+ pub fn ccx ( & self ) -> & ' blk CrateContext < ' blk , ' tcx > {
741+ self . bcx . ccx ( )
742+ }
743+ pub fn fcx ( & self ) -> & ' blk FunctionContext < ' blk , ' tcx > {
744+ self . bcx . fcx ( )
745+ }
746+ pub fn tcx ( & self ) -> & ' blk ty:: ctxt < ' tcx > {
747+ self . bcx . tcx ( )
748+ }
749+ pub fn sess ( & self ) -> & ' blk Session {
750+ self . bcx . sess ( )
751+ }
752+
753+ pub fn llbb ( & self ) -> BasicBlockRef {
754+ self . bcx . llbb
755+ }
756+
757+ pub fn mir ( & self ) -> & ' blk Mir < ' tcx > {
758+ self . bcx . mir ( )
759+ }
760+
761+ pub fn val_to_string ( & self , val : ValueRef ) -> String {
762+ self . bcx . val_to_string ( val)
763+ }
764+
765+ pub fn monomorphize < T > ( & self , value : & T ) -> T
766+ where T : TypeFoldable < ' tcx >
767+ {
768+ self . bcx . monomorphize ( value)
769+ }
770+ }
771+
772+ impl < ' blk , ' tcx > Deref for BlockAndBuilder < ' blk , ' tcx > {
773+ type Target = Builder < ' blk , ' tcx > ;
774+ fn deref ( & self ) -> & Self :: Target {
775+ & self . owned_builder . builder
776+ }
662777}
663778
664779/// A structure representing an active landing pad for the duration of a basic
0 commit comments