aboutsummaryrefslogtreecommitdiff
path: root/include/clang/ASTMatchers
diff options
context:
space:
mode:
authorDmitri Gribenko <gribozavr@gmail.com>2019-06-13 13:48:24 +0000
committerDmitri Gribenko <gribozavr@gmail.com>2019-06-13 13:48:24 +0000
commitb235d6c5fbead823fefcb70877860d9c99e150c3 (patch)
tree7bbdcbd0856f987cc5117170f43ecaaa098c59f0 /include/clang/ASTMatchers
parent345d700bbe3692551ea4bda6b2b45a223f9e0f74 (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.h38
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.
//----------------------------------------------------------------------------//