[InstCombine] Signed saturation patterns
[llvm-core.git] / include / llvm / Testing / Support / Error.h
blob85328f26440ba65e1ec20c91e00e5bccbc49297a
1 //===- llvm/Testing/Support/Error.h ---------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_TESTING_SUPPORT_ERROR_H
10 #define LLVM_TESTING_SUPPORT_ERROR_H
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/Support/Error.h"
14 #include "llvm/Testing/Support/SupportHelpers.h"
16 #include "gmock/gmock.h"
17 #include <ostream>
19 namespace llvm {
20 namespace detail {
21 ErrorHolder TakeError(Error Err);
23 template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &Exp) {
24 return {TakeError(Exp.takeError()), Exp};
27 template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &&Exp) {
28 return TakeExpected(Exp);
31 template <typename T>
32 class ValueMatchesMono
33 : public testing::MatcherInterface<const ExpectedHolder<T> &> {
34 public:
35 explicit ValueMatchesMono(const testing::Matcher<T> &Matcher)
36 : Matcher(Matcher) {}
38 bool MatchAndExplain(const ExpectedHolder<T> &Holder,
39 testing::MatchResultListener *listener) const override {
40 if (!Holder.Success())
41 return false;
43 bool result = Matcher.MatchAndExplain(*Holder.Exp, listener);
45 if (result)
46 return result;
47 *listener << "(";
48 Matcher.DescribeNegationTo(listener->stream());
49 *listener << ")";
50 return result;
53 void DescribeTo(std::ostream *OS) const override {
54 *OS << "succeeded with value (";
55 Matcher.DescribeTo(OS);
56 *OS << ")";
59 void DescribeNegationTo(std::ostream *OS) const override {
60 *OS << "did not succeed or value (";
61 Matcher.DescribeNegationTo(OS);
62 *OS << ")";
65 private:
66 testing::Matcher<T> Matcher;
69 template<typename M>
70 class ValueMatchesPoly {
71 public:
72 explicit ValueMatchesPoly(const M &Matcher) : Matcher(Matcher) {}
74 template <typename T>
75 operator testing::Matcher<const ExpectedHolder<T> &>() const {
76 return MakeMatcher(
77 new ValueMatchesMono<T>(testing::SafeMatcherCast<T>(Matcher)));
80 private:
81 M Matcher;
84 template <typename InfoT>
85 class ErrorMatchesMono : public testing::MatcherInterface<const ErrorHolder &> {
86 public:
87 explicit ErrorMatchesMono(Optional<testing::Matcher<InfoT &>> Matcher)
88 : Matcher(std::move(Matcher)) {}
90 bool MatchAndExplain(const ErrorHolder &Holder,
91 testing::MatchResultListener *listener) const override {
92 if (Holder.Success())
93 return false;
95 if (Holder.Infos.size() > 1) {
96 *listener << "multiple errors";
97 return false;
100 auto &Info = *Holder.Infos[0];
101 if (!Info.isA<InfoT>()) {
102 *listener << "Error was not of given type";
103 return false;
106 if (!Matcher)
107 return true;
109 return Matcher->MatchAndExplain(static_cast<InfoT &>(Info), listener);
112 void DescribeTo(std::ostream *OS) const override {
113 *OS << "failed with Error of given type";
114 if (Matcher) {
115 *OS << " and the error ";
116 Matcher->DescribeTo(OS);
120 void DescribeNegationTo(std::ostream *OS) const override {
121 *OS << "succeeded or did not fail with the error of given type";
122 if (Matcher) {
123 *OS << " or the error ";
124 Matcher->DescribeNegationTo(OS);
128 private:
129 Optional<testing::Matcher<InfoT &>> Matcher;
131 } // namespace detail
133 #define EXPECT_THAT_ERROR(Err, Matcher) \
134 EXPECT_THAT(llvm::detail::TakeError(Err), Matcher)
135 #define ASSERT_THAT_ERROR(Err, Matcher) \
136 ASSERT_THAT(llvm::detail::TakeError(Err), Matcher)
138 #define EXPECT_THAT_EXPECTED(Err, Matcher) \
139 EXPECT_THAT(llvm::detail::TakeExpected(Err), Matcher)
140 #define ASSERT_THAT_EXPECTED(Err, Matcher) \
141 ASSERT_THAT(llvm::detail::TakeExpected(Err), Matcher)
143 MATCHER(Succeeded, "") { return arg.Success(); }
144 MATCHER(Failed, "") { return !arg.Success(); }
146 template <typename InfoT>
147 testing::Matcher<const detail::ErrorHolder &> Failed() {
148 return MakeMatcher(new detail::ErrorMatchesMono<InfoT>(None));
151 template <typename InfoT, typename M>
152 testing::Matcher<const detail::ErrorHolder &> Failed(M Matcher) {
153 return MakeMatcher(new detail::ErrorMatchesMono<InfoT>(
154 testing::SafeMatcherCast<InfoT &>(Matcher)));
157 template <typename M>
158 detail::ValueMatchesPoly<M> HasValue(M Matcher) {
159 return detail::ValueMatchesPoly<M>(Matcher);
162 } // namespace llvm
164 #endif