[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / libc / test / UnitTest / ErrnoSetterMatcher.h
blobb748c29751c328367649ed81d684b95f55a39713
1 //===-- ErrnoSetterMatcher.h ------------------------------------*- C++ -*-===//
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_LIBC_TEST_ERRNOSETTERMATCHER_H
10 #define LLVM_LIBC_TEST_ERRNOSETTERMATCHER_H
12 #include "src/__support/FPUtil/FPBits.h"
13 #include "src/__support/FPUtil/fpbits_str.h"
14 #include "src/__support/StringUtil/error_to_string.h"
15 #include "src/__support/macros/properties/architectures.h"
16 #include "src/errno/libc_errno.h"
17 #include "test/UnitTest/Test.h"
19 namespace LIBC_NAMESPACE {
20 namespace testing {
22 namespace internal {
24 enum class CompareAction { EQ = 0, GE, GT, LE, LT, NE };
26 constexpr const char *CompareMessage[] = {
27 "equal to", "greater than or equal to",
28 "greater than", "less than or equal to",
29 "less than", "not equal to"};
31 template <typename T> struct Comparator {
32 CompareAction cmp;
33 T expected;
34 bool compare(T actual) {
35 switch (cmp) {
36 case CompareAction::EQ:
37 return actual == expected;
38 case CompareAction::NE:
39 return actual != expected;
40 case CompareAction::GE:
41 return actual >= expected;
42 case CompareAction::GT:
43 return actual > expected;
44 case CompareAction::LE:
45 return actual <= expected;
46 case CompareAction::LT:
47 return actual < expected;
49 __builtin_unreachable();
52 // The NVPTX backend cannot handle circular dependencies on global variables.
53 // We provide a constant dummy implementation to prevent this from occurring.
54 #ifdef LIBC_TARGET_ARCH_IS_NVPTX
55 constexpr const char *str() { return ""; }
56 #else
57 const char *str() { return CompareMessage[static_cast<int>(cmp)]; }
58 #endif
61 template <typename T> class ErrnoSetterMatcher : public Matcher<T> {
62 Comparator<T> return_cmp;
63 Comparator<int> errno_cmp;
64 T actual_return;
65 int actual_errno;
67 // Even though this is a errno matcher primarily, it has to cater to platforms
68 // which do not have an errno. This predicate checks if errno matching is to
69 // be skipped.
70 static constexpr bool ignore_errno() {
71 #ifdef LIBC_TARGET_ARCH_IS_GPU
72 return true;
73 #else
74 return false;
75 #endif
78 public:
79 ErrnoSetterMatcher(Comparator<T> rcmp) : return_cmp(rcmp) {}
80 ErrnoSetterMatcher(Comparator<T> rcmp, Comparator<int> ecmp)
81 : return_cmp(rcmp), errno_cmp(ecmp) {}
83 ErrnoSetterMatcher<T> with_errno(Comparator<int> ecmp) {
84 errno_cmp = ecmp;
85 return *this;
88 void explainError() override {
89 if (!return_cmp.compare(actual_return)) {
90 if constexpr (cpp::is_floating_point_v<T>) {
91 tlog << "Expected return value to be " << return_cmp.str() << ": "
92 << str(fputil::FPBits<T>(return_cmp.expected)) << '\n'
93 << " But got: "
94 << str(fputil::FPBits<T>(actual_return)) << '\n';
95 } else {
96 tlog << "Expected return value to be " << return_cmp.str() << " "
97 << return_cmp.expected << " but got " << actual_return << ".\n";
101 if constexpr (!ignore_errno()) {
102 if (!errno_cmp.compare(actual_errno)) {
103 tlog << "Expected errno to be " << errno_cmp.str() << " \""
104 << get_error_string(errno_cmp.expected) << "\" but got \""
105 << get_error_string(actual_errno) << "\".\n";
110 bool match(T got) {
111 actual_return = got;
112 actual_errno = libc_errno;
113 libc_errno = 0;
114 if constexpr (ignore_errno())
115 return return_cmp.compare(actual_return);
116 else
117 return return_cmp.compare(actual_return) &&
118 errno_cmp.compare(actual_errno);
122 } // namespace internal
124 namespace ErrnoSetterMatcher {
126 template <typename T> internal::Comparator<T> LT(T val) {
127 return internal::Comparator<T>{internal::CompareAction::LT, val};
130 template <typename T> internal::Comparator<T> LE(T val) {
131 return internal::Comparator<T>{internal::CompareAction::LE, val};
134 template <typename T> internal::Comparator<T> GT(T val) {
135 return internal::Comparator<T>{internal::CompareAction::GT, val};
138 template <typename T> internal::Comparator<T> GE(T val) {
139 return internal::Comparator<T>{internal::CompareAction::GE, val};
142 template <typename T> internal::Comparator<T> EQ(T val) {
143 return internal::Comparator<T>{internal::CompareAction::EQ, val};
146 template <typename T> internal::Comparator<T> NE(T val) {
147 return internal::Comparator<T>{internal::CompareAction::NE, val};
150 template <typename RetT = int>
151 static internal::ErrnoSetterMatcher<RetT> Succeeds(RetT ExpectedReturn = 0,
152 int ExpectedErrno = 0) {
153 return internal::ErrnoSetterMatcher<RetT>(EQ(ExpectedReturn),
154 EQ(ExpectedErrno));
157 template <typename RetT = int>
158 static internal::ErrnoSetterMatcher<RetT> Fails(int ExpectedErrno,
159 RetT ExpectedReturn = -1) {
160 return internal::ErrnoSetterMatcher<RetT>(EQ(ExpectedReturn),
161 EQ(ExpectedErrno));
164 template <typename RetT>
165 static internal::ErrnoSetterMatcher<RetT>
166 returns(internal::Comparator<RetT> cmp) {
167 return internal::ErrnoSetterMatcher<RetT>(cmp);
170 } // namespace ErrnoSetterMatcher
172 } // namespace testing
173 } // namespace LIBC_NAMESPACE
175 #endif // LLVM_LIBC_TEST_ERRNOSETTERMATCHER_H