On Wed, May 4, 2011 at 15:56, John McCall <[email protected]> wrote: > > On May 4, 2011, at 3:10 PM, Matt Beaumont-Gay wrote: > >> Author: matthewbg >> Date: Wed May 4 17:10:40 2011 >> New Revision: 130878 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=130878&view=rev >> Log: >> Implement Sema::isExprCallable. >> >> We can use this to produce nice diagnostics (and try to fixit-and-recover) in >> various cases where we might see "MyFunction" instead of "MyFunction()". The >> changes in SemaExpr are an example of how to use isExprCallable. >> >> Modified: >> cfe/trunk/include/clang/Sema/Sema.h >> cfe/trunk/lib/Sema/Sema.cpp >> cfe/trunk/lib/Sema/SemaExpr.cpp >> cfe/trunk/test/SemaCXX/member-expr.cpp >> >> Modified: cfe/trunk/include/clang/Sema/Sema.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=130878&r1=130877&r2=130878&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Sema/Sema.h (original) >> +++ cfe/trunk/include/clang/Sema/Sema.h Wed May 4 17:10:40 2011 >> @@ -2074,7 +2074,14 @@ >> void MarkDeclarationReferenced(SourceLocation Loc, Decl *D); >> void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T); >> void MarkDeclarationsReferencedInExpr(Expr *E); >> - >> + >> + /// \brief Figure out if an expression could be turned into a call. >> + bool isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, >> + UnresolvedSetImpl &NonTemplateOverloads); >> + /// \brief Give notes for a set of overloads. >> + void NoteOverloads(const UnresolvedSetImpl &Overloads, >> + const SourceLocation FinalNoteLoc); >> + >> /// \brief Conditionally issue a diagnostic based on the current >> /// evaluation context. >> /// >> >> Modified: cfe/trunk/lib/Sema/Sema.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=130878&r1=130877&r2=130878&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/Sema.cpp (original) >> +++ cfe/trunk/lib/Sema/Sema.cpp Wed May 4 17:10:40 2011 >> @@ -31,6 +31,7 @@ >> #include "clang/AST/DeclCXX.h" >> #include "clang/AST/DeclObjC.h" >> #include "clang/AST/Expr.h" >> +#include "clang/AST/ExprCXX.h" >> #include "clang/AST/StmtCXX.h" >> #include "clang/Lex/Preprocessor.h" >> #include "clang/Basic/PartialDiagnostic.h" >> @@ -766,3 +767,102 @@ >> >> OS << '\n'; >> } >> + >> +/// \brief Figure out if an expression could be turned into a call. >> +/// >> +/// Use this when trying to recover from an error where the programmer may >> have >> +/// written just the name of a function instead of actually calling it. >> +/// >> +/// \param E - The expression to examine. >> +/// \param ZeroArgCallReturnTy - If the expression can be turned into a call >> +/// with no arguments, this parameter is set to the type returned by such a >> +/// call; otherwise, it is set to an empty QualType. >> +/// \param NonTemplateOverloads - If the expression is an overloaded >> function >> +/// name, this parameter is populated with the decls of the various >> overloads. >> +bool Sema::isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, >> + UnresolvedSetImpl &NonTemplateOverloads) { >> + ZeroArgCallReturnTy = QualType(); >> + NonTemplateOverloads.clear(); >> + if (const OverloadExpr *Overloads = dyn_cast<OverloadExpr>(&E)) { >> + for (OverloadExpr::decls_iterator it = Overloads->decls_begin(), >> + DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) { >> + // Our overload set may include TemplateDecls, which we'll ignore for >> our >> + // present purpose. >> + if (const FunctionDecl *OverloadDecl = dyn_cast<FunctionDecl>(*it)) { >> + NonTemplateOverloads.addDecl(*it); >> + if (OverloadDecl->getMinRequiredArguments() == 0) >> + ZeroArgCallReturnTy = OverloadDecl->getResultType(); >> + } >> + } >> + return true; >> + } >> + >> + if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(&E)) { >> + if (const FunctionDecl *Fun = >> dyn_cast<FunctionDecl>(DeclRef->getDecl())) { >> + if (Fun->getMinRequiredArguments() == 0) >> + ZeroArgCallReturnTy = Fun->getResultType(); >> + return true; >> + } >> + } >> + >> + // We don't have an expression that's convenient to get a FunctionDecl >> from, >> + // but we can at least check if the type is "function of 0 arguments". >> + QualType ExprTy = E.getType(); >> + const FunctionType *FunTy = NULL; >> + if (const PointerType *Ptr = ExprTy->getAs<PointerType>()) >> + FunTy = Ptr->getPointeeType()->getAs<FunctionType>(); >> + else if (const ReferenceType *Ref = ExprTy->getAs<ReferenceType>()) >> + FunTy = Ref->getPointeeType()->getAs<FunctionType>(); > > Please look through BlockPointerTypes here, too. > >> + if (!FunTy) >> + FunTy = ExprTy->getAs<FunctionType>(); >> + if (!FunTy && ExprTy == Context.BoundMemberTy) { >> + // Look for the bound-member type. If it's still overloaded, give up, >> + // although we probably should have fallen into the OverloadExpr case >> above >> + // if we actually have an overloaded bound member. >> + QualType BoundMemberTy = Expr::findBoundMemberType(&E); >> + if (!BoundMemberTy.isNull()) >> + FunTy = BoundMemberTy->castAs<FunctionType>(); > > For what it's worth, that's not true; if all the functions in an overload > set for > are non-static member functions, the expression will have BoundMember > type. This is a useful case to get right, too, because a lot of common > member functions are overloaded, like the STL's begin() and end().
Take a guess who added the original version of this snippet to SemaExpr :) http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?r1=130239&r2=130238&pathrev=130239 I'm not clear on what part of this you're saying is untrue. FWIW, for simple cases involving member functions, we do the right thing: struct S { int x; }; struct T { S fun() { return S(); } S fun(int i) { return S(); } }; int g() { T t; return t.fun.x; } member-expr.cpp:156:12: error: base of member reference is an overloaded function; perhaps you meant to call it with no arguments? return t.fun.x; ^~~~~ () _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
