@@ -35,10 +35,40 @@ static auto GetOperatorOpFunction(Context& context, SemIR::LocId loc_id,
35
35
op_name_id);
36
36
}
37
37
38
+ // Returns whether the type of the instruction is a C++ class.
39
+ static auto IsOfCppClassType (Context& context, SemIR::InstId inst_id) -> bool {
40
+ auto class_type = context.insts ().TryGetAs <SemIR::ClassType>(
41
+ context.types ().GetInstId (context.insts ().Get (inst_id).type_id ()));
42
+ if (!class_type) {
43
+ // Not a class.
44
+ return false ;
45
+ }
46
+
47
+ const auto & class_info = context.classes ().Get (class_type->class_id );
48
+ if (!class_info.is_complete ()) {
49
+ return false ;
50
+ }
51
+
52
+ return context.name_scopes ().Get (class_info.scope_id ).is_cpp_scope ();
53
+ }
54
+
38
55
auto BuildUnaryOperator (Context& context, SemIR::LocId loc_id, Operator op,
39
56
SemIR::InstId operand_id,
40
57
MakeDiagnosticBuilderFn missing_impl_diagnoser)
41
58
-> SemIR::InstId {
59
+ // For unary operators with a C++ class as the operand, try to import and call
60
+ // the C++ operator.
61
+ // TODO: Change impl lookup instead. See
62
+ // https://github.com/carbon-language/carbon-lang/blob/db0a00d713015436844c55e7ac190a0f95556499/toolchain/check/operator.cpp#L76
63
+ if (IsOfCppClassType (context, operand_id)) {
64
+ SemIR::ScopeLookupResult cpp_lookup_result =
65
+ ImportOperatorFromCpp (context, loc_id, op);
66
+ if (cpp_lookup_result.is_found ()) {
67
+ return PerformCall (context, loc_id, cpp_lookup_result.target_inst_id (),
68
+ {operand_id});
69
+ }
70
+ }
71
+
42
72
// Look up the operator function.
43
73
auto op_fn = GetOperatorOpFunction (context, loc_id, op);
44
74
@@ -53,20 +83,6 @@ auto BuildUnaryOperator(Context& context, SemIR::LocId loc_id, Operator op,
53
83
return PerformCall (context, loc_id, bound_op_id, {});
54
84
}
55
85
56
- // Returns whether the type of the instruction is a C++ class.
57
- static auto IsOfCppClassType (Context& context, SemIR::InstId inst_id) -> bool {
58
- auto class_type = context.insts ().TryGetAs <SemIR::ClassType>(
59
- context.types ().GetInstId (context.insts ().Get (inst_id).type_id ()));
60
- if (!class_type) {
61
- // Not a class.
62
- return false ;
63
- }
64
-
65
- return context.name_scopes ()
66
- .Get (context.classes ().Get (class_type->class_id ).scope_id )
67
- .is_cpp_scope ();
68
- }
69
-
70
86
auto BuildBinaryOperator (Context& context, SemIR::LocId loc_id, Operator op,
71
87
SemIR::InstId lhs_id, SemIR::InstId rhs_id,
72
88
MakeDiagnosticBuilderFn missing_impl_diagnoser)
0 commit comments