C++ interop: Support C++20 operator and overload resolution for expression rewriting (#6171)

This allows to find the spaceship `operator<=>` when a comparison
operator is not available, and `operator==` when `operator!=` is not
available.
Support added to both lookup and overload resolution, by adding
`OperatorRewriteInfo` and propagating it in `CppOverloadSet`.
In case overload resolution chooses to use an operator which requires
rewriting, we emit a `TODO` since rewriting is not yet supported.

Part of #6170.
This commit is contained in:
Boaz Brickner
2025-10-08 06:28:50 +00:00
committed by GitHub
parent c9bb6b11a4
commit 7c13bddc92
7 changed files with 419 additions and 17 deletions
+7 -5
View File
@@ -190,10 +190,12 @@ auto LookupCppOperator(Context& context, SemIR::LocId loc_id, Operator op,
return SemIR::ErrorInst::InstId;
}
clang::SourceLocation loc = GetCppLocation(context, loc_id);
clang::OverloadCandidateSet::OperatorRewriteInfo operator_rewrite_info(
*op_kind, loc, /*AllowRewritten=*/true);
clang::UnresolvedSet<4> functions;
clang::OverloadCandidateSet candidate_set(
GetCppLocation(context, loc_id),
clang::OverloadCandidateSet::CSK_Operator);
loc, clang::OverloadCandidateSet::CSK_Operator, operator_rewrite_info);
// This works for both unary and binary operators.
context.clang_sema().LookupOverloadedBinOp(candidate_set, *op_kind, functions,
*arg_exprs);
@@ -205,9 +207,9 @@ auto LookupCppOperator(Context& context, SemIR::LocId loc_id, Operator op,
functions.addDecl(it.Function, it.FoundDecl.getAccess());
}
return ImportCppOverloadSet(context, SemIR::NameScopeId::None,
SemIR::NameId::CppOperator,
/*naming_class=*/nullptr, std::move(functions));
return ImportCppOverloadSet(
context, SemIR::NameScopeId::None, SemIR::NameId::CppOperator,
/*naming_class=*/nullptr, std::move(functions), operator_rewrite_info);
}
auto IsCppOperatorMethodDecl(clang::Decl* decl) -> bool {