Format the decl block for a declaration as a trailing block. (#3731)

Previously we used the default inst block formatting, which writes out a
parenthesized list of references, which would always be 'unexpected
instref's because nothing else prints the instructions in the decl
block.

In addition, track the decl block for function declarations like we do
for other kinds of declaration. This means that the parameter
declarations for a function are now properly rendered into the formatted
IR. Note that this adds a lot of verbosity to `function_decl`, but it
does accurately reflect the IR, and we'll probably want this information
to be printed once we start supporting more complex generic function
declarations.

This removes almost all the 'unexpected instref's in our formatted
output. There are remaining cases when a declarative scope contains
multiple blocks, where we only track one of those blocks. That happens
when there is control flow within declarative scopes, and for error
recovery when a class or interface or similar is defined more than once.

As requested in #3730.
This commit is contained in:
Richard Smith
2024-02-28 21:28:59 +00:00
committed by GitHub
parent 33c1e9ca95
commit 5f4e6c768a
285 changed files with 2152 additions and 828 deletions
+2 -9
View File
@@ -60,14 +60,7 @@ static auto BuildFunctionDecl(Context& context,
Parse::AnyFunctionDeclId parse_node,
bool is_definition)
-> std::pair<SemIR::FunctionId, SemIR::InstId> {
// TODO: This contains the IR block for the parameters and return type. At
// present, it's just loose, but it's not strictly required for parameter
// refs; we should either stop constructing it completely or, if it turns out
// to be needed, store it. Note, the underlying issue is that the LLVM IR has
// nowhere clear to emit, so changing storage would require addressing that
// problem. For comparison with function calls, the IR needs to be emitted
// prior to the call.
context.inst_block_stack().Pop();
auto decl_block_id = context.inst_block_stack().Pop();
auto return_type_id = SemIR::TypeId::Invalid;
auto return_slot_id = SemIR::InstId::Invalid;
@@ -123,7 +116,7 @@ static auto BuildFunctionDecl(Context& context,
// Add the function declaration.
auto function_decl = SemIR::FunctionDecl{
context.GetBuiltinType(SemIR::BuiltinKind::FunctionType),
SemIR::FunctionId::Invalid};
SemIR::FunctionId::Invalid, decl_block_id};
auto function_decl_id =
context.AddPlaceholderInst({parse_node, function_decl});