forked from OSchip/llvm-project
Preserve access bits through overload resolution much better. Some
general refactoring in operator resolution. llvm-svn: 94498
This commit is contained in:
parent
47751d6c21
commit
4c4c1dfc2b
|
@ -1137,6 +1137,10 @@ public:
|
|||
UnresolvedSetImpl::const_iterator End,
|
||||
const TemplateArgumentListInfo *Args);
|
||||
|
||||
void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
|
||||
Results.append(Begin, End);
|
||||
}
|
||||
|
||||
void addDecl(NamedDecl *Decl) {
|
||||
Results.addDecl(Decl);
|
||||
}
|
||||
|
|
|
@ -224,6 +224,10 @@ public:
|
|||
return Ambiguity;
|
||||
}
|
||||
|
||||
const UnresolvedSetImpl &asUnresolvedSet() const {
|
||||
return Decls;
|
||||
}
|
||||
|
||||
iterator begin() const { return iterator(Decls.begin()); }
|
||||
iterator end() const { return iterator(Decls.end()); }
|
||||
|
||||
|
|
|
@ -950,10 +950,15 @@ public:
|
|||
// Members have to be NamespaceDecl* or TranslationUnitDecl*.
|
||||
// TODO: make this is a typesafe union.
|
||||
typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet;
|
||||
|
||||
typedef llvm::SmallPtrSet<AnyFunctionDecl, 16> FunctionSet;
|
||||
// Members have to be a function or function template.
|
||||
typedef llvm::SmallPtrSet<NamedDecl*, 16> ADLFunctionSet;
|
||||
typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
|
||||
|
||||
void AddOverloadCandidate(NamedDecl *Function,
|
||||
AccessSpecifier Access,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet &CandidateSet);
|
||||
|
||||
void AddOverloadCandidate(FunctionDecl *Function,
|
||||
AccessSpecifier Access,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
|
@ -961,7 +966,7 @@ public:
|
|||
bool SuppressUserConversions = false,
|
||||
bool ForceRValue = false,
|
||||
bool PartialOverloading = false);
|
||||
void AddFunctionCandidates(const FunctionSet &Functions,
|
||||
void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet& CandidateSet,
|
||||
bool SuppressUserConversions = false);
|
||||
|
@ -1029,6 +1034,7 @@ public:
|
|||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet& CandidateSet);
|
||||
void AddArgumentDependentLookupCandidates(DeclarationName Name,
|
||||
bool Operator,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
const TemplateArgumentListInfo *ExplicitTemplateArgs,
|
||||
OverloadCandidateSet& CandidateSet,
|
||||
|
@ -1080,12 +1086,12 @@ public:
|
|||
|
||||
OwningExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
|
||||
unsigned Opc,
|
||||
FunctionSet &Functions,
|
||||
const UnresolvedSetImpl &Fns,
|
||||
ExprArg input);
|
||||
|
||||
OwningExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
|
||||
unsigned Opc,
|
||||
FunctionSet &Functions,
|
||||
const UnresolvedSetImpl &Fns,
|
||||
Expr *LHS, Expr *RHS);
|
||||
|
||||
OwningExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
|
||||
|
@ -1230,11 +1236,11 @@ public:
|
|||
|
||||
void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
|
||||
QualType T1, QualType T2,
|
||||
FunctionSet &Functions);
|
||||
UnresolvedSetImpl &Functions);
|
||||
|
||||
void ArgumentDependentLookup(DeclarationName Name, bool Operator,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
FunctionSet &Functions);
|
||||
ADLFunctionSet &Functions);
|
||||
|
||||
void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
|
||||
VisibleDeclConsumer &Consumer);
|
||||
|
|
|
@ -6337,17 +6337,11 @@ Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
|
|||
// point. We perform both an operator-name lookup from the local
|
||||
// scope and an argument-dependent lookup based on the types of
|
||||
// the arguments.
|
||||
FunctionSet Functions;
|
||||
UnresolvedSet<16> Functions;
|
||||
OverloadedOperatorKind OverOp = BinaryOperator::getOverloadedOperator(Opc);
|
||||
if (OverOp != OO_None) {
|
||||
if (S)
|
||||
LookupOverloadedOperatorName(OverOp, S, lhs->getType(), rhs->getType(),
|
||||
Functions);
|
||||
Expr *Args[2] = { lhs, rhs };
|
||||
DeclarationName OpName
|
||||
= Context.DeclarationNames.getCXXOperatorName(OverOp);
|
||||
ArgumentDependentLookup(OpName, /*Operator*/true, Args, 2, Functions);
|
||||
}
|
||||
if (S && OverOp != OO_None)
|
||||
LookupOverloadedOperatorName(OverOp, S, lhs->getType(), rhs->getType(),
|
||||
Functions);
|
||||
|
||||
// Build the (potentially-overloaded, potentially-dependent)
|
||||
// binary operation.
|
||||
|
@ -6456,16 +6450,11 @@ Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
|
|||
// point. We perform both an operator-name lookup from the local
|
||||
// scope and an argument-dependent lookup based on the types of
|
||||
// the arguments.
|
||||
FunctionSet Functions;
|
||||
UnresolvedSet<16> Functions;
|
||||
OverloadedOperatorKind OverOp = UnaryOperator::getOverloadedOperator(Opc);
|
||||
if (OverOp != OO_None) {
|
||||
if (S)
|
||||
LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
|
||||
Functions);
|
||||
DeclarationName OpName
|
||||
= Context.DeclarationNames.getCXXOperatorName(OverOp);
|
||||
ArgumentDependentLookup(OpName, /*Operator*/true, &Input, 1, Functions);
|
||||
}
|
||||
if (S && OverOp != OO_None)
|
||||
LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
|
||||
Functions);
|
||||
|
||||
return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(input));
|
||||
}
|
||||
|
|
|
@ -1693,7 +1693,7 @@ ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II) {
|
|||
|
||||
void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
|
||||
QualType T1, QualType T2,
|
||||
FunctionSet &Functions) {
|
||||
UnresolvedSetImpl &Functions) {
|
||||
// C++ [over.match.oper]p3:
|
||||
// -- The set of non-member candidates is the result of the
|
||||
// unqualified lookup of operator@ in the context of the
|
||||
|
@ -1719,29 +1719,21 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
|
|||
Op != OpEnd; ++Op) {
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op)) {
|
||||
if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
|
||||
Functions.insert(FD); // FIXME: canonical FD
|
||||
Functions.addDecl(FD, Op.getAccess()); // FIXME: canonical FD
|
||||
} else if (FunctionTemplateDecl *FunTmpl
|
||||
= dyn_cast<FunctionTemplateDecl>(*Op)) {
|
||||
// FIXME: friend operators?
|
||||
// FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
|
||||
// later?
|
||||
if (!FunTmpl->getDeclContext()->isRecord())
|
||||
Functions.insert(FunTmpl);
|
||||
Functions.addDecl(FunTmpl, Op.getAccess());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CollectFunctionDecl(Sema::FunctionSet &Functions,
|
||||
Decl *D) {
|
||||
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
|
||||
Functions.insert(Func);
|
||||
else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
|
||||
Functions.insert(FunTmpl);
|
||||
}
|
||||
|
||||
void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
FunctionSet &Functions) {
|
||||
ADLFunctionSet &Functions) {
|
||||
// Find all of the associated namespaces and classes based on the
|
||||
// arguments we have.
|
||||
AssociatedNamespaceSet AssociatedNamespaces;
|
||||
|
@ -1784,7 +1776,7 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
|
|||
// lookup (11.4).
|
||||
DeclContext::lookup_iterator I, E;
|
||||
for (llvm::tie(I, E) = (*NS)->lookup(Name); I != E; ++I) {
|
||||
Decl *D = *I;
|
||||
NamedDecl *D = *I;
|
||||
// If the only declaration here is an ordinary friend, consider
|
||||
// it only if it was declared in an associated classes.
|
||||
if (D->getIdentifierNamespace() == Decl::IDNS_OrdinaryFriend) {
|
||||
|
@ -1793,10 +1785,16 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
|
|||
continue;
|
||||
}
|
||||
|
||||
// FIXME: using decls? canonical decls?
|
||||
|
||||
FunctionDecl *Fn;
|
||||
if (!Operator || !(Fn = dyn_cast<FunctionDecl>(D)) ||
|
||||
IsAcceptableNonMemberOperatorCandidate(Fn, T1, T2, Context))
|
||||
CollectFunctionDecl(Functions, D);
|
||||
IsAcceptableNonMemberOperatorCandidate(Fn, T1, T2, Context)) {
|
||||
if (isa<FunctionDecl>(D))
|
||||
Functions.insert(D);
|
||||
else if (isa<FunctionTemplateDecl>(D))
|
||||
Functions.insert(D);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2475,17 +2475,15 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
|
|||
|
||||
/// \brief Add all of the function declarations in the given function set to
|
||||
/// the overload canddiate set.
|
||||
void Sema::AddFunctionCandidates(const FunctionSet &Functions,
|
||||
void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet& CandidateSet,
|
||||
bool SuppressUserConversions) {
|
||||
for (FunctionSet::const_iterator F = Functions.begin(),
|
||||
FEnd = Functions.end();
|
||||
F != FEnd; ++F) {
|
||||
for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) {
|
||||
// FIXME: using declarations
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F)) {
|
||||
if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
|
||||
AddMethodCandidate(cast<CXXMethodDecl>(FD), /*FIXME*/ FD->getAccess(),
|
||||
AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getAccess(),
|
||||
cast<CXXMethodDecl>(FD)->getParent(),
|
||||
Args[0]->getType(), Args + 1, NumArgs - 1,
|
||||
CandidateSet, SuppressUserConversions);
|
||||
|
@ -2496,7 +2494,7 @@ void Sema::AddFunctionCandidates(const FunctionSet &Functions,
|
|||
FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*F);
|
||||
if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
|
||||
!cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic())
|
||||
AddMethodTemplateCandidate(FunTmpl, /*FIXME*/ FunTmpl->getAccess(),
|
||||
AddMethodTemplateCandidate(FunTmpl, F.getAccess(),
|
||||
cast<CXXRecordDecl>(FunTmpl->getDeclContext()),
|
||||
/*FIXME: explicit args */ 0,
|
||||
Args[0]->getType(), Args + 1, NumArgs - 1,
|
||||
|
@ -2986,7 +2984,7 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
|
|||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet& CandidateSet,
|
||||
SourceRange OpRange) {
|
||||
FunctionSet Functions;
|
||||
UnresolvedSet<16> Fns;
|
||||
|
||||
QualType T1 = Args[0]->getType();
|
||||
QualType T2;
|
||||
|
@ -2995,9 +2993,10 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
|
|||
|
||||
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
|
||||
if (S)
|
||||
LookupOverloadedOperatorName(Op, S, T1, T2, Functions);
|
||||
ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs, Functions);
|
||||
AddFunctionCandidates(Functions, Args, NumArgs, CandidateSet);
|
||||
LookupOverloadedOperatorName(Op, S, T1, T2, Fns);
|
||||
AddFunctionCandidates(Fns, Args, NumArgs, CandidateSet, false);
|
||||
AddArgumentDependentLookupCandidates(OpName, false, Args, NumArgs, 0,
|
||||
CandidateSet);
|
||||
AddMemberOperatorCandidates(Op, OpLoc, Args, NumArgs, CandidateSet, OpRange);
|
||||
AddBuiltinOperatorCandidates(Op, OpLoc, Args, NumArgs, CandidateSet);
|
||||
}
|
||||
|
@ -4127,31 +4126,19 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
|
|||
/// candidate set (C++ [basic.lookup.argdep]).
|
||||
void
|
||||
Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
|
||||
bool Operator,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
const TemplateArgumentListInfo *ExplicitTemplateArgs,
|
||||
OverloadCandidateSet& CandidateSet,
|
||||
bool PartialOverloading) {
|
||||
FunctionSet Functions;
|
||||
ADLFunctionSet Functions;
|
||||
|
||||
// FIXME: Should we be trafficking in canonical function decls throughout?
|
||||
|
||||
// Record all of the function candidates that we've already
|
||||
// added to the overload set, so that we don't add those same
|
||||
// candidates a second time.
|
||||
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
|
||||
CandEnd = CandidateSet.end();
|
||||
Cand != CandEnd; ++Cand)
|
||||
if (Cand->Function) {
|
||||
Functions.insert(Cand->Function);
|
||||
if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
|
||||
Functions.insert(FunTmpl);
|
||||
}
|
||||
|
||||
// FIXME: Pass in the explicit template arguments?
|
||||
ArgumentDependentLookup(Name, /*Operator*/false, Args, NumArgs, Functions);
|
||||
ArgumentDependentLookup(Name, Operator, Args, NumArgs, Functions);
|
||||
|
||||
// Erase all of the candidates we already knew about.
|
||||
// FIXME: This is suboptimal. Is there a better way?
|
||||
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
|
||||
CandEnd = CandidateSet.end();
|
||||
Cand != CandEnd; ++Cand)
|
||||
|
@ -4163,17 +4150,16 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
|
|||
|
||||
// For each of the ADL candidates we found, add it to the overload
|
||||
// set.
|
||||
for (FunctionSet::iterator Func = Functions.begin(),
|
||||
FuncEnd = Functions.end();
|
||||
Func != FuncEnd; ++Func) {
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func)) {
|
||||
for (ADLFunctionSet::iterator I = Functions.begin(),
|
||||
E = Functions.end(); I != E; ++I) {
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
|
||||
if (ExplicitTemplateArgs)
|
||||
continue;
|
||||
|
||||
AddOverloadCandidate(FD, AS_none, Args, NumArgs, CandidateSet,
|
||||
false, false, PartialOverloading);
|
||||
} else
|
||||
AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func),
|
||||
AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*I),
|
||||
AS_none, ExplicitTemplateArgs,
|
||||
Args, NumArgs, CandidateSet);
|
||||
}
|
||||
|
@ -5242,7 +5228,8 @@ void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
|
|||
PartialOverloading);
|
||||
|
||||
if (ULE->requiresADL())
|
||||
AddArgumentDependentLookupCandidates(ULE->getName(), Args, NumArgs,
|
||||
AddArgumentDependentLookupCandidates(ULE->getName(), /*Operator*/ false,
|
||||
Args, NumArgs,
|
||||
ExplicitTemplateArgs,
|
||||
CandidateSet,
|
||||
PartialOverloading);
|
||||
|
@ -5392,7 +5379,7 @@ Sema::BuildOverloadedCallExpr(Expr *Fn, UnresolvedLookupExpr *ULE,
|
|||
return ExprError();
|
||||
}
|
||||
|
||||
static bool IsOverloaded(const Sema::FunctionSet &Functions) {
|
||||
static bool IsOverloaded(const UnresolvedSetImpl &Functions) {
|
||||
return Functions.size() > 1 ||
|
||||
(Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
|
||||
}
|
||||
|
@ -5413,10 +5400,10 @@ static bool IsOverloaded(const Sema::FunctionSet &Functions) {
|
|||
/// by CreateOverloadedUnaryOp().
|
||||
///
|
||||
/// \param input The input argument.
|
||||
Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
|
||||
unsigned OpcIn,
|
||||
FunctionSet &Functions,
|
||||
ExprArg input) {
|
||||
Sema::OwningExprResult
|
||||
Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
|
||||
const UnresolvedSetImpl &Fns,
|
||||
ExprArg input) {
|
||||
UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
|
||||
Expr *Input = (Expr *)input.get();
|
||||
|
||||
|
@ -5441,11 +5428,8 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
|
|||
UnresolvedLookupExpr *Fn
|
||||
= UnresolvedLookupExpr::Create(Context, /*Dependent*/ true,
|
||||
0, SourceRange(), OpName, OpLoc,
|
||||
/*ADL*/ true, IsOverloaded(Functions));
|
||||
for (FunctionSet::iterator Func = Functions.begin(),
|
||||
FuncEnd = Functions.end();
|
||||
Func != FuncEnd; ++Func)
|
||||
Fn->addDecl(*Func);
|
||||
/*ADL*/ true, IsOverloaded(Fns));
|
||||
Fn->addDecls(Fns.begin(), Fns.end());
|
||||
|
||||
input.release();
|
||||
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
|
||||
|
@ -5458,11 +5442,17 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
|
|||
OverloadCandidateSet CandidateSet;
|
||||
|
||||
// Add the candidates from the given function set.
|
||||
AddFunctionCandidates(Functions, &Args[0], NumArgs, CandidateSet, false);
|
||||
AddFunctionCandidates(Fns, &Args[0], NumArgs, CandidateSet, false);
|
||||
|
||||
// Add operator candidates that are member functions.
|
||||
AddMemberOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet);
|
||||
|
||||
// Add candidates from ADL.
|
||||
AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
|
||||
Args, 1,
|
||||
/*ExplicitTemplateArgs*/ 0,
|
||||
CandidateSet);
|
||||
|
||||
// Add builtin operator candidates.
|
||||
AddBuiltinOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet);
|
||||
|
||||
|
@ -5575,7 +5565,7 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
|
|||
Sema::OwningExprResult
|
||||
Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
|
||||
unsigned OpcIn,
|
||||
FunctionSet &Functions,
|
||||
const UnresolvedSetImpl &Fns,
|
||||
Expr *LHS, Expr *RHS) {
|
||||
Expr *Args[2] = { LHS, RHS };
|
||||
LHS=RHS=0; //Please use only Args instead of LHS/RHS couple
|
||||
|
@ -5587,7 +5577,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
|
|||
// If either side is type-dependent, create an appropriate dependent
|
||||
// expression.
|
||||
if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
|
||||
if (Functions.empty()) {
|
||||
if (Fns.empty()) {
|
||||
// If there are no functions to store, just build a dependent
|
||||
// BinaryOperator or CompoundAssignment.
|
||||
if (Opc <= BinaryOperator::Assign || Opc > BinaryOperator::OrAssign)
|
||||
|
@ -5601,16 +5591,13 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
|
|||
OpLoc));
|
||||
}
|
||||
|
||||
// FIXME: save results of ADL from here?
|
||||
UnresolvedLookupExpr *Fn
|
||||
= UnresolvedLookupExpr::Create(Context, /*Dependent*/ true,
|
||||
0, SourceRange(), OpName, OpLoc,
|
||||
/* ADL */ true, IsOverloaded(Functions));
|
||||
|
||||
for (FunctionSet::iterator Func = Functions.begin(),
|
||||
FuncEnd = Functions.end();
|
||||
Func != FuncEnd; ++Func)
|
||||
Fn->addDecl(*Func);
|
||||
/*ADL*/ true, IsOverloaded(Fns));
|
||||
|
||||
Fn->addDecls(Fns.begin(), Fns.end());
|
||||
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
|
||||
Args, 2,
|
||||
Context.DependentTy,
|
||||
|
@ -5635,11 +5622,17 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
|
|||
OverloadCandidateSet CandidateSet;
|
||||
|
||||
// Add the candidates from the given function set.
|
||||
AddFunctionCandidates(Functions, Args, 2, CandidateSet, false);
|
||||
AddFunctionCandidates(Fns, Args, 2, CandidateSet, false);
|
||||
|
||||
// Add operator candidates that are member functions.
|
||||
AddMemberOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet);
|
||||
|
||||
// Add candidates from ADL.
|
||||
AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
|
||||
Args, 2,
|
||||
/*ExplicitTemplateArgs*/ 0,
|
||||
CandidateSet);
|
||||
|
||||
// Add builtin operator candidates.
|
||||
AddBuiltinOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet);
|
||||
|
||||
|
|
|
@ -5644,28 +5644,21 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
|
|||
|
||||
// Compute the transformed set of functions (and function templates) to be
|
||||
// used during overload resolution.
|
||||
Sema::FunctionSet Functions;
|
||||
UnresolvedSet<16> Functions;
|
||||
|
||||
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
|
||||
assert(ULE->requiresADL());
|
||||
|
||||
// FIXME: Do we have to check
|
||||
// IsAcceptableNonMemberOperatorCandidate for each of these?
|
||||
for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
|
||||
E = ULE->decls_end(); I != E; ++I)
|
||||
Functions.insert(AnyFunctionDecl::getFromNamedDecl(*I));
|
||||
Functions.append(ULE->decls_begin(), ULE->decls_end());
|
||||
} else {
|
||||
Functions.insert(AnyFunctionDecl::getFromNamedDecl(
|
||||
cast<DeclRefExpr>(CalleeExpr)->getDecl()));
|
||||
Functions.addDecl(cast<DeclRefExpr>(CalleeExpr)->getDecl());
|
||||
}
|
||||
|
||||
// Add any functions found via argument-dependent lookup.
|
||||
Expr *Args[2] = { FirstExpr, SecondExpr };
|
||||
unsigned NumArgs = 1 + (SecondExpr != 0);
|
||||
DeclarationName OpName
|
||||
= SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
|
||||
SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
|
||||
Functions);
|
||||
|
||||
// Create the overloaded operator invocation for unary operators.
|
||||
if (NumArgs == 1 || isPostIncDec) {
|
||||
|
|
Loading…
Reference in New Issue