Replace 'AllowExplicit' bool with an enum. No functionality change.

In passing, split it up into three values (no explicit functions /
explicit conversion functions only / any explicit functions) in
preparation for using that in a future change.
This commit is contained in:
Richard Smith 2020-01-29 12:07:14 -08:00
parent 2d3174c4df
commit d28763cad0
5 changed files with 45 additions and 31 deletions

View File

@ -2936,10 +2936,19 @@ public:
bool ConsiderCudaAttrs = true, bool ConsiderCudaAttrs = true,
bool ConsiderRequiresClauses = true); bool ConsiderRequiresClauses = true);
enum class AllowedExplicit {
/// Allow no explicit functions to be used.
None,
/// Allow explicit conversion functions but not explicit constructors.
Conversions,
/// Allow both explicit conversion functions and explicit constructors.
All
};
ImplicitConversionSequence ImplicitConversionSequence
TryImplicitConversion(Expr *From, QualType ToType, TryImplicitConversion(Expr *From, QualType ToType,
bool SuppressUserConversions, bool SuppressUserConversions,
bool AllowExplicit, AllowedExplicit AllowExplicit,
bool InOverloadResolution, bool InOverloadResolution,
bool CStyle, bool CStyle,
bool AllowObjCWritebackConversion); bool AllowObjCWritebackConversion);

View File

@ -8701,7 +8701,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
ImplicitConversionSequence ICS = ImplicitConversionSequence ICS =
TryImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(), TryImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(),
/*SuppressUserConversions=*/false, /*SuppressUserConversions=*/false,
/*AllowExplicit=*/false, AllowedExplicit::None,
/*InOverloadResolution=*/false, /*InOverloadResolution=*/false,
/*CStyle=*/false, /*CStyle=*/false,
/*AllowObjCWritebackConversion=*/false); /*AllowObjCWritebackConversion=*/false);

View File

@ -4924,7 +4924,7 @@ static void TryReferenceInitializationCore(Sema &S,
ImplicitConversionSequence ICS ImplicitConversionSequence ICS
= S.TryImplicitConversion(Initializer, TempEntity.getType(), = S.TryImplicitConversion(Initializer, TempEntity.getType(),
/*SuppressUserConversions=*/false, /*SuppressUserConversions=*/false,
/*AllowExplicit=*/false, Sema::AllowedExplicit::None,
/*FIXME:InOverloadResolution=*/false, /*FIXME:InOverloadResolution=*/false,
/*CStyle=*/Kind.isCStyleOrFunctionalCast(), /*CStyle=*/Kind.isCStyleOrFunctionalCast(),
/*AllowObjCWritebackConversion=*/false); /*AllowObjCWritebackConversion=*/false);
@ -5863,7 +5863,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
ImplicitConversionSequence ICS ImplicitConversionSequence ICS
= S.TryImplicitConversion(Initializer, DestType, = S.TryImplicitConversion(Initializer, DestType,
/*SuppressUserConversions*/true, /*SuppressUserConversions*/true,
/*AllowExplicitConversions*/ false, Sema::AllowedExplicit::None,
/*InOverloadResolution*/ false, /*InOverloadResolution*/ false,
/*CStyle=*/Kind.isCStyleOrFunctionalCast(), /*CStyle=*/Kind.isCStyleOrFunctionalCast(),
allowObjCWritebackConversion); allowObjCWritebackConversion);

View File

@ -5388,7 +5388,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
ImplicitConversionSequence ICS = ImplicitConversionSequence ICS =
TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
/*SuppressUserConversions=*/false, /*SuppressUserConversions=*/false,
/*AllowExplicit=*/false, AllowedExplicit::None,
/*InOverloadResolution=*/false, /*InOverloadResolution=*/false,
/*CStyle=*/false, /*CStyle=*/false,
/*AllowObjCWritebackConversion=*/false); /*AllowObjCWritebackConversion=*/false);

View File

@ -38,6 +38,8 @@
using namespace clang; using namespace clang;
using namespace sema; using namespace sema;
using AllowedExplicit = Sema::AllowedExplicit;
static bool functionHasPassObjectSizeParams(const FunctionDecl *FD) { static bool functionHasPassObjectSizeParams(const FunctionDecl *FD) {
return llvm::any_of(FD->parameters(), [](const ParmVarDecl *P) { return llvm::any_of(FD->parameters(), [](const ParmVarDecl *P) {
return P->hasAttr<PassObjectSizeAttr>(); return P->hasAttr<PassObjectSizeAttr>();
@ -91,10 +93,9 @@ static OverloadingResult
IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
UserDefinedConversionSequence& User, UserDefinedConversionSequence& User,
OverloadCandidateSet& Conversions, OverloadCandidateSet& Conversions,
bool AllowExplicit, AllowedExplicit AllowExplicit,
bool AllowObjCConversionOnExplicit); bool AllowObjCConversionOnExplicit);
static ImplicitConversionSequence::CompareKind static ImplicitConversionSequence::CompareKind
CompareStandardConversionSequences(Sema &S, SourceLocation Loc, CompareStandardConversionSequences(Sema &S, SourceLocation Loc,
const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS1,
@ -1317,7 +1318,7 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
static ImplicitConversionSequence static ImplicitConversionSequence
TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
bool SuppressUserConversions, bool SuppressUserConversions,
bool AllowExplicit, AllowedExplicit AllowExplicit,
bool InOverloadResolution, bool InOverloadResolution,
bool CStyle, bool CStyle,
bool AllowObjCWritebackConversion, bool AllowObjCWritebackConversion,
@ -1420,7 +1421,7 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
static ImplicitConversionSequence static ImplicitConversionSequence
TryImplicitConversion(Sema &S, Expr *From, QualType ToType, TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
bool SuppressUserConversions, bool SuppressUserConversions,
bool AllowExplicit, AllowedExplicit AllowExplicit,
bool InOverloadResolution, bool InOverloadResolution,
bool CStyle, bool CStyle,
bool AllowObjCWritebackConversion, bool AllowObjCWritebackConversion,
@ -1475,13 +1476,12 @@ TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
ImplicitConversionSequence ImplicitConversionSequence
Sema::TryImplicitConversion(Expr *From, QualType ToType, Sema::TryImplicitConversion(Expr *From, QualType ToType,
bool SuppressUserConversions, bool SuppressUserConversions,
bool AllowExplicit, AllowedExplicit AllowExplicit,
bool InOverloadResolution, bool InOverloadResolution,
bool CStyle, bool CStyle,
bool AllowObjCWritebackConversion) { bool AllowObjCWritebackConversion) {
return ::TryImplicitConversion(*this, From, ToType, return ::TryImplicitConversion(*this, From, ToType, SuppressUserConversions,
SuppressUserConversions, AllowExplicit, AllowExplicit, InOverloadResolution, CStyle,
InOverloadResolution, CStyle,
AllowObjCWritebackConversion, AllowObjCWritebackConversion,
/*AllowObjCConversionOnExplicit=*/false); /*AllowObjCConversionOnExplicit=*/false);
} }
@ -1514,10 +1514,10 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
From->getType(), From); From->getType(), From);
ICS = ::TryImplicitConversion(*this, From, ToType, ICS = ::TryImplicitConversion(*this, From, ToType,
/*SuppressUserConversions=*/false, /*SuppressUserConversions=*/false,
AllowExplicit, AllowExplicit ? AllowedExplicit::All
: AllowedExplicit::None,
/*InOverloadResolution=*/false, /*InOverloadResolution=*/false,
/*CStyle=*/false, /*CStyle=*/false, AllowObjCWritebackConversion,
AllowObjCWritebackConversion,
/*AllowObjCConversionOnExplicit=*/false); /*AllowObjCConversionOnExplicit=*/false);
return PerformImplicitConversion(From, ToType, ICS, Action); return PerformImplicitConversion(From, ToType, ICS, Action);
} }
@ -3397,9 +3397,10 @@ static OverloadingResult
IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
UserDefinedConversionSequence &User, UserDefinedConversionSequence &User,
OverloadCandidateSet &CandidateSet, OverloadCandidateSet &CandidateSet,
bool AllowExplicit, AllowedExplicit AllowExplicit,
bool AllowObjCConversionOnExplicit) { bool AllowObjCConversionOnExplicit) {
assert(AllowExplicit || !AllowObjCConversionOnExplicit); assert(AllowExplicit != AllowedExplicit::None ||
!AllowObjCConversionOnExplicit);
CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion); CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion);
// Whether we will only visit constructors. // Whether we will only visit constructors.
@ -3432,7 +3433,8 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
if (InitListExpr *InitList = dyn_cast<InitListExpr>(From)) { if (InitListExpr *InitList = dyn_cast<InitListExpr>(From)) {
// But first, see if there is an init-list-constructor that will work. // But first, see if there is an init-list-constructor that will work.
OverloadingResult Result = IsInitializerListConstructorConversion( OverloadingResult Result = IsInitializerListConstructorConversion(
S, From, ToType, ToRecordDecl, User, CandidateSet, AllowExplicit); S, From, ToType, ToRecordDecl, User, CandidateSet,
AllowExplicit == AllowedExplicit::All);
if (Result != OR_No_Viable_Function) if (Result != OR_No_Viable_Function)
return Result; return Result;
// Never mind. // Never mind.
@ -3471,14 +3473,16 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
Info.ConstructorTmpl, Info.FoundDecl, Info.ConstructorTmpl, Info.FoundDecl,
/*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs), /*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs),
CandidateSet, SuppressUserConversions, CandidateSet, SuppressUserConversions,
/*PartialOverloading*/ false, AllowExplicit); /*PartialOverloading*/ false,
AllowExplicit == AllowedExplicit::All);
else else
// Allow one user-defined conversion when user specifies a // Allow one user-defined conversion when user specifies a
// From->ToType conversion via an static cast (c-style, etc). // From->ToType conversion via an static cast (c-style, etc).
S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl,
llvm::makeArrayRef(Args, NumArgs), llvm::makeArrayRef(Args, NumArgs),
CandidateSet, SuppressUserConversions, CandidateSet, SuppressUserConversions,
/*PartialOverloading*/ false, AllowExplicit); /*PartialOverloading*/ false,
AllowExplicit == AllowedExplicit::All);
} }
} }
} }
@ -3511,11 +3515,12 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
if (ConvTemplate) if (ConvTemplate)
S.AddTemplateConversionCandidate( S.AddTemplateConversionCandidate(
ConvTemplate, FoundDecl, ActingContext, From, ToType, ConvTemplate, FoundDecl, ActingContext, From, ToType,
CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit); CandidateSet, AllowObjCConversionOnExplicit,
AllowExplicit != AllowedExplicit::None);
else else
S.AddConversionCandidate( S.AddConversionCandidate(Conv, FoundDecl, ActingContext, From, ToType,
Conv, FoundDecl, ActingContext, From, ToType, CandidateSet, CandidateSet, AllowObjCConversionOnExplicit,
AllowObjCConversionOnExplicit, AllowExplicit); AllowExplicit != AllowedExplicit::None);
} }
} }
} }
@ -3601,7 +3606,7 @@ Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
OverloadCandidateSet::CSK_Normal); OverloadCandidateSet::CSK_Normal);
OverloadingResult OvResult = OverloadingResult OvResult =
IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined, IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined,
CandidateSet, false, false); CandidateSet, AllowedExplicit::None, false);
if (!(OvResult == OR_Ambiguous || if (!(OvResult == OR_Ambiguous ||
(OvResult == OR_No_Viable_Function && !CandidateSet.empty()))) (OvResult == OR_No_Viable_Function && !CandidateSet.empty())))
@ -4862,7 +4867,7 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
// cv-qualification is subsumed by the initialization itself // cv-qualification is subsumed by the initialization itself
// and does not constitute a conversion. // and does not constitute a conversion.
ICS = TryImplicitConversion(S, Init, T1, SuppressUserConversions, ICS = TryImplicitConversion(S, Init, T1, SuppressUserConversions,
/*AllowExplicit=*/false, AllowedExplicit::None,
/*InOverloadResolution=*/false, /*InOverloadResolution=*/false,
/*CStyle=*/false, /*CStyle=*/false,
/*AllowObjCWritebackConversion=*/false, /*AllowObjCWritebackConversion=*/false,
@ -5031,7 +5036,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
if (ToType->isRecordType() && !ToType->isAggregateType()) { if (ToType->isRecordType() && !ToType->isAggregateType()) {
// This function can deal with initializer lists. // This function can deal with initializer lists.
return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions, return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions,
/*AllowExplicit=*/false, AllowedExplicit::None,
InOverloadResolution, /*CStyle=*/false, InOverloadResolution, /*CStyle=*/false,
AllowObjCWritebackConversion, AllowObjCWritebackConversion,
/*AllowObjCConversionOnExplicit=*/false); /*AllowObjCConversionOnExplicit=*/false);
@ -5183,7 +5188,7 @@ TryCopyInitialization(Sema &S, Expr *From, QualType ToType,
return TryImplicitConversion(S, From, ToType, return TryImplicitConversion(S, From, ToType,
SuppressUserConversions, SuppressUserConversions,
/*AllowExplicit=*/false, AllowedExplicit::None,
InOverloadResolution, InOverloadResolution,
/*CStyle=*/false, /*CStyle=*/false,
AllowObjCWritebackConversion, AllowObjCWritebackConversion,
@ -5431,7 +5436,7 @@ static ImplicitConversionSequence
TryContextuallyConvertToBool(Sema &S, Expr *From) { TryContextuallyConvertToBool(Sema &S, Expr *From) {
return TryImplicitConversion(S, From, S.Context.BoolTy, return TryImplicitConversion(S, From, S.Context.BoolTy,
/*SuppressUserConversions=*/false, /*SuppressUserConversions=*/false,
/*AllowExplicit=*/true, AllowedExplicit::Conversions,
/*InOverloadResolution=*/false, /*InOverloadResolution=*/false,
/*CStyle=*/false, /*CStyle=*/false,
/*AllowObjCWritebackConversion=*/false, /*AllowObjCWritebackConversion=*/false,
@ -5703,7 +5708,7 @@ TryContextuallyConvertToObjCPointer(Sema &S, Expr *From) {
= TryImplicitConversion(S, From, Ty, = TryImplicitConversion(S, From, Ty,
// FIXME: Are these flags correct? // FIXME: Are these flags correct?
/*SuppressUserConversions=*/false, /*SuppressUserConversions=*/false,
/*AllowExplicit=*/true, AllowedExplicit::Conversions,
/*InOverloadResolution=*/false, /*InOverloadResolution=*/false,
/*CStyle=*/false, /*CStyle=*/false,
/*AllowObjCWritebackConversion=*/false, /*AllowObjCWritebackConversion=*/false,