@@ -71,6 +71,30 @@ class Sema;
7171 OCD_ViableCandidates
7272 };
7373
74+ // / The parameter ordering that will be used for the candidate. This is
75+ // / used to represent C++20 binary operator rewrites that reverse the order
76+ // / of the arguments. If the parameter ordering is Reversed, the Args list is
77+ // / reversed (but obviously the ParamDecls for the function are not).
78+ // /
79+ // / After forming an OverloadCandidate with reversed parameters, the list
80+ // / of conversions will (as always) be indexed by argument, so will be
81+ // / in reverse parameter order.
82+ enum class OverloadCandidateParamOrder : char { Normal, Reversed };
83+
84+ // / The kinds of rewrite we perform on overload candidates. Note that the
85+ // / values here are chosen to serve as both bitflags and as a rank (lower
86+ // / values are preferred by overload resolution).
87+ enum OverloadCandidateRewriteKind : unsigned {
88+ // / Candidate is not a rewritten candidate.
89+ CRK_None = 0x0 ,
90+
91+ // / Candidate is a rewritten candidate with a different operator name.
92+ CRK_DifferentOperator = 0x1 ,
93+
94+ // / Candidate is a rewritten candidate with a reversed order of parameters.
95+ CRK_Reversed = 0x2 ,
96+ };
97+
7498 // / ImplicitConversionKind - The kind of implicit conversion used to
7599 // / convert an argument to a parameter's type. The enumerator values
76100 // / match with the table titled 'Conversions' in [over.ics.scs] and are listed
@@ -757,7 +781,8 @@ class Sema;
757781 CXXConversionDecl *Surrogate;
758782
759783 // / The conversion sequences used to convert the function arguments
760- // / to the function parameters.
784+ // / to the function parameters. Note that these are indexed by argument,
785+ // / so may not match the parameter order of Function.
761786 ConversionSequenceList Conversions;
762787
763788 // / The FixIt hints which can be used to fix the Bad candidate.
@@ -783,6 +808,9 @@ class Sema;
783808 // / True if the candidate was found using ADL.
784809 CallExpr::ADLCallKind IsADLCandidate : 1 ;
785810
811+ // / Whether this is a rewritten candidate, and if so, of what kind?
812+ OverloadCandidateRewriteKind RewriteKind : 2 ;
813+
786814 // / FailureKind - The reason why this candidate is not viable.
787815 // / Actually an OverloadFailureKind.
788816 unsigned char FailureKind;
@@ -838,7 +866,8 @@ class Sema;
838866
839867 private:
840868 friend class OverloadCandidateSet ;
841- OverloadCandidate () : IsADLCandidate(CallExpr::NotADL) {}
869+ OverloadCandidate ()
870+ : IsADLCandidate(CallExpr::NotADL), RewriteKind(CRK_None) {}
842871 };
843872
844873 // / OverloadCandidateSet - A set of overload candidates, used in C++
@@ -867,16 +896,62 @@ class Sema;
867896 CSK_InitByConstructor,
868897 };
869898
899+ // / Information about operator rewrites to consider when adding operator
900+ // / functions to a candidate set.
901+ struct OperatorRewriteInfo {
902+ OperatorRewriteInfo ()
903+ : OriginalOperator(OO_None), AllowRewrittenCandidates(false ) {}
904+ OperatorRewriteInfo (OverloadedOperatorKind Op, bool AllowRewritten)
905+ : OriginalOperator(Op), AllowRewrittenCandidates(AllowRewritten) {}
906+
907+ // / The original operator as written in the source.
908+ OverloadedOperatorKind OriginalOperator;
909+ // / Whether we should include rewritten candidates in the overload set.
910+ bool AllowRewrittenCandidates;
911+
912+ // / Would use of this function result in a rewrite using a different
913+ // / operator?
914+ bool isRewrittenOperator (const FunctionDecl *FD) {
915+ return OriginalOperator &&
916+ FD->getDeclName ().getCXXOverloadedOperator () != OriginalOperator;
917+ }
918+
919+ bool isAcceptableCandidate (const FunctionDecl *FD) {
920+ return AllowRewrittenCandidates || !isRewrittenOperator (FD);
921+ }
922+
923+ // / Determine the kind of rewrite that should be performed for this
924+ // / candidate.
925+ OverloadCandidateRewriteKind
926+ getRewriteKind (const FunctionDecl *FD, OverloadCandidateParamOrder PO) {
927+ OverloadCandidateRewriteKind CRK = CRK_None;
928+ if (isRewrittenOperator (FD))
929+ CRK = OverloadCandidateRewriteKind (CRK | CRK_DifferentOperator);
930+ if (PO == OverloadCandidateParamOrder::Reversed)
931+ CRK = OverloadCandidateRewriteKind (CRK | CRK_Reversed);
932+ return CRK;
933+ }
934+
935+ // / Determine whether we should consider looking for and adding reversed
936+ // / candidates for operator Op.
937+ bool shouldAddReversed (OverloadedOperatorKind Op);
938+
939+ // / Determine whether we should add a rewritten candidate for \p FD with
940+ // / reversed parameter order.
941+ bool shouldAddReversed (ASTContext &Ctx, const FunctionDecl *FD);
942+ };
943+
870944 private:
871945 SmallVector<OverloadCandidate, 16 > Candidates;
872- llvm::SmallPtrSet<Decl * , 16 > Functions;
946+ llvm::SmallPtrSet<uintptr_t , 16 > Functions;
873947
874948 // Allocator for ConversionSequenceLists. We store the first few of these
875949 // inline to avoid allocation for small sets.
876950 llvm::BumpPtrAllocator SlabAllocator;
877951
878952 SourceLocation Loc;
879953 CandidateSetKind Kind;
954+ OperatorRewriteInfo RewriteInfo;
880955
881956 constexpr static unsigned NumInlineBytes =
882957 24 * sizeof (ImplicitConversionSequence);
@@ -915,19 +990,24 @@ class Sema;
915990 void destroyCandidates ();
916991
917992 public:
918- OverloadCandidateSet (SourceLocation Loc, CandidateSetKind CSK)
919- : Loc(Loc), Kind(CSK) {}
993+ OverloadCandidateSet (SourceLocation Loc, CandidateSetKind CSK,
994+ OperatorRewriteInfo RewriteInfo = {})
995+ : Loc(Loc), Kind(CSK), RewriteInfo(RewriteInfo) {}
920996 OverloadCandidateSet (const OverloadCandidateSet &) = delete ;
921997 OverloadCandidateSet &operator =(const OverloadCandidateSet &) = delete ;
922998 ~OverloadCandidateSet () { destroyCandidates (); }
923999
9241000 SourceLocation getLocation () const { return Loc; }
9251001 CandidateSetKind getKind () const { return Kind; }
1002+ OperatorRewriteInfo getRewriteInfo () const { return RewriteInfo; }
9261003
9271004 // / Determine when this overload candidate will be new to the
9281005 // / overload set.
929- bool isNewCandidate (Decl *F) {
930- return Functions.insert (F->getCanonicalDecl ()).second ;
1006+ bool isNewCandidate (Decl *F, OverloadCandidateParamOrder PO =
1007+ OverloadCandidateParamOrder::Normal) {
1008+ uintptr_t Key = reinterpret_cast <uintptr_t >(F->getCanonicalDecl ());
1009+ Key |= static_cast <uintptr_t >(PO);
1010+ return Functions.insert (Key).second ;
9311011 }
9321012
9331013 // / Clear out all of the candidates.
0 commit comments