param_and_arg_refs_stack.h 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_CHECK_PARAM_AND_ARG_REFS_STACK_H_
  5. #define CARBON_TOOLCHAIN_CHECK_PARAM_AND_ARG_REFS_STACK_H_
  6. #include "common/check.h"
  7. #include "toolchain/check/inst_block_stack.h"
  8. #include "toolchain/check/node_stack.h"
  9. namespace Carbon::Check {
  10. // The stack of instruction blocks being used for per-element tracking of
  11. // instructions in parameter and argument instruction blocks. Versus
  12. // InstBlockStack, an element will have 1 or more instructions in blocks in
  13. // InstBlockStack, but only ever 1 instruction in blocks here. The result is
  14. // typically referred to as "param_refs" or "arg_refs".
  15. class ParamAndArgRefsStack {
  16. public:
  17. explicit ParamAndArgRefsStack(SemIR::File& sem_ir,
  18. llvm::raw_ostream* vlog_stream,
  19. NodeStack& node_stack)
  20. : node_stack_(&node_stack),
  21. stack_("param_and_arg_refs_stack", sem_ir, vlog_stream) {}
  22. // Starts handling parameters or arguments.
  23. auto Push() -> void { stack_.Push(); }
  24. // On a comma, pushes the most recent instruction, becoming param or arg ref.
  25. // This also pops the NodeStack, meaning its top will remain start_kind.
  26. auto ApplyComma() -> void {
  27. // Support expressions, parameters, and other nodes like
  28. // `StructLiteralField` that produce InstIds.
  29. stack_.AddInstId(node_stack_->Pop<SemIR::InstId>());
  30. }
  31. // Detects whether there's an entry to push from the end of a parameter or
  32. // argument list, and if so, moves it to the current parameter or argument
  33. // list. Does not pop the list. `start_kind` is the node kind at the start
  34. // of the parameter or argument list, and will be at the top of the parse node
  35. // stack when this function returns.
  36. auto EndNoPop(Parse::NodeKind start_kind) -> void {
  37. if (!node_stack_->PeekIs(start_kind)) {
  38. // Support expressions, parameters, and other nodes like
  39. // `StructLiteralField` that produce InstIds.
  40. stack_.AddInstId(node_stack_->Pop<SemIR::InstId>());
  41. }
  42. }
  43. // Pops the current parameter or argument list. Should only be called after
  44. // `EndNoPop`.
  45. auto Pop() -> SemIR::InstBlockId { return stack_.Pop(); }
  46. // Detects whether there's an entry to push. Pops and returns the argument
  47. // list. This is the same as `EndNoPop` followed by `Pop`.
  48. auto EndAndPop(Parse::NodeKind start_kind) -> SemIR::InstBlockId {
  49. EndNoPop(start_kind);
  50. return Pop();
  51. }
  52. // Pops the top instruction block, and discards it if it hasn't had an ID
  53. // allocated.
  54. auto PopAndDiscard() -> void { stack_.PopAndDiscard(); }
  55. // Returns a view of the contents of the top instruction block on the stack.
  56. auto PeekCurrentBlockContents() -> llvm::ArrayRef<SemIR::InstId> {
  57. return stack_.PeekCurrentBlockContents();
  58. }
  59. // Runs verification that the processing cleanly finished.
  60. auto VerifyOnFinish() const -> void { stack_.VerifyOnFinish(); }
  61. // Prints the stack for a stack dump.
  62. auto PrintForStackDump(int indent, llvm::raw_ostream& output) const -> void {
  63. stack_.PrintForStackDump(indent, output);
  64. }
  65. private:
  66. // The node stack is manipulated when adding refs.
  67. NodeStack* node_stack_;
  68. // The refs stack.
  69. InstBlockStack stack_;
  70. };
  71. } // namespace Carbon::Check
  72. #endif // CARBON_TOOLCHAIN_CHECK_PARAM_AND_ARG_REFS_STACK_H_