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);
///
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;
FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
FunctionTemplateDecl *FT2,
+ SourceLocation Loc,
TemplatePartialOrderingContext TPOC);
UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin,
UnresolvedSetIterator SEnd,
ClassTemplatePartialSpecializationDecl *
getMoreSpecializedPartialSpecialization(
ClassTemplatePartialSpecializationDecl *PS1,
- ClassTemplatePartialSpecializationDecl *PS2);
+ ClassTemplatePartialSpecializationDecl *PS2,
+ SourceLocation Loc);
void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
bool OnlyDeduced,
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);
}
};
}
}
// 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?
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(),
RHSType,
CurrentLocation));
Expr *Args[2] = { &*LHS, &*RHS };
- OverloadCandidateSet CandidateSet;
+ OverloadCandidateSet CandidateSet(CurrentLocation);
AddMemberOperatorCandidates(clang::OO_Equal, SourceLocation(), Args, 2,
CandidateSet);
OverloadCandidateSet::iterator Best;
SourceLocation Loc,
InitializationKind Kind) {
// Build the overload candidate set
- OverloadCandidateSet CandidateSet;
+ OverloadCandidateSet CandidateSet(Loc);
AddConstructorInitializationCandidates(*this, ClassType, Args, NumArgs, Kind,
CandidateSet);
CXXRecordDecl *T2RecordDecl
= dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
- OverloadCandidateSet CandidateSet;
+ OverloadCandidateSet CandidateSet(DeclLoc);
const UnresolvedSetImpl *Conversions
= T2RecordDecl->getVisibleConversionFunctions();
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
// 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
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;
const InitializedEntity &Entity,
const InitializationKind &Kind,
Expr **Args,
- unsigned NumArgs) {
+ unsigned NumArgs)
+ : FailedCandidateSet(Kind.getLocation()) {
ASTContext &Context = S.Context;
// C++0x [dcl.init]p16:
= 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).
// 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
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
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);
// 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,
// 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,
if (!CandidateSet.isNewCandidate(FunctionTemplate))
return;
- TemplateDeductionInfo Info(Context);
+ TemplateDeductionInfo Info(Context, CandidateSet.getLocation());
CXXConversionDecl *Specialization = 0;
if (TemplateDeductionResult Result
= DeduceTemplateArguments(FunctionTemplate, ToType,
/// 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)
if (FunctionTemplateDecl *BetterTemplate
= getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
Cand2.Function->getPrimaryTemplate(),
+ Loc,
isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
: TPOC_Call))
return BetterTemplate == Cand1.Function->getPrimaryTemplate();
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;
}
}
Cand != CandidateSet.end(); ++Cand) {
if (Cand->Viable &&
Cand != Best &&
- !isBetterOverloadCandidate(*Best, *Cand)) {
+ !isBetterOverloadCandidate(*Best, *Cand, Loc)) {
Best = CandidateSet.end();
return OR_Ambiguous;
}
// 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;
// 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)) {
// 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)) {
}
#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.
}
// 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);
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);
}
// Build an empty overload set.
- OverloadCandidateSet CandidateSet;
+ OverloadCandidateSet CandidateSet(LLoc);
// Subscript can only be overloaded as a member function.
QualType ObjectType = UnresExpr->getBaseType();
// Add overload candidates
- OverloadCandidateSet CandidateSet;
+ OverloadCandidateSet CandidateSet(UnresExpr->getMemberLoc());
// FIXME: avoid copy.
TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = 0;
// 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(),
Expr *Base = static_cast<Expr *>(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
// 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<RecordType>();
- if (RequireCompleteType(Base->getLocStart(), Base->getType(),
+ if (RequireCompleteType(Loc, Base->getType(),
PDiag(diag::err_typecheck_incomplete_tag)
<< Base->getSourceRange()))
return ExprError();
class OverloadCandidateSet : public llvm::SmallVector<OverloadCandidate, 16> {
typedef llvm::SmallVector<OverloadCandidate, 16> inherited;
llvm::SmallPtrSet<Decl *, 16> 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) {
// 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,
if (!FunTmpl)
continue;
- TemplateDeductionInfo Info(Context);
+ TemplateDeductionInfo Info(Context, D.getIdentifierLoc());
FunctionDecl *Specialization = 0;
if (TemplateDeductionResult TDK
= DeduceTemplateArguments(FunTmpl,
// 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.
// the deduced template argument values are then combined.
// So we do not reject deductions which were made elsewhere.
llvm::SmallVector<TemplateArgument, 8> Deduced(TemplateParams->size());
- Sema::TemplateDeductionInfo Info(S.Context);
+ Sema::TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
unsigned TDF = 0;
Sema::TemplateDeductionResult Result
/// \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,
// 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
FunctionTemplateDecl *
Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
FunctionTemplateDecl *FT2,
+ SourceLocation Loc,
TemplatePartialOrderingContext TPOC) {
llvm::SmallVector<DeductionQualifierComparison, 4> 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
= cast<FunctionDecl>(*I)->getPrimaryTemplate();
assert(Challenger && "Not a function template specialization?");
if (isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger,
- TPOC),
+ Loc, TPOC),
Challenger)) {
Best = I;
BestTemplate = Challenger;
= cast<FunctionDecl>(*I)->getPrimaryTemplate();
if (I != Best &&
!isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger,
- TPOC),
+ Loc, TPOC),
BestTemplate)) {
Ambiguous = true;
break;
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
// template partial ordering, because class template partial specializations
// are more constrained. We know that every template parameter is deduc
llvm::SmallVector<TemplateArgument, 4> 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());
PartialEnd = Template->getPartialSpecializations().end();
Partial != PartialEnd;
++Partial) {
- TemplateDeductionInfo Info(Context);
+ TemplateDeductionInfo Info(Context, PointOfInstantiation);
if (TemplateDeductionResult Result
= DeduceTemplateArguments(&*Partial,
ClassTemplateSpec->getTemplateArgs(),
for (llvm::SmallVector<MatchResult, 4>::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;
}
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;