@@ -4665,6 +4665,32 @@ std::string Converter::GetComparisonCall(const clang::FunctionDecl *op,
46654665 arg (0 , lhs), arg (1 , rhs));
46664666}
46674667
4668+ std::string Converter::GetComparisonBool (const clang::FunctionDecl *op,
4669+ const clang::CXXRecordDecl *decl,
4670+ std::string_view lhs,
4671+ std::string_view rhs) {
4672+ auto call = GetComparisonCall (op, decl, lhs, rhs);
4673+ auto ret = op->getReturnType ();
4674+ if (ret->isBooleanType ()) {
4675+ return call;
4676+ }
4677+ if (ret->isIntegerType ()) {
4678+ return std::format (" (({}) != 0)" , call);
4679+ }
4680+ const auto *record = ret->getAsCXXRecordDecl ();
4681+ assert (record && " unsupported comparison operator return type" );
4682+ for (const auto *found : record->getVisibleConversionFunctions ()) {
4683+ const auto *conversion = clang::dyn_cast<clang::CXXConversionDecl>(found);
4684+ if (conversion && conversion->getConversionType ()->isBooleanType ()) {
4685+ return std::format (" {{ let __cmp = &{}; {}::{}({}) }}" , call,
4686+ GetUFCSName (conversion), GetMethodName (conversion),
4687+ GetComparisonReceiver (conversion, record, " __cmp" ));
4688+ }
4689+ }
4690+ assert (0 && " comparison operator result has no conversion to bool" );
4691+ return call;
4692+ }
4693+
46684694std::string
46694695Converter::GetComparisonReferenceArg (const clang::CXXRecordDecl *decl,
46704696 std::string_view value) {
@@ -4692,19 +4718,19 @@ void Converter::ConvertOrdAndPartialOrdTraits(const clang::CXXRecordDecl *decl,
46924718 cmp_body = std::format (" if {} {{ std::cmp::Ordering::Less }} else if {} {{ "
46934719 " std::cmp::Ordering::Greater }} else {{ "
46944720 " std::cmp::Ordering::Equal }}" ,
4695- GetComparisonCall (lt, decl, " self" , " other" ),
4696- GetComparisonCall (lt, decl, " other" , " self" ));
4721+ GetComparisonBool (lt, decl, " self" , " other" ),
4722+ GetComparisonBool (lt, decl, " other" , " self" ));
46974723 }
46984724
46994725 if (eq) {
4700- eq_body = GetComparisonCall (eq, decl, " self" , " other" );
4726+ eq_body = GetComparisonBool (eq, decl, " self" , " other" );
47014727 } else if (cmp) {
47024728 eq_body = std::format (" {} == std::cmp::Ordering::Equal" ,
47034729 GetComparisonCall (cmp, decl, " self" , " other" ));
47044730 } else {
47054731 eq_body = std::format (" !({}) && !({})" ,
4706- GetComparisonCall (lt, decl, " self" , " other" ),
4707- GetComparisonCall (lt, decl, " other" , " self" ));
4732+ GetComparisonBool (lt, decl, " self" , " other" ),
4733+ GetComparisonBool (lt, decl, " other" , " self" ));
47084734 }
47094735
47104736 ConvertOrdAndPartialOrdTraitsBase (cmp_body, eq_body, GetRecordName (decl));
@@ -4719,6 +4745,10 @@ void Converter::AddOrdTrait(const clang::CXXRecordDecl *decl) {
47194745 fn->getDescribedFunctionTemplate () || !IsSameTypeComparison (fn, decl)) {
47204746 return ;
47214747 }
4748+ if (fn->getOverloadedOperator () == clang::OO_Spaceship &&
4749+ !ctx_.CompCategories .lookupInfoForType (fn->getReturnType ())) {
4750+ return ;
4751+ }
47224752 switch (fn->getOverloadedOperator ()) {
47234753 case clang::OO_EqualEqual:
47244754 eq = fn;
0 commit comments