Files
carbon-lang/toolchain/check/param_and_arg_refs_stack.h
T
Jon Ross-Perkins 138ecf108f Remove verbose formatting of instructions on crash messages. (#4495)
Undoes a chunk of #4125 because nobody's really in favor of keeping the
formatting, and it's occasionally caused a crash in Formatter to
dominate output (and even when working, it can be verbose; the source
location in (5) is often more helpful).

Basically goes back to:

```
4.	Check::Context
          NodeStack:
            0. LetIntroducer: no value
            1. BindingPattern: inst+15
            2. LetInitializer: no value
            3. StructLiteralStart: no value
          inst_block_stack_:
            0.	block<invalid>	{inst+0, inst+1, inst+6, inst+7, inst+8, inst+9, inst+10, inst+11, inst+12}
            1.	global_init	{}
          pattern_block_stack_:
            0.	block<invalid>	{}
          param_and_arg_refs_stack:
            0.	block<invalid>	{}
          args_type_info_stack_:
            0.	block<invalid>	{}
5.	alias_of_alias.carbon:15:12: checking StructLiteral
          let d: c = {};
                     ^~
```

Fixes #4145
2024-11-07 16:22:36 +00:00

90 lines
3.4 KiB
C++

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef CARBON_TOOLCHAIN_CHECK_PARAM_AND_ARG_REFS_STACK_H_
#define CARBON_TOOLCHAIN_CHECK_PARAM_AND_ARG_REFS_STACK_H_
#include "common/check.h"
#include "toolchain/check/inst_block_stack.h"
#include "toolchain/check/node_stack.h"
namespace Carbon::Check {
// The stack of instruction blocks being used for per-element tracking of
// instructions in parameter and argument instruction blocks. Versus
// InstBlockStack, an element will have 1 or more instructions in blocks in
// InstBlockStack, but only ever 1 instruction in blocks here. The result is
// typically referred to as "param_refs" or "arg_refs".
class ParamAndArgRefsStack {
public:
explicit ParamAndArgRefsStack(SemIR::File& sem_ir,
llvm::raw_ostream* vlog_stream,
NodeStack& node_stack)
: node_stack_(&node_stack),
stack_("param_and_arg_refs_stack", sem_ir, vlog_stream) {}
// Starts handling parameters or arguments.
auto Push() -> void { stack_.Push(); }
// On a comma, pushes the most recent instruction, becoming param or arg ref.
// This also pops the NodeStack, meaning its top will remain start_kind.
auto ApplyComma() -> void {
// Support expressions, parameters, and other nodes like
// `StructLiteralField` that produce InstIds.
stack_.AddInstId(node_stack_->Pop<SemIR::InstId>());
}
// Detects whether there's an entry to push from the end of a parameter or
// argument list, and if so, moves it to the current parameter or argument
// list. Does not pop the list. `start_kind` is the node kind at the start
// of the parameter or argument list, and will be at the top of the parse node
// stack when this function returns.
auto EndNoPop(Parse::NodeKind start_kind) -> void {
if (!node_stack_->PeekIs(start_kind)) {
// Support expressions, parameters, and other nodes like
// `StructLiteralField` that produce InstIds.
stack_.AddInstId(node_stack_->Pop<SemIR::InstId>());
}
}
// Pops the current parameter or argument list. Should only be called after
// `EndNoPop`.
auto Pop() -> SemIR::InstBlockId { return stack_.Pop(); }
// Detects whether there's an entry to push. Pops and returns the argument
// list. This is the same as `EndNoPop` followed by `Pop`.
auto EndAndPop(Parse::NodeKind start_kind) -> SemIR::InstBlockId {
EndNoPop(start_kind);
return Pop();
}
// Pops the top instruction block, and discards it if it hasn't had an ID
// allocated.
auto PopAndDiscard() -> void { stack_.PopAndDiscard(); }
// Returns a view of the contents of the top instruction block on the stack.
auto PeekCurrentBlockContents() -> llvm::ArrayRef<SemIR::InstId> {
return stack_.PeekCurrentBlockContents();
}
// Runs verification that the processing cleanly finished.
auto VerifyOnFinish() -> void { stack_.VerifyOnFinish(); }
// Prints the stack for a stack dump.
auto PrintForStackDump(int indent, llvm::raw_ostream& output) const -> void {
return stack_.PrintForStackDump(indent, output);
}
private:
// The node stack is manipulated when adding refs.
NodeStack* node_stack_;
// The refs stack.
InstBlockStack stack_;
};
} // namespace Carbon::Check
#endif // CARBON_TOOLCHAIN_CHECK_PARAM_AND_ARG_REFS_STACK_H_