@@ -26,6 +26,7 @@ use middle::lang_items::LangItem;
26
26
use middle:: subst:: { self , Substs } ;
27
27
use trans:: base;
28
28
use trans:: build;
29
+ use trans:: builder:: Builder ;
29
30
use trans:: callee;
30
31
use trans:: cleanup;
31
32
use trans:: consts;
@@ -45,6 +46,7 @@ use util::nodemap::{FnvHashMap, NodeMap};
45
46
46
47
use arena:: TypedArena ;
47
48
use libc:: { c_uint, c_char} ;
49
+ use std:: ops:: Deref ;
48
50
use std:: ffi:: CString ;
49
51
use std:: cell:: { Cell , RefCell } ;
50
52
use std:: vec:: Vec ;
@@ -365,6 +367,9 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
365
367
// The arena that blocks are allocated from.
366
368
pub block_arena : & ' a TypedArena < BlockS < ' a , ' tcx > > ,
367
369
370
+ // The arena that landing pads are allocated from.
371
+ pub lpad_arena : TypedArena < LandingPad > ,
372
+
368
373
// This function's enclosing crate context.
369
374
pub ccx : & ' a CrateContext < ' a , ' tcx > ,
370
375
@@ -582,7 +587,7 @@ pub struct BlockS<'blk, 'tcx: 'blk> {
582
587
583
588
// If this block part of a landing pad, then this is `Some` indicating what
584
589
// kind of landing pad its in, otherwise this is none.
585
- pub lpad : RefCell < Option < LandingPad > > ,
590
+ pub lpad : Cell < Option < & ' blk LandingPad > > ,
586
591
587
592
// AST node-id associated with this block, if any. Used for
588
593
// debugging purposes only.
@@ -604,7 +609,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
604
609
llbb : llbb,
605
610
terminated : Cell :: new ( false ) ,
606
611
unreachable : Cell :: new ( false ) ,
607
- lpad : RefCell :: new ( None ) ,
612
+ lpad : Cell :: new ( None ) ,
608
613
opt_node_id : opt_node_id,
609
614
fcx : fcx
610
615
} )
@@ -613,11 +618,18 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
613
618
pub fn ccx ( & self ) -> & ' blk CrateContext < ' blk , ' tcx > {
614
619
self . fcx . ccx
615
620
}
621
+ pub fn fcx ( & self ) -> & ' blk FunctionContext < ' blk , ' tcx > {
622
+ self . fcx
623
+ }
616
624
pub fn tcx ( & self ) -> & ' blk ty:: ctxt < ' tcx > {
617
625
self . fcx . ccx . tcx ( )
618
626
}
619
627
pub fn sess ( & self ) -> & ' blk Session { self . fcx . ccx . sess ( ) }
620
628
629
+ pub fn lpad ( & self ) -> Option < & ' blk LandingPad > {
630
+ self . lpad . get ( )
631
+ }
632
+
621
633
pub fn mir ( & self ) -> & ' blk Mir < ' tcx > {
622
634
self . fcx . mir ( )
623
635
}
@@ -659,6 +671,109 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
659
671
self . fcx . param_substs ,
660
672
value)
661
673
}
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
+ }
662
777
}
663
778
664
779
/// A structure representing an active landing pad for the duration of a basic
0 commit comments