summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.cpp')
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.cpp b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.cpp
new file mode 100644
index 00000000000..32095e167b7
--- /dev/null
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.cpp
@@ -0,0 +1,80 @@
+//===-- PassByValueMatchers.cpp -------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file contains the definitions for matcher-generating functions
+/// and names for bound nodes found by AST matchers.
+///
+//===----------------------------------------------------------------------===//
+
+#include "PassByValueMatchers.h"
+
+const char *PassByValueCtorId = "Ctor";
+const char *PassByValueParamId = "Param";
+const char *PassByValueInitializerId = "Initializer";
+
+namespace clang {
+namespace ast_matchers {
+
+/// \brief Matches move constructible classes.
+///
+/// Given
+/// \code
+/// // POD types are trivially move constructible
+/// struct Foo { int a; };
+///
+/// struct Bar {
+/// Bar(Bar &&) = deleted;
+/// int a;
+/// };
+/// \endcode
+/// recordDecl(isMoveConstructible())
+/// matches "Foo".
+AST_MATCHER(CXXRecordDecl, isMoveConstructible) {
+ for (CXXRecordDecl::ctor_iterator I = Node.ctor_begin(), E = Node.ctor_end(); I != E; ++I) {
+ const CXXConstructorDecl *Ctor = *I;
+ if (Ctor->isMoveConstructor() && !Ctor->isDeleted())
+ return true;
+ }
+ return false;
+}
+
+/// \brief Matches non-deleted copy constructors.
+///
+/// Given
+/// \code
+/// struct Foo { Foo(const Foo &) = default; };
+/// struct Bar { Bar(const Bar &) = deleted; };
+/// \endcode
+/// constructorDecl(isNonDeletedCopyConstructor())
+/// matches "Foo(const Foo &)".
+AST_MATCHER(CXXConstructorDecl, isNonDeletedCopyConstructor) {
+ return Node.isCopyConstructor() && !Node.isDeleted();
+}
+} // namespace ast_matchers
+} // namespace clang
+
+using namespace clang;
+using namespace clang::ast_matchers;
+
+DeclarationMatcher makePassByValueCtorParamMatcher() {
+ return constructorDecl(
+ forEachConstructorInitializer(ctorInitializer(
+ // Clang builds a CXXConstructExpr only when it knowns which
+ // constructor will be called. In dependent contexts a ParenListExpr
+ // is generated instead of a CXXConstructExpr, filtering out templates
+ // automatically for us.
+ withInitializer(constructExpr(
+ has(declRefExpr(to(parmVarDecl().bind(PassByValueParamId)))),
+ hasDeclaration(constructorDecl(
+ isNonDeletedCopyConstructor(),
+ hasDeclContext(recordDecl(isMoveConstructible())))))))
+ .bind(PassByValueInitializerId)))
+ .bind(PassByValueCtorId);
+}
OpenPOWER on IntegriCloud