mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:20:11 +01:00
When an instruction is created as part of an implicit call to an interface member, we generated a bunch of constants for naming the interface, finding the corresponding specific, accessing its member function, and so on. This led to significant bloat in SemIR. Instead, we now track whether an instruction is created implicitly in its location, and where relevant, we use the constant value of the instruction directly instead of storing a new `Inst`. This doesn't reduce the amount of work we need to do, but does make the representation in SemIR smaller and more readable.
69 lines
2.6 KiB
C++
69 lines
2.6 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
|
|
|
|
#include "toolchain/check/operator.h"
|
|
|
|
#include "toolchain/check/call.h"
|
|
#include "toolchain/check/context.h"
|
|
#include "toolchain/check/generic.h"
|
|
#include "toolchain/check/member_access.h"
|
|
#include "toolchain/sem_ir/ids.h"
|
|
#include "toolchain/sem_ir/typed_insts.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
// Returns the `Op` function for the specified operator.
|
|
static auto GetOperatorOpFunction(Context& context, SemIR::LocId loc_id,
|
|
Operator op) -> SemIR::InstId {
|
|
// Look up the interface, and pass it any generic arguments.
|
|
auto interface_id = context.LookupNameInCore(loc_id, op.interface_name);
|
|
if (!op.interface_args_ref.empty()) {
|
|
interface_id =
|
|
PerformCall(context, loc_id, interface_id, op.interface_args_ref);
|
|
}
|
|
|
|
// Look up the interface member.
|
|
auto op_name_id =
|
|
SemIR::NameId::ForIdentifier(context.identifiers().Add(op.op_name));
|
|
return PerformMemberAccess(context, loc_id, interface_id, op_name_id);
|
|
}
|
|
|
|
auto BuildUnaryOperator(Context& context, SemIR::LocId loc_id, Operator op,
|
|
SemIR::InstId operand_id,
|
|
Context::BuildDiagnosticFn missing_impl_diagnoser)
|
|
-> SemIR::InstId {
|
|
// Look up the operator function.
|
|
auto op_fn = GetOperatorOpFunction(context, loc_id.ToImplicit(), op);
|
|
|
|
// Form `operand.(Op)`.
|
|
auto bound_op_id = PerformCompoundMemberAccess(context, loc_id, operand_id,
|
|
op_fn, missing_impl_diagnoser);
|
|
if (bound_op_id == SemIR::InstId::BuiltinError) {
|
|
return SemIR::InstId::BuiltinError;
|
|
}
|
|
|
|
// Form `bound_op()`.
|
|
return PerformCall(context, loc_id, bound_op_id, {});
|
|
}
|
|
|
|
auto BuildBinaryOperator(Context& context, SemIR::LocId loc_id, Operator op,
|
|
SemIR::InstId lhs_id, SemIR::InstId rhs_id,
|
|
Context::BuildDiagnosticFn missing_impl_diagnoser)
|
|
-> SemIR::InstId {
|
|
// Look up the operator function.
|
|
auto op_fn = GetOperatorOpFunction(context, loc_id.ToImplicit(), op);
|
|
|
|
// Form `lhs.(Op)`.
|
|
auto bound_op_id = PerformCompoundMemberAccess(context, loc_id, lhs_id, op_fn,
|
|
missing_impl_diagnoser);
|
|
if (bound_op_id == SemIR::InstId::BuiltinError) {
|
|
return SemIR::InstId::BuiltinError;
|
|
}
|
|
|
|
// Form `bound_op(rhs)`.
|
|
return PerformCall(context, loc_id, bound_op_id, {rhs_id});
|
|
}
|
|
|
|
} // namespace Carbon::Check
|