mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:40:12 +01:00
See [here](https://docs.google.com/document/d/1rWcueFwIfZox6GKVGxiUG4cBzjrZ6djXiIDGyJDtrE4/edit?tab=t.0) for the design doc. This also removes the default value of the `result_type_inst_id` parameter of `HandleAction`, moves it before the action in the parameter list, and documents it. This solves two problems: - The default made it easy to forget, leading to unnecessary `TypeOfInst` instructions. - When it was present, putting it after the fairly "bulky" action argument tended to make the callsite harder to read.
127 lines
5.5 KiB
C++
127 lines
5.5 KiB
C++
// 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 <typename LocT, typename InstT>
|
|
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 <typename ActionT, typename LocIdT>
|
|
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 <typename ActionT>
|
|
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_
|