diff options
Diffstat (limited to 'include/clang/Sema/Overload.h')
-rw-r--r-- | include/clang/Sema/Overload.h | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 144e6d927c..a97a7181f7 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -71,6 +71,30 @@ class Sema; OCD_ViableCandidates }; + /// The parameter ordering that will be used for the candidate. This is + /// used to represent C++20 binary operator rewrites that reverse the order + /// of the arguments. If the parameter ordering is Reversed, the Args list is + /// reversed (but obviously the ParamDecls for the function are not). + /// + /// After forming an OverloadCandidate with reversed parameters, the list + /// of conversions will (as always) be indexed by argument, so will be + /// in reverse parameter order. + enum class OverloadCandidateParamOrder : char { Normal, Reversed }; + + /// The kinds of rewrite we perform on overload candidates. Note that the + /// values here are chosen to serve as both bitflags and as a rank (lower + /// values are preferred by overload resolution). + enum OverloadCandidateRewriteKind : unsigned { + /// Candidate is not a rewritten candidate. + CRK_None = 0x0, + + /// Candidate is a rewritten candidate with a different operator name. + CRK_DifferentOperator = 0x1, + + /// Candidate is a rewritten candidate with a reversed order of parameters. + CRK_Reversed = 0x2, + }; + /// ImplicitConversionKind - The kind of implicit conversion used to /// convert an argument to a parameter's type. The enumerator values /// match with the table titled 'Conversions' in [over.ics.scs] and are listed @@ -757,7 +781,8 @@ class Sema; CXXConversionDecl *Surrogate; /// The conversion sequences used to convert the function arguments - /// to the function parameters. + /// to the function parameters. Note that these are indexed by argument, + /// so may not match the parameter order of Function. ConversionSequenceList Conversions; /// The FixIt hints which can be used to fix the Bad candidate. @@ -783,6 +808,9 @@ class Sema; /// True if the candidate was found using ADL. CallExpr::ADLCallKind IsADLCandidate : 1; + /// Whether this is a rewritten candidate, and if so, of what kind? + OverloadCandidateRewriteKind RewriteKind : 2; + /// FailureKind - The reason why this candidate is not viable. /// Actually an OverloadFailureKind. unsigned char FailureKind; @@ -838,7 +866,8 @@ class Sema; private: friend class OverloadCandidateSet; - OverloadCandidate() : IsADLCandidate(CallExpr::NotADL) {} + OverloadCandidate() + : IsADLCandidate(CallExpr::NotADL), RewriteKind(CRK_None) {} }; /// OverloadCandidateSet - A set of overload candidates, used in C++ @@ -867,9 +896,54 @@ class Sema; CSK_InitByConstructor, }; + /// Information about operator rewrites to consider when adding operator + /// functions to a candidate set. + struct OperatorRewriteInfo { + OperatorRewriteInfo() + : OriginalOperator(OO_None), AllowRewrittenCandidates(false) {} + OperatorRewriteInfo(OverloadedOperatorKind Op, bool AllowRewritten) + : OriginalOperator(Op), AllowRewrittenCandidates(AllowRewritten) {} + + /// The original operator as written in the source. + OverloadedOperatorKind OriginalOperator; + /// Whether we should include rewritten candidates in the overload set. + bool AllowRewrittenCandidates; + + /// Would use of this function result in a rewrite using a different + /// operator? + bool isRewrittenOperator(const FunctionDecl *FD) { + return OriginalOperator && + FD->getDeclName().getCXXOverloadedOperator() != OriginalOperator; + } + + bool isAcceptableCandidate(const FunctionDecl *FD) { + return AllowRewrittenCandidates || !isRewrittenOperator(FD); + } + + /// Determine the kind of rewrite that should be performed for this + /// candidate. + OverloadCandidateRewriteKind + getRewriteKind(const FunctionDecl *FD, OverloadCandidateParamOrder PO) { + OverloadCandidateRewriteKind CRK = CRK_None; + if (isRewrittenOperator(FD)) + CRK = OverloadCandidateRewriteKind(CRK | CRK_DifferentOperator); + if (PO == OverloadCandidateParamOrder::Reversed) + CRK = OverloadCandidateRewriteKind(CRK | CRK_Reversed); + return CRK; + } + + /// Determine whether we should consider looking for and adding reversed + /// candidates for operator Op. + bool shouldAddReversed(OverloadedOperatorKind Op); + + /// Determine whether we should add a rewritten candidate for \p FD with + /// reversed parameter order. + bool shouldAddReversed(ASTContext &Ctx, const FunctionDecl *FD); + }; + private: SmallVector<OverloadCandidate, 16> Candidates; - llvm::SmallPtrSet<Decl *, 16> Functions; + llvm::SmallPtrSet<uintptr_t, 16> Functions; // Allocator for ConversionSequenceLists. We store the first few of these // inline to avoid allocation for small sets. @@ -877,6 +951,7 @@ class Sema; SourceLocation Loc; CandidateSetKind Kind; + OperatorRewriteInfo RewriteInfo; constexpr static unsigned NumInlineBytes = 24 * sizeof(ImplicitConversionSequence); @@ -915,19 +990,24 @@ class Sema; void destroyCandidates(); public: - OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK) - : Loc(Loc), Kind(CSK) {} + OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK, + OperatorRewriteInfo RewriteInfo = {}) + : Loc(Loc), Kind(CSK), RewriteInfo(RewriteInfo) {} OverloadCandidateSet(const OverloadCandidateSet &) = delete; OverloadCandidateSet &operator=(const OverloadCandidateSet &) = delete; ~OverloadCandidateSet() { destroyCandidates(); } SourceLocation getLocation() const { return Loc; } CandidateSetKind getKind() const { return Kind; } + OperatorRewriteInfo getRewriteInfo() const { return RewriteInfo; } /// Determine when this overload candidate will be new to the /// overload set. - bool isNewCandidate(Decl *F) { - return Functions.insert(F->getCanonicalDecl()).second; + bool isNewCandidate(Decl *F, OverloadCandidateParamOrder PO = + OverloadCandidateParamOrder::Normal) { + uintptr_t Key = reinterpret_cast<uintptr_t>(F->getCanonicalDecl()); + Key |= static_cast<uintptr_t>(PO); + return Functions.insert(Key).second; } /// Clear out all of the candidates. |