diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index 13562312fc6e..a7cb36cc3714 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -4,6 +4,7 @@ #include "toolchain/lower/file_context.h" +#include "common/check.h" #include "common/vlog.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Sequence.h" @@ -184,6 +185,8 @@ auto FileContext::GetOrCreateFunction(SemIR::FunctionId function_id, // TODO: Add this function to a list of specific functions whose definitions // we need to emit. specific_functions_[specific_id.index] = result; + // TODO: Should this be a pair of ? + specific_function_definitions_.push_back(specific_id); return result; } @@ -315,13 +318,22 @@ auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id) 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_); - // TODO: Pass in a specific ID for generic functions. - const auto specific_id = SemIR::SpecificId::None; - // Add parameters to locals. // TODO: This duplicates the mapping between sem_ir instructions and LLVM // function parameters that was already computed in BuildFunctionDecl. diff --git a/toolchain/lower/file_context.h b/toolchain/lower/file_context.h index 5cd68da6917f..305baf40195f 100644 --- a/toolchain/lower/file_context.h +++ b/toolchain/lower/file_context.h @@ -11,6 +11,7 @@ #include "llvm/IR/Module.h" #include "toolchain/check/sem_ir_loc_diagnostic_emitter.h" #include "toolchain/sem_ir/file.h" +#include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/inst_namer.h" namespace Carbon::Lower { @@ -105,6 +106,12 @@ class FileContext { // declaration with no definition, does nothing. auto BuildFunctionDefinition(SemIR::FunctionId function_id) -> void; + // Builds a functions body. Common functionality for all functions. + auto BuildFunctionBody( + SemIR::FunctionId function_id, const SemIR::Function& function, + llvm::Function* llvm_function, + SemIR::SpecificId specific_id = SemIR::SpecificId::None) -> void; + // Build the DISubprogram metadata for the given function. auto BuildDISubprogram(const SemIR::Function& function, const llvm::Function* llvm_function) @@ -152,6 +159,12 @@ class FileContext { // `SpecificId` indexes. We resize this directly to the correct size. llvm::SmallVector specific_functions_; + // Maps which specific functions are generics that need to have their + // definitions lowered after the lowering of other definitions. + // This list may grow while lowering generic definitions from this list. + // The list uses the `SpecificId` to index into specific_functions_. + llvm::SmallVector specific_function_definitions_; + // Provides lowered versions of types. // Vector indexes correspond to `TypeId` indexes for non-symbolic types. We // resize this directly to the (often large) correct size.