<div dir="rtl"><div dir="ltr">clang r203448 builds OK on MSVC 2013.</div><div dir="ltr"><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote"><div dir="ltr">2014-03-10 2:35 GMT+02:00 Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span>:</div>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Sun Mar  9 19:35:47 2014<br>
New Revision: 203426<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=203426&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=203426&view=rev</a><br>
Log:<br>
[PM] I have been educated by several folks that MSVC will never<br>
synthesize a move constructor. Thus, for any types where move semantics<br>
are important (yea, that's essentially every type...) you must<br>
explicitly define the special members. Do so systematically throughout<br>
the pass manager as the core of the design relies heavily on move<br>
semantics.<br>
<br>
This will hopefully fix the build with MSVC 2013. We still don't know<br>
why MSVC 2012 accepted this code, but it almost certainly wasn't doing<br>
the right thing.<br>
<br>
I've also added explicit to a few single-argument constructors spotted<br>
in passing.<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/PassManager.h<br>
<br>
Modified: llvm/trunk/include/llvm/IR/PassManager.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=203426&r1=203425&r2=203426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=203426&r1=203425&r2=203426&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/IR/PassManager.h (original)<br>
+++ llvm/trunk/include/llvm/IR/PassManager.h Sun Mar  9 19:35:47 2014<br>
@@ -64,6 +64,16 @@ class Function;<br>
 /// the IR is not mutated at all.<br>
 class PreservedAnalyses {<br>
 public:<br>
+  PreservedAnalyses() {}<br>
+  PreservedAnalyses(const PreservedAnalyses &Arg)<br>
+      : PreservedPassIDs(Arg.PreservedPassIDs) {}<br>
+  PreservedAnalyses(PreservedAnalyses &&Arg)<br>
+      : PreservedPassIDs(Arg.PreservedPassIDs) {}<br>
+  PreservedAnalyses &operator=(PreservedAnalyses RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
+<br>
   /// \brief Convenience factory function for the empty preserved set.<br>
   static PreservedAnalyses none() { return PreservedAnalyses(); }<br>
<br>
@@ -74,15 +84,6 @@ public:<br>
     return PA;<br>
   }<br>
<br>
-  PreservedAnalyses &operator=(PreservedAnalyses Arg) {<br>
-    swap(Arg);<br>
-    return *this;<br>
-  }<br>
-<br>
-  void swap(PreservedAnalyses &Arg) {<br>
-    PreservedPassIDs.swap(Arg.PreservedPassIDs);<br>
-  }<br>
-<br>
   /// \brief Mark a particular pass as preserved, adding it to the set.<br>
   template <typename PassT> void preserve() {<br>
     if (!areAllPreserved())<br>
@@ -147,10 +148,6 @@ private:<br>
   SmallPtrSet<void *, 2> PreservedPassIDs;<br>
 };<br>
<br>
-inline void swap(PreservedAnalyses &LHS, PreservedAnalyses &RHS) {<br>
-  LHS.swap(RHS);<br>
-}<br>
-<br>
 /// \brief Implementation details of the pass manager interfaces.<br>
 namespace detail {<br>
<br>
@@ -204,7 +201,14 @@ struct PassModel;<br>
 template <typename IRUnitT, typename AnalysisManagerT, typename PassT><br>
 struct PassModel<IRUnitT, AnalysisManagerT, PassT,<br>
                  true> : PassConcept<IRUnitT, AnalysisManagerT> {<br>
-  PassModel(PassT Pass) : Pass(std::move(Pass)) {}<br>
+  explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}<br>
+  PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}<br>
+  PassModel(PassModel &&Arg) : Pass(Arg.Pass) {}<br>
+  PassModel &operator=(PassModel RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
+<br>
   PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {<br>
     return Pass.run(IR, AM);<br>
   }<br>
@@ -217,7 +221,14 @@ struct PassModel<IRUnitT, AnalysisManage<br>
 template <typename IRUnitT, typename AnalysisManagerT, typename PassT><br>
 struct PassModel<IRUnitT, AnalysisManagerT, PassT,<br>
                  false> : PassConcept<IRUnitT, AnalysisManagerT> {<br>
-  PassModel(PassT Pass) : Pass(std::move(Pass)) {}<br>
+  explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}<br>
+  PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}<br>
+  PassModel(PassModel &&Arg) : Pass(Arg.Pass) {}<br>
+  PassModel &operator=(PassModel RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
+<br>
   PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {<br>
     return Pass.run(IR);<br>
   }<br>
@@ -277,7 +288,13 @@ struct AnalysisResultModel;<br>
 template <typename IRUnitT, typename PassT, typename ResultT><br>
 struct AnalysisResultModel<IRUnitT, PassT, ResultT,<br>
                            false> : AnalysisResultConcept<IRUnitT> {<br>
-  AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}<br>
+  explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}<br>
+  AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}<br>
+  AnalysisResultModel(AnalysisResultModel &&Arg) : Result(Arg.Result) {}<br>
+  AnalysisResultModel &operator=(AnalysisResultModel RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
<br>
   /// \brief The model bases invalidation solely on being in the preserved set.<br>
   //<br>
@@ -296,7 +313,13 @@ struct AnalysisResultModel<IRUnitT, Pass<br>
 template <typename IRUnitT, typename PassT, typename ResultT><br>
 struct AnalysisResultModel<IRUnitT, PassT, ResultT,<br>
                            true> : AnalysisResultConcept<IRUnitT> {<br>
-  AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}<br>
+  explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}<br>
+  AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}<br>
+  AnalysisResultModel(AnalysisResultModel &&Arg) : Result(Arg.Result) {}<br>
+  AnalysisResultModel &operator=(AnalysisResultModel RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
<br>
   /// \brief The model delegates to the \c ResultT method.<br>
   bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) override {<br>
@@ -337,7 +360,13 @@ template <typename IRUnitT, typename Ana<br>
 struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT,<br>
                          true> : AnalysisPassConcept<IRUnitT,<br>
                                                      AnalysisManagerT> {<br>
-  AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}<br>
+  explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}<br>
+  AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}<br>
+  AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(Arg.Pass) {}<br>
+  AnalysisPassModel &operator=(AnalysisPassModel RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
<br>
   // FIXME: Replace PassT::Result with type traits when we use C++11.<br>
   typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result><br>
@@ -360,7 +389,13 @@ template <typename IRUnitT, typename Ana<br>
 struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT,<br>
                          false> : AnalysisPassConcept<IRUnitT,<br>
                                                      AnalysisManagerT> {<br>
-  AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}<br>
+  explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}<br>
+  AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}<br>
+  AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(Arg.Pass) {}<br>
+  AnalysisPassModel &operator=(AnalysisPassModel RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
<br>
   // FIXME: Replace PassT::Result with type traits when we use C++11.<br>
   typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result><br>
@@ -383,6 +418,15 @@ class ModuleAnalysisManager;<br>
<br>
 class ModulePassManager {<br>
 public:<br>
+  // We have to explicitly define all the special member functions because MSVC<br>
+  // 2013 refuses to generate them.<br>
+  ModulePassManager() {}<br>
+  ModulePassManager(ModulePassManager &&Arg) : Passes(std::move(Arg.Passes)) {}<br>
+  ModulePassManager &operator=(ModulePassManager &&RHS) {<br>
+    Passes = std::move(RHS.Passes);<br>
+    return *this;<br>
+  }<br>
+<br>
   /// \brief Run all of the module passes in this module pass manager over<br>
   /// a module.<br>
   ///<br>
@@ -407,6 +451,9 @@ private:<br>
               std::move(Pass)) {}<br>
   };<br>
<br>
+  ModulePassManager(const ModulePassManager &) LLVM_DELETED_FUNCTION;<br>
+  ModulePassManager &operator=(const ModulePassManager &) LLVM_DELETED_FUNCTION;<br>
+<br>
   std::vector<std::unique_ptr<ModulePassConcept>> Passes;<br>
 };<br>
<br>
@@ -414,6 +461,15 @@ class FunctionAnalysisManager;<br>
<br>
 class FunctionPassManager {<br>
 public:<br>
+  // We have to explicitly define all the special member functions because MSVC<br>
+  // 2013 refuses to generate them.<br>
+  FunctionPassManager() {}<br>
+  FunctionPassManager(FunctionPassManager &&Arg) : Passes(std::move(Arg.Passes)) {}<br>
+  FunctionPassManager &operator=(FunctionPassManager &&RHS) {<br>
+    Passes = std::move(RHS.Passes);<br>
+    return *this;<br>
+  }<br>
+<br>
   template <typename FunctionPassT> void addPass(FunctionPassT Pass) {<br>
     Passes.emplace_back(new FunctionPassModel<FunctionPassT>(std::move(Pass)));<br>
   }<br>
@@ -434,6 +490,10 @@ private:<br>
               std::move(Pass)) {}<br>
   };<br>
<br>
+  FunctionPassManager(const FunctionPassManager &) LLVM_DELETED_FUNCTION;<br>
+  FunctionPassManager &<br>
+  operator=(const FunctionPassManager &) LLVM_DELETED_FUNCTION;<br>
+<br>
   std::vector<std::unique_ptr<FunctionPassConcept>> Passes;<br>
 };<br>
<br>
@@ -455,6 +515,10 @@ class AnalysisManagerBase {<br>
   DerivedT *derived_this() { return static_cast<DerivedT *>(this); }<br>
   const DerivedT *derived_this() const { return static_cast<const DerivedT *>(this); }<br>
<br>
+  AnalysisManagerBase(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;<br>
+  AnalysisManagerBase &<br>
+  operator=(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;<br>
+<br>
 protected:<br>
   typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;<br>
   typedef detail::AnalysisPassConcept<IRUnitT, DerivedT> PassConceptT;<br>
@@ -462,6 +526,14 @@ protected:<br>
   // FIXME: Provide template aliases for the models when we're using C++11 in<br>
   // a mode supporting them.<br>
<br>
+  AnalysisManagerBase() {}<br>
+  AnalysisManagerBase(AnalysisManagerBase &&Arg)<br>
+      : AnalysisPasses(std::move(Arg.AnalysisPasses)) {}<br>
+  AnalysisManagerBase &operator=(AnalysisManagerBase &&RHS) {<br>
+    AnalysisPasses = std::move(RHS.AnalysisPasses);<br>
+    return *this;<br>
+  }<br>
+<br>
 public:<br>
   /// \brief Get the result of an analysis pass for this module.<br>
   ///<br>
@@ -564,9 +636,21 @@ class ModuleAnalysisManager<br>
   typedef BaseT::PassConceptT PassConceptT;<br>
<br>
 public:<br>
-  // Public methods provided by the base class.<br>
+  ModuleAnalysisManager() {}<br>
+  ModuleAnalysisManager(ModuleAnalysisManager &&Arg)<br>
+      : BaseT(std::move(static_cast<BaseT &>(Arg))),<br>
+        ModuleAnalysisResults(std::move(Arg.ModuleAnalysisResults)) {}<br>
+  ModuleAnalysisManager &operator=(ModuleAnalysisManager &&RHS) {<br>
+    BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));<br>
+    ModuleAnalysisResults = std::move(RHS.ModuleAnalysisResults);<br>
+    return *this;<br>
+  }<br>
<br>
 private:<br>
+  ModuleAnalysisManager(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;<br>
+  ModuleAnalysisManager &<br>
+  operator=(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;<br>
+<br>
   /// \brief Get a module pass result, running the pass if necessary.<br>
   ResultConceptT &getResultImpl(void *PassID, Module *M);<br>
<br>
@@ -600,6 +684,16 @@ class FunctionAnalysisManager<br>
 public:<br>
   // Most public APIs are inherited from the CRTP base class.<br>
<br>
+  FunctionAnalysisManager() {}<br>
+  FunctionAnalysisManager(FunctionAnalysisManager &&Arg)<br>
+      : BaseT(std::move(static_cast<BaseT &>(Arg))),<br>
+        FunctionAnalysisResults(std::move(Arg.FunctionAnalysisResults)) {}<br>
+  FunctionAnalysisManager &operator=(FunctionAnalysisManager &&RHS) {<br>
+    BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));<br>
+    FunctionAnalysisResults = std::move(RHS.FunctionAnalysisResults);<br>
+    return *this;<br>
+  }<br>
+<br>
   /// \brief Returns true if the analysis manager has an empty results cache.<br>
   bool empty() const;<br>
<br>
@@ -612,6 +706,10 @@ public:<br>
   void clear();<br>
<br>
 private:<br>
+  FunctionAnalysisManager(const FunctionAnalysisManager &) LLVM_DELETED_FUNCTION;<br>
+  FunctionAnalysisManager &<br>
+  operator=(const FunctionAnalysisManager &) LLVM_DELETED_FUNCTION;<br>
+<br>
   /// \brief Get a function pass result, running the pass if necessary.<br>
   ResultConceptT &getResultImpl(void *PassID, Function *F);<br>
<br>
@@ -668,7 +766,18 @@ public:<br>
<br>
   static void *ID() { return (void *)&PassID; }<br>
<br>
-  FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM) : FAM(FAM) {}<br>
+  explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM)<br>
+      : FAM(FAM) {}<br>
+  FunctionAnalysisManagerModuleProxy(<br>
+      const FunctionAnalysisManagerModuleProxy &Arg)<br>
+      : FAM(Arg.FAM) {}<br>
+  FunctionAnalysisManagerModuleProxy(FunctionAnalysisManagerModuleProxy &&Arg)<br>
+      : FAM(Arg.FAM) {}<br>
+  FunctionAnalysisManagerModuleProxy &<br>
+  operator=(FunctionAnalysisManagerModuleProxy RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
<br>
   /// \brief Run the analysis pass and create our proxy result object.<br>
   ///<br>
@@ -693,7 +802,13 @@ private:<br>
 /// See its documentation for more information.<br>
 class FunctionAnalysisManagerModuleProxy::Result {<br>
 public:<br>
-  Result(FunctionAnalysisManager &FAM) : FAM(FAM) {}<br>
+  explicit Result(FunctionAnalysisManager &FAM) : FAM(FAM) {}<br>
+  Result(const Result &Arg) : FAM(Arg.FAM) {}<br>
+  Result(Result &&Arg) : FAM(Arg.FAM) {}<br>
+  Result &operator=(Result RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
   ~Result();<br>
<br>
   /// \brief Accessor for the \c FunctionAnalysisManager.<br>
@@ -732,7 +847,13 @@ public:<br>
   /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.<br>
   class Result {<br>
   public:<br>
-    Result(const ModuleAnalysisManager &MAM) : MAM(MAM) {}<br>
+    explicit Result(const ModuleAnalysisManager &MAM) : MAM(MAM) {}<br>
+    Result(const Result &Arg) : MAM(Arg.MAM) {}<br>
+    Result(Result &&Arg) : MAM(Arg.MAM) {}<br>
+    Result &operator=(Result RHS) {<br>
+      std::swap(*this, RHS);<br>
+      return *this;<br>
+    }<br>
<br>
     const ModuleAnalysisManager &getManager() const { return MAM; }<br>
<br>
@@ -772,6 +893,14 @@ class ModuleToFunctionPassAdaptor {<br>
 public:<br>
   explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass)<br>
       : Pass(std::move(Pass)) {}<br>
+  ModuleToFunctionPassAdaptor(const ModuleToFunctionPassAdaptor &Arg)<br>
+      : Pass(Arg.Pass) {}<br>
+  ModuleToFunctionPassAdaptor(ModuleToFunctionPassAdaptor &&Arg)<br>
+      : Pass(std::move(Arg.Pass)) {}<br>
+  ModuleToFunctionPassAdaptor &operator=(ModuleToFunctionPassAdaptor RHS) {<br>
+    std::swap(*this, RHS);<br>
+    return *this;<br>
+  }<br>
<br>
   /// \brief Runs the function pass across every function in the module.<br>
   PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>