Emit a method for generating the instruction `inst`. The method will create and insert an instruction, then return the result values, or the instruction reference itself for instructions that don't have results.
(inst: &Instruction, format: &InstructionFormat, fmt: &mut Formatter)
| 1111 | /// The method will create and insert an instruction, then return the result values, or the |
| 1112 | /// instruction reference itself for instructions that don't have results. |
| 1113 | fn gen_inst_builder(inst: &Instruction, format: &InstructionFormat, fmt: &mut Formatter) { |
| 1114 | // Construct method arguments. |
| 1115 | let mut args = vec![String::new()]; |
| 1116 | |
| 1117 | let mut args_doc = Vec::new(); |
| 1118 | let mut rets_doc = Vec::new(); |
| 1119 | |
| 1120 | // The controlling type variable will be inferred from the input values if |
| 1121 | // possible. Otherwise, it is the first method argument. |
| 1122 | if let Some(poly) = &inst.polymorphic_info { |
| 1123 | if !poly.use_typevar_operand { |
| 1124 | args.push(format!("{}: crate::ir::Type", poly.ctrl_typevar.name)); |
| 1125 | args_doc.push(format!( |
| 1126 | "- {} (controlling type variable): {}", |
| 1127 | poly.ctrl_typevar.name, poly.ctrl_typevar.doc |
| 1128 | )); |
| 1129 | } |
| 1130 | } |
| 1131 | |
| 1132 | let mut tmpl_types = Vec::new(); |
| 1133 | let mut into_args = Vec::new(); |
| 1134 | let mut block_args = Vec::new(); |
| 1135 | let mut lifetime_param = None; |
| 1136 | for op in &inst.operands_in { |
| 1137 | if op.kind.is_block() { |
| 1138 | args.push(format!("{}_label: {}", op.name, "ir::Block")); |
| 1139 | args_doc.push(format!( |
| 1140 | "- {}_label: {}", |
| 1141 | op.name, "Destination basic block" |
| 1142 | )); |
| 1143 | |
| 1144 | let lifetime = *lifetime_param.get_or_insert_with(|| { |
| 1145 | tmpl_types.insert(0, "'a".to_string()); |
| 1146 | "'a" |
| 1147 | }); |
| 1148 | args.push(format!( |
| 1149 | "{}_args: impl IntoIterator<Item = &{} BlockArg>", |
| 1150 | op.name, lifetime, |
| 1151 | )); |
| 1152 | args_doc.push(format!("- {}_args: {}", op.name, "Block arguments")); |
| 1153 | |
| 1154 | block_args.push(op); |
| 1155 | } else if op.kind.is_raw_block() { |
| 1156 | args.push("block: ir::Block".into()); |
| 1157 | args_doc.push("- block: raw basic block".into()); |
| 1158 | } else { |
| 1159 | let t = if op.is_immediate() { |
| 1160 | let t = format!("T{}", tmpl_types.len() + 1); |
| 1161 | // For memflags, the public API type is MemFlagsData (the data), |
| 1162 | // while InstructionData stores MemFlags (the entity index). |
| 1163 | let api_type = if op.kind.rust_type == "ir::MemFlags" { |
| 1164 | "ir::MemFlagsData" |
| 1165 | } else { |
| 1166 | op.kind.rust_type |
| 1167 | }; |
| 1168 | tmpl_types.push(format!("{t}: Into<{api_type}>")); |
| 1169 | into_args.push(op.name); |
| 1170 | t |
no test coverage detected