@@ -25,6 +25,7 @@ use rustc_codegen_ssa::traits::{
25
25
BuilderMethods ,
26
26
ConstMethods ,
27
27
DerivedTypeMethods ,
28
+ LayoutTypeMethods ,
28
29
HasCodegen ,
29
30
OverflowOp ,
30
31
StaticBuilderMethods ,
@@ -514,8 +515,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
514
515
self . block . expect ( "block" ) . end_with_switch ( None , value, default_block, & gcc_cases) ;
515
516
}
516
517
517
- fn invoke ( & mut self , _func : RValue < ' gcc > , _args : & [ RValue < ' gcc > ] , _then : Block < ' gcc > , _catch : Block < ' gcc > , _funclet : Option < & Funclet > ) -> RValue < ' gcc > {
518
- unimplemented ! ( ) ;
518
+ fn invoke ( & mut self , _typ : Type < ' gcc > , _func : RValue < ' gcc > , _args : & [ RValue < ' gcc > ] , then : Block < ' gcc > , catch : Block < ' gcc > , _funclet : Option < & Funclet > ) -> RValue < ' gcc > {
519
+ let condition = self . context . new_rvalue_from_int ( self . bool_type , 0 ) ;
520
+ self . llbb ( ) . end_with_conditional ( None , condition, then, catch) ;
521
+ self . context . new_rvalue_from_int ( self . int_type , 0 )
522
+
523
+ // TODO
519
524
/*debug!("invoke {:?} with args ({:?})", func, args);
520
525
521
526
let args = self.check_call("invoke", func, args);
@@ -1001,9 +1006,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1001
1006
}
1002
1007
else if let abi:: Abi :: ScalarPair ( ref a, ref b) = place. layout . abi {
1003
1008
let b_offset = a. value . size ( self ) . align_to ( b. value . align ( self ) . abi ) ;
1009
+ let pair_type = place. layout . gcc_type ( self , false ) ;
1004
1010
1005
1011
let mut load = |i, scalar : & abi:: Scalar , align| {
1006
- let llptr = self . struct_gep ( place. llval , i as u64 ) ;
1012
+ let llptr = self . struct_gep ( pair_type , place. llval , i as u64 ) ;
1007
1013
let load = self . load ( llptr. get_type ( ) , llptr, align) ;
1008
1014
scalar_load_metadata ( self , load, scalar) ;
1009
1015
if scalar. is_bool ( ) { self . trunc ( load, self . type_i1 ( ) ) } else { load }
@@ -1044,7 +1050,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1044
1050
let align = dest. align . restrict_for_offset ( dest. layout . field ( self . cx ( ) , 0 ) . size ) ;
1045
1051
cg_elem. val . store ( & mut body_bx, PlaceRef :: new_sized_aligned ( current_val, cg_elem. layout , align) ) ;
1046
1052
1047
- let next = body_bx. inbounds_gep ( current. to_rvalue ( ) , & [ self . const_usize ( 1 ) ] ) ;
1053
+ let next = body_bx. inbounds_gep ( self . backend_type ( cg_elem . layout ) , current. to_rvalue ( ) , & [ self . const_usize ( 1 ) ] ) ;
1048
1054
body_bx. llbb ( ) . add_assignment ( None , current, next) ;
1049
1055
body_bx. br ( header_bx. llbb ( ) ) ;
1050
1056
@@ -1130,15 +1136,15 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1130
1136
. add_eval ( None , self . context . new_call ( None , atomic_store, & [ ptr, value, ordering] ) ) ;
1131
1137
}
1132
1138
1133
- fn gep ( & mut self , ptr : RValue < ' gcc > , indices : & [ RValue < ' gcc > ] ) -> RValue < ' gcc > {
1139
+ fn gep ( & mut self , _typ : Type < ' gcc > , ptr : RValue < ' gcc > , indices : & [ RValue < ' gcc > ] ) -> RValue < ' gcc > {
1134
1140
let mut result = ptr;
1135
1141
for index in indices {
1136
1142
result = self . context . new_array_access ( None , result, * index) . get_address ( None ) . to_rvalue ( ) ;
1137
1143
}
1138
1144
result
1139
1145
}
1140
1146
1141
- fn inbounds_gep ( & mut self , ptr : RValue < ' gcc > , indices : & [ RValue < ' gcc > ] ) -> RValue < ' gcc > {
1147
+ fn inbounds_gep ( & mut self , _typ : Type < ' gcc > , ptr : RValue < ' gcc > , indices : & [ RValue < ' gcc > ] ) -> RValue < ' gcc > {
1142
1148
// FIXME: would be safer if doing the same thing (loop) as gep.
1143
1149
// TODO: specify inbounds somehow.
1144
1150
match indices. len ( ) {
@@ -1153,11 +1159,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1153
1159
}
1154
1160
}
1155
1161
1156
- fn struct_gep ( & mut self , ptr : RValue < ' gcc > , idx : u64 ) -> RValue < ' gcc > {
1162
+ fn struct_gep ( & mut self , value_type : Type < ' gcc > , ptr : RValue < ' gcc > , idx : u64 ) -> RValue < ' gcc > {
1157
1163
// FIXME: it would be better if the API only called this on struct, not on arrays.
1158
1164
assert_eq ! ( idx as usize as u64 , idx) ;
1159
1165
let value = ptr. dereference ( None ) . to_rvalue ( ) ;
1160
- let value_type = value. get_type ( ) ;
1161
1166
1162
1167
if value_type. is_array ( ) . is_some ( ) {
1163
1168
let index = self . context . new_rvalue_from_long ( self . u64_type , i64:: try_from ( idx) . expect ( "i64::try_from" ) ) ;
@@ -1449,14 +1454,19 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1449
1454
}
1450
1455
1451
1456
fn landing_pad ( & mut self , _ty : Type < ' gcc > , _pers_fn : RValue < ' gcc > , _num_clauses : usize ) -> RValue < ' gcc > {
1452
- unimplemented ! ( ) ;
1457
+ let field1 = self . context . new_field ( None , self . u8_type , "landing_pad_field_1" ) ;
1458
+ let field2 = self . context . new_field ( None , self . i32_type , "landing_pad_field_1" ) ;
1459
+ let struct_type = self . context . new_struct_type ( None , "landing_pad" , & [ field1, field2] ) ;
1460
+ self . current_func ( ) . new_local ( None , struct_type. as_type ( ) , "landing_pad" )
1461
+ . to_rvalue ( )
1462
+ // TODO
1453
1463
/*unsafe {
1454
1464
llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn, num_clauses as c_uint, UNNAMED)
1455
1465
}*/
1456
1466
}
1457
1467
1458
1468
fn set_cleanup ( & mut self , _landing_pad : RValue < ' gcc > ) {
1459
- unimplemented ! ( ) ;
1469
+ // TODO
1460
1470
/*unsafe {
1461
1471
llvm::LLVMSetCleanup(landing_pad, llvm::True);
1462
1472
}*/
@@ -1527,7 +1537,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1527
1537
}
1528
1538
1529
1539
fn set_personality_fn ( & mut self , _personality : RValue < ' gcc > ) {
1530
- unimplemented ! ( ) ;
1540
+ // TODO
1531
1541
/*unsafe {
1532
1542
llvm::LLVMSetPersonalityFn(self.llfn(), personality);
1533
1543
}*/
@@ -1620,7 +1630,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1620
1630
//self.call_lifetime_intrinsic("llvm.lifetime.end.p0i8", ptr, size);
1621
1631
}
1622
1632
1623
- fn call ( & mut self , func : RValue < ' gcc > , args : & [ RValue < ' gcc > ] , funclet : Option < & Funclet > ) -> RValue < ' gcc > {
1633
+ fn call ( & mut self , _typ : Type < ' gcc > , func : RValue < ' gcc > , args : & [ RValue < ' gcc > ] , funclet : Option < & Funclet > ) -> RValue < ' gcc > {
1624
1634
// FIXME: remove when having a proper API.
1625
1635
let gcc_func = unsafe { std:: mem:: transmute ( func) } ;
1626
1636
if self . functions . borrow ( ) . values ( ) . find ( |value| * * value == gcc_func) . is_some ( ) {
0 commit comments