From: Chandler Carruth Date: Fri, 22 Nov 2013 00:48:49 +0000 (+0000) Subject: [PM] Simplify how the SFINAE for AnalysisResultModel is applied by X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=ef70984795844da3632d9df579d9007ef1b29af3;hp=4fc9a4827307a52b386dace405889ff8f929e32b;ds=sidebyside [PM] Simplify how the SFINAE for AnalysisResultModel is applied by factoring it out into the default template argument so clients don't have to even think about it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195402 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 66e5703af5b..151f1a533a3 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -241,6 +241,22 @@ template struct AnalysisResultConcept { virtual bool invalidate(IRUnitT *IR, const PreservedAnalyses &PA) = 0; }; +/// \brief SFINAE metafunction for computing whether \c ResultT provides an +/// \c invalidate member function. +template class ResultHasInvalidateMethod { + typedef char SmallType; + struct BigType { char a, b; }; + + template + struct Checker; + + template static SmallType f(Checker *); + template static BigType f(...); + +public: + enum { Value = sizeof(f(0)) == sizeof(SmallType) }; +}; + /// \brief Wrapper to model the analysis result concept. /// /// By default, this will implement the invalidate method with a trivial @@ -248,8 +264,15 @@ template struct AnalysisResultConcept { /// an invalidation handler. It is only selected when the invalidation handler /// is not part of the ResultT's interface. template -struct AnalysisResultModel : AnalysisResultConcept { + bool HasInvalidateHandler = + ResultHasInvalidateMethod::Value> +struct AnalysisResultModel; + +/// \brief Specialization of \c AnalysisResultModel which provides the default +/// invalidate functionality. +template +struct AnalysisResultModel : AnalysisResultConcept { AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {} virtual AnalysisResultModel *clone() { return new AnalysisResultModel(Result); @@ -267,10 +290,8 @@ struct AnalysisResultModel : AnalysisResultConcept { ResultT Result; }; -/// \brief Wrapper to model the analysis result concept. -/// -/// Can wrap any type which implements a suitable invalidate member and model -/// the AnalysisResultConcept for the AnalysisManager. +/// \brief Specialization of \c AnalysisResultModel which delegates invalidate +/// handling to \c ResultT. template struct AnalysisResultModel : AnalysisResultConcept { @@ -287,22 +308,6 @@ struct AnalysisResultModel class ResultHasInvalidateMethod { - typedef char SmallType; - struct BigType { char a, b; }; - - template - struct Checker; - - template static SmallType f(Checker *); - template static BigType f(...); - -public: - enum { Value = sizeof(f(0)) == sizeof(SmallType) }; -}; - /// \brief Abstract concept of an analysis pass. /// /// This concept is parameterized over the IR unit that it can run over and @@ -331,10 +336,8 @@ struct AnalysisPassModel : AnalysisPassConcept { typedef typename PassT::IRUnitT IRUnitT; // FIXME: Replace PassT::Result with type traits when we use C++11. - typedef AnalysisResultModel< - IRUnitT, PassT, typename PassT::Result, - ResultHasInvalidateMethod::Value> - ResultModelT; + typedef AnalysisResultModel + ResultModelT; /// \brief The model delegates to the \c PassT::run method. /// @@ -422,10 +425,8 @@ public: const detail::AnalysisResultConcept &ResultConcept = getResultImpl(PassT::ID(), M); - typedef detail::AnalysisResultModel< - Module, PassT, typename PassT::Result, - detail::ResultHasInvalidateMethod< - Module, typename PassT::Result>::Value> ResultModelT; + typedef detail::AnalysisResultModel + ResultModelT; return static_cast(ResultConcept).Result; } @@ -506,10 +507,8 @@ public: const detail::AnalysisResultConcept &ResultConcept = getResultImpl(PassT::ID(), F); - typedef detail::AnalysisResultModel< - Function, PassT, typename PassT::Result, - detail::ResultHasInvalidateMethod< - Function, typename PassT::Result>::Value> ResultModelT; + typedef detail::AnalysisResultModel + ResultModelT; return static_cast(ResultConcept).Result; }