@@ -375,7 +375,7 @@ bool IsConvertibleCXXMethodDecl(const clang::CXXMethodDecl *decl) {
375375 if (llvm::isa<clang::CXXDestructorDecl>(decl)) {
376376 return GetUserDefinedDestructor (decl->getParent ()) != nullptr ;
377377 }
378- return !decl->isImplicit ();
378+ return !decl->isImplicit () || IsComparisonOperator (decl) ;
379379}
380380
381381bool IsConvertibleFunctionDecl (const clang::FunctionDecl *decl) {
@@ -648,12 +648,17 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
648648 auto *pdecl = llvm::dyn_cast<clang::ParmVarDecl>(decl);
649649 assert (pdecl && " Unexpected unnamed construct" );
650650
651- const auto *ctor =
652- llvm::dyn_cast<clang::CXXConstructorDecl>(pdecl->getDeclContext ());
653- name = (pdecl->isExplicitObjectParameter () ||
654- (ctor && ctor->isCopyOrMoveConstructor ()))
655- ? " self"
656- : " _" ;
651+ const auto *fn =
652+ llvm::dyn_cast<clang::FunctionDecl>(pdecl->getDeclContext ());
653+ const auto *ctor = llvm::dyn_cast_or_null<clang::CXXConstructorDecl>(fn);
654+ if (pdecl->isExplicitObjectParameter () ||
655+ (ctor && ctor->isCopyOrMoveConstructor ())) {
656+ name = " self" ;
657+ } else if (fn && fn->isDefaulted () && IsComparisonOperator (fn)) {
658+ name = std::format (" _arg{}" , pdecl->getFunctionScopeIndex ());
659+ } else {
660+ name = " _" ;
661+ }
657662 } else if (auto *pdecl = llvm::dyn_cast<clang::ParmVarDecl>(decl)) {
658663 // Expanded parameter packs share one name across the expansion
659664 if (auto *fn = llvm::dyn_cast_or_null<clang::FunctionDecl>(
@@ -804,7 +809,14 @@ bool IsSameTypeComparison(const clang::FunctionDecl *fn,
804809
805810bool IsUserOperatorCall (const clang::CXXOperatorCallExpr *expr) {
806811 const auto *callee = expr->getDirectCallee ();
807- if (!callee || !callee->isUserProvided () || !IsUserDefinedDecl (callee)) {
812+ if (!callee) {
813+ return false ;
814+ }
815+ if (const auto *method = clang::dyn_cast<clang::CXXMethodDecl>(callee);
816+ method && method->isDefaulted () && IsComparisonOperator (method)) {
817+ return IsUserDefinedDecl (method->getParent ());
818+ }
819+ if (!callee->isUserProvided () || !IsUserDefinedDecl (callee)) {
808820 return false ;
809821 }
810822 if (const auto *method = clang::dyn_cast<clang::CXXMethodDecl>(callee)) {
@@ -864,6 +876,21 @@ bool RecordNeedsDestruction(const clang::CXXRecordDecl *decl) {
864876 return GetUserDefinedDestructor (decl) || HasFieldsNeedingDestruction (decl);
865877}
866878
879+ bool IsComparisonOperator (const clang::FunctionDecl *fn) {
880+ switch (fn->getOverloadedOperator ()) {
881+ case clang::OO_EqualEqual:
882+ case clang::OO_ExclaimEqual:
883+ case clang::OO_Less:
884+ case clang::OO_LessEqual:
885+ case clang::OO_Greater:
886+ case clang::OO_GreaterEqual:
887+ case clang::OO_Spaceship:
888+ return true ;
889+ default :
890+ return false ;
891+ }
892+ }
893+
867894bool IsEmittableMethod (clang::CXXMethodDecl *method) {
868895 if (method->isDeleted ()) {
869896 return false ;
@@ -876,6 +903,9 @@ bool IsEmittableMethod(clang::CXXMethodDecl *method) {
876903 if (method->isVirtual ()) {
877904 return false ;
878905 }
906+ if (IsComparisonOperator (method)) {
907+ return method->hasBody ();
908+ }
879909 // Compiler-generated members are covered by derived traits
880910 if (method->isImplicit ()) {
881911 return false ;
@@ -889,16 +919,20 @@ bool IsEmittableMethod(clang::CXXMethodDecl *method) {
889919}
890920
891921bool IsMethodOnPtr (const clang::CXXMethodDecl *method) {
892- if (method->isImplicit () || method->isDeleted () || method->isStatic () ||
893- method->isVirtual () || clang::isa<clang::CXXConstructorDecl>(method)) {
922+ if (method->isDeleted () || method->isStatic () || method->isVirtual () ||
923+ clang::isa<clang::CXXConstructorDecl>(method)) {
924+ return false ;
925+ }
926+ if (method->isImplicit () && !IsComparisonOperator (method)) {
894927 return false ;
895928 }
896929 if (!IsUserDefinedDecl (method->getParent ()) ||
897930 method->getParent ()->isLambda ()) {
898931 return false ;
899932 }
900933 if (auto *definition = method->getDefinition ();
901- definition && definition->isDefaulted ()) {
934+ definition && definition->isDefaulted () &&
935+ !IsComparisonOperator (method)) {
902936 return false ;
903937 }
904938 if (clang::isa<clang::CXXDestructorDecl>(method)) {
0 commit comments