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

Code before:

  // Specific functions are lowered when we emit a reference to them.
  specific_functions_.resize(sem_ir_->specifics().size());

  // Lower global variable declarations.
  for (auto inst_id :
       sem_ir().inst_blocks().Get(sem_ir().top_inst_block_id())) {
    // Only `VarStorage` indicates a global variable declaration in the
    // top instruction block.
    if (auto var = sem_ir().insts().TryGetAs<SemIR::VarStorage>(inst_id)) {
      global_variables_.Insert(inst_id, BuildGlobalVariableDecl(*var));
    }
  }

  // Lower constants.
  constants_.resize(sem_ir_->insts().size());
  LowerConstants(*this, constants_);

  // Lower function definitions.
  for (auto [id, _] : sem_ir_->functions().enumerate()) {
    BuildFunctionDefinition(id);
  }

  // Lower function definitions for generics.
  // TODO: this needs to be an iterator as new definitions can be added
  // while building.
  for (size_t i = 0; i < specific_function_definitions_.size(); ++i) {
    auto [function_id, specific_id] = specific_function_definitions_[i];
    BuildFunctionDefinition(function_id, specific_id);
  }

  // Append `__global_init` to `llvm::global_ctors` to initialize global
  // variables.
  if (sem_ir().global_ctor_id().has_value()) {
    llvm::appendToGlobalCtors(llvm_module(),
                              GetFunction(sem_ir().global_ctor_id()),
                              /*Priority=*/0);
  }
  return std::move(llvm_module_);
}

auto FileContext::BuildDICompileUnit(llvm::StringRef module_name,
                                     llvm::Module& llvm_module,
                                     llvm::DIBuilder& di_builder)
    -> llvm::DICompileUnit* {
  llvm_module.addModuleFlag(llvm::Module::Max, "Dwarf Version", 5);
  llvm_module.addModuleFlag(llvm::Module::Warning, "Debug Info Version",
                            llvm::DEBUG_METADATA_VERSION);
  // TODO: Include directory path in the compile_unit_file.
  llvm::DIFile* compile_unit_file = di_builder.createFile(module_name, "");
  // TODO: Introduce a new language code for Carbon. C works well for now since

Review comment (suggestion):
vector iterators aren't stable across insertions - so perhaps the opposite? The code you have looks like the right code for iterating through a vector that might have things added to it during the iteration? (because it re-queries the size each time, and indexes each time - rather than keeping an iterator/pointer or size from the start to the end))

Only one minor change: The bound check should be `!=` rather than `<` to match C++ norms.

Code after:

  // Specific functions are lowered when we emit a reference to them.
  specific_functions_.resize(sem_ir_->specifics().size());

  // Lower global variable declarations.
  for (auto inst_id :
       sem_ir().inst_blocks().Get(sem_ir().top_inst_block_id())) {
    // Only `VarStorage` indicates a global variable declaration in the
    // top instruction block.
    if (auto var = sem_ir().insts().TryGetAs<SemIR::VarStorage>(inst_id)) {
      global_variables_.Insert(inst_id, BuildGlobalVariableDecl(*var));
    }
  }

  // Lower constants.
  constants_.resize(sem_ir_->insts().size());
  LowerConstants(*this, constants_);

  // Lower function definitions.
  for (auto [id, _] : sem_ir_->functions().enumerate()) {
    BuildFunctionDefinition(id);
  }

  // Lower function definitions for generics.
  // This cannot be a range-based loop, as new definitions can be added
  // while building other definitions.
  // NOLINTNEXTLINE
  for (size_t i = 0; i != specific_function_definitions_.size(); ++i) {
    auto [function_id, specific_id] = specific_function_definitions_[i];
    BuildFunctionDefinition(function_id, specific_id);
  }

  // Append `__global_init` to `llvm::global_ctors` to initialize global
  // variables.
  if (sem_ir().global_ctor_id().has_value()) {
    llvm::appendToGlobalCtors(llvm_module(),
                              GetFunction(sem_ir().global_ctor_id()),
                              /*Priority=*/0);
  }

  return std::move(llvm_module_);
}

auto FileContext::BuildDICompileUnit(llvm::StringRef module_name,
                                     llvm::Module& llvm_module,
                                     llvm::DIBuilder& di_builder)
    -> llvm::DICompileUnit* {
  llvm_module.addModuleFlag(llvm::Module::Max, "Dwarf Version", 5);
  llvm_module.addModuleFlag(llvm::Module::Warning, "Debug Info Version",
                            llvm::DEBUG_METADATA_VERSION);
  // TODO: Include directory path in the compile_unit_file.