global_init.cpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  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/global_init.h"
  5. #include "toolchain/check/context.h"
  6. #include "toolchain/check/inst.h"
  7. namespace Carbon::Check {
  8. auto GlobalInit::Resume() -> void {
  9. context_->inst_block_stack().Push(block_id_, block_);
  10. }
  11. auto GlobalInit::Suspend() -> void {
  12. // TODO: Consider splicing together blocks in order to avoid sizable copies
  13. // here.
  14. auto contents = context_->inst_block_stack().PeekCurrentBlockContents();
  15. block_.assign(contents.begin(), contents.end());
  16. block_id_ = context_->inst_block_stack().PeekOrAdd();
  17. context_->inst_block_stack().PopAndDiscard();
  18. }
  19. auto GlobalInit::Finalize() -> void {
  20. // __global_init is only added if there are initialization instructions.
  21. if (block_.empty() && block_id_ == SemIR::InstBlockId::GlobalInit) {
  22. return;
  23. }
  24. Resume();
  25. AddInst<SemIR::Return>(*context_, Parse::NodeId::None, {});
  26. // Pop the GlobalInit block here to finalize it.
  27. context_->inst_block_stack().Pop();
  28. auto name_id = context_->sem_ir().identifiers().Add("__global_init");
  29. context_->sem_ir().set_global_ctor_id(context_->sem_ir().functions().Add(
  30. {{.name_id = SemIR::NameId::ForIdentifier(name_id),
  31. .parent_scope_id = SemIR::NameScopeId::Package,
  32. .generic_id = SemIR::GenericId::None,
  33. .first_param_node_id = Parse::NodeId::None,
  34. .last_param_node_id = Parse::NodeId::None,
  35. .pattern_block_id = SemIR::InstBlockId::Empty,
  36. .implicit_param_patterns_id = SemIR::InstBlockId::None,
  37. .param_patterns_id = SemIR::InstBlockId::Empty,
  38. .is_extern = false,
  39. .extern_library_id = SemIR::LibraryNameId::None,
  40. .non_owning_decl_id = SemIR::InstId::None,
  41. .first_owning_decl_id = SemIR::InstId::None},
  42. {.call_params_id = SemIR::InstBlockId::Empty,
  43. .return_slot_pattern_id = SemIR::InstId::None,
  44. .body_block_ids = {SemIR::InstBlockId::GlobalInit}}}));
  45. }
  46. } // namespace Carbon::Check