<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>