ZeroArgCallReturnTy = QualType();
OverloadSet.clear();
+ const OverloadExpr *Overloads = NULL;
if (E.getType() == Context.OverloadTy) {
OverloadExpr::FindResult FR = OverloadExpr::find(const_cast<Expr*>(&E));
- const OverloadExpr *Overloads = FR.Expression;
+ // Ignore overloads that are pointer-to-member constants.
+ if (FR.HasFormOfMemberPointer)
+ return false;
+
+ Overloads = FR.Expression;
+ } else if (E.getType() == Context.BoundMemberTy) {
+ Overloads = dyn_cast<UnresolvedMemberExpr>(E.IgnoreParens());
+ }
+ if (Overloads) {
+ bool Ambiguous = false;
for (OverloadExpr::decls_iterator it = Overloads->decls_begin(),
DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) {
OverloadSet.addDecl(*it);
// arguments.
if (const FunctionDecl *OverloadDecl
= dyn_cast<FunctionDecl>((*it)->getUnderlyingDecl())) {
- if (OverloadDecl->getMinRequiredArguments() == 0)
- ZeroArgCallReturnTy = OverloadDecl->getResultType();
+ if (OverloadDecl->getMinRequiredArguments() == 0) {
+ if (!ZeroArgCallReturnTy.isNull() && !Ambiguous) {
+ ZeroArgCallReturnTy = QualType();
+ Ambiguous = true;
+ } else
+ ZeroArgCallReturnTy = OverloadDecl->getResultType();
+ }
}
}
- // Ignore overloads that are pointer-to-member constants.
- if (FR.HasFormOfMemberPointer)
- return false;
-
- return true;
+ return !Ambiguous;
}
if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(E.IgnoreParens())) {
namespace member_pointers {
struct S {
- template <typename T> bool f(T) { return false; }
+ template <typename T> bool f(T) { return false; } // expected-note 4 {{possible target for call}}
template <typename T> static bool g(T) { return false; }
template <typename T> bool h(T) { return false; } // expected-note 3 {{possible target for call}}
struct C {
C &getC() {
- return makeAC; // expected-error{{reference to non-static member function must be called}}
+ return makeAC; // expected-error-re{{reference to non-static member function must be called$}}
}
- C &makeAC();
- const C &makeAC() const;
+ // FIXME: filter by const so we can unambiguously suggest '()' & point to just the one candidate, probably
+ C &makeAC(); // expected-note{{possible target for call}}
+ const C &makeAC() const; // expected-note{{possible target for call}}
static void f(); // expected-note{{candidate function}}
static void f(int); // expected-note{{candidate function}}
static int& NestedFuncTemplate() { return variable; } // expected-note{{possible target for call}}
template <class T>
- int& NestedMemfunTemplate() { return variable; }
+ int& NestedMemfunTemplate() { return variable; } // expected-note{{possible target for call}}
int operator*() const;
template <class T>
- int operator+(T) const;
+ int operator+(T) const; // expected-note{{possible target for call}}
int NonstaticMemberFunction();
static int StaticMemberFunction();
namespace rdar9136502 {
struct X {
- int i();
- int i(int);
+ int i(); // expected-note{{possible target for call}}
+ int i(int); // expected-note{{possible target for call}}
};
struct Y {
void f(X x, Y y) {
y << x
- .i; // expected-error{{reference to non-static member function must be called}}
+ .i; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
}
}