diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2949,6 +2949,14 @@ bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl, bool ConsiderCudaAttrs = true, bool ConsiderRequiresClauses = true); + + enum class UserDefinedConversions { + /// Find user-defined conversions. + Allow, + + /// Don't find user-defined conversions. + Suppress, + }; enum class AllowedExplicit { /// Allow no explicit functions to be used. @@ -2961,7 +2969,7 @@ ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, - bool SuppressUserConversions, + UserDefinedConversions UserConversions, AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, @@ -3162,7 +3170,8 @@ void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef Args, OverloadCandidateSet &CandidateSet, - bool SuppressUserConversions = false, + UserDefinedConversions UserConversions + = UserDefinedConversions::Allow, bool PartialOverloading = false, bool AllowExplicit = true, bool AllowExplicitConversion = false, @@ -3173,7 +3182,8 @@ ArrayRef Args, OverloadCandidateSet &CandidateSet, TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, - bool SuppressUserConversions = false, + UserDefinedConversions UserConversions + = UserDefinedConversions::Allow, bool PartialOverloading = false, bool FirstArgumentIsBase = false); void AddMethodCandidate(DeclAccessPair FoundDecl, @@ -3181,7 +3191,8 @@ Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet& CandidateSet, - bool SuppressUserConversion = false, + UserDefinedConversions UserConversions + = UserDefinedConversions::Allow, OverloadCandidateParamOrder PO = {}); void AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, @@ -3189,7 +3200,8 @@ Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions = false, + UserDefinedConversions UserConversions + = UserDefinedConversions::Allow, bool PartialOverloading = false, ConversionSequenceList EarlyConversions = None, OverloadCandidateParamOrder PO = {}); @@ -3201,20 +3213,22 @@ Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions = false, + UserDefinedConversions UserConversions + = UserDefinedConversions::Allow, bool PartialOverloading = false, OverloadCandidateParamOrder PO = {}); void AddTemplateOverloadCandidate( FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef Args, - OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false, + OverloadCandidateSet &CandidateSet, + UserDefinedConversions UserConversions = UserDefinedConversions::Allow, bool PartialOverloading = false, bool AllowExplicit = true, ADLCallKind IsADLCandidate = ADLCallKind::NotADL, OverloadCandidateParamOrder PO = {}); bool CheckNonDependentConversions( FunctionTemplateDecl *FunctionTemplate, ArrayRef ParamTypes, ArrayRef Args, OverloadCandidateSet &CandidateSet, - ConversionSequenceList &Conversions, bool SuppressUserConversions, + ConversionSequenceList &Conversions, UserDefinedConversions UserConversions, CXXRecordDecl *ActingContext = nullptr, QualType ObjectType = QualType(), Expr::Classification ObjectClassification = {}, OverloadCandidateParamOrder PO = {}); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -5181,7 +5181,7 @@ Decls.append(UME->decls_begin(), UME->decls_end()); const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase(); AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs, - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, /*PartialOverloading=*/true, FirstArgumentIsBase); } else { FunctionDecl *FD = nullptr; @@ -5196,7 +5196,7 @@ else AddOverloadCandidate(FD, DeclAccessPair::make(FD, FD->getAccess()), Args, CandidateSet, - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, /*PartialOverloading=*/true); } else if (auto DC = NakedFn->getType()->getAsCXXRecordDecl()) { @@ -5213,7 +5213,7 @@ ArgExprs.append(Args.begin(), Args.end()); AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs, CandidateSet, /*ExplicitArgs=*/nullptr, - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, /*PartialOverloading=*/true); } } else { @@ -5261,14 +5261,14 @@ if (auto *FD = dyn_cast(C)) { AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), Args, CandidateSet, - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, /*PartialOverloading=*/true, /*AllowExplicit*/ true); } else if (auto *FTD = dyn_cast(C)) { AddTemplateOverloadCandidate( FTD, DeclAccessPair::make(FTD, C->getAccess()), /*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet, - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, /*PartialOverloading=*/true); } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -8701,7 +8701,7 @@ } else { ImplicitConversionSequence ICS = TryImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(), - /*SuppressUserConversions=*/false, + UserDefinedConversions::Allow, AllowedExplicit::None, /*InOverloadResolution=*/false, /*CStyle=*/false, diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2236,13 +2236,13 @@ S.AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(), /*ExplicitTemplateArgs=*/nullptr, Args, Candidates, - /*SuppressUserConversions=*/false); + Sema::UserDefinedConversions::Allow); continue; } FunctionDecl *Fn = cast(D); S.AddOverloadCandidate(Fn, Alloc.getPair(), Args, Candidates, - /*SuppressUserConversions=*/false); + Sema::UserDefinedConversions::Allow); } // Do the resolution. @@ -3469,13 +3469,13 @@ S.AddTemplateOverloadCandidate(FnTemplate, FnOvl.getPair(), /*ExplicitTemplateArgs=*/nullptr, Args, Candidates, - /*SuppressUserConversions=*/false); + Sema::UserDefinedConversions::Allow); continue; } FunctionDecl *Fn = cast(D); S.AddOverloadCandidate(Fn, FnOvl.getPair(), Args, Candidates, - /*SuppressUserConversions=*/false); + Sema::UserDefinedConversions::Allow); } SourceRange Range = TheCall->getSourceRange(); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3891,15 +3891,17 @@ // the first parameter of a constructor of class X, and the conversion // is to X or reference to (possibly cv-qualified X), // user-defined conversion sequences are not considered. - bool SuppressUserConversions = + Sema::UserDefinedConversions UserConversions = SecondStepOfCopyInit || (IsListInit && Args.size() == 1 && isa(Args[0]) && - hasCopyOrMoveCtorParam(S.Context, Info)); + hasCopyOrMoveCtorParam(S.Context, Info)) + ? Sema::UserDefinedConversions::Suppress + : Sema::UserDefinedConversions::Allow; if (Info.ConstructorTmpl) S.AddTemplateOverloadCandidate( Info.ConstructorTmpl, Info.FoundDecl, - /*ExplicitArgs*/ nullptr, Args, CandidateSet, SuppressUserConversions, + /*ExplicitArgs*/ nullptr, Args, CandidateSet, UserConversions, /*PartialOverloading=*/false, AllowExplicit); else { // C++ [over.match.copy]p1: @@ -3913,7 +3915,7 @@ Args.size() == 1 && hasCopyOrMoveCtorParam(S.Context, Info); S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, Args, - CandidateSet, SuppressUserConversions, + CandidateSet, UserConversions, /*PartialOverloading=*/false, AllowExplicit, AllowExplicitConv); } @@ -4495,12 +4497,12 @@ S.AddTemplateOverloadCandidate( Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, Initializer, CandidateSet, - /*SuppressUserConversions=*/true, + Sema::UserDefinedConversions::Suppress, /*PartialOverloading*/ false, AllowExplicitCtors); else S.AddOverloadCandidate( Info.Constructor, Info.FoundDecl, Initializer, CandidateSet, - /*SuppressUserConversions=*/true, + Sema::UserDefinedConversions::Suppress, /*PartialOverloading*/ false, AllowExplicitCtors); } } @@ -4923,7 +4925,7 @@ // copy-initialization? ImplicitConversionSequence ICS = S.TryImplicitConversion(Initializer, TempEntity.getType(), - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, Sema::AllowedExplicit::None, /*FIXME:InOverloadResolution=*/false, /*CStyle=*/Kind.isCStyleOrFunctionalCast(), @@ -5152,12 +5154,12 @@ S.AddTemplateOverloadCandidate( Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, Initializer, CandidateSet, - /*SuppressUserConversions=*/true, + Sema::UserDefinedConversions::Suppress, /*PartialOverloading*/ false, AllowExplicit); else S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, Initializer, CandidateSet, - /*SuppressUserConversions=*/true, + Sema::UserDefinedConversions::Suppress, /*PartialOverloading*/ false, AllowExplicit); } } @@ -5862,7 +5864,7 @@ ImplicitConversionSequence ICS = S.TryImplicitConversion(Initializer, DestType, - /*SuppressUserConversions*/true, + Sema::UserDefinedConversions::Suppress, Sema::AllowedExplicit::None, /*InOverloadResolution*/ false, /*CStyle=*/Kind.isCStyleOrFunctionalCast(), @@ -9805,16 +9807,18 @@ // FIXME: The "second phase of [over.match.list] case can also // theoretically happen here, but it's not clear whether we can // ever have a parameter of the right type. - bool SuppressUserConversions = Kind.isCopyInit(); + Sema::UserDefinedConversions UserConversions = Kind.isCopyInit() + ? Sema::UserDefinedConversions::Suppress + : Sema::UserDefinedConversions::Allow; if (TD) AddTemplateOverloadCandidate(TD, I.getPair(), /*ExplicitArgs*/ nullptr, - Inits, Candidates, SuppressUserConversions, + Inits, Candidates, UserConversions, /*PartialOverloading*/ false, AllowExplicit); else AddOverloadCandidate(GD, I.getPair(), Inits, Candidates, - SuppressUserConversions, + UserConversions, /*PartialOverloading*/ false, AllowExplicit); } return Candidates.BestViableFunction(*this, Kind.getLocation(), Best); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3247,27 +3247,29 @@ if (CXXMethodDecl *M = dyn_cast(Cand->getUnderlyingDecl())) { if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) AddMethodCandidate(M, Cand, RD, ThisTy, Classification, - llvm::makeArrayRef(&Arg, NumArgs), OCS, true); + llvm::makeArrayRef(&Arg, NumArgs), OCS, + UserDefinedConversions::Suppress); else if (CtorInfo) AddOverloadCandidate(CtorInfo.Constructor, CtorInfo.FoundDecl, llvm::makeArrayRef(&Arg, NumArgs), OCS, - /*SuppressUserConversions*/ true); + UserDefinedConversions::Suppress); else AddOverloadCandidate(M, Cand, llvm::makeArrayRef(&Arg, NumArgs), OCS, - /*SuppressUserConversions*/ true); + UserDefinedConversions::Suppress); } else if (FunctionTemplateDecl *Tmpl = dyn_cast(Cand->getUnderlyingDecl())) { if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) AddMethodTemplateCandidate( Tmpl, Cand, RD, nullptr, ThisTy, Classification, - llvm::makeArrayRef(&Arg, NumArgs), OCS, true); + llvm::makeArrayRef(&Arg, NumArgs), OCS, UserDefinedConversions::Suppress); else if (CtorInfo) AddTemplateOverloadCandidate( CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl, nullptr, - llvm::makeArrayRef(&Arg, NumArgs), OCS, true); + llvm::makeArrayRef(&Arg, NumArgs), OCS, UserDefinedConversions::Suppress); else AddTemplateOverloadCandidate( - Tmpl, Cand, nullptr, llvm::makeArrayRef(&Arg, NumArgs), OCS, true); + Tmpl, Cand, nullptr, llvm::makeArrayRef(&Arg, NumArgs), OCS, + UserDefinedConversions::Suppress); } else { assert(isa(Cand.getDecl()) && "illegal Kind of operator = Decl"); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5427,7 +5427,7 @@ } ImplicitConversionSequence ICS = TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, AllowedExplicit::None, /*InOverloadResolution=*/false, /*CStyle=*/false, diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1317,7 +1317,7 @@ /// is not an option. See TryImplicitConversion for more information. static ImplicitConversionSequence TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, @@ -1325,7 +1325,7 @@ bool AllowObjCConversionOnExplicit) { ImplicitConversionSequence ICS; - if (SuppressUserConversions) { + if (UserConversions == Sema::UserDefinedConversions::Suppress) { // We're not in the case above, so there is no conversion that // we can perform. ICS.setBad(BadConversionSequence::no_conversion, From, ToType); @@ -1410,8 +1410,8 @@ /// but will instead return an implicit conversion sequence of kind /// "BadConversion". /// -/// If @p SuppressUserConversions, then user-defined conversions are -/// not permitted. +/// If @p UserConversions is UserDefinedConversions::Suppress, then +/// user-defined conversions are not permitted. /// If @p AllowExplicit, then explicit user-defined conversions are /// permitted. /// @@ -1420,7 +1420,7 @@ /// be initialized with __strong id* or __weak id* arguments. static ImplicitConversionSequence TryImplicitConversion(Sema &S, Expr *From, QualType ToType, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, @@ -1467,7 +1467,7 @@ return ICS; } - return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions, + return TryUserDefinedConversion(S, From, ToType, UserConversions, AllowExplicit, InOverloadResolution, CStyle, AllowObjCWritebackConversion, AllowObjCConversionOnExplicit); @@ -1475,12 +1475,12 @@ ImplicitConversionSequence Sema::TryImplicitConversion(Expr *From, QualType ToType, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion) { - return ::TryImplicitConversion(*this, From, ToType, SuppressUserConversions, + return ::TryImplicitConversion(*this, From, ToType, UserConversions, AllowExplicit, InOverloadResolution, CStyle, AllowObjCWritebackConversion, /*AllowObjCConversionOnExplicit=*/false); @@ -1513,7 +1513,7 @@ CheckObjCBridgeRelatedConversions(From->getBeginLoc(), ToType, From->getType(), From); ICS = ::TryImplicitConversion(*this, From, ToType, - /*SuppressUserConversions=*/false, + UserDefinedConversions::Allow, AllowExplicit ? AllowedExplicit::All : AllowedExplicit::None, /*InOverloadResolution=*/false, @@ -3334,17 +3334,19 @@ if (Usable) { // If the first argument is (a reference to) the target type, // suppress conversions. - bool SuppressUserConversions = isFirstArgumentCompatibleWithType( - S.Context, Info.Constructor, ToType); + Sema::UserDefinedConversions UserConversions = + isFirstArgumentCompatibleWithType(S.Context, Info.Constructor, ToType) + ? Sema::UserDefinedConversions::Suppress + : Sema::UserDefinedConversions::Allow; if (Info.ConstructorTmpl) S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, From, - CandidateSet, SuppressUserConversions, + CandidateSet,UserConversions, /*PartialOverloading*/ false, AllowExplicit); else S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, From, - CandidateSet, SuppressUserConversions, + CandidateSet, UserConversions, /*PartialOverloading*/ false, AllowExplicit); } } @@ -3468,11 +3470,15 @@ S.Context, Info.Constructor, ToType); } } + Sema::UserDefinedConversions UserConversions + = SuppressUserConversions + ? Sema::UserDefinedConversions::Suppress + : Sema::UserDefinedConversions::Allow; if (Info.ConstructorTmpl) S.AddTemplateOverloadCandidate( Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs), - CandidateSet, SuppressUserConversions, + CandidateSet, UserConversions, /*PartialOverloading*/ false, AllowExplicit == AllowedExplicit::All); else @@ -3480,7 +3486,7 @@ // From->ToType conversion via an static cast (c-style, etc). S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, llvm::makeArrayRef(Args, NumArgs), - CandidateSet, SuppressUserConversions, + CandidateSet, UserConversions, /*PartialOverloading*/ false, AllowExplicit == AllowedExplicit::All); } @@ -4652,10 +4658,13 @@ static ImplicitConversionSequence TryReferenceInit(Sema &S, Expr *Init, QualType DeclType, SourceLocation DeclLoc, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, bool AllowExplicit) { assert(DeclType->isReferenceType() && "Reference init needs a reference"); + bool SuppressUserConversions = + UserConversions == Sema::UserDefinedConversions::Suppress; + // Most paths end in a failed conversion. ImplicitConversionSequence ICS; ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType); @@ -4866,7 +4875,7 @@ // the argument expression. Any difference in top-level // cv-qualification is subsumed by the initialization itself // and does not constitute a conversion. - ICS = TryImplicitConversion(S, Init, T1, SuppressUserConversions, + ICS = TryImplicitConversion(S, Init, T1, UserConversions, AllowedExplicit::None, /*InOverloadResolution=*/false, /*CStyle=*/false, @@ -4913,7 +4922,7 @@ static ImplicitConversionSequence TryCopyInitialization(Sema &S, Expr *From, QualType ToType, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, bool InOverloadResolution, bool AllowObjCWritebackConversion, bool AllowExplicit = false); @@ -4922,7 +4931,7 @@ /// initializer list From. static ImplicitConversionSequence TryListConversion(Sema &S, InitListExpr *From, QualType ToType, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, bool InOverloadResolution, bool AllowObjCWritebackConversion) { // C++11 [over.ics.list]p1: @@ -4953,7 +4962,7 @@ if (S.Context.hasSameUnqualifiedType(InitType, ToType) || S.IsDerivedFrom(From->getBeginLoc(), InitType, ToType)) return TryCopyInitialization(S, From->getInit(0), ToType, - SuppressUserConversions, + UserConversions, InOverloadResolution, AllowObjCWritebackConversion); } @@ -4998,7 +5007,7 @@ for (unsigned i = 0, e = From->getNumInits(); i < e; ++i) { Expr *Init = From->getInit(i); ImplicitConversionSequence ICS = - TryCopyInitialization(S, Init, X, SuppressUserConversions, + TryCopyInitialization(S, Init, X, UserConversions, InOverloadResolution, AllowObjCWritebackConversion); // If a single element isn't convertible, fail. @@ -5035,7 +5044,7 @@ // implicit conversion sequence is a user-defined conversion sequence. if (ToType->isRecordType() && !ToType->isAggregateType()) { // This function can deal with initializer lists. - return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions, + return TryUserDefinedConversion(S, From, ToType, UserConversions, AllowedExplicit::None, InOverloadResolution, /*CStyle=*/false, AllowObjCWritebackConversion, @@ -5103,14 +5112,14 @@ if (RefRelationship >= Sema::Ref_Related) { return TryReferenceInit(S, Init, ToType, /*FIXME*/ From->getBeginLoc(), - SuppressUserConversions, + UserConversions, /*AllowExplicit=*/false); } } // Otherwise, we bind the reference to a temporary created from the // initializer list. - Result = TryListConversion(S, From, T1, SuppressUserConversions, + Result = TryListConversion(S, From, T1, UserConversions, InOverloadResolution, AllowObjCWritebackConversion); if (Result.isFailure()) @@ -5145,7 +5154,7 @@ unsigned NumInits = From->getNumInits(); if (NumInits == 1 && !isa(From->getInit(0))) Result = TryCopyInitialization(S, From->getInit(0), ToType, - SuppressUserConversions, + UserConversions, InOverloadResolution, AllowObjCWritebackConversion); // - if the initializer list has no elements, the implicit conversion @@ -5169,25 +5178,26 @@ /// ToType from the expression From. Return the implicit conversion /// sequence required to pass this argument, which may be a bad /// conversion sequence (meaning that the argument cannot be passed to -/// a parameter of this type). If @p SuppressUserConversions, then we -/// do not permit any user-defined conversion sequences. +/// a parameter of this type). If @p UserConversions is +/// UserDefinedConversions::Suppress, then we do not permit any user-defined +/// conversion sequences. static ImplicitConversionSequence TryCopyInitialization(Sema &S, Expr *From, QualType ToType, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, bool InOverloadResolution, bool AllowObjCWritebackConversion, bool AllowExplicit) { if (InitListExpr *FromInitList = dyn_cast(From)) - return TryListConversion(S, FromInitList, ToType, SuppressUserConversions, + return TryListConversion(S, FromInitList, ToType, UserConversions, InOverloadResolution,AllowObjCWritebackConversion); if (ToType->isReferenceType()) return TryReferenceInit(S, From, ToType, /*FIXME:*/ From->getBeginLoc(), - SuppressUserConversions, AllowExplicit); + UserConversions, AllowExplicit); return TryImplicitConversion(S, From, ToType, - SuppressUserConversions, + UserConversions, AllowedExplicit::None, InOverloadResolution, /*CStyle=*/false, @@ -5202,7 +5212,9 @@ ExprValueKind FromVK) { OpaqueValueExpr TmpExpr(Loc, FromQTy, FromVK); ImplicitConversionSequence ICS = - TryCopyInitialization(S, &TmpExpr, ToQTy, true, true, false); + TryCopyInitialization(S, &TmpExpr, ToQTy, + Sema::UserDefinedConversions::Suppress, + true, false); return !ICS.isBad(); } @@ -5435,7 +5447,7 @@ static ImplicitConversionSequence TryContextuallyConvertToBool(Sema &S, Expr *From) { return TryImplicitConversion(S, From, S.Context.BoolTy, - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, AllowedExplicit::Conversions, /*InOverloadResolution=*/false, /*CStyle=*/false, @@ -5551,7 +5563,7 @@ CCE == Sema::CCEK_ConstexprIf || CCE == Sema::CCEK_ExplicitBool ? TryContextuallyConvertToBool(S, From) : TryCopyInitialization(S, From, T, - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/false, /*AllowExplicit=*/false); @@ -5707,7 +5719,7 @@ ImplicitConversionSequence ICS = TryImplicitConversion(S, From, Ty, // FIXME: Are these flags correct? - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, AllowedExplicit::Conversions, /*InOverloadResolution=*/false, /*CStyle=*/false, @@ -6124,15 +6136,16 @@ /// AddOverloadCandidate - Adds the given function to the set of /// candidate functions, using the given function call arguments. If -/// @p SuppressUserConversions, then don't allow user-defined -/// conversions via constructors or conversion operators. +/// @p UserConversions is UserDefinedConversions::Suppress, then don't allow +/// user-defined conversions via constructors or conversion operators. /// /// \param PartialOverloading true if we are performing "partial" overloading /// based on an incomplete set of function arguments. This feature is used by /// code completion. void Sema::AddOverloadCandidate( FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef Args, - OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, + OverloadCandidateSet &CandidateSet, + Sema::UserDefinedConversions UserConversions, bool PartialOverloading, bool AllowExplicit, bool AllowExplicitConversions, ADLCallKind IsADLCandidate, ConversionSequenceList EarlyConversions, OverloadCandidateParamOrder PO) { @@ -6153,7 +6166,7 @@ // is irrelevant. AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(), Expr::Classification::makeSimpleLValue(), Args, - CandidateSet, SuppressUserConversions, + CandidateSet, UserConversions, PartialOverloading, EarlyConversions, PO); return; } @@ -6325,7 +6338,7 @@ // parameter of F. QualType ParamType = Proto->getParamType(ArgIdx); Candidate.Conversions[ConvIdx] = TryCopyInitialization( - *this, Args[ArgIdx], ParamType, SuppressUserConversions, + *this, Args[ArgIdx], ParamType, UserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, AllowExplicitConversions); @@ -6398,7 +6411,7 @@ ImplicitConversionSequence ConversionState = TryCopyInitialization(*this, argExpr, param->getType(), - /*SuppressUserConversions*/false, + UserDefinedConversions::Allow, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, @@ -6624,7 +6637,7 @@ ArrayRef Args, OverloadCandidateSet &CandidateSet, TemplateArgumentListInfo *ExplicitTemplateArgs, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, bool PartialOverloading, bool FirstArgumentIsBase) { for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { @@ -6656,13 +6669,13 @@ FunTmpl, F.getPair(), cast(FunTmpl->getDeclContext()), ExplicitTemplateArgs, ObjectType, ObjectClassification, - FunctionArgs, CandidateSet, SuppressUserConversions, + FunctionArgs, CandidateSet, UserConversions, PartialOverloading); } else { AddMethodCandidate(cast(FD), F.getPair(), cast(FD)->getParent(), ObjectType, ObjectClassification, FunctionArgs, CandidateSet, - SuppressUserConversions, PartialOverloading); + UserConversions, PartialOverloading); } } else { // This branch handles both standalone functions and static methods. @@ -6678,11 +6691,11 @@ if (FunTmpl) { AddTemplateOverloadCandidate(FunTmpl, F.getPair(), ExplicitTemplateArgs, FunctionArgs, - CandidateSet, SuppressUserConversions, + CandidateSet, UserConversions, PartialOverloading); } else { AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet, - SuppressUserConversions, PartialOverloading); + UserConversions, PartialOverloading); } } } @@ -6694,7 +6707,7 @@ Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet &CandidateSet, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, OverloadCandidateParamOrder PO) { NamedDecl *Decl = FoundDecl.getDecl(); CXXRecordDecl *ActingContext = cast(Decl->getDeclContext()); @@ -6708,11 +6721,11 @@ AddMethodTemplateCandidate(TD, FoundDecl, ActingContext, /*ExplicitArgs*/ nullptr, ObjectType, ObjectClassification, Args, CandidateSet, - SuppressUserConversions, false, PO); + UserConversions, false, PO); } else { AddMethodCandidate(cast(Decl), FoundDecl, ActingContext, ObjectType, ObjectClassification, Args, CandidateSet, - SuppressUserConversions, false, None, PO); + UserConversions, false, None, PO); } } @@ -6720,16 +6733,16 @@ /// of candidate functions, using the given function call arguments /// and the object argument (@c Object). For example, in a call /// @c o.f(a1,a2), @c Object will contain @c o and @c Args will contain -/// both @c a1 and @c a2. If @p SuppressUserConversions, then don't -/// allow user-defined conversions via constructors or conversion -/// operators. +/// both @c a1 and @c a2. If @p UserConversions is +/// UserDefinedConversions::Suppress, then don't allow user-defined conversions +/// via constructors or conversion operators. void Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet &CandidateSet, - bool SuppressUserConversions, + Sema::UserDefinedConversions UserConversions, bool PartialOverloading, ConversionSequenceList EarlyConversions, OverloadCandidateParamOrder PO) { @@ -6843,7 +6856,7 @@ QualType ParamType = Proto->getParamType(ArgIdx); Candidate.Conversions[ConvIdx] = TryCopyInitialization(*this, Args[ArgIdx], ParamType, - SuppressUserConversions, + UserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount); @@ -6882,7 +6895,8 @@ CXXRecordDecl *ActingContext, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef Args, - OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, + OverloadCandidateSet &CandidateSet, + Sema::UserDefinedConversions UserConversions, bool PartialOverloading, OverloadCandidateParamOrder PO) { if (!CandidateSet.isNewCandidate(MethodTmpl, PO)) return; @@ -6904,7 +6918,7 @@ PartialOverloading, [&](ArrayRef ParamTypes) { return CheckNonDependentConversions( MethodTmpl, ParamTypes, Args, CandidateSet, Conversions, - SuppressUserConversions, ActingContext, ObjectType, + UserConversions, ActingContext, ObjectType, ObjectClassification, PO); })) { OverloadCandidate &Candidate = @@ -6936,7 +6950,7 @@ "Specialization is not a member function?"); AddMethodCandidate(cast(Specialization), FoundDecl, ActingContext, ObjectType, ObjectClassification, Args, - CandidateSet, SuppressUserConversions, PartialOverloading, + CandidateSet, UserConversions, PartialOverloading, Conversions, PO); } @@ -6952,7 +6966,8 @@ void Sema::AddTemplateOverloadCandidate( FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef Args, - OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, + OverloadCandidateSet &CandidateSet, + Sema::UserDefinedConversions UserConversions, bool PartialOverloading, bool AllowExplicit, ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO) { if (!CandidateSet.isNewCandidate(FunctionTemplate, PO)) @@ -6987,7 +7002,7 @@ PartialOverloading, [&](ArrayRef ParamTypes) { return CheckNonDependentConversions( FunctionTemplate, ParamTypes, Args, CandidateSet, Conversions, - SuppressUserConversions, nullptr, QualType(), {}, PO); + UserConversions, nullptr, QualType(), {}, PO); })) { OverloadCandidate &Candidate = CandidateSet.addCandidate(Conversions.size(), Conversions); @@ -7018,7 +7033,7 @@ // deduction as a candidate. assert(Specialization && "Missing function template specialization?"); AddOverloadCandidate( - Specialization, FoundDecl, Args, CandidateSet, SuppressUserConversions, + Specialization, FoundDecl, Args, CandidateSet, UserConversions, PartialOverloading, AllowExplicit, /*AllowExplicitConversions*/ false, IsADLCandidate, Conversions, PO); } @@ -7029,7 +7044,8 @@ bool Sema::CheckNonDependentConversions( FunctionTemplateDecl *FunctionTemplate, ArrayRef ParamTypes, ArrayRef Args, OverloadCandidateSet &CandidateSet, - ConversionSequenceList &Conversions, bool SuppressUserConversions, + ConversionSequenceList &Conversions, + Sema::UserDefinedConversions UserConversions, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, OverloadCandidateParamOrder PO) { // FIXME: The cases in which we allow explicit conversions for constructor @@ -7071,7 +7087,7 @@ : (ThisConversions + I); Conversions[ConvIdx] = TryCopyInitialization(*this, Args[I], ParamType, - SuppressUserConversions, + UserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, @@ -7271,7 +7287,7 @@ ImplicitConversionSequence ICS = TryCopyInitialization(*this, TheTemporaryCall, ToType, - /*SuppressUserConversions=*/true, + UserDefinedConversions::Suppress, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/false); @@ -7466,7 +7482,7 @@ QualType ParamType = Proto->getParamType(ArgIdx); Candidate.Conversions[ArgIdx + 1] = TryCopyInitialization(*this, Args[ArgIdx], ParamType, - /*SuppressUserConversions=*/false, + UserDefinedConversions::Allow, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount); @@ -7518,8 +7534,9 @@ if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) AddTemplateOverloadCandidate( FunTmpl, F.getPair(), ExplicitTemplateArgs, - {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, false, false, - true, ADLCallKind::NotADL, OverloadCandidateParamOrder::Reversed); + {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, + UserDefinedConversions::Allow, false, true, + ADLCallKind::NotADL, OverloadCandidateParamOrder::Reversed); } else { if (ExplicitTemplateArgs) continue; @@ -7527,8 +7544,9 @@ if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) AddOverloadCandidate(FD, F.getPair(), {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, - false, false, true, false, ADLCallKind::NotADL, - None, OverloadCandidateParamOrder::Reversed); + UserDefinedConversions::Allow, false, true, false, + ADLCallKind::NotADL, None, + OverloadCandidateParamOrder::Reversed); } } } @@ -7580,7 +7598,7 @@ ++Oper) AddMethodCandidate(Oper.getPair(), Args[0]->getType(), Args[0]->Classify(Context), Args.slice(1), - CandidateSet, /*SuppressUserConversion=*/false, PO); + CandidateSet, UserDefinedConversions::Allow, PO); } } @@ -7633,7 +7651,9 @@ } else { Candidate.Conversions[ArgIdx] = TryCopyInitialization(*this, Args[ArgIdx], ParamTys[ArgIdx], - ArgIdx == 0 && IsAssignmentOperator, + ArgIdx == 0 && IsAssignmentOperator + ? UserDefinedConversions::Suppress + : UserDefinedConversions::Allow, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount); @@ -9279,13 +9299,13 @@ continue; AddOverloadCandidate( - FD, FoundDecl, Args, CandidateSet, /*SuppressUserConversions=*/false, + FD, FoundDecl, Args, CandidateSet, UserDefinedConversions::Allow, PartialOverloading, /*AllowExplicit=*/true, /*AllowExplicitConversions=*/false, ADLCallKind::UsesADL); if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) { AddOverloadCandidate( FD, FoundDecl, {Args[1], Args[0]}, CandidateSet, - /*SuppressUserConversions=*/false, PartialOverloading, + UserDefinedConversions::Allow, PartialOverloading, /*AllowExplicit=*/true, /*AllowExplicitConversions=*/false, ADLCallKind::UsesADL, None, OverloadCandidateParamOrder::Reversed); } @@ -9293,13 +9313,13 @@ auto *FTD = cast(*I); AddTemplateOverloadCandidate( FTD, FoundDecl, ExplicitTemplateArgs, Args, CandidateSet, - /*SuppressUserConversions=*/false, PartialOverloading, + UserDefinedConversions::Allow, PartialOverloading, /*AllowExplicit=*/true, ADLCallKind::UsesADL); if (CandidateSet.getRewriteInfo().shouldAddReversed( Context, FTD->getTemplatedDecl())) { AddTemplateOverloadCandidate( FTD, FoundDecl, ExplicitTemplateArgs, {Args[1], Args[0]}, - CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, + CandidateSet, UserDefinedConversions::Allow, PartialOverloading, /*AllowExplicit=*/true, ADLCallKind::UsesADL, OverloadCandidateParamOrder::Reversed); } @@ -11287,10 +11307,6 @@ } } - // FIXME: this should probably be preserved from the overload - // operation somehow. - bool SuppressUserConversions = false; - unsigned ConvIdx = 0; unsigned ArgIdx = 0; ArrayRef ParamTypes; @@ -11336,7 +11352,7 @@ else { Cand->Conversions[ConvIdx] = TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ParamIdx], - SuppressUserConversions, + Sema::UserDefinedConversions::Allow, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ S.getLangOpts().ObjCAutoRefCount); @@ -12349,7 +12365,7 @@ return; S.AddOverloadCandidate(Func, FoundDecl, Args, CandidateSet, - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, PartialOverloading); return; } @@ -12358,7 +12374,7 @@ = dyn_cast(Callee)) { S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl, ExplicitTemplateArgs, Args, CandidateSet, - /*SuppressUserConversions=*/false, + Sema::UserDefinedConversions::Allow, PartialOverloading); return; } @@ -13894,7 +13910,7 @@ if (getLangOpts().MicrosoftExt && isa(Func)) { AddOverloadCandidate(cast(Func), I.getPair(), Args, CandidateSet, - /*SuppressUserConversions*/ false); + UserDefinedConversions::Allow); } else if ((Method = dyn_cast(Func))) { // If explicit template arguments were provided, we can't call a // non-template member function. @@ -13903,12 +13919,12 @@ AddMethodCandidate(Method, I.getPair(), ActingDC, ObjectType, ObjectClassification, Args, CandidateSet, - /*SuppressUserConversions=*/false); + UserDefinedConversions::Allow); } else { AddMethodTemplateCandidate( cast(Func), I.getPair(), ActingDC, TemplateArgs, ObjectType, ObjectClassification, Args, CandidateSet, - /*SuppressUserConversions=*/false); + UserDefinedConversions::Allow); } } @@ -14105,7 +14121,7 @@ Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Object.get()->getType(), Object.get()->Classify(Context), Args, CandidateSet, - /*SuppressUserConversion=*/false); + UserDefinedConversions::Allow); } // C++ [over.call.object]p2: @@ -14377,7 +14393,7 @@ for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context), - None, CandidateSet, /*SuppressUserConversion=*/false); + None, CandidateSet, UserDefinedConversions::Allow); } bool HadMultipleCandidates = (CandidateSet.size() > 1);