mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 09:01:04 +01:00
I'm seeing three issues with CalleeParamsInfo: 1. Although ResolveCalleeInCall had been extracted out and the EntityWithParamsBase could be used directly, that had not been cleaned up. 2. implicit_param_refs_id is unused; param_refs_id was only used by ResolveCalleeInCall. The factoring as a struct seems to be obscuring what's used and what isn't (creating unnecessary copies). 3. On #4446, CalleeParamsInfo seemed to be obfuscating what ConvertCallArgs actually worked with (a Function, not a generic entity). I'm thinking that just removing CalleeParamsInfo is the best resolution here, it looks like it's tripping people up more than it's helping. Note, I think Function used to be named Callable, which was where the "callable" name originally came from (I might be wrong about this). But "function" seems clearer about the type now.
121 lines
4.8 KiB
C++
121 lines
4.8 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_CONVERT_H_
|
|
#define CARBON_TOOLCHAIN_CHECK_CONVERT_H_
|
|
|
|
#include "toolchain/check/context.h"
|
|
#include "toolchain/check/pending_block.h"
|
|
#include "toolchain/sem_ir/entity_with_params_base.h"
|
|
#include "toolchain/sem_ir/ids.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
// Description of the target of a conversion.
|
|
struct ConversionTarget {
|
|
enum Kind : int8_t {
|
|
// Convert to a value of type `type_id`.
|
|
Value,
|
|
// Convert to either a value or a reference of type `type_id`.
|
|
ValueOrRef,
|
|
// Convert for an explicit `as` cast. This allows any expression category
|
|
// as the result, and uses the `As` interface instead of the `ImplicitAs`
|
|
// interface.
|
|
ExplicitAs,
|
|
// The result of the conversion is discarded. It can't be an initializing
|
|
// expression, but can be anything else.
|
|
Discarded,
|
|
// Convert to an initializer for the object denoted by `init_id`.
|
|
Initializer,
|
|
// Convert to an initializer for the object denoted by `init_id`,
|
|
// including a final destination store if needed.
|
|
FullInitializer,
|
|
Last = FullInitializer
|
|
};
|
|
// The kind of the target for this conversion.
|
|
Kind kind;
|
|
// The target type for the conversion.
|
|
SemIR::TypeId type_id;
|
|
// For an initializer, the object being initialized.
|
|
SemIR::InstId init_id = SemIR::InstId::Invalid;
|
|
// For an initializer, a block of pending instructions that are needed to
|
|
// form the value of `init_id`, and that can be discarded if no
|
|
// initialization is needed.
|
|
PendingBlock* init_block = nullptr;
|
|
|
|
// Are we converting this value into an initializer for an object?
|
|
auto is_initializer() const -> bool {
|
|
return kind == Initializer || kind == FullInitializer;
|
|
}
|
|
};
|
|
|
|
// Convert a value to another type and expression category.
|
|
auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
|
|
ConversionTarget target) -> SemIR::InstId;
|
|
|
|
// Performs initialization of `target_id` from `value_id`. Returns the
|
|
// possibly-converted initializing expression, which should be assigned to the
|
|
// target using a suitable node for the kind of initialization.
|
|
auto Initialize(Context& context, SemIR::LocId loc_id, SemIR::InstId target_id,
|
|
SemIR::InstId value_id) -> SemIR::InstId;
|
|
|
|
// Convert the given expression to a value expression of the same type.
|
|
auto ConvertToValueExpr(Context& context, SemIR::InstId expr_id)
|
|
-> SemIR::InstId;
|
|
|
|
// Convert the given expression to a value or reference expression of the same
|
|
// type.
|
|
auto ConvertToValueOrRefExpr(Context& context, SemIR::InstId expr_id)
|
|
-> SemIR::InstId;
|
|
|
|
// Converts `expr_id` to a value expression of type `type_id`.
|
|
auto ConvertToValueOfType(Context& context, SemIR::LocId loc_id,
|
|
SemIR::InstId expr_id, SemIR::TypeId type_id)
|
|
-> SemIR::InstId;
|
|
|
|
// Convert the given expression to a value or reference expression of the given
|
|
// type.
|
|
auto ConvertToValueOrRefOfType(Context& context, SemIR::LocId loc_id,
|
|
SemIR::InstId expr_id, SemIR::TypeId type_id)
|
|
-> SemIR::InstId;
|
|
|
|
// Converts `value_id` to a value expression of type `bool`.
|
|
auto ConvertToBoolValue(Context& context, SemIR::LocId loc_id,
|
|
SemIR::InstId value_id) -> SemIR::InstId;
|
|
|
|
// Converts `value_id` to type `type_id` for an `as` expression.
|
|
auto ConvertForExplicitAs(Context& context, Parse::NodeId as_node,
|
|
SemIR::InstId value_id, SemIR::TypeId type_id)
|
|
-> SemIR::InstId;
|
|
|
|
// Implicitly converts a set of arguments to match the parameter types in a
|
|
// function call. Returns a block containing the converted implicit and explicit
|
|
// argument values for runtime parameters.
|
|
auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id,
|
|
SemIR::InstId self_id,
|
|
llvm::ArrayRef<SemIR::InstId> arg_refs,
|
|
SemIR::InstId return_slot_arg_id,
|
|
const SemIR::Function& callee,
|
|
SemIR::SpecificId callee_specific_id)
|
|
-> SemIR::InstBlockId;
|
|
|
|
// A type that has been converted for use as a type expression.
|
|
struct TypeExpr {
|
|
// The converted expression of type `type`, or `InstId::BuiltinError`.
|
|
SemIR::InstId inst_id;
|
|
// The corresponding type, or `TypeId::Error`.
|
|
SemIR::TypeId type_id;
|
|
};
|
|
|
|
// Converts an expression for use as a type.
|
|
// TODO: Most of the callers of this function discard the `inst_id` and lose
|
|
// track of the conversion. In most cases we should be retaining that as the
|
|
// operand of some downstream instruction.
|
|
auto ExprAsType(Context& context, SemIR::LocId loc_id, SemIR::InstId value_id)
|
|
-> TypeExpr;
|
|
|
|
} // namespace Carbon::Check
|
|
|
|
#endif // CARBON_TOOLCHAIN_CHECK_CONVERT_H_
|