- enum { Value = sizeof(f<ResultT>(nullptr)) == sizeof(SmallType) };
-};
-
-/// \brief Wrapper to model the analysis result concept.
-///
-/// By default, this will implement the invalidate method with a trivial
-/// implementation so that the actual analysis result doesn't need to provide
-/// 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 =
- 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> {
- explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
- AnalysisResultModel(AnalysisResultModel &&Arg)
- : Result(std::move(Arg.Result)) {}
- friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
- using std::swap;
- swap(LHS.Result, RHS.Result);
- }
- AnalysisResultModel &operator=(AnalysisResultModel RHS) {
- swap(*this, RHS);
- return *this;
- }
-
- /// \brief The model bases invalidation solely on being in the preserved set.
- //
- // FIXME: We should actually use two different concepts for analysis results
- // rather than two different models, and avoid the indirect function call for
- // ones that use the trivial behavior.
- bool invalidate(IRUnitT, const PreservedAnalyses &PA) override {
- return !PA.preserved(PassT::ID());
- }
-
- ResultT Result;
-};
-
-/// \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> {
- explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
- AnalysisResultModel(AnalysisResultModel &&Arg)
- : Result(std::move(Arg.Result)) {}
- friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
- using std::swap;
- swap(LHS.Result, RHS.Result);
- }
- AnalysisResultModel &operator=(AnalysisResultModel RHS) {
- swap(*this, RHS);
- return *this;
- }
-
- /// \brief The model delegates to the \c ResultT method.
- bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) override {
- return Result.invalidate(IR, PA);
- }
-
- ResultT Result;
-};
-
-/// \brief Abstract concept of an analysis pass.
-///
-/// This concept is parameterized over the IR unit that it can run over and
-/// produce an analysis result.
-template <typename IRUnitT, typename AnalysisManagerT>
-struct AnalysisPassConcept {
- virtual ~AnalysisPassConcept() {}
-
- /// \brief Method to run this analysis over a unit of IR.
- /// \returns A unique_ptr to the analysis result object to be queried by
- /// users.
- virtual std::unique_ptr<AnalysisResultConcept<IRUnitT>>
- run(IRUnitT IR, AnalysisManagerT *AM) = 0;
-};
-
-/// \brief Wrapper to model the analysis pass concept.
-///
-/// Can wrap any type which implements a suitable \c run method. The method
-/// must accept the IRUnitT as an argument and produce an object which can be
-/// wrapped in a \c AnalysisResultModel.
-template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
- bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
- IRUnitT, AnalysisManagerT, PassT, typename PassT::Result>::Value>
-struct AnalysisPassModel;
-
-/// \brief Specialization of \c AnalysisPassModel which passes an
-/// \c AnalysisManager to PassT's run method.
-template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
-struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT, true>
- : AnalysisPassConcept<IRUnitT, AnalysisManagerT> {
- explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}