summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
4fc9a48)
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
virtual bool invalidate(IRUnitT *IR, const PreservedAnalyses &PA) = 0;
};
virtual bool invalidate(IRUnitT *IR, const PreservedAnalyses &PA) = 0;
};
+/// \brief SFINAE metafunction for computing whether \c ResultT provides an
+/// \c invalidate member function.
+template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
+ typedef char SmallType;
+ struct BigType { char a, b; };
+
+ template <typename T, bool (T::*)(IRUnitT *, const PreservedAnalyses &)>
+ struct Checker;
+
+ template <typename T> static SmallType f(Checker<T, &T::invalidate> *);
+ template <typename T> static BigType f(...);
+
+public:
+ enum { Value = sizeof(f<ResultT>(0)) == sizeof(SmallType) };
+};
+
/// \brief Wrapper to model the analysis result concept.
///
/// By default, this will implement the invalidate method with a trivial
/// \brief Wrapper to model the analysis result concept.
///
/// By default, this will implement the invalidate method with a trivial
/// an invalidation handler. It is only selected when the invalidation handler
/// is not part of the ResultT's interface.
template <typename IRUnitT, typename PassT, typename ResultT,
/// an invalidation handler. It is only selected when the invalidation handler
/// is not part of the ResultT's interface.
template <typename IRUnitT, typename PassT, typename ResultT,
- bool HasInvalidateHandler = false>
-struct AnalysisResultModel : AnalysisResultConcept<IRUnitT> {
+ bool HasInvalidateHandler =
+ ResultHasInvalidateMethod<IRUnitT, ResultT>::Value>
+struct AnalysisResultModel;
+
+/// \brief Specialization of \c AnalysisResultModel which provides the default
+/// invalidate functionality.
+template <typename IRUnitT, typename PassT, typename ResultT>
+struct AnalysisResultModel<IRUnitT, PassT, ResultT,
+ false> : AnalysisResultConcept<IRUnitT> {
AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {}
virtual AnalysisResultModel *clone() {
return new AnalysisResultModel(Result);
AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {}
virtual AnalysisResultModel *clone() {
return new AnalysisResultModel(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 <typename IRUnitT, typename PassT, typename ResultT>
struct AnalysisResultModel<IRUnitT, PassT, ResultT,
true> : AnalysisResultConcept<IRUnitT> {
template <typename IRUnitT, typename PassT, typename ResultT>
struct AnalysisResultModel<IRUnitT, PassT, ResultT,
true> : AnalysisResultConcept<IRUnitT> {
-/// \brief SFINAE metafunction for computing whether \c ResultT provides an
-/// \c invalidate member function.
-template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
- typedef char SmallType;
- struct BigType { char a, b; };
-
- template <typename T, bool (T::*)(IRUnitT *, const PreservedAnalyses &)>
- struct Checker;
-
- template <typename T> static SmallType f(Checker<T, &T::invalidate> *);
- template <typename T> static BigType f(...);
-
-public:
- enum { Value = sizeof(f<ResultT>(0)) == sizeof(SmallType) };
-};
-
/// \brief Abstract concept of an analysis pass.
///
/// This concept is parameterized over the IR unit that it can run over and
/// \brief Abstract concept of an analysis pass.
///
/// This concept is parameterized over the IR unit that it can run over and
typedef typename PassT::IRUnitT IRUnitT;
// FIXME: Replace PassT::Result with type traits when we use C++11.
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<IRUnitT, typename PassT::Result>::Value>
- ResultModelT;
+ typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
+ ResultModelT;
/// \brief The model delegates to the \c PassT::run method.
///
/// \brief The model delegates to the \c PassT::run method.
///
const detail::AnalysisResultConcept<Module> &ResultConcept =
getResultImpl(PassT::ID(), M);
const detail::AnalysisResultConcept<Module> &ResultConcept =
getResultImpl(PassT::ID(), M);
- typedef detail::AnalysisResultModel<
- Module, PassT, typename PassT::Result,
- detail::ResultHasInvalidateMethod<
- Module, typename PassT::Result>::Value> ResultModelT;
+ typedef detail::AnalysisResultModel<Module, PassT, typename PassT::Result>
+ ResultModelT;
return static_cast<const ResultModelT &>(ResultConcept).Result;
}
return static_cast<const ResultModelT &>(ResultConcept).Result;
}
const detail::AnalysisResultConcept<Function> &ResultConcept =
getResultImpl(PassT::ID(), F);
const detail::AnalysisResultConcept<Function> &ResultConcept =
getResultImpl(PassT::ID(), F);
- typedef detail::AnalysisResultModel<
- Function, PassT, typename PassT::Result,
- detail::ResultHasInvalidateMethod<
- Function, typename PassT::Result>::Value> ResultModelT;
+ typedef detail::AnalysisResultModel<Function, PassT, typename PassT::Result>
+ ResultModelT;
return static_cast<const ResultModelT &>(ResultConcept).Result;
}
return static_cast<const ResultModelT &>(ResultConcept).Result;
}