diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 762 |
1 files changed, 428 insertions, 334 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 52be0598fbc0..f632a4d3bd1a 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1,9 +1,8 @@ //===--- SemaOverload.cpp - C++ Overloading -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -1057,6 +1056,7 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, // third bullet. If the type of the friend is dependent, skip this lookup // until instantiation. if (New->getFriendObjectKind() && New->getQualifier() && + !New->getDescribedFunctionTemplate() && !New->getDependentSpecializationInfo() && !New->getType()->isDependentType()) { LookupResult TemplateSpecResult(LookupResult::Temporary, Old); @@ -1172,16 +1172,14 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, // function yet (because we haven't yet resolved whether this is a static // or non-static member function). Add it now, on the assumption that this // is a redeclaration of OldMethod. - // FIXME: OpenCL: Need to consider address spaces - unsigned OldQuals = OldMethod->getTypeQualifiers().getCVRUQualifiers(); - unsigned NewQuals = NewMethod->getTypeQualifiers().getCVRUQualifiers(); + auto OldQuals = OldMethod->getMethodQualifiers(); + auto NewQuals = NewMethod->getMethodQualifiers(); if (!getLangOpts().CPlusPlus14 && NewMethod->isConstexpr() && !isa<CXXConstructorDecl>(NewMethod)) - NewQuals |= Qualifiers::Const; - + NewQuals.addConst(); // We do not allow overloading based off of '__restrict'. - OldQuals &= ~Qualifiers::Restrict; - NewQuals &= ~Qualifiers::Restrict; + OldQuals.removeRestrict(); + NewQuals.removeRestrict(); if (OldQuals != NewQuals) return true; } @@ -1232,24 +1230,6 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, return false; } -/// Checks availability of the function depending on the current -/// function context. Inside an unavailable function, unavailability is ignored. -/// -/// \returns true if \arg FD is unavailable and current context is inside -/// an available function, false otherwise. -bool Sema::isFunctionConsideredUnavailable(FunctionDecl *FD) { - if (!FD->isUnavailable()) - return false; - - // Walk up the context of the caller. - Decl *C = cast<Decl>(CurContext); - do { - if (C->isUnavailable()) - return false; - } while ((C = cast_or_null<Decl>(C->getDeclContext()))); - return true; -} - /// Tries a user-defined conversion from From to ToType. /// /// Produces an implicit conversion sequence for when a standard conversion @@ -1871,6 +1851,10 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, (From->EvaluateKnownConstInt(S.getASTContext()) == 0)) { SCS.Second = ICK_Zero_Queue_Conversion; FromType = ToType; + } else if (ToType->isSamplerT() && + From->isIntegerConstantExpr(S.getASTContext())) { + SCS.Second = ICK_Compatible_Conversion; + FromType = ToType; } else { // No second conversion required. SCS.Second = ICK_Identity; @@ -1970,7 +1954,7 @@ IsTransparentUnionStandardConversion(Sema &S, Expr* From, // It's compatible if the expression matches any of the fields. for (const auto *it : UD->fields()) { if (IsStandardConversion(S, From, it->getType(), InOverloadResolution, SCS, - CStyle, /*ObjCWritebackConversion=*/false)) { + CStyle, /*AllowObjCWritebackConversion=*/false)) { ToType = it->getType(); return true; } @@ -2547,7 +2531,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, // function types are obviously different. if (FromFunctionType->getNumParams() != ToFunctionType->getNumParams() || FromFunctionType->isVariadic() != ToFunctionType->isVariadic() || - FromFunctionType->getTypeQuals() != ToFunctionType->getTypeQuals()) + FromFunctionType->getMethodQuals() != ToFunctionType->getMethodQuals()) return false; bool HasObjCConversion = false; @@ -2854,9 +2838,9 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, return; } - if (FromFunction->getTypeQuals() != ToFunction->getTypeQuals()) { - PDiag << ft_qualifer_mismatch << ToFunction->getTypeQuals() - << FromFunction->getTypeQuals(); + if (FromFunction->getMethodQuals() != ToFunction->getMethodQuals()) { + PDiag << ft_qualifer_mismatch << ToFunction->getMethodQuals() + << FromFunction->getMethodQuals(); return; } @@ -3262,10 +3246,13 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType, if (Info.ConstructorTmpl) S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, From, - CandidateSet, SuppressUserConversions); + CandidateSet, SuppressUserConversions, + /*PartialOverloading*/ false, + AllowExplicit); else S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, From, - CandidateSet, SuppressUserConversions); + CandidateSet, SuppressUserConversions, + /*PartialOverloading*/ false, AllowExplicit); } } @@ -3392,13 +3379,15 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, S.AddTemplateOverloadCandidate( Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs), - CandidateSet, SuppressUserConversions); + CandidateSet, SuppressUserConversions, + /*PartialOverloading*/ false, AllowExplicit); else // Allow one user-defined conversion when user specifies a // From->ToType conversion via an static cast (c-style, etc). S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, llvm::makeArrayRef(Args, NumArgs), - CandidateSet, SuppressUserConversions); + CandidateSet, SuppressUserConversions, + /*PartialOverloading*/ false, AllowExplicit); } } } @@ -3430,14 +3419,13 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, if (AllowExplicit || !Conv->isExplicit()) { if (ConvTemplate) - S.AddTemplateConversionCandidate(ConvTemplate, FoundDecl, - ActingContext, From, ToType, - CandidateSet, - AllowObjCConversionOnExplicit); + S.AddTemplateConversionCandidate( + ConvTemplate, FoundDecl, ActingContext, From, ToType, + CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit); else - S.AddConversionCandidate(Conv, FoundDecl, ActingContext, - From, ToType, CandidateSet, - AllowObjCConversionOnExplicit); + S.AddConversionCandidate( + Conv, FoundDecl, ActingContext, From, ToType, CandidateSet, + AllowObjCConversionOnExplicit, AllowExplicit); } } } @@ -3525,18 +3513,25 @@ Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) { OverloadingResult OvResult = IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined, CandidateSet, false, false); + + if (!(OvResult == OR_Ambiguous || + (OvResult == OR_No_Viable_Function && !CandidateSet.empty()))) + return false; + + auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, From); if (OvResult == OR_Ambiguous) Diag(From->getBeginLoc(), diag::err_typecheck_ambiguous_condition) << From->getType() << ToType << From->getSourceRange(); - else if (OvResult == OR_No_Viable_Function && !CandidateSet.empty()) { + else { // OR_No_Viable_Function && !CandidateSet.empty() if (!RequireCompleteType(From->getBeginLoc(), ToType, diag::err_typecheck_nonviable_condition_incomplete, From->getType(), From->getSourceRange())) Diag(From->getBeginLoc(), diag::err_typecheck_nonviable_condition) << false << From->getType() << From->getSourceRange() << ToType; - } else - return false; - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, From); + } + + CandidateSet.NoteCandidates( + *this, From, Cands); return true; } @@ -4019,9 +4014,12 @@ CompareQualificationConversions(Sema &S, // to unwrap. This essentially mimics what // IsQualificationConversion does, but here we're checking for a // strict subset of qualifiers. - if (T1.getCVRQualifiers() == T2.getCVRQualifiers()) + if (T1.getQualifiers().withoutObjCLifetime() == + T2.getQualifiers().withoutObjCLifetime()) // The qualifiers are the same, so this doesn't tell us anything // about how the sequences rank. + // ObjC ownership quals are omitted above as they interfere with + // the ARC overload rule. ; else if (T2.isMoreQualifiedThan(T1)) { // T1 has fewer qualifiers, so it could be the better sequence. @@ -4455,13 +4453,13 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, } if (ConvTemplate) - S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC, - Init, DeclType, CandidateSet, - /*AllowObjCConversionOnExplicit=*/false); + S.AddTemplateConversionCandidate( + ConvTemplate, I.getPair(), ActingDC, Init, DeclType, CandidateSet, + /*AllowObjCConversionOnExplicit=*/false, AllowExplicit); else - S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init, - DeclType, CandidateSet, - /*AllowObjCConversionOnExplicit=*/false); + S.AddConversionCandidate( + Conv, I.getPair(), ActingDC, Init, DeclType, CandidateSet, + /*AllowObjCConversionOnExplicit=*/false, AllowExplicit); } bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -5095,12 +5093,10 @@ TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType, QualType ClassType = S.Context.getTypeDeclType(ActingContext); // [class.dtor]p2: A destructor can be invoked for a const, volatile or // const volatile object. - Qualifiers Quals; + Qualifiers Quals = Method->getMethodQualifiers(); if (isa<CXXDestructorDecl>(Method)) { Quals.addConst(); Quals.addVolatile(); - } else { - Quals = Method->getTypeQualifiers(); } QualType ImplicitParamType = S.Context.getQualifiedType(ClassType, Quals); @@ -5148,6 +5144,16 @@ TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType, return ICS; } + if (FromTypeCanon.getQualifiers().hasAddressSpace()) { + Qualifiers QualsImplicitParamType = ImplicitParamType.getQualifiers(); + Qualifiers QualsFromType = FromTypeCanon.getQualifiers(); + if (!QualsImplicitParamType.isAddressSpaceSupersetOf(QualsFromType)) { + ICS.setBad(BadConversionSequence::bad_qualifiers, + FromType, ImplicitParamType); + return ICS; + } + } + // Check that we have either the same type or a derived type. It // affects the conversion rank. QualType ClassTypeCanon = S.Context.getCanonicalType(ClassType); @@ -5286,12 +5292,12 @@ Sema::PerformObjectArgumentInitialization(Expr *From, } if (!Context.hasSameType(From->getType(), DestType)) { - if (From->getType().getAddressSpace() != DestType.getAddressSpace()) - From = ImpCastExprToType(From, DestType, CK_AddressSpaceConversion, - From->getValueKind()).get(); + CastKind CK; + if (FromRecordType.getAddressSpace() != DestType.getAddressSpace()) + CK = CK_AddressSpaceConversion; else - From = ImpCastExprToType(From, DestType, CK_NoOp, - From->getValueKind()).get(); + CK = CK_NoOp; + From = ImpCastExprToType(From, DestType, CK, From->getValueKind()).get(); } return From; } @@ -5414,12 +5420,12 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, // condition shall be a contextually converted constant expression of type // bool. ImplicitConversionSequence ICS = - CCE == Sema::CCEK_ConstexprIf + CCE == Sema::CCEK_ConstexprIf || CCE == Sema::CCEK_ExplicitBool ? TryContextuallyConvertToBool(S, From) : TryCopyInitialization(S, From, T, /*SuppressUserConversions=*/false, /*InOverloadResolution=*/false, - /*AllowObjcWritebackConversion=*/false, + /*AllowObjCWritebackConversion=*/false, /*AllowExplicit=*/false); StandardConversionSequence *SCS = nullptr; switch (ICS.getKind()) { @@ -5510,7 +5516,7 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, if (Notes.empty()) { // It's a constant expression. - return ConstantExpr::Create(S.Context, Result.get()); + return ConstantExpr::Create(S.Context, Result.get(), Value); } } @@ -5730,12 +5736,13 @@ collectViableConversionCandidates(Sema &SemaRef, Expr *From, QualType ToType, if (ConvTemplate) SemaRef.AddTemplateConversionCandidate( - ConvTemplate, FoundDecl, ActingContext, From, ToType, CandidateSet, - /*AllowObjCConversionOnExplicit=*/false); + ConvTemplate, FoundDecl, ActingContext, From, ToType, CandidateSet, + /*AllowObjCConversionOnExplicit=*/false, /*AllowExplicit*/ true); else SemaRef.AddConversionCandidate(Conv, FoundDecl, ActingContext, From, ToType, CandidateSet, - /*AllowObjCConversionOnExplicit=*/false); + /*AllowObjCConversionOnExplicit=*/false, + /*AllowExplicit*/ true); } } @@ -5987,13 +5994,11 @@ static bool IsAcceptableNonMemberOperatorCandidate(ASTContext &Context, /// \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, - bool PartialOverloading, bool AllowExplicit, - ADLCallKind IsADLCandidate, - ConversionSequenceList EarlyConversions) { +void Sema::AddOverloadCandidate( + FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef<Expr *> Args, + OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, + bool PartialOverloading, bool AllowExplicit, bool AllowExplicitConversions, + ADLCallKind IsADLCandidate, ConversionSequenceList EarlyConversions) { const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>()); assert(Proto && "Functions without a prototype cannot be overloaded"); @@ -6098,6 +6103,15 @@ void Sema::AddOverloadCandidate(FunctionDecl *Function, return; } } + + // Check that the constructor is capable of constructing an object in the + // destination address space. + if (!Qualifiers::isAddressSpaceSupersetOf( + Constructor->getMethodQualifiers().getAddressSpace(), + CandidateSet.getDestAS())) { + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_object_addrspace_mismatch; + } } unsigned NumParams = Proto->getNumParams(); @@ -6150,13 +6164,11 @@ void Sema::AddOverloadCandidate(FunctionDecl *Function, // (13.3.3.1) that converts that argument to the corresponding // parameter of F. QualType ParamType = Proto->getParamType(ArgIdx); - Candidate.Conversions[ArgIdx] - = TryCopyInitialization(*this, Args[ArgIdx], ParamType, - SuppressUserConversions, - /*InOverloadResolution=*/true, - /*AllowObjCWritebackConversion=*/ - getLangOpts().ObjCAutoRefCount, - AllowExplicit); + Candidate.Conversions[ArgIdx] = TryCopyInitialization( + *this, Args[ArgIdx], ParamType, SuppressUserConversions, + /*InOverloadResolution=*/true, + /*AllowObjCWritebackConversion=*/ + getLangOpts().ObjCAutoRefCount, AllowExplicitConversions); if (Candidate.Conversions[ArgIdx].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; @@ -6170,6 +6182,15 @@ void Sema::AddOverloadCandidate(FunctionDecl *Function, } } + if (!AllowExplicit) { + ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(Function); + if (ES.getKind() != ExplicitSpecKind::ResolvedFalse) { + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_explicit_resolved; + return; + } + } + if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; @@ -6366,7 +6387,8 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, APValue Result; // FIXME: This doesn't consider value-dependent cases, because doing so is // very difficult. Ideally, we should handle them more gracefully. - if (!EIA->getCond()->EvaluateWithSubstitution( + if (EIA->getCond()->isValueDependent() || + !EIA->getCond()->EvaluateWithSubstitution( Result, Context, Function, llvm::makeArrayRef(ConvertedArgs))) return EIA; @@ -6759,7 +6781,7 @@ void Sema::AddTemplateOverloadCandidate( FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, - bool PartialOverloading, ADLCallKind IsADLCandidate) { + bool PartialOverloading, bool AllowExplicit, ADLCallKind IsADLCandidate) { if (!CandidateSet.isNewCandidate(FunctionTemplate)) return; @@ -6808,9 +6830,10 @@ void Sema::AddTemplateOverloadCandidate( // Add the function template specialization produced by template argument // deduction as a candidate. assert(Specialization && "Missing function template specialization?"); - AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet, - SuppressUserConversions, PartialOverloading, - /*AllowExplicit*/ false, IsADLCandidate, Conversions); + AddOverloadCandidate( + Specialization, FoundDecl, Args, CandidateSet, SuppressUserConversions, + PartialOverloading, AllowExplicit, + /*AllowExplicitConversions*/ false, IsADLCandidate, Conversions); } /// Check that implicit conversion sequences can be formed for each argument @@ -6915,14 +6938,11 @@ static bool isAllowableExplicitConversion(Sema &S, /// and ToType is the type that we're eventually trying to convert to /// (which may or may not be the same type as the type that the /// conversion function produces). -void -Sema::AddConversionCandidate(CXXConversionDecl *Conversion, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, - Expr *From, QualType ToType, - OverloadCandidateSet& CandidateSet, - bool AllowObjCConversionOnExplicit, - bool AllowResultConversion) { +void Sema::AddConversionCandidate( + CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, + CXXRecordDecl *ActingContext, Expr *From, QualType ToType, + OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, + bool AllowExplicit, bool AllowResultConversion) { assert(!Conversion->getDescribedFunctionTemplate() && "Conversion function templates use AddTemplateConversionCandidate"); QualType ConvType = Conversion->getConversionType().getNonReferenceType(); @@ -7081,6 +7101,13 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, "Can only end up with a standard conversion sequence or failure"); } + if (!AllowExplicit && Conversion->getExplicitSpecifier().getKind() != + ExplicitSpecKind::ResolvedFalse) { + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_explicit_resolved; + return; + } + if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, None)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; @@ -7100,14 +7127,11 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, /// to deduce the template arguments of the conversion function /// template from the type that we are converting to (C++ /// [temp.deduct.conv]). -void -Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingDC, - Expr *From, QualType ToType, - OverloadCandidateSet &CandidateSet, - bool AllowObjCConversionOnExplicit, - bool AllowResultConversion) { +void Sema::AddTemplateConversionCandidate( + FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, + CXXRecordDecl *ActingDC, Expr *From, QualType ToType, + OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, + bool AllowExplicit, bool AllowResultConversion) { assert(isa<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl()) && "Only conversion function templates permitted here"); @@ -7137,7 +7161,7 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, assert(Specialization && "Missing function template specialization?"); AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType, CandidateSet, AllowObjCConversionOnExplicit, - AllowResultConversion); + AllowExplicit, AllowResultConversion); } /// AddSurrogateCandidate - Adds a "surrogate" candidate function that @@ -7297,7 +7321,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, ++Oper) AddMethodCandidate(Oper.getPair(), Args[0]->getType(), Args[0]->Classify(Context), Args.slice(1), - CandidateSet, /*SuppressUserConversions=*/false); + CandidateSet, /*SuppressUserConversion=*/false); } } @@ -7649,6 +7673,12 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty, } } } +/// Helper function for adjusting address spaces for the pointer or reference +/// operands of builtin operators depending on the argument. +static QualType AdjustAddressSpaceForBuiltinOperandType(Sema &S, QualType T, + Expr *Arg) { + return S.Context.getAddrSpaceQualType(T, Arg->getType().getAddressSpace()); +} /// Helper function for AddBuiltinOperatorCandidates() that adds /// the volatile- and non-volatile-qualified assignment operators for the @@ -7660,15 +7690,17 @@ static void AddBuiltinAssignmentOperatorCandidates(Sema &S, QualType ParamTypes[2]; // T& operator=(T&, T) - ParamTypes[0] = S.Context.getLValueReferenceType(T); + ParamTypes[0] = S.Context.getLValueReferenceType( + AdjustAddressSpaceForBuiltinOperandType(S, T, Args[0])); ParamTypes[1] = T; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); if (!S.Context.getCanonicalType(T).isVolatileQualified()) { // volatile T& operator=(volatile T&, T) - ParamTypes[0] - = S.Context.getLValueReferenceType(S.Context.getVolatileType(T)); + ParamTypes[0] = S.Context.getLValueReferenceType( + AdjustAddressSpaceForBuiltinOperandType(S, S.Context.getVolatileType(T), + Args[0])); ParamTypes[1] = T; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); @@ -7947,7 +7979,7 @@ public: continue; if (const FunctionProtoType *Proto =PointeeTy->getAs<FunctionProtoType>()) - if (Proto->getTypeQuals() || Proto->getRefQualifier()) + if (Proto->getMethodQuals() || Proto->getRefQualifier()) continue; S.AddBuiltinCandidate(&ParamTy, Args, CandidateSet); @@ -8390,7 +8422,7 @@ public: isEqualOp ? *Ptr : S.Context.getPointerDiffType(), }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/ isEqualOp); + /*IsAssignmentOperator=*/ isEqualOp); bool NeedVolatile = !(*Ptr).isVolatileQualified() && VisibleTypeConversionsQuals.hasVolatile(); @@ -8399,7 +8431,7 @@ public: ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/isEqualOp); + /*IsAssignmentOperator=*/isEqualOp); } if (!(*Ptr).isRestrictQualified() && @@ -8408,7 +8440,7 @@ public: ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/isEqualOp); + /*IsAssignmentOperator=*/isEqualOp); if (NeedVolatile) { // volatile restrict version @@ -8418,7 +8450,7 @@ public: (Qualifiers::Volatile | Qualifiers::Restrict))); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/isEqualOp); + /*IsAssignmentOperator=*/isEqualOp); } } } @@ -8439,7 +8471,7 @@ public: // non-volatile version S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/true); + /*IsAssignmentOperator=*/true); bool NeedVolatile = !(*Ptr).isVolatileQualified() && VisibleTypeConversionsQuals.hasVolatile(); @@ -8448,7 +8480,7 @@ public: ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/true); + /*IsAssignmentOperator=*/true); } if (!(*Ptr).isRestrictQualified() && @@ -8457,7 +8489,7 @@ public: ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/true); + /*IsAssignmentOperator=*/true); if (NeedVolatile) { // volatile restrict version @@ -8467,7 +8499,7 @@ public: (Qualifiers::Volatile | Qualifiers::Restrict))); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/true); + /*IsAssignmentOperator=*/true); } } } @@ -8495,20 +8527,19 @@ public: Right < LastPromotedArithmeticType; ++Right) { QualType ParamTypes[2]; ParamTypes[1] = ArithmeticTypes[Right]; - + auto LeftBaseTy = AdjustAddressSpaceForBuiltinOperandType( + S, ArithmeticTypes[Left], Args[0]); // Add this built-in operator as a candidate (VQ is empty). - ParamTypes[0] = - S.Context.getLValueReferenceType(ArithmeticTypes[Left]); + ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/isEqualOp); + /*IsAssignmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { - ParamTypes[0] = - S.Context.getVolatileType(ArithmeticTypes[Left]); + ParamTypes[0] = S.Context.getVolatileType(LeftBaseTy); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/isEqualOp); + /*IsAssignmentOperator=*/isEqualOp); } } } @@ -8527,14 +8558,14 @@ public: // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(*Vec1); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/isEqualOp); + /*IsAssignmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = S.Context.getVolatileType(*Vec1); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, - /*IsAssigmentOperator=*/isEqualOp); + /*IsAssignmentOperator=*/isEqualOp); } } } @@ -8561,14 +8592,14 @@ public: Right < LastPromotedIntegralType; ++Right) { QualType ParamTypes[2]; ParamTypes[1] = ArithmeticTypes[Right]; - + auto LeftBaseTy = AdjustAddressSpaceForBuiltinOperandType( + S, ArithmeticTypes[Left], Args[0]); // Add this built-in operator as a candidate (VQ is empty). - ParamTypes[0] = - S.Context.getLValueReferenceType(ArithmeticTypes[Left]); + ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); if (VisibleTypeConversionsQuals.hasVolatile()) { // Add this built-in operator as a candidate (VQ is 'volatile'). - ParamTypes[0] = ArithmeticTypes[Left]; + ParamTypes[0] = LeftBaseTy; ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); @@ -8983,13 +9014,16 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, continue; AddOverloadCandidate(FD, FoundDecl, Args, CandidateSet, - /*SupressUserConversions=*/false, PartialOverloading, - /*AllowExplicit=*/false, ADLCallKind::UsesADL); + /*SuppressUserConversions=*/false, PartialOverloading, + /*AllowExplicit*/ true, + /*AllowExplicitConversions*/ false, + ADLCallKind::UsesADL); } else { - AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*I), FoundDecl, - ExplicitTemplateArgs, Args, CandidateSet, - /*SupressUserConversions=*/false, - PartialOverloading, ADLCallKind::UsesADL); + AddTemplateOverloadCandidate( + cast<FunctionTemplateDecl>(*I), FoundDecl, ExplicitTemplateArgs, Args, + CandidateSet, + /*SuppressUserConversions=*/false, PartialOverloading, + /*AllowExplicit*/true, ADLCallKind::UsesADL); } } } @@ -9436,9 +9470,7 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, } // Best is the best viable function. - if (Best->Function && - (Best->Function->isDeleted() || - S.isFunctionConsideredUnavailable(Best->Function))) + if (Best->Function && Best->Function->isDeleted()) return OR_Deleted; if (!EquivalentCands.empty()) @@ -9542,7 +9574,8 @@ static bool isFunctionAlwaysEnabled(const ASTContext &Ctx, const FunctionDecl *FD) { for (auto *EnableIf : FD->specific_attrs<EnableIfAttr>()) { bool AlwaysTrue; - if (!EnableIf->getCond()->EvaluateAsBooleanCondition(AlwaysTrue, Ctx)) + if (EnableIf->getCond()->isValueDependent() || + !EnableIf->getCond()->EvaluateAsBooleanCondition(AlwaysTrue, Ctx)) return false; if (!AlwaysTrue) return false; @@ -10322,6 +10355,33 @@ static void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) { << Attr->getCond()->getSourceRange() << Attr->getMessage(); } +static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) { + ExplicitSpecifier ES; + const char *DeclName; + switch (Cand->Function->getDeclKind()) { + case Decl::Kind::CXXConstructor: + ES = cast<CXXConstructorDecl>(Cand->Function)->getExplicitSpecifier(); + DeclName = "constructor"; + break; + case Decl::Kind::CXXConversion: + ES = cast<CXXConversionDecl>(Cand->Function)->getExplicitSpecifier(); + DeclName = "conversion operator"; + break; + case Decl::Kind::CXXDeductionGuide: + ES = cast<CXXDeductionGuideDecl>(Cand->Function)->getExplicitSpecifier(); + DeclName = "deductiong guide"; + break; + default: + llvm_unreachable("invalid Decl"); + } + assert(ES.getExpr() && "null expression should be handled before"); + S.Diag(Cand->Function->getLocation(), + diag::note_ovl_candidate_explicit_forbidden) + << DeclName; + S.Diag(ES.getExpr()->getBeginLoc(), + diag::note_explicit_bool_resolved_to_true); +} + static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Callee = Cand->Function; @@ -10343,14 +10403,17 @@ static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) { /// It would be great to be able to express per-candidate problems /// more richly for those diagnostic clients that cared, but we'd /// still have to be just as careful with the default diagnostics. +/// \param CtorDestAS Addr space of object being constructed (for ctor +/// candidates only). static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, - bool TakingCandidateAddress) { + bool TakingCandidateAddress, + LangAS CtorDestAS = LangAS::Default) { FunctionDecl *Fn = Cand->Function; // Note deleted candidates, but only if they're viable. if (Cand->Viable) { - if (Fn->isDeleted() || S.isFunctionConsideredUnavailable(Fn)) { + if (Fn->isDeleted()) { std::string FnDesc; std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); @@ -10383,6 +10446,16 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, return; } + case ovl_fail_object_addrspace_mismatch: { + Qualifiers QualsForPrinting; + QualsForPrinting.setAddressSpace(CtorDestAS); + S.Diag(Fn->getLocation(), + diag::note_ovl_candidate_illegal_constructor_adrspace_mismatch) + << QualsForPrinting; + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); + return; + } + case ovl_fail_trivial_conversion: case ovl_fail_bad_final_conversion: case ovl_fail_final_conversion_not_exact: @@ -10406,6 +10479,9 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, case ovl_fail_enable_if: return DiagnoseFailedEnableIfAttr(S, Cand); + case ovl_fail_explicit_resolved: + return DiagnoseFailedExplicitSpec(S, Cand); + case ovl_fail_ext_disabled: return DiagnoseOpenCLExtensionDisabled(S, Cand); @@ -10747,11 +10823,9 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, } } -/// When overload resolution fails, prints diagnostic messages containing the -/// candidates in the candidate set. -void OverloadCandidateSet::NoteCandidates( +SmallVector<OverloadCandidate *, 32> OverloadCandidateSet::CompleteCandidates( Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef<Expr *> Args, - StringRef Opc, SourceLocation OpLoc, + SourceLocation OpLoc, llvm::function_ref<bool(OverloadCandidate &)> Filter) { // Sort the candidates by viability and position. Sorting directly would // be prohibitive, so we make a set of pointers and sort those. @@ -10771,15 +10845,35 @@ void OverloadCandidateSet::NoteCandidates( } } - std::stable_sort(Cands.begin(), Cands.end(), - CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size(), Kind)); + llvm::stable_sort( + Cands, CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size(), Kind)); + return Cands; +} + +/// When overload resolution fails, prints diagnostic messages containing the +/// candidates in the candidate set. +void OverloadCandidateSet::NoteCandidates(PartialDiagnosticAt PD, + Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef<Expr *> Args, + StringRef Opc, SourceLocation OpLoc, + llvm::function_ref<bool(OverloadCandidate &)> Filter) { + + auto Cands = CompleteCandidates(S, OCD, Args, OpLoc, Filter); + + S.Diag(PD.first, PD.second); + + NoteCandidates(S, Args, Cands, Opc, OpLoc); +} + +void OverloadCandidateSet::NoteCandidates(Sema &S, ArrayRef<Expr *> Args, + ArrayRef<OverloadCandidate *> Cands, + StringRef Opc, SourceLocation OpLoc) { bool ReportedAmbiguousConversions = false; - SmallVectorImpl<OverloadCandidate*>::iterator I, E; const OverloadsShown ShowOverloads = S.Diags.getShowOverloads(); unsigned CandsShown = 0; - for (I = Cands.begin(), E = Cands.end(); I != E; ++I) { + auto I = Cands.begin(), E = Cands.end(); + for (; I != E; ++I) { OverloadCandidate *Cand = *I; // Set an arbitrary limit on the number of candidate functions we'll spam @@ -10792,7 +10886,7 @@ void OverloadCandidateSet::NoteCandidates( if (Cand->Function) NoteFunctionCandidate(S, Cand, Args.size(), - /*TakingCandidateAddress=*/false); + /*TakingCandidateAddress=*/false, DestAS); else if (Cand->IsSurrogate) NoteSurrogateCandidate(S, Cand); else { @@ -11671,7 +11765,7 @@ static void AddOverloadedCallCandidate(Sema &S, return; S.AddOverloadCandidate(Func, FoundDecl, Args, CandidateSet, - /*SuppressUsedConversions=*/false, + /*SuppressUserConversions=*/false, PartialOverloading); return; } @@ -11680,7 +11774,7 @@ static void AddOverloadedCallCandidate(Sema &S, = dyn_cast<FunctionTemplateDecl>(Callee)) { S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl, ExplicitTemplateArgs, Args, CandidateSet, - /*SuppressUsedConversions=*/false, + /*SuppressUserConversions=*/false, PartialOverloading); return; } @@ -11895,15 +11989,6 @@ public: } -static std::unique_ptr<CorrectionCandidateCallback> -MakeValidator(Sema &SemaRef, MemberExpr *ME, size_t NumArgs, - bool HasTemplateArgs, bool AllowTypoCorrection) { - if (!AllowTypoCorrection) - return llvm::make_unique<NoTypoCorrectionCCC>(); - return llvm::make_unique<FunctionCallFilterCCC>(SemaRef, NumArgs, - HasTemplateArgs, ME); -} - /// Attempts to recover from a call where no functions were found. /// /// Returns true if new candidates were found. @@ -11938,16 +12023,22 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(), Sema::LookupOrdinaryName); bool DoDiagnoseEmptyLookup = EmptyLookup; - if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R, - OverloadCandidateSet::CSK_Normal, - ExplicitTemplateArgs, Args, - &DoDiagnoseEmptyLookup) && - (!DoDiagnoseEmptyLookup || SemaRef.DiagnoseEmptyLookup( - S, SS, R, - MakeValidator(SemaRef, dyn_cast<MemberExpr>(Fn), Args.size(), - ExplicitTemplateArgs != nullptr, AllowTypoCorrection), - ExplicitTemplateArgs, Args))) - return ExprError(); + if (!DiagnoseTwoPhaseLookup( + SemaRef, Fn->getExprLoc(), SS, R, OverloadCandidateSet::CSK_Normal, + ExplicitTemplateArgs, Args, &DoDiagnoseEmptyLookup)) { + NoTypoCorrectionCCC NoTypoValidator{}; + FunctionCallFilterCCC FunctionCallValidator(SemaRef, Args.size(), + ExplicitTemplateArgs != nullptr, + dyn_cast<MemberExpr>(Fn)); + CorrectionCandidateCallback &Validator = + AllowTypoCorrection + ? static_cast<CorrectionCandidateCallback &>(FunctionCallValidator) + : static_cast<CorrectionCandidateCallback &>(NoTypoValidator); + if (!DoDiagnoseEmptyLookup || + SemaRef.DiagnoseEmptyLookup(S, SS, R, Validator, ExplicitTemplateArgs, + Args)) + return ExprError(); + } assert(!R.empty() && "lookup results empty despite recovery"); @@ -11975,7 +12066,7 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, // This shouldn't cause an infinite loop because we're giving it // an expression with viable lookup results, which should never // end up here. - return SemaRef.ActOnCallExpr(/*Scope*/ nullptr, NewFn.get(), LParenLoc, + return SemaRef.BuildCallExpr(/*Scope*/ nullptr, NewFn.get(), LParenLoc, MultiExprArg(Args.data(), Args.size()), RParenLoc); } @@ -11997,7 +12088,8 @@ bool Sema::buildOverloadedCallSet(Scope *S, Expr *Fn, // We don't perform ADL for implicit declarations of builtins. // Verify that this was correctly set up. FunctionDecl *F; - if (ULE->decls_begin() + 1 == ULE->decls_end() && + if (ULE->decls_begin() != ULE->decls_end() && + ULE->decls_begin() + 1 == ULE->decls_end() && (F = dyn_cast<FunctionDecl>(*ULE->decls_begin())) && F->getBuiltinID() && F->isImplicit()) llvm_unreachable("performing ADL for builtin"); @@ -12101,24 +12193,29 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, } } - SemaRef.Diag(Fn->getBeginLoc(), diag::err_ovl_no_viable_function_in_call) - << ULE->getName() << Fn->getSourceRange(); - CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates, Args); + CandidateSet->NoteCandidates( + PartialDiagnosticAt( + Fn->getBeginLoc(), + SemaRef.PDiag(diag::err_ovl_no_viable_function_in_call) + << ULE->getName() << Fn->getSourceRange()), + SemaRef, OCD_AllCandidates, Args); break; } case OR_Ambiguous: - SemaRef.Diag(Fn->getBeginLoc(), diag::err_ovl_ambiguous_call) - << ULE->getName() << Fn->getSourceRange(); - CandidateSet->NoteCandidates(SemaRef, OCD_ViableCandidates, Args); + CandidateSet->NoteCandidates( + PartialDiagnosticAt(Fn->getBeginLoc(), + SemaRef.PDiag(diag::err_ovl_ambiguous_call) + << ULE->getName() << Fn->getSourceRange()), + SemaRef, OCD_ViableCandidates, Args); break; case OR_Deleted: { - SemaRef.Diag(Fn->getBeginLoc(), diag::err_ovl_deleted_call) - << (*Best)->Function->isDeleted() << ULE->getName() - << SemaRef.getDeletedOrUnavailableSuffix((*Best)->Function) - << Fn->getSourceRange(); - CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates, Args); + CandidateSet->NoteCandidates( + PartialDiagnosticAt(Fn->getBeginLoc(), + SemaRef.PDiag(diag::err_ovl_deleted_call) + << ULE->getName() << Fn->getSourceRange()), + SemaRef, OCD_AllCandidates, Args); // We emitted an error for the unavailable/deleted function call but keep // the call in the AST. @@ -12176,10 +12273,9 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, OverloadingResult OverloadResult = CandidateSet.BestViableFunction(*this, Fn->getBeginLoc(), Best); - return FinishOverloadedCallExpr(*this, S, Fn, ULE, LParenLoc, Args, - RParenLoc, ExecConfig, &CandidateSet, - &Best, OverloadResult, - AllowTypoCorrection); + return FinishOverloadedCallExpr(*this, S, Fn, ULE, LParenLoc, Args, RParenLoc, + ExecConfig, &CandidateSet, &Best, + OverloadResult, AllowTypoCorrection); } static bool IsOverloaded(const UnresolvedSetImpl &Functions) { @@ -12352,22 +12448,22 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, break; case OR_Ambiguous: - Diag(OpLoc, diag::err_ovl_ambiguous_oper_unary) - << UnaryOperator::getOpcodeStr(Opc) - << Input->getType() - << Input->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, ArgsArray, - UnaryOperator::getOpcodeStr(Opc), OpLoc); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(OpLoc, + PDiag(diag::err_ovl_ambiguous_oper_unary) + << UnaryOperator::getOpcodeStr(Opc) + << Input->getType() << Input->getSourceRange()), + *this, OCD_ViableCandidates, ArgsArray, + UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); case OR_Deleted: - Diag(OpLoc, diag::err_ovl_deleted_oper) - << Best->Function->isDeleted() - << UnaryOperator::getOpcodeStr(Opc) - << getDeletedOrUnavailableSuffix(Best->Function) - << Input->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, ArgsArray, - UnaryOperator::getOpcodeStr(Opc), OpLoc); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper) + << UnaryOperator::getOpcodeStr(Opc) + << Input->getSourceRange()), + *this, OCD_AllCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc), + OpLoc); return ExprError(); } @@ -12601,6 +12697,9 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // operator do not fall through to handling in built-in, but report that // no overloaded assignment operator found ExprResult Result = ExprError(); + StringRef OpcStr = BinaryOperator::getOpcodeStr(Opc); + auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, + Args, OpLoc); if (Args[0]->getType()->isRecordType() && Opc >= BO_Assign && Opc <= BO_OrAssign) { Diag(OpLoc, diag::err_ovl_no_viable_oper) @@ -12625,19 +12724,20 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, } assert(Result.isInvalid() && "C++ binary operator overloading is missing candidates!"); - if (Result.isInvalid()) - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, - BinaryOperator::getOpcodeStr(Opc), OpLoc); + CandidateSet.NoteCandidates(*this, Args, Cands, OpcStr, OpLoc); return Result; } case OR_Ambiguous: - Diag(OpLoc, diag::err_ovl_ambiguous_oper_binary) - << BinaryOperator::getOpcodeStr(Opc) - << Args[0]->getType() << Args[1]->getType() - << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, - BinaryOperator::getOpcodeStr(Opc), OpLoc); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_binary) + << BinaryOperator::getOpcodeStr(Opc) + << Args[0]->getType() + << Args[1]->getType() + << Args[0]->getSourceRange() + << Args[1]->getSourceRange()), + *this, OCD_ViableCandidates, Args, BinaryOperator::getOpcodeStr(Opc), + OpLoc); return ExprError(); case OR_Deleted: @@ -12651,15 +12751,14 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // explain why it's deleted. NoteDeletedFunction(Method); return ExprError(); - } else { - Diag(OpLoc, diag::err_ovl_deleted_oper) - << Best->Function->isDeleted() - << BinaryOperator::getOpcodeStr(Opc) - << getDeletedOrUnavailableSuffix(Best->Function) - << Args[0]->getSourceRange() << Args[1]->getSourceRange(); } - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, - BinaryOperator::getOpcodeStr(Opc), OpLoc); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper) + << BinaryOperator::getOpcodeStr(Opc) + << Args[0]->getSourceRange() + << Args[1]->getSourceRange()), + *this, OCD_AllCandidates, Args, BinaryOperator::getOpcodeStr(Opc), + OpLoc); return ExprError(); } @@ -12801,35 +12900,34 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, } case OR_No_Viable_Function: { - if (CandidateSet.empty()) - Diag(LLoc, diag::err_ovl_no_oper) - << Args[0]->getType() << /*subscript*/ 0 - << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - else - Diag(LLoc, diag::err_ovl_no_viable_subscript) - << Args[0]->getType() - << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, - "[]", LLoc); + PartialDiagnostic PD = CandidateSet.empty() + ? (PDiag(diag::err_ovl_no_oper) + << Args[0]->getType() << /*subscript*/ 0 + << Args[0]->getSourceRange() << Args[1]->getSourceRange()) + : (PDiag(diag::err_ovl_no_viable_subscript) + << Args[0]->getType() << Args[0]->getSourceRange() + << Args[1]->getSourceRange()); + CandidateSet.NoteCandidates(PartialDiagnosticAt(LLoc, PD), *this, + OCD_AllCandidates, Args, "[]", LLoc); return ExprError(); } case OR_Ambiguous: - Diag(LLoc, diag::err_ovl_ambiguous_oper_binary) - << "[]" - << Args[0]->getType() << Args[1]->getType() - << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, - "[]", LLoc); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(LLoc, PDiag(diag::err_ovl_ambiguous_oper_binary) + << "[]" << Args[0]->getType() + << Args[1]->getType() + << Args[0]->getSourceRange() + << Args[1]->getSourceRange()), + *this, OCD_ViableCandidates, Args, "[]", LLoc); return ExprError(); case OR_Deleted: - Diag(LLoc, diag::err_ovl_deleted_oper) - << Best->Function->isDeleted() << "[]" - << getDeletedOrUnavailableSuffix(Best->Function) - << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, - "[]", LLoc); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(LLoc, PDiag(diag::err_ovl_deleted_oper) + << "[]" << Args[0]->getSourceRange() + << Args[1]->getSourceRange()), + *this, OCD_AllCandidates, Args, "[]", LLoc); return ExprError(); } @@ -12870,7 +12968,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, // Check that the object type isn't more qualified than the // member function we're calling. - Qualifiers funcQuals = proto->getTypeQuals(); + Qualifiers funcQuals = proto->getMethodQuals(); QualType objectType = op->getLHS()->getType(); if (op->getOpcode() == BO_PtrMemI) @@ -12954,8 +13052,9 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, // Microsoft supports direct constructor calls. if (getLangOpts().MicrosoftExt && isa<CXXConstructorDecl>(Func)) { - AddOverloadCandidate(cast<CXXConstructorDecl>(Func), I.getPair(), - Args, CandidateSet); + AddOverloadCandidate(cast<CXXConstructorDecl>(Func), I.getPair(), Args, + CandidateSet, + /*SuppressUserConversions*/ false); } else if ((Method = dyn_cast<CXXMethodDecl>(Func))) { // If explicit template arguments were provided, we can't call a // non-template member function. @@ -12969,7 +13068,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, AddMethodTemplateCandidate( cast<FunctionTemplateDecl>(Func), I.getPair(), ActingDC, TemplateArgs, ObjectType, ObjectClassification, Args, CandidateSet, - /*SuppressUsedConversions=*/false); + /*SuppressUserConversions=*/false); } } @@ -12998,27 +13097,30 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, break; case OR_No_Viable_Function: - Diag(UnresExpr->getMemberLoc(), - diag::err_ovl_no_viable_member_function_in_call) - << DeclName << MemExprE->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args); + CandidateSet.NoteCandidates( + PartialDiagnosticAt( + UnresExpr->getMemberLoc(), + PDiag(diag::err_ovl_no_viable_member_function_in_call) + << DeclName << MemExprE->getSourceRange()), + *this, OCD_AllCandidates, Args); // FIXME: Leaking incoming expressions! return ExprError(); case OR_Ambiguous: - Diag(UnresExpr->getMemberLoc(), diag::err_ovl_ambiguous_member_call) - << DeclName << MemExprE->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(UnresExpr->getMemberLoc(), + PDiag(diag::err_ovl_ambiguous_member_call) + << DeclName << MemExprE->getSourceRange()), + *this, OCD_AllCandidates, Args); // FIXME: Leaking incoming expressions! return ExprError(); case OR_Deleted: - Diag(UnresExpr->getMemberLoc(), diag::err_ovl_deleted_member_call) - << Best->Function->isDeleted() - << DeclName - << getDeletedOrUnavailableSuffix(Best->Function) - << MemExprE->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(UnresExpr->getMemberLoc(), + PDiag(diag::err_ovl_deleted_member_call) + << DeclName << MemExprE->getSourceRange()), + *this, OCD_AllCandidates, Args); // FIXME: Leaking incoming expressions! return ExprError(); } @@ -13162,7 +13264,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Object.get()->getType(), Object.get()->Classify(Context), Args, CandidateSet, - /*SuppressUserConversions=*/false); + /*SuppressUserConversion=*/false); } // C++ [over.call.object]p2: @@ -13222,29 +13324,35 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, // below. break; - case OR_No_Viable_Function: - if (CandidateSet.empty()) - Diag(Object.get()->getBeginLoc(), diag::err_ovl_no_oper) - << Object.get()->getType() << /*call*/ 1 - << Object.get()->getSourceRange(); - else - Diag(Object.get()->getBeginLoc(), diag::err_ovl_no_viable_object_call) - << Object.get()->getType() << Object.get()->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args); + case OR_No_Viable_Function: { + PartialDiagnostic PD = + CandidateSet.empty() + ? (PDiag(diag::err_ovl_no_oper) + << Object.get()->getType() << /*call*/ 1 + << Object.get()->getSourceRange()) + : (PDiag(diag::err_ovl_no_viable_object_call) + << Object.get()->getType() << Object.get()->getSourceRange()); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(Object.get()->getBeginLoc(), PD), *this, + OCD_AllCandidates, Args); break; - + } case OR_Ambiguous: - Diag(Object.get()->getBeginLoc(), diag::err_ovl_ambiguous_object_call) - << Object.get()->getType() << Object.get()->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(Object.get()->getBeginLoc(), + PDiag(diag::err_ovl_ambiguous_object_call) + << Object.get()->getType() + << Object.get()->getSourceRange()), + *this, OCD_ViableCandidates, Args); break; case OR_Deleted: - Diag(Object.get()->getBeginLoc(), diag::err_ovl_deleted_object_call) - << Best->Function->isDeleted() << Object.get()->getType() - << getDeletedOrUnavailableSuffix(Best->Function) - << Object.get()->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(Object.get()->getBeginLoc(), + PDiag(diag::err_ovl_deleted_object_call) + << Object.get()->getType() + << Object.get()->getSourceRange()), + *this, OCD_AllCandidates, Args); break; } @@ -13268,7 +13376,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, "Found Decl & conversion-to-functionptr should be same, right?!"); // We selected one of the surrogate functions that converts the // object parameter to a function pointer. Perform the conversion - // on the object argument, then let ActOnCallExpr finish the job. + // on the object argument, then let BuildCallExpr finish the job. // Create an implicit member expr to refer to the conversion operator. // and then call it. @@ -13281,7 +13389,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, CK_UserDefinedConversion, Call.get(), nullptr, VK_RValue); - return ActOnCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc); + return BuildCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc); } CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr, Best->FoundDecl); @@ -13431,7 +13539,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context), - None, CandidateSet, /*SuppressUserConversions=*/false); + None, CandidateSet, /*SuppressUserConversion=*/false); } bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -13443,7 +13551,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, // Overload resolution succeeded; we'll build the call below. break; - case OR_No_Viable_Function: + case OR_No_Viable_Function: { + auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, Base); if (CandidateSet.empty()) { QualType BaseType = Base->getType(); if (NoArrowOperatorFound) { @@ -13461,22 +13570,22 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, } else Diag(OpLoc, diag::err_ovl_no_viable_oper) << "operator->" << Base->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Base); + CandidateSet.NoteCandidates(*this, Base, Cands); return ExprError(); - + } case OR_Ambiguous: - Diag(OpLoc, diag::err_ovl_ambiguous_oper_unary) - << "->" << Base->getType() << Base->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Base); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_unary) + << "->" << Base->getType() + << Base->getSourceRange()), + *this, OCD_ViableCandidates, Base); return ExprError(); case OR_Deleted: - Diag(OpLoc, diag::err_ovl_deleted_oper) - << Best->Function->isDeleted() - << "->" - << getDeletedOrUnavailableSuffix(Best->Function) - << Base->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Base); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper) + << "->" << Base->getSourceRange()), + *this, OCD_AllCandidates, Base); return ExprError(); } @@ -13538,14 +13647,18 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R, break; case OR_No_Viable_Function: - Diag(UDSuffixLoc, diag::err_ovl_no_viable_function_in_call) - << R.getLookupName(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(UDSuffixLoc, + PDiag(diag::err_ovl_no_viable_function_in_call) + << R.getLookupName()), + *this, OCD_AllCandidates, Args); return ExprError(); case OR_Ambiguous: - Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call) << R.getLookupName(); - CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(R.getNameLoc(), PDiag(diag::err_ovl_ambiguous_call) + << R.getLookupName()), + *this, OCD_ViableCandidates, Args); return ExprError(); } @@ -13615,7 +13728,7 @@ Sema::BuildForRangeBeginEndCall(SourceLocation Loc, *CallExpr = ExprError(); return FRS_DiagnosticIssued; } - *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, None, Loc, nullptr); + *CallExpr = BuildCallExpr(S, MemberRef.get(), Loc, None, Loc, nullptr); if (CallExpr->isInvalid()) { *CallExpr = ExprError(); return FRS_DiagnosticIssued; @@ -13701,7 +13814,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, unsigned ResultIdx = GSE->getResultIndex(); AssocExprs[ResultIdx] = SubExpr; - return new (Context) GenericSelectionExpr( + return GenericSelectionExpr::Create( Context, GSE->getGenericLoc(), GSE->getControllingExpr(), GSE->getAssocTypeSourceInfos(), AssocExprs, GSE->getDefaultLoc(), GSE->getRParenLoc(), GSE->containsUnexpandedParameterPack(), @@ -13775,17 +13888,10 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, TemplateArgs = &TemplateArgsBuffer; } - DeclRefExpr *DRE = DeclRefExpr::Create(Context, - ULE->getQualifierLoc(), - ULE->getTemplateKeywordLoc(), - Fn, - /*enclosing*/ false, // FIXME? - ULE->getNameLoc(), - Fn->getType(), - VK_LValue, - Found.getDecl(), - TemplateArgs); - MarkDeclRefReferenced(DRE); + DeclRefExpr *DRE = + BuildDeclRefExpr(Fn, Fn->getType(), VK_LValue, ULE->getNameInfo(), + ULE->getQualifierLoc(), Found.getDecl(), + ULE->getTemplateKeywordLoc(), TemplateArgs); DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1); return DRE; } @@ -13804,27 +13910,18 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, // implicit member access, rewrite to a simple decl ref. if (MemExpr->isImplicitAccess()) { if (cast<CXXMethodDecl>(Fn)->isStatic()) { - DeclRefExpr *DRE = DeclRefExpr::Create(Context, - MemExpr->getQualifierLoc(), - MemExpr->getTemplateKeywordLoc(), - Fn, - /*enclosing*/ false, - MemExpr->getMemberLoc(), - Fn->getType(), - VK_LValue, - Found.getDecl(), - TemplateArgs); - MarkDeclRefReferenced(DRE); + DeclRefExpr *DRE = BuildDeclRefExpr( + Fn, Fn->getType(), VK_LValue, MemExpr->getNameInfo(), + MemExpr->getQualifierLoc(), Found.getDecl(), + MemExpr->getTemplateKeywordLoc(), TemplateArgs); DRE->setHadMultipleCandidates(MemExpr->getNumDecls() > 1); return DRE; } else { SourceLocation Loc = MemExpr->getMemberLoc(); if (MemExpr->getQualifier()) Loc = MemExpr->getQualifierLoc().getBeginLoc(); - CheckCXXThisCapture(Loc); - Base = new (Context) CXXThisExpr(Loc, - MemExpr->getBaseType(), - /*isImplicit=*/true); + Base = + BuildCXXThisExpr(Loc, MemExpr->getBaseType(), /*IsImplicit=*/true); } } else Base = MemExpr->getBase(); @@ -13839,14 +13936,11 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, type = Context.BoundMemberTy; } - MemberExpr *ME = MemberExpr::Create( - Context, Base, MemExpr->isArrow(), MemExpr->getOperatorLoc(), + return BuildMemberExpr( + 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; + /*HadMultipleCandidates=*/true, MemExpr->getMemberNameInfo(), + type, valueKind, OK_Ordinary, TemplateArgs); } llvm_unreachable("Invalid reference to overloaded function"); |