// 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_ACTION_H_ #define CARBON_TOOLCHAIN_CHECK_ACTION_H_ #include "toolchain/check/context.h" #include "toolchain/check/inst.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/inst.h" namespace Carbon::Check { // Performs a member access action. Defined in member_access.cpp. auto PerformAction(Context& context, SemIR::LocId loc_id, SemIR::AccessMemberAction action) -> SemIR::InstId; auto PerformAction(Context& context, SemIR::LocId loc_id, SemIR::AccessOptionalMemberAction action) -> SemIR::InstId; // Performs a conversion action. Defined in convert.cpp. auto PerformAction(Context& context, SemIR::LocId loc_id, SemIR::ConvertToValueAction action) -> SemIR::InstId; // Performs a form parameter pattern action. Defined in pattern.cpp. auto PerformAction(Context& context, SemIR::LocId loc_id, SemIR::FormParamPatternAction action) -> SemIR::InstId; // Performs an output form parameter pattern action. Defined in pattern.cpp. auto PerformAction(Context& context, SemIR::LocId loc_id, SemIR::OutFormParamPatternAction action) -> SemIR::InstId; // Performs a callee pattern match action. Defined in pattern_match.cpp. auto PerformAction(Context& context, SemIR::LocId loc_id, SemIR::CalleePatternMatchAction action) -> SemIR::InstId; // Performs a type refinement action, by creating a conversion from an // instruction with a template-dependent symbolic type to the corresponding // instantiated type. auto PerformAction(Context& context, SemIR::LocId loc_id, SemIR::RefineTypeAction action) -> SemIR::InstId; // Performs a form refinement action. auto PerformAction(Context& context, SemIR::LocId loc_id, SemIR::RefineFormAction action) -> SemIR::InstId; // Determines whether the given action can be performed immediately (i.e. // whether it is non-template-dependent). auto ActionIsPerformable(Context& context, SemIR::Inst action_inst) -> bool; // Returns the constant-dependence of `inst_id` (i.e. the maximum of the // constant-dependences of its type and its value). auto OperandDependence(Context& context, SemIR::InstId inst_id) -> SemIR::ConstantDependence; auto OperandDependence(Context& context, SemIR::TypeInstId inst_id) -> SemIR::ConstantDependence; // Returns the constant-dependence of `type_id` (i.e. the constant-dependence // of the corresponding type constant). auto OperandDependence(Context& context, SemIR::TypeId type_id) -> SemIR::ConstantDependence; // Adds an instruction to the current block to splice in the result of // performing a dependent action. auto AddDependentActionSplice(Context& context, SemIR::LocIdAndInst action, SemIR::TypeInstId result_type_inst_id) -> SemIR::InstId; // Convenience wrapper for `AddDependentActionSplice`. template auto AddDependentActionSplice(Context& context, LocT loc, InstT inst, SemIR::TypeInstId result_type_inst_id) -> SemIR::InstId { return AddDependentActionSplice(context, SemIR::LocIdAndInst(loc, inst), result_type_inst_id); } // Handles a new action. If the action is not dependent, it is performed // immediately. Otherwise, adds the action to the enclosing template's eval // block and creates an instruction to splice in the result of the action. // `result_type_inst_id` is the type of inst produced by the action. If not // known, it can be set to `None`, and a `TypeOfInst` instruction will be added // to act as the type of the splice. template auto HandleAction(Context& context, LocIdT loc_id, SemIR::TypeInstId result_type_inst_id, ActionT action_inst) -> SemIR::InstId { CARBON_CHECK(action_inst.type_id == SemIR::InstType::TypeId); if (!ActionIsPerformable(context, action_inst)) { return AddDependentActionSplice(context, SemIR::LocIdAndInst::RuntimeVerified( context.sem_ir(), loc_id, action_inst), result_type_inst_id); } return PerformAction(context, loc_id, action_inst); } namespace Internal { // Performs setup steps for performing a delayed action. This is an // implementation detail of PerformDelayedAction and should not be called // directly. auto BeginPerformDelayedAction(Context& context) -> void; // Performs cleanup steps for performing a delayed action. This is an // implementation detail of PerformDelayedAction and should not be called // directly. auto EndPerformDelayedAction(Context& context, SemIR::InstId result_id) -> SemIR::InstId; } // namespace Internal // Performs an action as a result of evaluation of a template's eval block. template auto PerformDelayedAction(Context& context, SemIR::LocId loc_id, ActionT action_inst) -> SemIR::InstId { if (!ActionIsPerformable(context, action_inst)) { return SemIR::InstId::None; } Internal::BeginPerformDelayedAction(context); auto inst_id = PerformAction(context, loc_id, action_inst); return Internal::EndPerformDelayedAction(context, inst_id); } } // namespace Carbon::Check #endif // CARBON_TOOLCHAIN_CHECK_ACTION_H_