Repository: carbon-language/carbon-lang
File: toolchain/lower/file_context.cpp (C++)

Code before:
  llvm::Function* llvm_function;
  if (!specific_id.has_value()) {
    llvm_function = GetFunction(function_id);
    if (!llvm_function) {
      // We chose not to lower this function at all, for example because it's a
      // generic function.
      return;
    }
  } else {
    llvm_function = specific_functions_[specific_id.index];
  }

  // For non-generics we do not lower. For generics, the llvm function was
  // created via GetOrCreateFunction prior to this when building the
  // declaration.
  CARBON_CHECK(llvm_function, "The llvm function must exist");

  BuildFunctionBody(function_id, function, llvm_function, specific_id);
}

auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id,
                                    const SemIR::Function& function,
                                    llvm::Function* llvm_function,
                                    SemIR::SpecificId specific_id) -> void {
  const auto& body_block_ids = function.body_block_ids;
  CARBON_DCHECK(llvm_function && !body_block_ids.empty());

  FunctionContext function_lowering(*this, llvm_function, specific_id,
                                    BuildDISubprogram(function, llvm_function),
                                    vlog_stream_);

  // Add parameters to locals.
  // TODO: This duplicates the mapping between sem_ir instructions and LLVM
  // function parameters that was already computed in BuildFunctionDecl.
  // We should only do that once.
  auto call_param_ids =
      sem_ir().inst_blocks().GetOrEmpty(function.call_params_id);
  int param_index = 0;

  // TODO: Find a way to ensure this code and the function-call lowering use
  // the same parameter ordering.

  // Lowers the given parameter. Must be called in LLVM calling convention
  // parameter order.
  auto lower_param = [&](SemIR::InstId param_id) {
    // Get the value of the parameter from the function argument.
    auto param_inst = sem_ir().insts().GetAs<SemIR::AnyParam>(param_id);
    llvm::Value* param_value;

    if (SemIR::ValueRepr::ForType(sem_ir(), param_inst.type_id).kind !=
        SemIR::ValueRepr::None) {

Review comment (bug):
```suggestion
  CARBON_DCHECK(llvm_function);
  CARBON_DCHECK(!body_block_ids.empty());
```
So you know which one failed

Code after:
    return;
  }

  llvm::Function* llvm_function;
  if (specific_id.has_value()) {
    llvm_function = specific_functions_[specific_id.index];
  } else {
    llvm_function = GetFunction(function_id);
    if (!llvm_function) {
      // We chose not to lower this function at all, for example because it's a
      // generic function.
      return;
    }
  }

  // For non-generics we do not lower. For generics, the llvm function was
  // created via GetOrCreateFunction prior to this when building the
  // declaration.
  BuildFunctionBody(function_id, function, llvm_function, specific_id);
}

auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id,
                                    const SemIR::Function& function,
                                    llvm::Function* llvm_function,
                                    SemIR::SpecificId specific_id) -> void {
  const auto& body_block_ids = function.body_block_ids;
  CARBON_DCHECK(llvm_function, "LLVM Function not found when lowering body.");
  CARBON_DCHECK(!body_block_ids.empty(),
                "No function body blocks found during lowering.");

  FunctionContext function_lowering(*this, llvm_function, specific_id,
                                    BuildDISubprogram(function, llvm_function),
                                    vlog_stream_);

  // Add parameters to locals.
  // TODO: This duplicates the mapping between sem_ir instructions and LLVM
  // function parameters that was already computed in BuildFunctionDecl.
  // We should only do that once.
  auto call_param_ids =
      sem_ir().inst_blocks().GetOrEmpty(function.call_params_id);
  int param_index = 0;

  // TODO: Find a way to ensure this code and the function-call lowering use
  // the same parameter ordering.

  // Lowers the given parameter. Must be called in LLVM calling convention
  // parameter order.
  auto lower_param = [&](SemIR::InstId param_id) {
    // Get the value of the parameter from the function argument.
    auto param_inst = sem_ir().insts().GetAs<SemIR::AnyParam>(param_id);
    llvm::Value* param_value;