From 5769d6195087229770d7ac90449443e026c47103 Mon Sep 17 00:00:00 2001 From: John McCall Date: Mon, 8 Feb 2010 23:07:23 +0000 Subject: [PATCH] Thread a source location into the template-argument deduction routines. There may be some other places that could take advantage of this new information, but I haven't really looked yet. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95600 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/Sema.h | 20 ++++++-- lib/Sema/SemaCodeComplete.cpp | 11 +++-- lib/Sema/SemaDeclCXX.cpp | 6 +-- lib/Sema/SemaExprCXX.cpp | 4 +- lib/Sema/SemaInit.cpp | 5 +- lib/Sema/SemaLookup.cpp | 2 +- lib/Sema/SemaOverload.cpp | 69 +++++++++++++++++----------- lib/Sema/SemaOverload.h | 7 ++- lib/Sema/SemaTemplate.cpp | 4 +- lib/Sema/SemaTemplateDeduction.cpp | 23 +++++----- lib/Sema/SemaTemplateInstantiate.cpp | 8 ++-- 11 files changed, 99 insertions(+), 60 deletions(-) diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 6a3ed3d0b7..ead808fdeb 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1081,7 +1081,8 @@ public: OverloadCandidateSet& CandidateSet, bool PartialOverloading = false); bool isBetterOverloadCandidate(const OverloadCandidate& Cand1, - const OverloadCandidate& Cand2); + const OverloadCandidate& Cand2, + SourceLocation Loc); OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet, SourceLocation Loc, OverloadCandidateSet::iterator& Best); @@ -2824,17 +2825,28 @@ public: /// TemplateArgumentList *Deduced; + /// \brief The source location at which template argument + /// deduction is occurring. + SourceLocation Loc; + // do not implement these TemplateDeductionInfo(const TemplateDeductionInfo&); TemplateDeductionInfo &operator=(const TemplateDeductionInfo&); public: - TemplateDeductionInfo(ASTContext &Context) : Context(Context), Deduced(0) { } + TemplateDeductionInfo(ASTContext &Context, SourceLocation Loc) + : Context(Context), Deduced(0), Loc(Loc) { } ~TemplateDeductionInfo() { // FIXME: if (Deduced) Deduced->Destroy(Context); } + /// \brief Returns the location at which template argument is + /// occuring. + SourceLocation getLocation() const { + return Loc; + } + /// \brief Take ownership of the deduced template argument list. TemplateArgumentList *take() { TemplateArgumentList *Result = Deduced; @@ -2932,6 +2944,7 @@ public: FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, + SourceLocation Loc, TemplatePartialOrderingContext TPOC); UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, @@ -2944,7 +2957,8 @@ public: ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization( ClassTemplatePartialSpecializationDecl *PS1, - ClassTemplatePartialSpecializationDecl *PS2); + ClassTemplatePartialSpecializationDecl *PS2, + SourceLocation Loc); void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, bool OnlyDeduced, diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 7219e31649..a862949718 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -2196,13 +2196,15 @@ void Sema::CodeCompleteCase(Scope *S) { namespace { struct IsBetterOverloadCandidate { Sema &S; + SourceLocation Loc; public: - explicit IsBetterOverloadCandidate(Sema &S) : S(S) { } + explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc) + : S(S), Loc(Loc) { } bool operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const { - return S.isBetterOverloadCandidate(X, Y); + return S.isBetterOverloadCandidate(X, Y, Loc); } }; } @@ -2228,7 +2230,8 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn, } // Build an overload candidate set based on the functions we find. - OverloadCandidateSet CandidateSet; + SourceLocation Loc = Fn->getExprLoc(); + OverloadCandidateSet CandidateSet(Loc); // FIXME: What if we're calling something that isn't a function declaration? // FIXME: What if we're calling a pseudo-destructor? @@ -2256,7 +2259,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn, if (!CandidateSet.empty()) { // Sort the overload candidate set by placing the best overloads first. std::stable_sort(CandidateSet.begin(), CandidateSet.end(), - IsBetterOverloadCandidate(*this)); + IsBetterOverloadCandidate(*this, Loc)); // Add the remaining viable overload candidates as code-completion reslults. for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index e156b62fdb..67c08225b4 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3854,7 +3854,7 @@ Sema::getAssignOperatorMethod(SourceLocation CurrentLocation, RHSType, CurrentLocation)); Expr *Args[2] = { &*LHS, &*RHS }; - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(CurrentLocation); AddMemberOperatorCandidates(clang::OO_Equal, SourceLocation(), Args, 2, CandidateSet); OverloadCandidateSet::iterator Best; @@ -4186,7 +4186,7 @@ Sema::TryInitializationByConstructor(QualType ClassType, SourceLocation Loc, InitializationKind Kind) { // Build the overload candidate set - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(Loc); AddConstructorInitializationCandidates(*this, ClassType, Args, NumArgs, Kind, CandidateSet); @@ -4443,7 +4443,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, CXXRecordDecl *T2RecordDecl = dyn_cast(T2->getAs()->getDecl()); - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(DeclLoc); const UnresolvedSetImpl *Conversions = T2RecordDecl->getVisibleConversionFunctions(); for (UnresolvedSetImpl::iterator I = Conversions->begin(), diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 2d6bfb433e..e27308a2b4 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -626,7 +626,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, // FIXME: handle ambiguity - OverloadCandidateSet Candidates; + OverloadCandidateSet Candidates(StartLoc); for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end(); Alloc != AllocEnd; ++Alloc) { // Even member operator new/delete are implicitly treated as @@ -1586,7 +1586,7 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS, SourceLocation Loc) { Expr *Args[2] = { LHS, RHS }; - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(Loc); Self.AddBuiltinOperatorCandidates(OO_Conditional, Loc, Args, 2, CandidateSet); OverloadCandidateSet::iterator Best; diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 1cdfde3488..f536701ec2 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2829,7 +2829,8 @@ InitializationSequence::InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, Expr **Args, - unsigned NumArgs) { + unsigned NumArgs) + : FailedCandidateSet(Kind.getLocation()) { ASTContext &Context = S.Context; // C++0x [dcl.init]p16: @@ -3084,7 +3085,7 @@ static Sema::OwningExprResult CopyIfRequiredForEntity(Sema &S, = S.Context.DeclarationNames.getCXXConstructorName( S.Context.getCanonicalType(S.Context.getTypeDeclType(Class))); DeclContext::lookup_iterator Con, ConEnd; - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(Loc); for (llvm::tie(Con, ConEnd) = Class->lookup(ConstructorName); Con != ConEnd; ++Con) { // Find the constructor (which may be a template). diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 3c8ab435a8..8cbcf127a4 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -493,7 +493,7 @@ static bool LookupDirect(LookupResult &R, const DeclContext *DC) { // result), perform template argument deduction and place the // specialization into the result set. We do this to avoid forcing all // callers to perform special deduction for conversion functions. - Sema::TemplateDeductionInfo Info(R.getSema().Context); + Sema::TemplateDeductionInfo Info(R.getSema().Context, R.getNameLoc()); FunctionDecl *Specialization = 0; const FunctionProtoType *ConvProto diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 3af914475c..452901cf22 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -447,16 +447,24 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType, bool InOverloadResolution, bool UserCast) { ImplicitConversionSequence ICS; - OverloadCandidateSet Conversions; - OverloadingResult UserDefResult = OR_Success; - if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard)) + if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard)) { ICS.setStandard(); - else if (getLangOptions().CPlusPlus && - (UserDefResult = IsUserDefinedConversion(From, ToType, - ICS.UserDefined, - Conversions, - !SuppressUserConversions, AllowExplicit, - ForceRValue, UserCast)) == OR_Success) { + return ICS; + } + + if (!getLangOptions().CPlusPlus) { + ICS.setBad(); + ICS.Bad.init(BadConversionSequence::no_conversion, From, ToType); + return ICS; + } + + OverloadCandidateSet Conversions(From->getExprLoc()); + OverloadingResult UserDefResult + = IsUserDefinedConversion(From, ToType, ICS.UserDefined, Conversions, + !SuppressUserConversions, AllowExplicit, + ForceRValue, UserCast); + + if (UserDefResult == OR_Success) { ICS.setUserDefined(); // C++ [over.ics.user]p4: // A conversion of an expression of class type to the same class @@ -1654,7 +1662,7 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType, bool Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) { ImplicitConversionSequence ICS; - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(From->getExprLoc()); OverloadingResult OvResult = IsUserDefinedConversion(From, ToType, ICS.UserDefined, CandidateSet, true, false, false); @@ -2694,7 +2702,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, // functions. In such a case, the candidate functions generated from each // function template are combined with the set of non-template candidate // functions. - TemplateDeductionInfo Info(Context); + TemplateDeductionInfo Info(Context, CandidateSet.getLocation()); FunctionDecl *Specialization = 0; if (TemplateDeductionResult Result = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs, @@ -2738,7 +2746,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, // functions. In such a case, the candidate functions generated from each // function template are combined with the set of non-template candidate // functions. - TemplateDeductionInfo Info(Context); + TemplateDeductionInfo Info(Context, CandidateSet.getLocation()); FunctionDecl *Specialization = 0; if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, @@ -2887,7 +2895,7 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, if (!CandidateSet.isNewCandidate(FunctionTemplate)) return; - TemplateDeductionInfo Info(Context); + TemplateDeductionInfo Info(Context, CandidateSet.getLocation()); CXXConversionDecl *Specialization = 0; if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, ToType, @@ -4204,7 +4212,8 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, /// candidate is a better candidate than the second (C++ 13.3.3p1). bool Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1, - const OverloadCandidate& Cand2) { + const OverloadCandidate& Cand2, + SourceLocation Loc) { // Define viable functions to be better candidates than non-viable // functions. if (!Cand2.Viable) @@ -4267,6 +4276,7 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1, if (FunctionTemplateDecl *BetterTemplate = getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(), Cand2.Function->getPrimaryTemplate(), + Loc, isa(Cand1.Function)? TPOC_Conversion : TPOC_Call)) return BetterTemplate == Cand1.Function->getPrimaryTemplate(); @@ -4319,7 +4329,8 @@ OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet, for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(); Cand != CandidateSet.end(); ++Cand) { if (Cand->Viable) { - if (Best == CandidateSet.end() || isBetterOverloadCandidate(*Cand, *Best)) + if (Best == CandidateSet.end() || + isBetterOverloadCandidate(*Cand, *Best, Loc)) Best = Cand; } } @@ -4334,7 +4345,7 @@ OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet, Cand != CandidateSet.end(); ++Cand) { if (Cand->Viable && Cand != Best && - !isBetterOverloadCandidate(*Best, *Cand)) { + !isBetterOverloadCandidate(*Best, *Cand, Loc)) { Best = CandidateSet.end(); return OR_Ambiguous; } @@ -4759,8 +4770,8 @@ struct CompareOverloadCandidatesForDisplay { // TODO: introduce a tri-valued comparison for overload // candidates. Would be more worthwhile if we had a sort // that could exploit it. - if (S.isBetterOverloadCandidate(*L, *R)) return true; - if (S.isBetterOverloadCandidate(*R, *L)) return false; + if (S.isBetterOverloadCandidate(*L, *R, SourceLocation())) return true; + if (S.isBetterOverloadCandidate(*R, *L, SourceLocation())) return false; } else if (R->Viable) return false; @@ -5045,7 +5056,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, // overloaded functions considered. // FIXME: We don't really want to build the specialization here, do we? FunctionDecl *Specialization = 0; - TemplateDeductionInfo Info(Context); + TemplateDeductionInfo Info(Context, OvlExpr->getNameLoc()); if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, FunctionType, Specialization, Info)) { @@ -5205,7 +5216,7 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From) { // function template specialization, which is added to the set of // overloaded functions considered. FunctionDecl *Specialization = 0; - TemplateDeductionInfo Info(Context); + TemplateDeductionInfo Info(Context, OvlExpr->getNameLoc()); if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs, Specialization, Info)) { @@ -5405,7 +5416,7 @@ Sema::BuildOverloadedCallExpr(Expr *Fn, UnresolvedLookupExpr *ULE, } #endif - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(Fn->getExprLoc()); // Add the functions denoted by the callee to the set of candidate // functions, including those from argument-dependent lookup. @@ -5518,7 +5529,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, } // Build an empty overload set. - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(OpLoc); // Add the candidates from the given function set. AddFunctionCandidates(Fns, &Args[0], NumArgs, CandidateSet, false); @@ -5701,7 +5712,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); // Build an empty overload set. - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(OpLoc); // Add the candidates from the given function set. AddFunctionCandidates(Fns, Args, 2, CandidateSet, false); @@ -5884,7 +5895,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, } // Build an empty overload set. - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(LLoc); // Subscript can only be overloaded as a member function. @@ -6023,7 +6034,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, QualType ObjectType = UnresExpr->getBaseType(); // Add overload candidates - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(UnresExpr->getMemberLoc()); // FIXME: avoid copy. TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = 0; @@ -6154,7 +6165,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, // operators of T. The function call operators of T are obtained by // ordinary lookup of the name operator() in the context of // (E).operator(). - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(LParenLoc); DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call); if (RequireCompleteType(LParenLoc, Object->getType(), @@ -6397,6 +6408,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) { Expr *Base = static_cast(BaseIn.get()); assert(Base->getType()->isRecordType() && "left-hand side must have class type"); + SourceLocation Loc = Base->getExprLoc(); + // C++ [over.ref]p1: // // [...] An expression x->m is interpreted as (x.operator->())->m @@ -6404,10 +6417,10 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) { // the operator is selected as the best match function by the // overload resolution mechanism (13.3). DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Arrow); - OverloadCandidateSet CandidateSet; + OverloadCandidateSet CandidateSet(Loc); const RecordType *BaseRecord = Base->getType()->getAs(); - if (RequireCompleteType(Base->getLocStart(), Base->getType(), + if (RequireCompleteType(Loc, Base->getType(), PDiag(diag::err_typecheck_incomplete_tag) << Base->getSourceRange())) return ExprError(); diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h index cc26277825..e6dfa74235 100644 --- a/lib/Sema/SemaOverload.h +++ b/lib/Sema/SemaOverload.h @@ -501,8 +501,13 @@ namespace clang { class OverloadCandidateSet : public llvm::SmallVector { typedef llvm::SmallVector inherited; llvm::SmallPtrSet Functions; - + + SourceLocation Loc; public: + OverloadCandidateSet(SourceLocation Loc) : Loc(Loc) {} + + SourceLocation getLocation() const { return Loc; } + /// \brief Determine when this overload candidate will be new to the /// overload set. bool isNewCandidate(Decl *F) { diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 6a094e48e8..b77702ba3f 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3861,7 +3861,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, // Perform template argument deduction to determine whether we may be // specializing this template. // FIXME: It is somewhat wasteful to build - TemplateDeductionInfo Info(Context); + TemplateDeductionInfo Info(Context, FD->getLocation()); FunctionDecl *Specialization = 0; if (TemplateDeductionResult TDK = DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs, @@ -4614,7 +4614,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S, if (!FunTmpl) continue; - TemplateDeductionInfo Info(Context); + TemplateDeductionInfo Info(Context, D.getIdentifierLoc()); FunctionDecl *Specialization = 0; if (TemplateDeductionResult TDK = DeduceTemplateArguments(FunTmpl, diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 3edc7ff228..df4d4a828d 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -653,9 +653,7 @@ DeduceTemplateArguments(Sema &S, // We cannot inspect base classes as part of deduction when the type // is incomplete, so either instantiate any templates necessary to // complete the type, or skip over it if it cannot be completed. - // FIXME: The location given becomes the PoI, so we should thread - // a better location through the TemplateDeductionInfo. - if (S.RequireCompleteType(RecordT->getDecl()->getLocStart(), Arg, 0)) + if (S.RequireCompleteType(Info.getLocation(), Arg, 0)) return Result; // Use data recursion to crawl through the list of base classes. @@ -1384,7 +1382,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, // the deduced template argument values are then combined. // So we do not reject deductions which were made elsewhere. llvm::SmallVector Deduced(TemplateParams->size()); - Sema::TemplateDeductionInfo Info(S.Context); + Sema::TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc()); unsigned TDF = 0; Sema::TemplateDeductionResult Result @@ -1858,6 +1856,7 @@ MarkUsedTemplateParameters(Sema &SemaRef, QualType T, /// \brief Determine whether the function template \p FT1 is at least as /// specialized as \p FT2. static bool isAtLeastAsSpecializedAs(Sema &S, + SourceLocation Loc, FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, TemplatePartialOrderingContext TPOC, @@ -1875,7 +1874,7 @@ static bool isAtLeastAsSpecializedAs(Sema &S, // C++0x [temp.deduct.partial]p3: // The types used to determine the ordering depend on the context in which // the partial ordering is done: - Sema::TemplateDeductionInfo Info(S.Context); + Sema::TemplateDeductionInfo Info(S.Context, Loc); switch (TPOC) { case TPOC_Call: { // - In the context of a function call, the function parameter types are @@ -1989,10 +1988,11 @@ static bool isAtLeastAsSpecializedAs(Sema &S, FunctionTemplateDecl * Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, + SourceLocation Loc, TemplatePartialOrderingContext TPOC) { llvm::SmallVector QualifierComparisons; - bool Better1 = isAtLeastAsSpecializedAs(*this, FT1, FT2, TPOC, 0); - bool Better2 = isAtLeastAsSpecializedAs(*this, FT2, FT1, TPOC, + bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC, 0); + bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC, &QualifierComparisons); if (Better1 != Better2) // We have a clear winner @@ -2119,7 +2119,7 @@ Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin, = cast(*I)->getPrimaryTemplate(); assert(Challenger && "Not a function template specialization?"); if (isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger, - TPOC), + Loc, TPOC), Challenger)) { Best = I; BestTemplate = Challenger; @@ -2134,7 +2134,7 @@ Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin, = cast(*I)->getPrimaryTemplate(); if (I != Best && !isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger, - TPOC), + Loc, TPOC), BestTemplate)) { Ambiguous = true; break; @@ -2172,7 +2172,8 @@ Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin, ClassTemplatePartialSpecializationDecl * Sema::getMoreSpecializedPartialSpecialization( ClassTemplatePartialSpecializationDecl *PS1, - ClassTemplatePartialSpecializationDecl *PS2) { + ClassTemplatePartialSpecializationDecl *PS2, + SourceLocation Loc) { // C++ [temp.class.order]p1: // For two class template partial specializations, the first is at least as // specialized as the second if, given the following rewrite to two @@ -2195,7 +2196,7 @@ Sema::getMoreSpecializedPartialSpecialization( // template partial ordering, because class template partial specializations // are more constrained. We know that every template parameter is deduc llvm::SmallVector Deduced; - Sema::TemplateDeductionInfo Info(Context); + Sema::TemplateDeductionInfo Info(Context, Loc); // Determine whether PS1 is at least as specialized as PS2 Deduced.resize(PS2->getTemplateParameters()->size()); diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 25610e4454..c8cc9dc98f 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1186,7 +1186,7 @@ Sema::InstantiateClassTemplateSpecialization( PartialEnd = Template->getPartialSpecializations().end(); Partial != PartialEnd; ++Partial) { - TemplateDeductionInfo Info(Context); + TemplateDeductionInfo Info(Context, PointOfInstantiation); if (TemplateDeductionResult Result = DeduceTemplateArguments(&*Partial, ClassTemplateSpec->getTemplateArgs(), @@ -1216,7 +1216,8 @@ Sema::InstantiateClassTemplateSpecialization( for (llvm::SmallVector::iterator P = Best + 1, PEnd = Matched.end(); P != PEnd; ++P) { - if (getMoreSpecializedPartialSpecialization(P->first, Best->first) + if (getMoreSpecializedPartialSpecialization(P->first, Best->first, + PointOfInstantiation) == P->first) Best = P; } @@ -1228,7 +1229,8 @@ Sema::InstantiateClassTemplateSpecialization( PEnd = Matched.end(); P != PEnd; ++P) { if (P != Best && - getMoreSpecializedPartialSpecialization(P->first, Best->first) + getMoreSpecializedPartialSpecialization(P->first, Best->first, + PointOfInstantiation) != Best->first) { Ambiguous = true; break; -- 2.40.0