logan-5 created this revision.
logan-5 added a reviewer: rsmith.
logan-5 added a project: clang.
Herald added a subscriber: cfe-commits.
logan-5 added a child revision: D74238: [clang] [clang] Improve diagnostic note
for implicit conversion sequences that would work if more than one implicit
user-defined conversion were allowed..
This is groundwork for a subsequent patch that adds a third mode for searching
for user conversions.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D74234
Files:
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaCodeComplete.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaLookup.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaOverload.cpp
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ 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<InitListExpr>(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<InitListExpr>(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<Expr *> 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<Expr *> 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<CXXRecordDecl>(FunTmpl->getDeclContext()),
ExplicitTemplateArgs, ObjectType, ObjectClassification,
- FunctionArgs, CandidateSet, SuppressUserConversions,
+ FunctionArgs, CandidateSet, UserConversions,
PartialOverloading);
} else {
AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(),
cast<CXXMethodDecl>(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<Expr *> Args,
OverloadCandidateSet &CandidateSet,
- bool SuppressUserConversions,
+ Sema::UserDefinedConversions UserConversions,
OverloadCandidateParamOrder PO) {
NamedDecl *Decl = FoundDecl.getDecl();
CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(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<CXXMethodDecl>(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<Expr *> 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<Expr *> 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<QualType> 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<CXXMethodDecl>(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<Expr *> 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<QualType> 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<QualType> ParamTypes,
ArrayRef<Expr *> 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<FunctionTemplateDecl>(*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<QualType> 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<FunctionTemplateDecl>(Callee)) {
S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl,
ExplicitTemplateArgs, Args, CandidateSet,
- /*SuppressUserConversions=*/false,
+ Sema::UserDefinedConversions::Allow,
PartialOverloading);
return;
}
@@ -13894,7 +13910,7 @@
if (getLangOpts().MicrosoftExt && isa<CXXConstructorDecl>(Func)) {
AddOverloadCandidate(cast<CXXConstructorDecl>(Func), I.getPair(), Args,
CandidateSet,
- /*SuppressUserConversions*/ false);
+ UserDefinedConversions::Allow);
} else if ((Method = dyn_cast<CXXMethodDecl>(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<FunctionTemplateDecl>(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);
Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ 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,
Index: clang/lib/Sema/SemaLookup.cpp
===================================================================
--- clang/lib/Sema/SemaLookup.cpp
+++ clang/lib/Sema/SemaLookup.cpp
@@ -3247,27 +3247,29 @@
if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(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<FunctionTemplateDecl>(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<UsingDecl>(Cand.getDecl()) &&
"illegal Kind of operator = Decl");
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ 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<InitListExpr>(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);
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ 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<FunctionDecl>(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<FunctionDecl>(D);
S.AddOverloadCandidate(Fn, FnOvl.getPair(), Args, Candidates,
- /*SuppressUserConversions=*/false);
+ Sema::UserDefinedConversions::Allow);
}
SourceRange Range = TheCall->getSourceRange();
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ 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,
Index: clang/lib/Sema/SemaCodeComplete.cpp
===================================================================
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ 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<FunctionDecl>(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<FunctionTemplateDecl>(C)) {
AddTemplateOverloadCandidate(
FTD, DeclAccessPair::make(FTD, C->getAccess()),
/*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet,
- /*SuppressUserConversions=*/false,
+ Sema::UserDefinedConversions::Allow,
/*PartialOverloading=*/true);
}
}
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ 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<Expr *> Args,
OverloadCandidateSet &CandidateSet,
- bool SuppressUserConversions = false,
+ UserDefinedConversions UserConversions
+ = UserDefinedConversions::Allow,
bool PartialOverloading = false,
bool AllowExplicit = true,
bool AllowExplicitConversion = false,
@@ -3173,7 +3182,8 @@
ArrayRef<Expr *> 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<Expr *> 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<Expr *> 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<Expr *> Args,
OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false,
+ UserDefinedConversions UserConversions
+ = UserDefinedConversions::Allow,
bool PartialOverloading = false,
OverloadCandidateParamOrder PO = {});
void AddTemplateOverloadCandidate(
FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> 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<QualType> ParamTypes,
ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet,
- ConversionSequenceList &Conversions, bool SuppressUserConversions,
+ ConversionSequenceList &Conversions, UserDefinedConversions UserConversions,
CXXRecordDecl *ActingContext = nullptr, QualType ObjectType = QualType(),
Expr::Classification ObjectClassification = {},
OverloadCandidateParamOrder PO = {});
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits