subpattern.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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. #include "toolchain/check/subpattern.h"
  5. #include "toolchain/check/inst.h"
  6. namespace Carbon::Check {
  7. auto BeginSubpattern(Context& context) -> void {
  8. context.inst_block_stack().Push();
  9. context.region_stack().PushRegion(context.inst_block_stack().PeekOrAdd());
  10. }
  11. auto EndSubpatternAsExpr(Context& context, SemIR::InstId result_id)
  12. -> SemIR::ExprRegionId {
  13. if (context.region_stack().PeekRegion().size() > 1) {
  14. // End the exit block with a branch to a successor block, whose contents
  15. // will be determined later.
  16. AddInst(context,
  17. SemIR::LocIdAndInst::NoLoc<SemIR::Branch>(
  18. {.target_id = context.inst_blocks().AddPlaceholder()}));
  19. } else {
  20. // This single-block region will be inserted as a SpliceBlock, so we don't
  21. // need control flow out of it.
  22. }
  23. auto block_id = context.inst_block_stack().Pop();
  24. CARBON_CHECK(block_id == context.region_stack().PeekRegion().back());
  25. // TODO: Is it possible to validate that this region is genuinely
  26. // single-entry, single-exit?
  27. return context.sem_ir().expr_regions().Add(
  28. {.block_ids = context.region_stack().PopRegion(),
  29. .result_id = result_id});
  30. }
  31. auto EndSubpatternAsNonExpr(Context& context) -> void {
  32. auto block_id = context.inst_block_stack().Pop();
  33. CARBON_CHECK(block_id == context.region_stack().PeekRegion().back());
  34. CARBON_CHECK(context.region_stack().PeekRegion().size() == 1);
  35. // TODO: Add `CARBON_CHECK(inst_blocks().Get(block_id).empty())`.
  36. // Currently that can fail when ending a tuple pattern in a name binding
  37. // decl in a class or interface.
  38. context.region_stack().PopAndDiscardRegion();
  39. }
  40. } // namespace Carbon::Check