Use C++14-style return type deduction in clang.

Summary:
Simplifies the C++11-style "-> decltype(...)" return-type deduction.

Note that you have to be careful about whether the function return type
is `auto` or `decltype(auto)`.  The difference is that bare `auto`
strips const and reference, just like lambda return type deduction.  In
some cases that's what we want (or more likely, we know that the return
type is a value type), but whenever we're wrapping a templated function
which might return a reference, we need to be sure that the return type
is decltype(auto).

No functional change.

Reviewers: bkramer, MaskRay, martong, shafik

Subscribers: martong, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D74423
This commit is contained in:
Justin Lebar 2020-02-11 10:34:01 -08:00
parent 846d0ac43e
commit ac66c61bf9
5 changed files with 7 additions and 13 deletions

View File

@ -204,9 +204,7 @@ namespace clang {
// Wrapper for an overload set.
template <typename ToDeclT> struct CallOverloadedCreateFun {
template <typename... Args>
auto operator()(Args &&... args)
-> decltype(ToDeclT::Create(std::forward<Args>(args)...)) {
template <typename... Args> decltype(auto) operator()(Args &&... args) {
return ToDeclT::Create(std::forward<Args>(args)...);
}
};

View File

@ -52,18 +52,16 @@ public:
BugReporter &BR) const;
};
auto callsName(const char *FunctionName)
-> decltype(callee(functionDecl())) {
decltype(auto) callsName(const char *FunctionName) {
return callee(functionDecl(hasName(FunctionName)));
}
auto equalsBoundArgDecl(int ArgIdx, const char *DeclName)
-> decltype(hasArgument(0, expr())) {
decltype(auto) equalsBoundArgDecl(int ArgIdx, const char *DeclName) {
return hasArgument(ArgIdx, ignoringParenCasts(declRefExpr(
to(varDecl(equalsBoundNode(DeclName))))));
}
auto bindAssignmentToDecl(const char *DeclName) -> decltype(hasLHS(expr())) {
decltype(auto) bindAssignmentToDecl(const char *DeclName) {
return hasLHS(ignoringParenImpCasts(
declRefExpr(to(varDecl().bind(DeclName)))));
}

View File

@ -55,8 +55,7 @@ static void emitDiagnostics(const BoundNodes &Nodes,
CE->getSourceRange());
}
static auto hasTypePointingTo(DeclarationMatcher DeclM)
-> decltype(hasType(pointerType())) {
static decltype(auto) hasTypePointingTo(DeclarationMatcher DeclM) {
return hasType(pointerType(pointee(hasDeclaration(DeclM))));
}

View File

@ -100,8 +100,7 @@ static inline std::vector<llvm::StringRef> toRefs(std::vector<std::string> V) {
return std::vector<llvm::StringRef>(V.begin(), V.end());
}
static auto callsNames(std::vector<std::string> FunctionNames)
-> decltype(callee(functionDecl())) {
static decltype(auto) callsNames(std::vector<std::string> FunctionNames) {
return callee(functionDecl(hasAnyName(toRefs(FunctionNames))));
}

View File

@ -54,7 +54,7 @@ static void emitDiagnostics(const BoundNodes &Match, const Decl *D,
OS.str(), Location, Range);
}
auto callsName(const char *FunctionName) -> decltype(callee(functionDecl())) {
decltype(auto) callsName(const char *FunctionName) {
return callee(functionDecl(hasName(FunctionName)));
}