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

Code before:

auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id)
    -> void {
  const auto& function = sem_ir().functions().Get(function_id);
  const auto& body_block_ids = function.body_block_ids;
  if (body_block_ids.empty()) {
    // Function is probably defined in another file; not an error.
    return;
  }

  llvm::Function* 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;
  }

  BuildFunctionBody(function_id, function, llvm_function);
}

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,
                                    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 =
        llvm::PoisonValue::get(GetType(param_inst.type_id));
    if (SemIR::ValueRepr::ForType(sem_ir(), param_inst.type_id).kind !=
        SemIR::ValueRepr::None) {

Review comment (suggestion):
```suggestion
  CARBON_DCHECK(llvm_function);
  CARBON_DCHECK(!body_block_ids.empty());
```

Code after:

auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id)
    -> void {
  const auto& function = sem_ir().functions().Get(function_id);
  const auto& body_block_ids = function.body_block_ids;
  if (body_block_ids.empty()) {
    // Function is probably defined in another file; not an error.
    return;
  }

  llvm::Function* 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;
  }

  BuildFunctionBody(function_id, function, llvm_function);
}

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,
                                    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 =
        llvm::PoisonValue::get(GetType(param_inst.type_id));