Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet);
void AddArgumentDependentLookupCandidates(DeclarationName Name,
- bool Operator,
+ bool Operator, SourceLocation Loc,
Expr **Args, unsigned NumArgs,
TemplateArgumentListInfo *ExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet,
CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
void ArgumentDependentLookup(DeclarationName Name, bool Operator,
+ SourceLocation Loc,
Expr **Args, unsigned NumArgs,
ADLResult &Functions,
bool StdNamespaceIsAssociated = false);
}
void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
+ SourceLocation Loc,
Expr **Args, unsigned NumArgs,
ADLResult &Result,
bool StdNamespaceIsAssociated) {
T2 = Args[1]->getType();
}
+ // Try to complete all associated classes, in case they contain a
+ // declaration of a friend function.
+ for (AssociatedClassSet::iterator C = AssociatedClasses.begin(),
+ CEnd = AssociatedClasses.end();
+ C != CEnd; ++C)
+ RequireCompleteType(Loc, Context.getRecordType(*C), 0);
+
// C++ [basic.lookup.argdep]p3:
// Let X be the lookup set produced by unqualified lookup (3.4.1)
// and let Y be the lookup set produced by argument dependent
/// Return true on unrecoverable error.
static bool checkPlaceholderForOverload(Sema &S, Expr *&E,
UnbridgedCastsSet *unbridgedCasts = 0) {
- S.RequireCompleteType(E->getExprLoc(), E->getType(), 0);
-
if (const BuiltinType *placeholder = E->getType()->getAsPlaceholderType()) {
// We can't handle overloaded expressions here because overload
// resolution might reasonably tweak them.
/// candidate set (C++ [basic.lookup.argdep]).
void
Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
- bool Operator,
+ bool Operator, SourceLocation Loc,
Expr **Args, unsigned NumArgs,
TemplateArgumentListInfo *ExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet,
// we supposed to consider on ADL candidates, anyway?
// FIXME: Pass in the explicit template arguments?
- ArgumentDependentLookup(Name, Operator, Args, NumArgs, Fns,
+ ArgumentDependentLookup(Name, Operator, Loc, Args, NumArgs, Fns,
StdNamespaceIsAssociated);
// Erase all of the candidates we already knew about.
if (ULE->requiresADL())
AddArgumentDependentLookupCandidates(ULE->getName(), /*Operator*/ false,
+ ULE->getExprLoc(),
Args, NumArgs,
ExplicitTemplateArgs,
CandidateSet,
// Add candidates from ADL.
AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
- Args, NumArgs,
+ OpLoc, Args, NumArgs,
/*ExplicitTemplateArgs*/ 0,
CandidateSet);
// Add candidates from ADL.
AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
- Args, 2,
+ OpLoc, Args, 2,
/*ExplicitTemplateArgs*/ 0,
CandidateSet);
}
namespace IncompleteArg {
- // Ensure that overload resolution attempts to complete argument types.
+ // Ensure that overload resolution attempts to complete argument types when
+ // performing ADL.
template<typename T> struct S {
friend int f(const S&);
};
extern S<int> s;
int k = f(s);
+
+ template<typename T> struct Op {
+ friend bool operator==(const Op &, const Op &);
+ };
+ extern Op<char> op;
+ bool b = op == op;
+
+ // ... and not in other cases! Nothing here requires U<int()> to be complete.
+ // (Note that instantiating U<int()> will fail.)
+ template<typename T> struct U {
+ T t;
+ };
+ struct Consumer {
+ template<typename T>
+ int operator()(const U<T> &);
+ };
+ template<typename T> U<T> &make();
+ Consumer c;
+ int n = sizeof(c(make<int()>()));
}