diff options
author | Dmitri Gribenko <gribozavr@gmail.com> | 2019-06-13 13:48:24 +0000 |
---|---|---|
committer | Dmitri Gribenko <gribozavr@gmail.com> | 2019-06-13 13:48:24 +0000 |
commit | b235d6c5fbead823fefcb70877860d9c99e150c3 (patch) | |
tree | 7bbdcbd0856f987cc5117170f43ecaaa098c59f0 /include/clang/ASTMatchers | |
parent | 345d700bbe3692551ea4bda6b2b45a223f9e0f74 (diff) |
Added AST matcher for ignoring elidable constructors
Summary: Added AST matcher for ignoring elidable move constructors
Reviewers: hokein, gribozavr
Reviewed By: hokein, gribozavr
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63149
Patch by Johan Vikström.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@363262 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/ASTMatchers')
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchers.h | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index d973b48a17..d3ebbff42e 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -6452,6 +6452,44 @@ AST_MATCHER(FunctionDecl, hasTrailingReturn) { return false; } +/// Matches expressions that match InnerMatcher that are possibly wrapped in an +/// elidable constructor. +/// +/// In C++17 copy elidable constructors are no longer being +/// generated in the AST as it is not permitted by the standard. They are +/// however part of the AST in C++14 and earlier. Therefore, to write a matcher +/// that works in all language modes, the matcher has to skip elidable +/// constructor AST nodes if they appear in the AST. This matcher can be used to +/// skip those elidable constructors. +/// +/// Given +/// +/// \code +/// struct H {}; +/// H G(); +/// void f() { +/// H D = G(); +/// } +/// \endcode +/// +/// ``varDecl(hasInitializer(any( +/// ignoringElidableConstructorCall(callExpr()), +/// exprWithCleanups(ignoringElidableConstructorCall(callExpr()))))`` +/// matches ``H D = G()`` +AST_MATCHER_P(Expr, ignoringElidableConstructorCall, + ast_matchers::internal::Matcher<Expr>, InnerMatcher) { + if (const auto *CtorExpr = dyn_cast<CXXConstructExpr>(&Node)) { + if (CtorExpr->isElidable()) { + if (const auto *MaterializeTemp = + dyn_cast<MaterializeTemporaryExpr>(CtorExpr->getArg(0))) { + return InnerMatcher.matches(*MaterializeTemp->GetTemporaryExpr(), + Finder, Builder); + } + } + } + return InnerMatcher.matches(Node, Finder, Builder); +} + //----------------------------------------------------------------------------// // OpenMP handling. //----------------------------------------------------------------------------// |