@@ -117,21 +117,36 @@ macro_rules! builder_methods_for_value_instructions {
117
117
}
118
118
}
119
119
120
+ // HACK(eddyb) this is an easy way to avoid a complex relationship between
121
+ // `Builder` and `UnpositionedBuilder`, even if it seems lopsided.
122
+ pub struct UnpositionedBuilder < ' a , ' ll , ' tcx > ( Builder < ' a , ' ll , ' tcx > ) ;
123
+
120
124
impl BuilderMethods < ' a , ' tcx > for Builder < ' a , ' ll , ' tcx > {
125
+ type Unpositioned = UnpositionedBuilder < ' a , ' ll , ' tcx > ;
126
+
127
+ fn unpositioned ( cx : & ' a CodegenCx < ' ll , ' tcx > ) -> Self :: Unpositioned {
128
+ // Create a fresh builder from the crate context.
129
+ let llbuilder = unsafe { llvm:: LLVMCreateBuilderInContext ( cx. llcx ) } ;
130
+ UnpositionedBuilder ( Builder { llbuilder, cx } )
131
+ }
132
+
133
+ fn position_at_end ( bx : Self :: Unpositioned , llbb : & ' ll BasicBlock ) -> Self {
134
+ unsafe {
135
+ llvm:: LLVMPositionBuilderAtEnd ( bx. 0 . llbuilder , llbb) ;
136
+ }
137
+ bx. 0
138
+ }
139
+
140
+ fn into_unpositioned ( self ) -> Self :: Unpositioned {
141
+ UnpositionedBuilder ( self )
142
+ }
143
+
121
144
fn new_block < ' b > ( cx : & ' a CodegenCx < ' ll , ' tcx > , llfn : & ' ll Value , name : & ' b str ) -> Self {
122
- let mut bx = Builder :: with_cx ( cx) ;
123
145
let llbb = unsafe {
124
146
let name = SmallCStr :: new ( name) ;
125
147
llvm:: LLVMAppendBasicBlockInContext ( cx. llcx , llfn, name. as_ptr ( ) )
126
148
} ;
127
- bx. position_at_end ( llbb) ;
128
- bx
129
- }
130
-
131
- fn with_cx ( cx : & ' a CodegenCx < ' ll , ' tcx > ) -> Self {
132
- // Create a fresh builder from the crate context.
133
- let llbuilder = unsafe { llvm:: LLVMCreateBuilderInContext ( cx. llcx ) } ;
134
- Builder { llbuilder, cx }
149
+ Self :: position_at_end ( Self :: unpositioned ( cx) , llbb)
135
150
}
136
151
137
152
fn build_sibling_block ( & self , name : & str ) -> Self {
@@ -144,12 +159,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
144
159
145
160
fn set_span ( & mut self , _span : Span ) { }
146
161
147
- fn position_at_end ( & mut self , llbb : & ' ll BasicBlock ) {
148
- unsafe {
149
- llvm:: LLVMPositionBuilderAtEnd ( self . llbuilder , llbb) ;
150
- }
151
- }
152
-
153
162
fn ret_void ( & mut self ) {
154
163
unsafe {
155
164
llvm:: LLVMBuildRetVoid ( self . llbuilder ) ;
@@ -384,9 +393,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
384
393
}
385
394
386
395
fn alloca ( & mut self , ty : & ' ll Type , align : Align ) -> & ' ll Value {
387
- let mut bx = Builder :: with_cx ( self . cx ) ;
388
- bx. position_at_start ( unsafe { llvm:: LLVMGetFirstBasicBlock ( self . llfn ( ) ) } ) ;
389
- bx. dynamic_alloca ( ty, align)
396
+ let entry_llbb = unsafe { llvm:: LLVMGetFirstBasicBlock ( self . llfn ( ) ) } ;
397
+ Self :: position_at_start ( Self :: unpositioned ( self . cx ) , entry_llbb) . dynamic_alloca ( ty, align)
390
398
}
391
399
392
400
fn dynamic_alloca ( & mut self , ty : & ' ll Type , align : Align ) -> & ' ll Value {
@@ -1169,10 +1177,11 @@ impl Builder<'a, 'll, 'tcx> {
1169
1177
unsafe { llvm:: LLVMGetBasicBlockParent ( self . llbb ( ) ) }
1170
1178
}
1171
1179
1172
- fn position_at_start ( & mut self , llbb : & ' ll BasicBlock ) {
1180
+ fn position_at_start ( bx : UnpositionedBuilder < ' a , ' ll , ' tcx > , llbb : & ' ll BasicBlock ) -> Self {
1173
1181
unsafe {
1174
- llvm:: LLVMRustPositionBuilderAtStart ( self . llbuilder , llbb) ;
1182
+ llvm:: LLVMRustPositionBuilderAtStart ( bx . 0 . llbuilder , llbb) ;
1175
1183
}
1184
+ bx. 0
1176
1185
}
1177
1186
1178
1187
pub fn minnum ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
0 commit comments