summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp307
1 files changed, 177 insertions, 130 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
index 9195ee5..9d87a10 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
@@ -286,6 +286,16 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx,
QualType FromType = getToType(0);
QualType ToType = getToType(1);
switch (Second) {
+ // 'bool' is an integral type; dispatch to the right place to handle it.
+ case ICK_Boolean_Conversion:
+ if (FromType->isRealFloatingType())
+ goto FloatingIntegralConversion;
+ if (FromType->isIntegralOrUnscopedEnumerationType())
+ goto IntegralConversion;
+ // Boolean conversions can be from pointers and pointers to members
+ // [conv.bool], and those aren't considered narrowing conversions.
+ return NK_Not_Narrowing;
+
// -- from a floating-point type to an integer type, or
//
// -- from an integer type or unscoped enumeration type to a floating-point
@@ -293,6 +303,7 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx,
// value after conversion will fit into the target type and will produce
// the original value when converted back to the original type, or
case ICK_Floating_Integral:
+ FloatingIntegralConversion:
if (FromType->isRealFloatingType() && ToType->isIntegralType(Ctx)) {
return NK_Type_Narrowing;
} else if (FromType->isIntegralType(Ctx) && ToType->isRealFloatingType()) {
@@ -357,13 +368,8 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx,
// the source is a constant expression and the actual value after
// conversion will fit into the target type and will produce the original
// value when converted back to the original type.
- case ICK_Boolean_Conversion: // Bools are integers too.
- if (!FromType->isIntegralOrUnscopedEnumerationType()) {
- // Boolean conversions can be from pointers and pointers to members
- // [conv.bool], and those aren't considered narrowing conversions.
- return NK_Not_Narrowing;
- } // Otherwise, fall through to the integral case.
- case ICK_Integral_Conversion: {
+ case ICK_Integral_Conversion:
+ IntegralConversion: {
assert(FromType->isIntegralOrUnscopedEnumerationType());
assert(ToType->isIntegralOrUnscopedEnumerationType());
const bool FromSigned = FromType->isSignedIntegerOrEnumerationType();
@@ -1098,11 +1104,11 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
// Attempt user-defined conversion.
OverloadCandidateSet Conversions(From->getExprLoc(),
OverloadCandidateSet::CSK_Normal);
- OverloadingResult UserDefResult
- = IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions,
- AllowExplicit, AllowObjCConversionOnExplicit);
-
- if (UserDefResult == OR_Success) {
+ switch (IsUserDefinedConversion(S, From, ToType, ICS.UserDefined,
+ Conversions, AllowExplicit,
+ AllowObjCConversionOnExplicit)) {
+ case OR_Success:
+ case OR_Deleted:
ICS.setUserDefined();
ICS.UserDefined.Before.setAsIdentityConversion();
// C++ [over.ics.user]p4:
@@ -1131,7 +1137,9 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
ICS.Standard.Second = ICK_Derived_To_Base;
}
}
- } else if (UserDefResult == OR_Ambiguous && !SuppressUserConversions) {
+ break;
+
+ case OR_Ambiguous:
ICS.setAmbiguous();
ICS.Ambiguous.setFromType(From->getType());
ICS.Ambiguous.setToType(ToType);
@@ -1139,8 +1147,12 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
Cand != Conversions.end(); ++Cand)
if (Cand->Viable)
ICS.Ambiguous.addConversion(Cand->Function);
- } else {
+ break;
+
+ // Fall through.
+ case OR_No_Viable_Function:
ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
+ break;
}
return ICS;
@@ -1740,18 +1752,20 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
return false;
// We can perform an integral promotion to the underlying type of the enum,
- // even if that's not the promoted type.
+ // even if that's not the promoted type. Note that the check for promoting
+ // the underlying type is based on the type alone, and does not consider
+ // the bitfield-ness of the actual source expression.
if (FromEnumType->getDecl()->isFixed()) {
QualType Underlying = FromEnumType->getDecl()->getIntegerType();
return Context.hasSameUnqualifiedType(Underlying, ToType) ||
- IsIntegralPromotion(From, Underlying, ToType);
+ IsIntegralPromotion(nullptr, Underlying, ToType);
}
// We have already pre-calculated the promotion type, so this is trivial.
if (ToType->isIntegerType() &&
!RequireCompleteType(From->getLocStart(), FromType, 0))
- return Context.hasSameUnqualifiedType(ToType,
- FromEnumType->getDecl()->getPromotionType());
+ return Context.hasSameUnqualifiedType(
+ ToType, FromEnumType->getDecl()->getPromotionType());
}
// C++0x [conv.prom]p2:
@@ -1799,13 +1813,12 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
// other value of that type for promotion purposes (C++ 4.5p3).
// FIXME: We should delay checking of bit-fields until we actually perform the
// conversion.
- using llvm::APSInt;
- if (From)
+ if (From) {
if (FieldDecl *MemberDecl = From->getSourceBitField()) {
- APSInt BitWidth;
+ llvm::APSInt BitWidth;
if (FromType->isIntegralType(Context) &&
MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) {
- APSInt ToSize(BitWidth.getBitWidth(), BitWidth.isUnsigned());
+ llvm::APSInt ToSize(BitWidth.getBitWidth(), BitWidth.isUnsigned());
ToSize = Context.getTypeSize(ToType);
// Are we promoting to an int from a bitfield that fits in an int?
@@ -1823,6 +1836,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
return false;
}
}
+ }
// An rvalue of type bool can be converted to an rvalue of type int,
// with false becoming zero and true becoming one (C++ 4.5p4).
@@ -2940,7 +2954,10 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
bool HadMultipleCandidates = (CandidateSet.size() > 1);
OverloadCandidateSet::iterator Best;
- switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best, true)) {
+ switch (auto Result =
+ CandidateSet.BestViableFunction(S, From->getLocStart(),
+ Best, true)) {
+ case OR_Deleted:
case OR_Success: {
// Record the standard conversion we used and the conversion function.
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
@@ -2953,13 +2970,11 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
User.After.setAsIdentityConversion();
User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType());
User.After.setAllToTypes(ToType);
- return OR_Success;
+ return Result;
}
case OR_No_Viable_Function:
return OR_No_Viable_Function;
- case OR_Deleted:
- return OR_Deleted;
case OR_Ambiguous:
return OR_Ambiguous;
}
@@ -3093,11 +3108,8 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
if (CXXRecordDecl *FromRecordDecl
= dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
// Add all of the conversion functions as candidates.
- std::pair<CXXRecordDecl::conversion_iterator,
- CXXRecordDecl::conversion_iterator>
- Conversions = FromRecordDecl->getVisibleConversionFunctions();
- for (CXXRecordDecl::conversion_iterator
- I = Conversions.first, E = Conversions.second; I != E; ++I) {
+ const auto &Conversions = FromRecordDecl->getVisibleConversionFunctions();
+ for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
DeclAccessPair FoundDecl = I.getPair();
NamedDecl *D = FoundDecl.getDecl();
CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
@@ -3129,8 +3141,10 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
bool HadMultipleCandidates = (CandidateSet.size() > 1);
OverloadCandidateSet::iterator Best;
- switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best, true)) {
+ switch (auto Result = CandidateSet.BestViableFunction(S, From->getLocStart(),
+ Best, true)) {
case OR_Success:
+ case OR_Deleted:
// Record the standard conversion we used and the conversion function.
if (CXXConstructorDecl *Constructor
= dyn_cast<CXXConstructorDecl>(Best->Function)) {
@@ -3158,7 +3172,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
User.After.setAsIdentityConversion();
User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType());
User.After.setAllToTypes(ToType);
- return OR_Success;
+ return Result;
}
if (CXXConversionDecl *Conversion
= dyn_cast<CXXConversionDecl>(Best->Function)) {
@@ -3184,15 +3198,12 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
// user-defined conversion sequence (see 13.3.3 and
// 13.3.3.1).
User.After = Best->FinalConversion;
- return OR_Success;
+ return Result;
}
llvm_unreachable("Not a constructor or conversion function?");
case OR_No_Viable_Function:
return OR_No_Viable_Function;
- case OR_Deleted:
- // No conversion here! We're done.
- return OR_Deleted;
case OR_Ambiguous:
return OR_Ambiguous;
@@ -3329,7 +3340,26 @@ CompareImplicitConversionSequences(Sema &S,
// Two implicit conversion sequences of the same form are
// indistinguishable conversion sequences unless one of the
// following rules apply: (C++ 13.3.3.2p3):
+
+ // List-initialization sequence L1 is a better conversion sequence than
+ // list-initialization sequence L2 if:
+ // - L1 converts to std::initializer_list<X> for some X and L2 does not, or,
+ // if not that,
+ // - L1 converts to type "array of N1 T", L2 converts to type "array of N2 T",
+ // and N1 is smaller than N2.,
+ // even if one of the other rules in this paragraph would otherwise apply.
+ if (!ICS1.isBad()) {
+ if (ICS1.isStdInitializerListElement() &&
+ !ICS2.isStdInitializerListElement())
+ return ImplicitConversionSequence::Better;
+ if (!ICS1.isStdInitializerListElement() &&
+ ICS2.isStdInitializerListElement())
+ return ImplicitConversionSequence::Worse;
+ }
+
if (ICS1.isStandard())
+ // Standard conversion sequence S1 is a better conversion sequence than
+ // standard conversion sequence S2 if [...]
Result = CompareStandardConversionSequences(S,
ICS1.Standard, ICS2.Standard);
else if (ICS1.isUserDefined()) {
@@ -3350,19 +3380,6 @@ CompareImplicitConversionSequences(Sema &S,
ICS2.UserDefined.ConversionFunction);
}
- // List-initialization sequence L1 is a better conversion sequence than
- // list-initialization sequence L2 if L1 converts to std::initializer_list<X>
- // for some X and L2 does not.
- if (Result == ImplicitConversionSequence::Indistinguishable &&
- !ICS1.isBad()) {
- if (ICS1.isStdInitializerListElement() &&
- !ICS2.isStdInitializerListElement())
- return ImplicitConversionSequence::Better;
- if (!ICS1.isStdInitializerListElement() &&
- ICS2.isStdInitializerListElement())
- return ImplicitConversionSequence::Worse;
- }
-
return Result;
}
@@ -4034,11 +4051,8 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
= dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
OverloadCandidateSet CandidateSet(DeclLoc, OverloadCandidateSet::CSK_Normal);
- std::pair<CXXRecordDecl::conversion_iterator,
- CXXRecordDecl::conversion_iterator>
- Conversions = T2RecordDecl->getVisibleConversionFunctions();
- for (CXXRecordDecl::conversion_iterator
- I = Conversions.first, E = Conversions.second; I != E; ++I) {
+ const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions();
+ for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
NamedDecl *D = *I;
CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
if (isa<UsingShadowDecl>(D))
@@ -4254,16 +4268,6 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
// -- Otherwise, the reference shall be an lvalue reference to a
// non-volatile const type (i.e., cv1 shall be const), or the reference
// shall be an rvalue reference.
- //
- // We actually handle one oddity of C++ [over.ics.ref] at this
- // point, which is that, due to p2 (which short-circuits reference
- // binding by only attempting a simple conversion for non-direct
- // bindings) and p3's strange wording, we allow a const volatile
- // reference to bind to an rvalue. Hence the check for the presence
- // of "const" rather than checking for "const" being the only
- // qualifier.
- // This is also the point where rvalue references and lvalue inits no longer
- // go together.
if (!isRValRef && (!T1.isConstQualified() || T1.isVolatileQualified()))
return ICS;
@@ -4456,11 +4460,57 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
if (S.RequireCompleteType(From->getLocStart(), ToType, 0))
return Result;
+ // Per DR1467:
+ // If the parameter type is a class X and the initializer list has a single
+ // element of type cv U, where U is X or a class derived from X, the
+ // implicit conversion sequence is the one required to convert the element
+ // to the parameter type.
+ //
+ // Otherwise, if the parameter type is a character array [... ]
+ // and the initializer list has a single element that is an
+ // appropriately-typed string literal (8.5.2 [dcl.init.string]), the
+ // implicit conversion sequence is the identity conversion.
+ if (From->getNumInits() == 1) {
+ if (ToType->isRecordType()) {
+ QualType InitType = From->getInit(0)->getType();
+ if (S.Context.hasSameUnqualifiedType(InitType, ToType) ||
+ S.IsDerivedFrom(InitType, ToType))
+ return TryCopyInitialization(S, From->getInit(0), ToType,
+ SuppressUserConversions,
+ InOverloadResolution,
+ AllowObjCWritebackConversion);
+ }
+ // FIXME: Check the other conditions here: array of character type,
+ // initializer is a string literal.
+ if (ToType->isArrayType()) {
+ InitializedEntity Entity =
+ InitializedEntity::InitializeParameter(S.Context, ToType,
+ /*Consumed=*/false);
+ if (S.CanPerformCopyInitialization(Entity, From)) {
+ Result.setStandard();
+ Result.Standard.setAsIdentityConversion();
+ Result.Standard.setFromType(ToType);
+ Result.Standard.setAllToTypes(ToType);
+ return Result;
+ }
+ }
+ }
+
+ // C++14 [over.ics.list]p2: Otherwise, if the parameter type [...] (below).
// C++11 [over.ics.list]p2:
// If the parameter type is std::initializer_list<X> or "array of X" and
// all the elements can be implicitly converted to X, the implicit
// conversion sequence is the worst conversion necessary to convert an
// element of the list to X.
+ //
+ // C++14 [over.ics.list]p3:
+ // Otherwise, if the parameter type is "array of N X", if the initializer
+ // list has exactly N elements or if it has fewer than N elements and X is
+ // default-constructible, and if all the elements of the initializer list
+ // can be implicitly converted to X, the implicit conversion sequence is
+ // the worst conversion necessary to convert an element of the list to X.
+ //
+ // FIXME: We're missing a lot of these checks.
bool toStdInitializerList = false;
QualType X;
if (ToType->isArrayType())
@@ -4499,6 +4549,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
return Result;
}
+ // C++14 [over.ics.list]p4:
// C++11 [over.ics.list]p3:
// Otherwise, if the parameter is a non-aggregate class X and overload
// resolution chooses a single best constructor [...] the implicit
@@ -4514,6 +4565,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
/*AllowObjCConversionOnExplicit=*/false);
}
+ // C++14 [over.ics.list]p5:
// C++11 [over.ics.list]p4:
// Otherwise, if the parameter has an aggregate type which can be
// initialized from the initializer list [...] the implicit conversion
@@ -4540,6 +4592,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
return Result;
}
+ // C++14 [over.ics.list]p6:
// C++11 [over.ics.list]p5:
// Otherwise, if the parameter is a reference, see 13.3.3.1.4.
if (ToType->isReferenceType()) {
@@ -4608,14 +4661,15 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
return Result;
}
+ // C++14 [over.ics.list]p7:
// C++11 [over.ics.list]p6:
// Otherwise, if the parameter type is not a class:
if (!ToType->isRecordType()) {
- // - if the initializer list has one element, the implicit conversion
- // sequence is the one required to convert the element to the
- // parameter type.
+ // - if the initializer list has one element that is not itself an
+ // initializer list, the implicit conversion sequence is the one
+ // required to convert the element to the parameter type.
unsigned NumInits = From->getNumInits();
- if (NumInits == 1)
+ if (NumInits == 1 && !isa<InitListExpr>(From->getInit(0)))
Result = TryCopyInitialization(S, From->getInit(0), ToType,
SuppressUserConversions,
InOverloadResolution,
@@ -4631,6 +4685,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
return Result;
}
+ // C++14 [over.ics.list]p8:
// C++11 [over.ics.list]p7:
// In all cases other than those enumerated above, no conversion is possible
return Result;
@@ -5347,21 +5402,18 @@ ExprResult Sema::PerformContextualImplicitConversion(
UnresolvedSet<4>
ViableConversions; // These are *potentially* viable in C++1y.
UnresolvedSet<4> ExplicitConversions;
- std::pair<CXXRecordDecl::conversion_iterator,
- CXXRecordDecl::conversion_iterator> Conversions =
+ const auto &Conversions =
cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
bool HadMultipleCandidates =
- (std::distance(Conversions.first, Conversions.second) > 1);
+ (std::distance(Conversions.begin(), Conversions.end()) > 1);
// To check that there is only one target type, in C++1y:
QualType ToType;
bool HasUniqueTargetType = true;
// Collect explicit or viable (potentially in C++1y) conversions.
- for (CXXRecordDecl::conversion_iterator I = Conversions.first,
- E = Conversions.second;
- I != E; ++I) {
+ for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
NamedDecl *D = (*I)->getUnderlyingDecl();
CXXConversionDecl *Conversion;
FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
@@ -5554,7 +5606,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
// is irrelevant.
AddMethodCandidate(Method, FoundDecl, Method->getParent(),
QualType(), Expr::Classification::makeSimpleLValue(),
- Args, CandidateSet, SuppressUserConversions);
+ Args, CandidateSet, SuppressUserConversions,
+ PartialOverloading);
return;
}
// We treat a constructor like a non-member function, since its object
@@ -5615,7 +5668,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
// (C++ 13.3.2p2): A candidate function having fewer than m
// parameters is viable only if it has an ellipsis in its parameter
// list (8.3.5).
- if ((Args.size() + (PartialOverloading && Args.size())) > NumParams &&
+ if (TooManyArguments(NumParams, Args.size(), PartialOverloading) &&
!Proto->isVariadic()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_too_many_arguments;
@@ -5850,8 +5903,9 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
+ TemplateArgumentListInfo *ExplicitTemplateArgs,
bool SuppressUserConversions,
- TemplateArgumentListInfo *ExplicitTemplateArgs) {
+ bool PartialOverloading) {
for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) {
NamedDecl *D = F.getDecl()->getUnderlyingDecl();
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
@@ -5860,10 +5914,10 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
cast<CXXMethodDecl>(FD)->getParent(),
Args[0]->getType(), Args[0]->Classify(Context),
Args.slice(1), CandidateSet,
- SuppressUserConversions);
+ SuppressUserConversions, PartialOverloading);
else
AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet,
- SuppressUserConversions);
+ SuppressUserConversions, PartialOverloading);
} else {
FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D);
if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
@@ -5873,11 +5927,13 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
ExplicitTemplateArgs,
Args[0]->getType(),
Args[0]->Classify(Context), Args.slice(1),
- CandidateSet, SuppressUserConversions);
+ CandidateSet, SuppressUserConversions,
+ PartialOverloading);
else
AddTemplateOverloadCandidate(FunTmpl, F.getPair(),
ExplicitTemplateArgs, Args,
- CandidateSet, SuppressUserConversions);
+ CandidateSet, SuppressUserConversions,
+ PartialOverloading);
}
}
}
@@ -5925,7 +5981,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
Expr::Classification ObjectClassification,
ArrayRef<Expr *> Args,
OverloadCandidateSet &CandidateSet,
- bool SuppressUserConversions) {
+ bool SuppressUserConversions,
+ bool PartialOverloading) {
const FunctionProtoType *Proto
= dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>());
assert(Proto && "Methods without a prototype cannot be overloaded");
@@ -5958,7 +6015,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
// (C++ 13.3.2p2): A candidate function having fewer than m
// parameters is viable only if it has an ellipsis in its parameter
// list (8.3.5).
- if (Args.size() > NumParams && !Proto->isVariadic()) {
+ if (TooManyArguments(NumParams, Args.size(), PartialOverloading) &&
+ !Proto->isVariadic()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_too_many_arguments;
return;
@@ -5970,7 +6028,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
// parameter list is truncated on the right, so that there are
// exactly m parameters.
unsigned MinRequiredArgs = Method->getMinRequiredArguments();
- if (Args.size() < MinRequiredArgs) {
+ if (Args.size() < MinRequiredArgs && !PartialOverloading) {
// Not enough arguments.
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_too_few_arguments;
@@ -6052,7 +6110,8 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
Expr::Classification ObjectClassification,
ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions) {
+ bool SuppressUserConversions,
+ bool PartialOverloading) {
if (!CandidateSet.isNewCandidate(MethodTmpl))
return;
@@ -6069,7 +6128,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
FunctionDecl *Specialization = nullptr;
if (TemplateDeductionResult Result
= DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs, Args,
- Specialization, Info)) {
+ Specialization, Info, PartialOverloading)) {
OverloadCandidate &Candidate = CandidateSet.addCandidate();
Candidate.FoundDecl = FoundDecl;
Candidate.Function = MethodTmpl->getTemplatedDecl();
@@ -6090,7 +6149,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
"Specialization is not a member function?");
AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl,
ActingContext, ObjectType, ObjectClassification, Args,
- CandidateSet, SuppressUserConversions);
+ CandidateSet, SuppressUserConversions, PartialOverloading);
}
/// \brief Add a C++ function template specialization as a candidate
@@ -6102,7 +6161,8 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
TemplateArgumentListInfo *ExplicitTemplateArgs,
ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions) {
+ bool SuppressUserConversions,
+ bool PartialOverloading) {
if (!CandidateSet.isNewCandidate(FunctionTemplate))
return;
@@ -6119,7 +6179,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
FunctionDecl *Specialization = nullptr;
if (TemplateDeductionResult Result
= DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, Args,
- Specialization, Info)) {
+ Specialization, Info, PartialOverloading)) {
OverloadCandidate &Candidate = CandidateSet.addCandidate();
Candidate.FoundDecl = FoundDecl;
Candidate.Function = FunctionTemplate->getTemplatedDecl();
@@ -6137,7 +6197,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
// deduction as a candidate.
assert(Specialization && "Missing function template specialization?");
AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet,
- SuppressUserConversions);
+ SuppressUserConversions, PartialOverloading);
}
/// Determine whether this is an allowable conversion from the result
@@ -6884,12 +6944,7 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
return;
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
- std::pair<CXXRecordDecl::conversion_iterator,
- CXXRecordDecl::conversion_iterator>
- Conversions = ClassDecl->getVisibleConversionFunctions();
- for (CXXRecordDecl::conversion_iterator
- I = Conversions.first, E = Conversions.second; I != E; ++I) {
- NamedDecl *D = I.getDecl();
+ for (NamedDecl *D : ClassDecl->getVisibleConversionFunctions()) {
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
@@ -6953,13 +7008,7 @@ static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) {
if (!ClassDecl->hasDefinition())
return VRQuals;
- std::pair<CXXRecordDecl::conversion_iterator,
- CXXRecordDecl::conversion_iterator>
- Conversions = ClassDecl->getVisibleConversionFunctions();
-
- for (CXXRecordDecl::conversion_iterator
- I = Conversions.first, E = Conversions.second; I != E; ++I) {
- NamedDecl *D = I.getDecl();
+ for (NamedDecl *D : ClassDecl->getVisibleConversionFunctions()) {
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D)) {
@@ -8078,7 +8127,7 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
bool HasArithmeticOrEnumeralCandidateType = false;
SmallVector<BuiltinCandidateTypeSet, 2> CandidateTypes;
for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
- CandidateTypes.push_back(BuiltinCandidateTypeSet(*this));
+ CandidateTypes.emplace_back(*this);
CandidateTypes[ArgIdx].AddTypesConvertedFrom(Args[ArgIdx]->getType(),
OpLoc,
true,
@@ -8291,7 +8340,7 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
} else
AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*I),
FoundDecl, ExplicitTemplateArgs,
- Args, CandidateSet);
+ Args, CandidateSet, PartialOverloading);
}
}
@@ -9451,10 +9500,7 @@ struct CompareOverloadCandidatesForDisplay {
numLFixes = (numLFixes == 0) ? UINT_MAX : numLFixes;
numRFixes = (numRFixes == 0) ? UINT_MAX : numRFixes;
if (numLFixes != numRFixes) {
- if (numLFixes < numRFixes)
- return true;
- else
- return false;
+ return numLFixes < numRFixes;
}
// If there's any ordering between the defined conversions...
@@ -10363,7 +10409,8 @@ static void AddOverloadedCallCandidate(Sema &S,
assert(!KnownValid && "Explicit template arguments?");
return;
}
- S.AddOverloadCandidate(Func, FoundDecl, Args, CandidateSet, false,
+ S.AddOverloadCandidate(Func, FoundDecl, Args, CandidateSet,
+ /*SuppressUsedConversions=*/false,
PartialOverloading);
return;
}
@@ -10371,7 +10418,9 @@ static void AddOverloadedCallCandidate(Sema &S,
if (FunctionTemplateDecl *FuncTemplate
= dyn_cast<FunctionTemplateDecl>(Callee)) {
S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl,
- ExplicitTemplateArgs, Args, CandidateSet);
+ ExplicitTemplateArgs, Args, CandidateSet,
+ /*SuppressUsedConversions=*/false,
+ PartialOverloading);
return;
}
@@ -10896,7 +10945,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator);
// Add the candidates from the given function set.
- AddFunctionCandidates(Fns, ArgsArray, CandidateSet, false);
+ AddFunctionCandidates(Fns, ArgsArray, CandidateSet);
// Add operator candidates that are member functions.
AddMemberOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet);
@@ -11105,7 +11154,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator);
// Add the candidates from the given function set.
- AddFunctionCandidates(Fns, Args, CandidateSet, false);
+ AddFunctionCandidates(Fns, Args, CandidateSet);
// Add operator candidates that are member functions.
AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet);
@@ -11546,6 +11595,10 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
return MaybeBindToTemporary(call);
}
+ if (isa<CXXPseudoDestructorExpr>(NakedMemExpr))
+ return new (Context)
+ CallExpr(Context, MemExprE, Args, Context.VoidTy, VK_RValue, RParenLoc);
+
UnbridgedCastsSet UnbridgedCasts;
if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts))
return ExprError();
@@ -11805,11 +11858,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
// functions for each conversion function declared in an
// accessible base class provided the function is not hidden
// within T by another intervening declaration.
- std::pair<CXXRecordDecl::conversion_iterator,
- CXXRecordDecl::conversion_iterator> Conversions
- = cast<CXXRecordDecl>(Record->getDecl())->getVisibleConversionFunctions();
- for (CXXRecordDecl::conversion_iterator
- I = Conversions.first, E = Conversions.second; I != E; ++I) {
+ const auto &Conversions =
+ cast<CXXRecordDecl>(Record->getDecl())->getVisibleConversionFunctions();
+ for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
NamedDecl *D = *I;
CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
if (isa<UsingShadowDecl>(D))
@@ -12154,8 +12205,8 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R,
OverloadCandidateSet CandidateSet(UDSuffixLoc,
OverloadCandidateSet::CSK_Normal);
- AddFunctionCandidates(R.asUnresolvedSet(), Args, CandidateSet, true,
- TemplateArgs);
+ AddFunctionCandidates(R.asUnresolvedSet(), Args, CandidateSet, TemplateArgs,
+ /*SuppressUserConversions=*/true);
bool HadMultipleCandidates = (CandidateSet.size() > 1);
@@ -12440,15 +12491,11 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
type = Context.BoundMemberTy;
}
- MemberExpr *ME = MemberExpr::Create(Context, Base,
- MemExpr->isArrow(),
- MemExpr->getQualifierLoc(),
- MemExpr->getTemplateKeywordLoc(),
- Fn,
- Found,
- MemExpr->getMemberNameInfo(),
- TemplateArgs,
- type, valueKind, OK_Ordinary);
+ MemberExpr *ME = MemberExpr::Create(
+ Context, Base, MemExpr->isArrow(), MemExpr->getOperatorLoc(),
+ MemExpr->getQualifierLoc(), MemExpr->getTemplateKeywordLoc(), Fn, Found,
+ MemExpr->getMemberNameInfo(), TemplateArgs, type, valueKind,
+ OK_Ordinary);
ME->setHadMultipleCandidates(true);
MarkMemberReferenced(ME);
return ME;
OpenPOWER on IntegriCloud