Repository: carbon-language/carbon-lang
File: toolchain/check/cpp_thunk.cpp (C++)

Code before:
  }

  return thunk_function_decl;
}

auto PerformCppThunkCall(Context& context, SemIR::LocId loc_id,
                         SemIR::FunctionId callee_function_id,
                         llvm::ArrayRef<SemIR::InstId> callee_arg_ids,
                         SemIR::InstId thunk_callee_id) -> SemIR::InstId {
  llvm::ArrayRef<SemIR::InstId> callee_function_params =
      context.inst_blocks().GetOrEmpty(
          context.functions().Get(callee_function_id).call_params_id);

  llvm::ArrayRef<SemIR::InstId> thunk_function_params =
      context.inst_blocks().GetOrEmpty(
          context.functions()
              .Get(GetCalleeFunction(context.sem_ir(), thunk_callee_id)
                       .function_id)
              .call_params_id);

  size_t num_params = callee_function_params.size();
  CARBON_CHECK(thunk_function_params.size() == num_params);
  CARBON_CHECK(callee_arg_ids.size() == num_params);
  llvm::SmallVector<SemIR::InstId> thunk_arg_ids;
  thunk_arg_ids.reserve(num_params);
  for (size_t i = 0; i < num_params; ++i) {
    SemIR::TypeId callee_param_type_id =
        context.insts()
            .GetAs<SemIR::AnyParam>(callee_function_params[i])
            .type_id;
    SemIR::TypeId thunk_param_type_id =
        context.insts()
            .GetAs<SemIR::AnyParam>(thunk_function_params[i])
            .type_id;

    SemIR::InstId arg_id = callee_arg_ids[i];
    if (callee_param_type_id != thunk_param_type_id) {
      CARBON_CHECK(thunk_param_type_id ==
                   GetPointerType(context, context.types().GetInstId(
                                               callee_param_type_id)));

      arg_id = Convert(context, loc_id, arg_id,
                       {.kind = ConversionTarget::CppThunkRef,
                        .type_id = callee_param_type_id});
      arg_id = AddInst<SemIR::AddrOf>(
          context, loc_id,
          {.type_id = thunk_param_type_id, .lvalue_id = arg_id});
    }
    thunk_arg_ids.push_back(arg_id);
  }


Review comment (suggestion):
Two minor thoughts glancing at this, you might consider seq or zip:

```suggestion
  for (auto i : llvm::seq(num_params)) {
```

```suggestion
  for (auto [callee_param, thunk_param, arg_id] : llvm::zip(callee_function_params, thunk_function_params, calle_arg_ids)) {
```

Code after:
  }

  return thunk_function_decl;
}

auto PerformCppThunkCall(Context& context, SemIR::LocId loc_id,
                         SemIR::FunctionId callee_function_id,
                         llvm::ArrayRef<SemIR::InstId> callee_arg_ids,
                         SemIR::InstId thunk_callee_id) -> SemIR::InstId {
  llvm::ArrayRef<SemIR::InstId> callee_function_params =
      context.inst_blocks().GetOrEmpty(
          context.functions().Get(callee_function_id).call_params_id);

  llvm::ArrayRef<SemIR::InstId> thunk_function_params =
      context.inst_blocks().GetOrEmpty(
          context.functions()
              .Get(GetCalleeFunction(context.sem_ir(), thunk_callee_id)
                       .function_id)
              .call_params_id);

  size_t num_params = callee_function_params.size();
  CARBON_CHECK(thunk_function_params.size() == num_params);
  CARBON_CHECK(callee_arg_ids.size() == num_params);
  llvm::SmallVector<SemIR::InstId> thunk_arg_ids;
  thunk_arg_ids.reserve(num_params);
  for (auto [callee_param_inst_id, thunk_param_inst_id, callee_arg_id] :
       llvm::zip(callee_function_params, thunk_function_params,
                 callee_arg_ids)) {
    SemIR::TypeId callee_param_type_id =
        context.insts().GetAs<SemIR::AnyParam>(callee_param_inst_id).type_id;
    SemIR::TypeId thunk_param_type_id =
        context.insts().GetAs<SemIR::AnyParam>(thunk_param_inst_id).type_id;

    SemIR::InstId arg_id = callee_arg_id;
    if (callee_param_type_id != thunk_param_type_id) {
      CARBON_CHECK(thunk_param_type_id ==
                   GetPointerType(context, context.types().GetInstId(
                                               callee_param_type_id)));

      arg_id = Convert(context, loc_id, arg_id,
                       {.kind = ConversionTarget::CppThunkRef,
                        .type_id = callee_param_type_id});
      arg_id = AddInst<SemIR::AddrOf>(
          context, loc_id,
          {.type_id = thunk_param_type_id, .lvalue_id = arg_id});
    }
    thunk_arg_ids.push_back(arg_id);
  }

  return PerformCall(context, loc_id, thunk_callee_id, thunk_arg_ids);
}