action.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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_ACTION_H_
  5. #define CARBON_TOOLCHAIN_CHECK_ACTION_H_
  6. #include "toolchain/check/context.h"
  7. #include "toolchain/check/inst.h"
  8. #include "toolchain/sem_ir/ids.h"
  9. #include "toolchain/sem_ir/inst.h"
  10. namespace Carbon::Check {
  11. // Performs a member access action. Defined in member_access.cpp.
  12. auto PerformAction(Context& context, SemIR::LocId loc_id,
  13. SemIR::AccessMemberAction action) -> SemIR::InstId;
  14. auto PerformAction(Context& context, SemIR::LocId loc_id,
  15. SemIR::AccessOptionalMemberAction action) -> SemIR::InstId;
  16. // Performs a conversion action. Defined in convert.cpp.
  17. auto PerformAction(Context& context, SemIR::LocId loc_id,
  18. SemIR::ConvertToValueAction action) -> SemIR::InstId;
  19. // Performs a form parameter pattern action. Defined in pattern.cpp.
  20. auto PerformAction(Context& context, SemIR::LocId loc_id,
  21. SemIR::FormParamPatternAction action) -> SemIR::InstId;
  22. // Performs an output form parameter pattern action. Defined in pattern.cpp.
  23. auto PerformAction(Context& context, SemIR::LocId loc_id,
  24. SemIR::OutFormParamPatternAction action) -> SemIR::InstId;
  25. // Performs a callee pattern match action. Defined in pattern_match.cpp.
  26. auto PerformAction(Context& context, SemIR::LocId loc_id,
  27. SemIR::CalleePatternMatchAction action) -> SemIR::InstId;
  28. // Performs a type refinement action, by creating a conversion from an
  29. // instruction with a template-dependent symbolic type to the corresponding
  30. // instantiated type.
  31. auto PerformAction(Context& context, SemIR::LocId loc_id,
  32. SemIR::RefineTypeAction action) -> SemIR::InstId;
  33. // Performs a form refinement action.
  34. auto PerformAction(Context& context, SemIR::LocId loc_id,
  35. SemIR::RefineFormAction action) -> SemIR::InstId;
  36. // Determines whether the given action can be performed immediately (i.e.
  37. // whether it is non-template-dependent).
  38. auto ActionIsPerformable(Context& context, SemIR::Inst action_inst) -> bool;
  39. // Returns the constant-dependence of `inst_id` (i.e. the maximum of the
  40. // constant-dependences of its type and its value).
  41. auto OperandDependence(Context& context, SemIR::InstId inst_id)
  42. -> SemIR::ConstantDependence;
  43. auto OperandDependence(Context& context, SemIR::TypeInstId inst_id)
  44. -> SemIR::ConstantDependence;
  45. // Returns the constant-dependence of `type_id` (i.e. the constant-dependence
  46. // of the corresponding type constant).
  47. auto OperandDependence(Context& context, SemIR::TypeId type_id)
  48. -> SemIR::ConstantDependence;
  49. // Adds an instruction to the current block to splice in the result of
  50. // performing a dependent action.
  51. auto AddDependentActionSplice(Context& context, SemIR::LocIdAndInst action,
  52. SemIR::TypeInstId result_type_inst_id)
  53. -> SemIR::InstId;
  54. // Convenience wrapper for `AddDependentActionSplice`.
  55. template <typename LocT, typename InstT>
  56. auto AddDependentActionSplice(Context& context, LocT loc, InstT inst,
  57. SemIR::TypeInstId result_type_inst_id)
  58. -> SemIR::InstId {
  59. return AddDependentActionSplice(context, SemIR::LocIdAndInst(loc, inst),
  60. result_type_inst_id);
  61. }
  62. // Handles a new action. If the action is not dependent, it is performed
  63. // immediately. Otherwise, adds the action to the enclosing template's eval
  64. // block and creates an instruction to splice in the result of the action.
  65. // `result_type_inst_id` is the type of inst produced by the action. If not
  66. // known, it can be set to `None`, and a `TypeOfInst` instruction will be added
  67. // to act as the type of the splice.
  68. template <typename ActionT, typename LocIdT>
  69. auto HandleAction(Context& context, LocIdT loc_id,
  70. SemIR::TypeInstId result_type_inst_id, ActionT action_inst)
  71. -> SemIR::InstId {
  72. CARBON_CHECK(action_inst.type_id == SemIR::InstType::TypeId);
  73. if (!ActionIsPerformable(context, action_inst)) {
  74. return AddDependentActionSplice(context,
  75. SemIR::LocIdAndInst::RuntimeVerified(
  76. context.sem_ir(), loc_id, action_inst),
  77. result_type_inst_id);
  78. }
  79. return PerformAction(context, loc_id, action_inst);
  80. }
  81. namespace Internal {
  82. // Performs setup steps for performing a delayed action. This is an
  83. // implementation detail of PerformDelayedAction and should not be called
  84. // directly.
  85. auto BeginPerformDelayedAction(Context& context) -> void;
  86. // Performs cleanup steps for performing a delayed action. This is an
  87. // implementation detail of PerformDelayedAction and should not be called
  88. // directly.
  89. auto EndPerformDelayedAction(Context& context, SemIR::InstId result_id)
  90. -> SemIR::InstId;
  91. } // namespace Internal
  92. // Performs an action as a result of evaluation of a template's eval block.
  93. template <typename ActionT>
  94. auto PerformDelayedAction(Context& context, SemIR::LocId loc_id,
  95. ActionT action_inst) -> SemIR::InstId {
  96. if (!ActionIsPerformable(context, action_inst)) {
  97. return SemIR::InstId::None;
  98. }
  99. Internal::BeginPerformDelayedAction(context);
  100. auto inst_id = PerformAction(context, loc_id, action_inst);
  101. return Internal::EndPerformDelayedAction(context, inst_id);
  102. }
  103. } // namespace Carbon::Check
  104. #endif // CARBON_TOOLCHAIN_CHECK_ACTION_H_