1//===-- Implementation header for libc_errno --------------------*- 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//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIBC_SRC___SUPPORT_LIBC_ERRNO_H
10#define LLVM_LIBC_SRC___SUPPORT_LIBC_ERRNO_H
11
12// This header is to be consumed by internal implementations, in which all of
13// them should refer to `libc_errno` instead of using `errno` directly from
14// <errno.h> header.
15
16// Unit and hermetic tests should:
17// - #include "src/__support/libc_errno.h"
18// - NOT #include <errno.h>
19// - Only use `libc_errno` in the code
20// - Depend on libc.src.errno.errno
21
22// Integration tests should:
23// - NOT #include "src/__support/libc_errno.h"
24// - #include <errno.h>
25// - Use regular `errno` in the code
26// - Still depend on libc.src.errno.errno
27
28// libc uses a fallback default value, either system or thread local.
29#define LIBC_ERRNO_MODE_DEFAULT 0
30// libc never stores a value; `errno` macro uses get link-time failure.
31#define LIBC_ERRNO_MODE_UNDEFINED 1
32// libc maintains per-thread state (requires C++ `thread_local` support).
33#define LIBC_ERRNO_MODE_THREAD_LOCAL 2
34// libc maintains shared state used by all threads, contrary to standard C
35// semantics unless always single-threaded; nothing prevents data races.
36#define LIBC_ERRNO_MODE_SHARED 3
37// libc doesn't maintain any internal state, instead the embedder must define
38// `int *__llvm_libc_errno(void);` C function.
39#define LIBC_ERRNO_MODE_EXTERNAL 4
40// DEPRECATED: #define LIBC_ERRNO_MODE_SYSTEM 5
41// In this mode, the libc_errno is simply a macro resolved to `errno` from the
42// system header <errno.h>. There is no need to link against the
43// `libc.src.errno.errno` object, and public C++ symbol
44// `LIBC_NAMESPACE::libc_errno` doesn't exist.
45#define LIBC_ERRNO_MODE_SYSTEM_INLINE 6
46
47#if !defined(LIBC_ERRNO_MODE) || LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_DEFAULT
48#undef LIBC_ERRNO_MODE
49#if defined(LIBC_FULL_BUILD) || !defined(LIBC_COPT_PUBLIC_PACKAGING)
50#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_THREAD_LOCAL
51#else
52#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM_INLINE
53#endif
54#endif // LIBC_ERRNO_MODE
55
56#if LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_DEFAULT && \
57 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_UNDEFINED && \
58 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_THREAD_LOCAL && \
59 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SHARED && \
60 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_EXTERNAL && \
61 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM_INLINE
62#error LIBC_ERRNO_MODE must be one of the following values: \
63LIBC_ERRNO_MODE_DEFAULT, \
64LIBC_ERRNO_MODE_UNDEFINED, \
65LIBC_ERRNO_MODE_THREAD_LOCAL, \
66LIBC_ERRNO_MODE_SHARED, \
67LIBC_ERRNO_MODE_EXTERNAL, \
68LIBC_ERRNO_MODE_SYSTEM_INLINE.
69#endif
70
71#if LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_SYSTEM_INLINE
72
73#include <errno.h>
74
75#define libc_errno errno
76
77#else // !LIBC_ERRNO_MODE_SYSTEM_INLINE
78
79#include "hdr/errno_macros.h"
80#include "src/__support/macros/config.h"
81
82namespace LIBC_NAMESPACE_DECL {
83
84extern "C" int *__llvm_libc_errno() noexcept;
85
86struct Errno {
87 void operator=(int);
88 operator int();
89};
90
91extern Errno libc_errno;
92
93} // namespace LIBC_NAMESPACE_DECL
94
95using LIBC_NAMESPACE::libc_errno;
96
97#endif // LIBC_ERRNO_MODE_SYSTEM_INLINE
98
99#endif // LLVM_LIBC_SRC___SUPPORT_LIBC_ERRNO_H
100