summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/cpp11-migrate
diff options
context:
space:
mode:
authorGuillaume Papin <guillaume.papin@epitech.eu>2013-08-27 16:11:26 +0000
committerGuillaume Papin <guillaume.papin@epitech.eu>2013-08-27 16:11:26 +0000
commitdcdae946f3ed6d737efe27b52aadec217eedf036 (patch)
tree13aec237dfda1aacc23f2f66a61ad3b48321ba3a /clang-tools-extra/cpp11-migrate
parentfe48aaf1a4aa0cf13bdd8c1754de11b39f03290f (diff)
downloadbcm5719-llvm-dcdae946f3ed6d737efe27b52aadec217eedf036.tar.gz
bcm5719-llvm-dcdae946f3ed6d737efe27b52aadec217eedf036.zip
cpp11-migrate: Add Pass-By-Value Transform
Currently only constructor parameters stored in class-local storage are modified to make use of the pass-by-value idiom but this is a base that can be be further improved to handle more situations. llvm-svn: 189363
Diffstat (limited to 'clang-tools-extra/cpp11-migrate')
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/Transform.h6
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.cpp80
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.h74
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.cpp167
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.h76
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.cpp80
-rw-r--r--clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.h44
-rw-r--r--clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt3
-rw-r--r--clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp2
-rw-r--r--clang-tools-extra/cpp11-migrate/tool/Makefile2
10 files changed, 534 insertions, 0 deletions
diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.h b/clang-tools-extra/cpp11-migrate/Core/Transform.h
index bb8c116726d..43082111d54 100644
--- a/clang-tools-extra/cpp11-migrate/Core/Transform.h
+++ b/clang-tools-extra/cpp11-migrate/Core/Transform.h
@@ -139,6 +139,12 @@ public:
bool isFileModifiable(const clang::SourceManager &SM,
const clang::SourceLocation &Loc) const;
+ /// \brief Whether a transformation with a risk level of \p RiskLevel is
+ /// acceptable or not.
+ bool isAcceptableRiskLevel(RiskLevel RiskLevel) const {
+ return RiskLevel <= GlobalOptions.MaxRiskLevel;
+ }
+
/// \brief Called before parsing a translation unit for a FrontendAction.
///
/// Transform uses this function to apply file overrides and start
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.cpp b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.cpp
new file mode 100644
index 00000000000..bbcba830296
--- /dev/null
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.cpp
@@ -0,0 +1,80 @@
+//===-- PassByValue.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 provides the implementation of the ReplaceAutoPtrTransform
+/// class.
+///
+//===----------------------------------------------------------------------===//
+
+#include "PassByValue.h"
+#include "PassByValueActions.h"
+#include "PassByValueMatchers.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace clang::ast_matchers;
+
+int PassByValueTransform::apply(
+ FileOverrides &InputStates, const tooling::CompilationDatabase &Database,
+ const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE {
+ ClangTool Tool(Database, SourcePaths);
+ unsigned AcceptedChanges = 0;
+ unsigned RejectedChanges = 0;
+ MatchFinder Finder;
+ ConstructorParamReplacer Replacer(getReplacements(), AcceptedChanges,
+ RejectedChanges,
+ /*Owner=*/ *this);
+
+ Finder.addMatcher(makePassByValueCtorParamMatcher(), &Replacer);
+
+ // make the replacer available to handleBeginSource()
+ this->Replacer = &Replacer;
+
+ setOverrides(InputStates);
+
+ if (Tool.run(createActionFactory(Finder))) {
+ llvm::errs() << "Error encountered during translation.\n";
+ return 1;
+ }
+
+ setAcceptedChanges(AcceptedChanges);
+ setRejectedChanges(RejectedChanges);
+ return 0;
+}
+
+bool PassByValueTransform::handleBeginSource(CompilerInstance &CI,
+ llvm::StringRef Filename) {
+ assert(Replacer && "Replacer not set");
+ IncludeManager.reset(new IncludeDirectives(CI));
+ Replacer->setIncludeDirectives(IncludeManager.get());
+ return Transform::handleBeginSource(CI, Filename);
+}
+
+struct PassByValueFactory : TransformFactory {
+ PassByValueFactory() {
+ // Based on the Replace Auto-Ptr Transform that is also using std::move().
+ Since.Clang = Version(3, 0);
+ Since.Gcc = Version(4, 6);
+ Since.Icc = Version(13);
+ Since.Msvc = Version(11);
+ }
+
+ Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
+ return new PassByValueTransform(Opts);
+ }
+};
+
+// Register the factory using this statically initialized variable.
+static TransformFactoryRegistry::Add<PassByValueFactory>
+X("pass-by-value", "Pass parameters by value where possible");
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the factory.
+volatile int PassByValueTransformAnchorSource = 0;
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.h b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.h
new file mode 100644
index 00000000000..00949526254
--- /dev/null
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValue.h
@@ -0,0 +1,74 @@
+//===-- PassByValue.h -------------------------------------------*- C++ -*-===//
+//
+// 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 provides the declaration of the PassByValueTransform
+/// class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CPP11_MIGRATE_PASS_BY_VALUE_H
+#define CPP11_MIGRATE_PASS_BY_VALUE_H
+
+#include "Core/Transform.h"
+#include "Core/IncludeDirectives.h"
+
+class ConstructorParamReplacer;
+
+/// \brief Subclass of Transform that uses pass-by-value semantic when move
+/// constructors are available to avoid copies.
+///
+/// When a class constructor accepts an object by const reference with the
+/// intention of copying the object the copy can be avoided in certain
+/// situations if the object has a move constructor. First, the constructor is
+/// changed to accept the object by value instead. Then this argument is moved
+/// instead of copied into class-local storage. If an l-value is provided to the
+/// constructor, there is no difference in the number of copies made. However,
+/// if an r-value is passed, the copy is avoided completely.
+///
+/// For example, given:
+/// \code
+/// #include <string>
+///
+/// class A {
+/// std::string S;
+/// public:
+/// A(const std::string &S) : S(S) {}
+/// };
+/// \endcode
+/// the code is transformed to:
+/// \code
+/// #include <string>
+///
+/// class A {
+/// std::string S;
+/// public:
+/// A(std::string S) : S(std::move(S)) {}
+/// };
+/// \endcode
+class PassByValueTransform : public Transform {
+public:
+ PassByValueTransform(const TransformOptions &Options)
+ : Transform("PassByValue", Options), Replacer(0) {}
+
+ /// \see Transform::apply().
+ virtual int apply(FileOverrides &InputStates,
+ const clang::tooling::CompilationDatabase &Database,
+ const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
+
+private:
+ /// \brief Setups the \c IncludeDirectives for the replacer.
+ virtual bool handleBeginSource(clang::CompilerInstance &CI,
+ llvm::StringRef Filename) LLVM_OVERRIDE;
+
+ llvm::OwningPtr<IncludeDirectives> IncludeManager;
+ ConstructorParamReplacer *Replacer;
+};
+
+#endif // CPP11_MIGRATE_PASS_BY_VALUE_H
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.cpp b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.cpp
new file mode 100644
index 00000000000..612850a70db
--- /dev/null
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.cpp
@@ -0,0 +1,167 @@
+//===-- PassByValueActions.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 definition of the ASTMatcher callback for the
+/// PassByValue transform.
+///
+//===----------------------------------------------------------------------===//
+
+#include "PassByValueActions.h"
+#include "PassByValueMatchers.h"
+#include "Core/IncludeDirectives.h"
+#include "Core/Transform.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace clang::ast_matchers;
+
+namespace {
+/// \brief \c clang::RecursiveASTVisitor that checks that the given
+/// \c ParmVarDecl is used exactly one time.
+///
+/// \see ExactlyOneUsageVisitor::hasExactlyOneUsageIn()
+class ExactlyOneUsageVisitor
+ : public RecursiveASTVisitor<ExactlyOneUsageVisitor> {
+ friend class RecursiveASTVisitor<ExactlyOneUsageVisitor>;
+
+public:
+ ExactlyOneUsageVisitor(const ParmVarDecl *ParamDecl) : ParamDecl(ParamDecl) {}
+
+ /// \brief Whether or not the parameter variable is referred only once in the
+ /// given constructor.
+ bool hasExactlyOneUsageIn(const CXXConstructorDecl *Ctor) {
+ Count = 0;
+ TraverseDecl(const_cast<CXXConstructorDecl *>(Ctor));
+ return Count == 1;
+ }
+
+private:
+ /// \brief Counts the number of references to a variable.
+ ///
+ /// Stops the AST traversal if more than one usage is found.
+ bool VisitDeclRefExpr(DeclRefExpr *D) {
+ if (const ParmVarDecl *To = llvm::dyn_cast<ParmVarDecl>(D->getDecl()))
+ if (To == ParamDecl) {
+ ++Count;
+ if (Count > 1)
+ // no need to look further, used more than once
+ return false;
+ }
+ return true;
+ }
+
+ const ParmVarDecl *ParamDecl;
+ unsigned Count;
+};
+} // end anonymous namespace
+
+/// \brief Whether or not \p ParamDecl is used exactly one time in \p Ctor.
+///
+/// Checks both in the init-list and the body of the constructor.
+static bool paramReferredExactlyOnce(const CXXConstructorDecl *Ctor,
+ const ParmVarDecl *ParamDecl) {
+ ExactlyOneUsageVisitor Visitor(ParamDecl);
+ return Visitor.hasExactlyOneUsageIn(Ctor);
+}
+
+/// \brief Find all references to \p ParamDecl accross all of the
+/// redeclarations of \p Ctor.
+static void
+collectParamDecls(const CXXConstructorDecl *Ctor, const ParmVarDecl *ParamDecl,
+ llvm::SmallVectorImpl<const ParmVarDecl *> &Results) {
+ unsigned ParamIdx = ParamDecl->getFunctionScopeIndex();
+
+ for (CXXConstructorDecl::redecl_iterator I = Ctor->redecls_begin(),
+ E = Ctor->redecls_end();
+ I != E; ++I)
+ Results.push_back((*I)->getParamDecl(ParamIdx));
+}
+
+void ConstructorParamReplacer::run(const MatchFinder::MatchResult &Result) {
+ assert(IncludeManager && "Include directives manager not set.");
+ SourceManager &SM = *Result.SourceManager;
+ const CXXConstructorDecl *Ctor =
+ Result.Nodes.getNodeAs<CXXConstructorDecl>(PassByValueCtorId);
+ const ParmVarDecl *ParamDecl =
+ Result.Nodes.getNodeAs<ParmVarDecl>(PassByValueParamId);
+ const CXXCtorInitializer *Initializer =
+ Result.Nodes.getNodeAs<CXXCtorInitializer>(PassByValueInitializerId);
+ assert(Ctor && ParamDecl && Initializer && "Bad Callback, missing node.");
+
+ // Check this now to avoid unecessary work. The param locations are checked
+ // later.
+ if (!Owner.isFileModifiable(SM, Initializer->getSourceLocation()))
+ return;
+
+ // The parameter will be in an unspecified state after the move, so check if
+ // the parameter is used for anything else other than the copy. If so do not
+ // apply any changes.
+ if (!paramReferredExactlyOnce(Ctor, ParamDecl))
+ return;
+
+ llvm::SmallVector<const ParmVarDecl *, 2> AllParamDecls;
+ collectParamDecls(Ctor, ParamDecl, AllParamDecls);
+
+ // Generate all replacements for the params.
+ llvm::SmallVector<Replacement, 2> ParamReplaces(AllParamDecls.size());
+ for (unsigned I = 0, E = AllParamDecls.size(); I != E; ++I) {
+ TypeLoc ParamTL = AllParamDecls[I]->getTypeSourceInfo()->getTypeLoc();
+ SourceRange Range(AllParamDecls[I]->getLocStart(), ParamTL.getLocEnd());
+ CharSourceRange CharRange = Lexer::makeFileCharRange(
+ CharSourceRange::getTokenRange(Range), SM, LangOptions());
+ TypeLoc ValueTypeLoc = ParamTL;
+ // transform non-value parameters (e.g: const-ref) to values
+ if (!ParamTL.getNextTypeLoc().isNull())
+ ValueTypeLoc = ParamTL.getNextTypeLoc();
+ llvm::SmallString<32> ValueStr = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(ValueTypeLoc.getSourceRange()), SM,
+ LangOptions());
+
+ // If it's impossible to change one of the parameter (e.g: comes from an
+ // unmodifiable header) quit the callback now, do not generate any changes.
+ if (CharRange.isInvalid() || ValueStr.empty() ||
+ !Owner.isFileModifiable(SM, CharRange.getBegin()))
+ return;
+
+ // 'const Foo &param' -> 'Foo param'
+ // ~~~~~~~~~~~ ~~~^
+ ValueStr += ' ';
+ ParamReplaces[I] = Replacement(SM, CharRange, ValueStr);
+ }
+
+ // Reject the changes if the the risk level is not acceptable.
+ if (!Owner.isAcceptableRiskLevel(RL_Reasonable)) {
+ RejectedChanges++;
+ return;
+ }
+
+ // if needed, include <utility> in the file that uses std::move()
+ const FileEntry *STDMoveFile =
+ SM.getFileEntryForID(SM.getFileID(Initializer->getLParenLoc()));
+ const tooling::Replacement &IncludeReplace =
+ IncludeManager->addAngledInclude(STDMoveFile, "utility");
+ if (IncludeReplace.isApplicable()) {
+ Replaces.insert(IncludeReplace);
+ AcceptedChanges++;
+ }
+
+ // const-ref params becomes values (const Foo & -> Foo)
+ Replaces.insert(ParamReplaces.begin(), ParamReplaces.end());
+ AcceptedChanges += ParamReplaces.size();
+
+ // move the value in the init-list
+ Replaces.insert(Replacement(
+ SM, Initializer->getLParenLoc().getLocWithOffset(1), 0, "std::move("));
+ Replaces.insert(Replacement(SM, Initializer->getRParenLoc(), 0, ")"));
+ AcceptedChanges += 2;
+}
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.h b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.h
new file mode 100644
index 00000000000..5564fc54caf
--- /dev/null
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueActions.h
@@ -0,0 +1,76 @@
+//===-- PassByValueActions.h ------------------------------------*- C++ -*-===//
+//
+// 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 declaration of the ASTMatcher callback for the
+/// PassByValue transform.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CPP11_MIGRATE_PASS_BY_VALUE_ACTIONS_H
+#define CPP11_MIGRATE_PASS_BY_VALUE_ACTIONS_H
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Refactoring.h"
+
+class Transform;
+class IncludeDirectives;
+
+/// \brief Callback that replaces const-ref parameters in constructors to use
+/// pass-by-value semantic where applicable.
+///
+/// Modifications done by the callback:
+/// - \#include \<utility\> is added if necessary for the definition of
+/// \c std::move() to be available.
+/// - The parameter type is changed from const-ref to value-type.
+/// - In the init-list the parameter is moved.
+///
+/// Example:
+/// \code
+/// + #include <utility>
+///
+/// class Foo(const std::string &S) {
+/// public:
+/// - Foo(const std::string &S) : S(S) {}
+/// + Foo(std::string S) : S(std::move(S)) {}
+///
+/// private:
+/// std::string S;
+/// };
+/// \endcode
+///
+/// \note Since an include may be added by this matcher it's necessary to call
+/// \c setIncludeDirectives() with an up-to-date \c IncludeDirectives. This is
+/// typically done by overloading \c Transform::handleBeginSource().
+class ConstructorParamReplacer
+ : public clang::ast_matchers::MatchFinder::MatchCallback {
+public:
+ ConstructorParamReplacer(clang::tooling::Replacements &Replaces,
+ unsigned &AcceptedChanges, unsigned &RejectedChanges,
+ const Transform &Owner)
+ : Replaces(Replaces), AcceptedChanges(AcceptedChanges),
+ RejectedChanges(RejectedChanges), Owner(Owner), IncludeManager(0) {}
+
+ void setIncludeDirectives(IncludeDirectives *Includes) {
+ IncludeManager = Includes;
+ }
+
+private:
+ /// \brief Entry point to the callback called when matches are made.
+ virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
+ LLVM_OVERRIDE;
+
+ clang::tooling::Replacements &Replaces;
+ unsigned &AcceptedChanges;
+ unsigned &RejectedChanges;
+ const Transform &Owner;
+ IncludeDirectives *IncludeManager;
+};
+
+#endif // CPP11_MIGRATE_PASS_BY_VALUE_ACTIONS_H
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);
+}
diff --git a/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.h b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.h
new file mode 100644
index 00000000000..8c2bade4385
--- /dev/null
+++ b/clang-tools-extra/cpp11-migrate/PassByValue/PassByValueMatchers.h
@@ -0,0 +1,44 @@
+//===-- PassByValueMatchers.h -----------------------------------*- C++ -*-===//
+//
+// 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 declarations for matcher-generating functions
+/// and names for bound nodes found by AST matchers.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CPP11_MIGRATE_REPLACE_AUTO_PTR_MATCHERS_H
+#define CPP11_MIGRATE_REPLACE_AUTO_PTR_MATCHERS_H
+
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+/// \name Names to bind with matched expressions
+/// @{
+extern const char *PassByValueCtorId;
+extern const char *PassByValueParamId;
+extern const char *PassByValueInitializerId;
+/// @}
+
+/// \brief Creates a matcher that finds class field initializations that can
+/// benefit from using the move constructor.
+///
+/// \code
+/// class A {
+/// public:
+/// A(const std::string &S) : S(S) {}
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PassByValueCtorId
+/// ~~~~~~~~~~~~~~~~~~~~ PassByValueParamId
+/// ~ PassByValueInitializerId
+/// private:
+/// std::string S;
+/// };
+/// \endcode
+clang::ast_matchers::DeclarationMatcher makePassByValueCtorParamMatcher();
+
+#endif // CPP11_MIGRATE_REPLACE_AUTO_PTR_MATCHERS_H
diff --git a/clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt b/clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt
index e03fbee3424..a40e0f3e31a 100644
--- a/clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt
+++ b/clang-tools-extra/cpp11-migrate/tool/CMakeLists.txt
@@ -19,6 +19,9 @@ list(APPEND Cpp11MigrateSources ${UseAutoSources})
file(GLOB_RECURSE AddOverrideSources "../AddOverride/*.cpp")
list(APPEND Cpp11MigrateSources ${AddOverrideSources})
+file(GLOB_RECURSE PassByValueSources "../PassByValue/*.cpp")
+list(APPEND Cpp11MigrateSources ${PassByValueSources})
+
file(GLOB_RECURSE ReplaceAutoPtrSources "../ReplaceAutoPtr/*.cpp")
list(APPEND Cpp11MigrateSources ${ReplaceAutoPtrSources})
diff --git a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
index a6240c48e7e..eaaec3c91de 100644
--- a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
+++ b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
@@ -414,6 +414,7 @@ int main(int argc, const char **argv) {
// These anchors are used to force the linker to link the transforms
extern volatile int AddOverrideTransformAnchorSource;
extern volatile int LoopConvertTransformAnchorSource;
+extern volatile int PassByValueTransformAnchorSource;
extern volatile int ReplaceAutoPtrTransformAnchorSource;
extern volatile int UseAutoTransformAnchorSource;
extern volatile int UseNullptrTransformAnchorSource;
@@ -421,6 +422,7 @@ extern volatile int UseNullptrTransformAnchorSource;
static int TransformsAnchorsDestination[] = {
AddOverrideTransformAnchorSource,
LoopConvertTransformAnchorSource,
+ PassByValueTransformAnchorSource,
ReplaceAutoPtrTransformAnchorSource,
UseAutoTransformAnchorSource,
UseNullptrTransformAnchorSource
diff --git a/clang-tools-extra/cpp11-migrate/tool/Makefile b/clang-tools-extra/cpp11-migrate/tool/Makefile
index d59fa14062c..f1780265aa9 100644
--- a/clang-tools-extra/cpp11-migrate/tool/Makefile
+++ b/clang-tools-extra/cpp11-migrate/tool/Makefile
@@ -30,6 +30,8 @@ SOURCES += $(addprefix ../UseAuto/,$(notdir $(wildcard $(PROJ_SRC_DIR)/../UseAut
BUILT_SOURCES += $(ObjDir)/../UseAuto/.objdir
SOURCES += $(addprefix ../AddOverride/,$(notdir $(wildcard $(PROJ_SRC_DIR)/../AddOverride/*.cpp)))
BUILT_SOURCES += $(ObjDir)/../AddOverride/.objdir
+SOURCES += $(addprefix ../PassByValue/,$(notdir $(wildcard $(PROJ_SRC_DIR)/../PassByValue/*.cpp)))
+BUILT_SOURCES += $(ObjDir)/../PassByValue/.objdir
SOURCES += $(addprefix ../ReplaceAutoPtr/,$(notdir $(wildcard $(PROJ_SRC_DIR)/../ReplaceAutoPtr/*.cpp)))
BUILT_SOURCES += $(ObjDir)/../ReplaceAutoPtr/.objdir
OpenPOWER on IntegriCloud