(
&mut self,
typ: &str,
llfn: &'ll Value,
args: &'b [&'ll Value],
)
| 1197 | } |
| 1198 | |
| 1199 | fn check_call<'b>( |
| 1200 | &mut self, |
| 1201 | typ: &str, |
| 1202 | llfn: &'ll Value, |
| 1203 | args: &'b [&'ll Value], |
| 1204 | ) -> Cow<'b, [&'ll Value]> { |
| 1205 | let mut fn_ty = self.cx.val_ty(llfn); |
| 1206 | // Strip off pointers |
| 1207 | while self.cx.type_kind(fn_ty) == TypeKind::Pointer { |
| 1208 | fn_ty = self.cx.element_type(fn_ty); |
| 1209 | } |
| 1210 | |
| 1211 | assert!( |
| 1212 | self.cx.type_kind(fn_ty) == TypeKind::Function, |
| 1213 | "builder::{} not passed a function, but {:?}", |
| 1214 | typ, |
| 1215 | fn_ty |
| 1216 | ); |
| 1217 | |
| 1218 | let param_tys = self.cx.func_params_types(fn_ty); |
| 1219 | |
| 1220 | let all_args_match = param_tys |
| 1221 | .iter() |
| 1222 | .zip(args.iter().map(|&v| self.val_ty(v))) |
| 1223 | .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); |
| 1224 | |
| 1225 | if all_args_match { |
| 1226 | return Cow::Borrowed(args); |
| 1227 | } |
| 1228 | |
| 1229 | let casted_args: Vec<_> = param_tys |
| 1230 | .into_iter() |
| 1231 | .zip(args.iter()) |
| 1232 | .enumerate() |
| 1233 | .map(|(_, (expected_ty, &actual_val))| { |
| 1234 | let actual_ty = self.val_ty(actual_val); |
| 1235 | |
| 1236 | if expected_ty != actual_ty { |
| 1237 | trace!( |
| 1238 | "Expected arg to be {:?} but instead found {:?}, bitcasting the pain away", |
| 1239 | expected_ty, |
| 1240 | actual_ty |
| 1241 | ); |
| 1242 | self.bitcast(actual_val, expected_ty) |
| 1243 | } else { |
| 1244 | actual_val |
| 1245 | } |
| 1246 | }) |
| 1247 | .collect(); |
| 1248 | |
| 1249 | Cow::Owned(casted_args) |
| 1250 | } |
| 1251 | |
| 1252 | pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { |
| 1253 | unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, unnamed()) } |
no test coverage detected