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 // libc uses system `<errno.h>` `errno` macro directly in the overlay mode; in 41 // fullbuild mode, effectively the same as `LIBC_ERRNO_MODE_EXTERNAL`. 42 // In this mode, the public C++ symbol `LIBC_NAMESPACE::libc_errno ` is still 43 // exported and get redirected to the system `errno` inside its implementation. 44 45 // TODO: Investigate deprecating LIBC_ERRNO_MODE_SYSTEM in favor of 46 // LIBC_ERRNO_MODE_SYSTEM_INLINE. 47 // https://github.com/llvm/llvm-project/issues/143454 48 #define LIBC_ERRNO_MODE_SYSTEM 5 49 // In this mode, the libc_errno is simply a macro resolved to `errno` from the 50 // system header <errno.h>. There is no need to link against the 51 // `libc.src.errno.errno` object. 52 #define LIBC_ERRNO_MODE_SYSTEM_INLINE 6 53 54 #if !defined(LIBC_ERRNO_MODE) || LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_DEFAULT 55 #undef LIBC_ERRNO_MODE 56 #if defined(LIBC_FULL_BUILD) || !defined(LIBC_COPT_PUBLIC_PACKAGING) 57 #define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_THREAD_LOCAL 58 #else 59 #define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM 60 #endif 61 #endif // LIBC_ERRNO_MODE 62 63 #if LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_DEFAULT && \ 64 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_UNDEFINED && \ 65 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_THREAD_LOCAL && \ 66 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SHARED && \ 67 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_EXTERNAL && \ 68 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM && \ 69 LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM_INLINE 70 #error LIBC_ERRNO_MODE must be one of the following values: \ 71 LIBC_ERRNO_MODE_DEFAULT, \ 72 LIBC_ERRNO_MODE_UNDEFINED, \ 73 LIBC_ERRNO_MODE_THREAD_LOCAL, \ 74 LIBC_ERRNO_MODE_SHARED, \ 75 LIBC_ERRNO_MODE_EXTERNAL, \ 76 LIBC_ERRNO_MODE_SYSTEM, \ 77 LIBC_ERRNO_MODE_SYSTEM_INLINE. 78 #endif 79 80 #if LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_SYSTEM_INLINE 81 82 #include <errno.h> 83 84 #define libc_errno errno 85 86 #else // !LIBC_ERRNO_MODE_SYSTEM_INLINE 87 88 #include "hdr/errno_macros.h" 89 #include "src/__support/macros/config.h" 90 91 namespace LIBC_NAMESPACE_DECL { 92 93 extern "C" int *__llvm_libc_errno() noexcept; 94 95 struct Errno { 96 void operator=(int); 97 operator int(); 98 }; 99 100 extern Errno libc_errno; 101 102 } // namespace LIBC_NAMESPACE_DECL 103 104 using LIBC_NAMESPACE::libc_errno; 105 106 #endif // LIBC_ERRNO_MODE_SYSTEM_INLINE 107 108 #endif // LLVM_LIBC_SRC___SUPPORT_LIBC_ERRNO_H 109