diff options
author | David Blaikie <dblaikie@gmail.com> | 2013-06-04 00:28:46 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2013-06-04 00:28:46 +0000 |
commit | 6df859d85954df08e201fd4506f19b20c37d49e6 (patch) | |
tree | 477dec586085df1ffac32c357553ac0acc7085f5 /clang/lib/Sema/Sema.cpp | |
parent | 1710d59553e98d6c0d604a541d9119eb14dc49fc (diff) | |
download | bcm5719-llvm-6df859d85954df08e201fd4506f19b20c37d49e6.tar.gz bcm5719-llvm-6df859d85954df08e201fd4506f19b20c37d49e6.zip |
Bound member function diagnostic - suggest no-args calls and note overload candidates
Still missing cases for templates, but this is a step in the right
direction. Also omits suggestions that would be ambiguous (eg: void
func(int = 0); + void func(float = 0); func;)
llvm-svn: 183173
Diffstat (limited to 'clang/lib/Sema/Sema.cpp')
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index c5f689fe493..4f79c938b80 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1148,10 +1148,20 @@ bool Sema::isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, 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); @@ -1160,16 +1170,17 @@ bool Sema::isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, // 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())) { |