@@ -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 ;
@@ -613,6 +615,9 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
613615 pub fn ccx ( & self ) -> & ' blk CrateContext < ' blk , ' tcx > {
614616 self . fcx . ccx
615617 }
618+ pub fn fcx ( & self ) -> & ' blk FunctionContext < ' blk , ' tcx > {
619+ self . fcx
620+ }
616621 pub fn tcx ( & self ) -> & ' blk ty:: ctxt < ' tcx > {
617622 self . fcx . ccx . tcx ( )
618623 }
@@ -659,6 +664,109 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
659664 self . fcx . param_substs ,
660665 value)
661666 }
667+
668+ pub fn build ( & ' blk self ) -> BlockAndBuilder < ' blk , ' tcx > {
669+ BlockAndBuilder :: new ( self , OwnedBuilder :: new_with_ccx ( self . ccx ( ) ) )
670+ }
671+ }
672+
673+ pub struct OwnedBuilder < ' blk , ' tcx : ' blk > {
674+ builder : Builder < ' blk , ' tcx >
675+ }
676+
677+ impl < ' blk , ' tcx > OwnedBuilder < ' blk , ' tcx > {
678+ pub fn new_with_ccx ( ccx : & ' blk CrateContext < ' blk , ' tcx > ) -> Self {
679+ // Create a fresh builder from the crate context.
680+ let llbuilder = unsafe {
681+ llvm:: LLVMCreateBuilderInContext ( ccx. llcx ( ) )
682+ } ;
683+ OwnedBuilder {
684+ builder : Builder {
685+ llbuilder : llbuilder,
686+ ccx : ccx,
687+ }
688+ }
689+ }
690+ }
691+
692+ impl < ' blk , ' tcx > Drop for OwnedBuilder < ' blk , ' tcx > {
693+ fn drop ( & mut self ) {
694+ unsafe {
695+ llvm:: LLVMDisposeBuilder ( self . builder . llbuilder ) ;
696+ }
697+ }
698+ }
699+
700+ pub struct BlockAndBuilder < ' blk , ' tcx : ' blk > {
701+ bcx : Block < ' blk , ' tcx > ,
702+ owned_builder : OwnedBuilder < ' blk , ' tcx > ,
703+ }
704+
705+ impl < ' blk , ' tcx > BlockAndBuilder < ' blk , ' tcx > {
706+ pub fn new ( bcx : Block < ' blk , ' tcx > , owned_builder : OwnedBuilder < ' blk , ' tcx > ) -> Self {
707+ // Set the builder's position to this block's end.
708+ owned_builder. builder . position_at_end ( bcx. llbb ) ;
709+ BlockAndBuilder {
710+ bcx : bcx,
711+ owned_builder : owned_builder,
712+ }
713+ }
714+
715+ pub fn with_block < F , R > ( & self , f : F ) -> R
716+ where F : FnOnce ( Block < ' blk , ' tcx > ) -> R
717+ {
718+ let result = f ( self . bcx ) ;
719+ self . position_at_end ( self . bcx . llbb ) ;
720+ result
721+ }
722+
723+ pub fn map_block < F > ( self , f : F ) -> Self
724+ where F : FnOnce ( Block < ' blk , ' tcx > ) -> Block < ' blk , ' tcx >
725+ {
726+ let BlockAndBuilder { bcx, owned_builder } = self ;
727+ let bcx = f ( bcx) ;
728+ BlockAndBuilder :: new ( bcx, owned_builder)
729+ }
730+
731+ // Methods delegated to bcx
732+
733+ pub fn ccx ( & self ) -> & ' blk CrateContext < ' blk , ' tcx > {
734+ self . bcx . ccx ( )
735+ }
736+ pub fn fcx ( & self ) -> & ' blk FunctionContext < ' blk , ' tcx > {
737+ self . bcx . fcx ( )
738+ }
739+ pub fn tcx ( & self ) -> & ' blk ty:: ctxt < ' tcx > {
740+ self . bcx . tcx ( )
741+ }
742+ pub fn sess ( & self ) -> & ' blk Session {
743+ self . bcx . sess ( )
744+ }
745+
746+ pub fn llbb ( & self ) -> BasicBlockRef {
747+ self . bcx . llbb
748+ }
749+
750+ pub fn mir ( & self ) -> & ' blk Mir < ' tcx > {
751+ self . bcx . mir ( )
752+ }
753+
754+ pub fn val_to_string ( & self , val : ValueRef ) -> String {
755+ self . bcx . val_to_string ( val)
756+ }
757+
758+ pub fn monomorphize < T > ( & self , value : & T ) -> T
759+ where T : TypeFoldable < ' tcx >
760+ {
761+ self . bcx . monomorphize ( value)
762+ }
763+ }
764+
765+ impl < ' blk , ' tcx > Deref for BlockAndBuilder < ' blk , ' tcx > {
766+ type Target = Builder < ' blk , ' tcx > ;
767+ fn deref ( & self ) -> & Self :: Target {
768+ & self . owned_builder . builder
769+ }
662770}
663771
664772/// A structure representing an active landing pad for the duration of a basic
0 commit comments