include "config/public_api.td"
+include "spec/linux.td"
+include "spec/posix.td"
include "spec/stdc.td"
def FloatT : TypeDecl<"float_t"> {
}];
}
+def ErrnoMacro : MacroDef<"errno"> {
+ let Defn = [{
+ int *__errno_location();
+ #define errno (*__errno_location())
+ }];
+}
+
def MathAPI : PublicAPI<"math.h"> {
let Functions = [
"acos",
"snprintf",
];
}
+
+def ErrnoAPI : PublicAPI<"errno.h"> {
+ let Macros = [
+ ErrnoMacro,
+ // We largely depend on linux/errno.h to give us the
+ // various error macro definitions. However, some libc
+ // implementations have chosen to provide definitions
+ // for some of the error macros to account for the ones
+ // missing in linux/errno.h. There is no harm in doing
+ // the same here if we define the macros only when they
+ // are not already defined.
+ MacroDefineIfNot<"ENOTSUP", "EOPNOTSUPP">,
+ MacroDefineIfNot<"ECANCELED", "125">,
+ MacroDefineIfNot<"EOWNERDEAD", "130">,
+ MacroDefineIfNot<"ENOTRECOVERABLE", "131">,
+ MacroDefineIfNot<"ERFKILL", "132">,
+ MacroDefineIfNot<"EHWPOISON", "133">,
+ ];
+}
--- /dev/null
+//===---------------- Linux specific errno.h definitions ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+%%begin()
+
+#include <linux/errno.h>
string Defn = "";
}
+class SimpleMacroDef<string name, string value> : MacroDef<name> {
+ let Defn = !strconcat("#define ", name, " ", value);
+}
+
+class MacroDefineIfNot<string name, string value> : MacroDef<name> {
+ let Defn = !strconcat("#ifndef ", name, "\n",
+ "#define " , name, " ", value, "\n",
+ "#endif // ", name);
+}
+
class PublicAPI<string name> {
string HeaderName = name;
list<MacroDef> Macros = [];
DEPENDS
llvm_libc_common_h
)
+
+add_gen_header(
+ errno_h
+ DEF_FILE errno.h.def
+ PARAMS
+ platform_errno=../config/${LIBC_TARGET_OS}/errno.h.in
+ GEN_HDR errno.h
+ DATA_FILES
+ ../config/${LIBC_TARGET_OS}/errno.h.in
+)
--- /dev/null
+//===---------------- C standard library header errno.h ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_ERRNO_H
+#define LLVM_LIBC_ERRNO_H
+
+#include <__llvm-libc-common.h>
+
+%%include_file(${platform_errno})
+
+%%public_api()
+
+#endif // LLVM_LIBC_ERRNO_H
add_entrypoint_library(
llvmlibc
DEPENDS
+ # errno.h entrypoints
+ __errno_location
+
# string.h entrypoints
- ## C standard library entrypoints
strcpy
strcat
)
--- /dev/null
+def Linux : StandardSpec<"Linux"> {
+ HeaderSpec Errno = HeaderSpec<
+ "errno.h",
+ [
+ Macro<"ENOMEDIUM">,
+ Macro<"ENOTBLK">,
+ Macro<"EMEDIUMTYPE">,
+ Macro<"EBADSLT">,
+ Macro<"ECHRNG">,
+ Macro<"ERFKILL">,
+ Macro<"EUSERS">,
+ Macro<"EBADR">,
+ Macro<"EL3HLT">,
+ Macro<"ENOTUNIQ">,
+ Macro<"EXFULL">,
+ Macro<"EHOSTDOWN">,
+ Macro<"EL3RST">,
+ Macro<"ENOPKG">,
+ Macro<"ENOCSI">,
+ Macro<"EUNATCH">,
+ Macro<"EREMCHG">,
+ Macro<"ETOOMANYREFS">,
+ Macro<"EL2HLT">,
+ Macro<"EBADFD">,
+ Macro<"EREMOTEIO">,
+ Macro<"ENAVAIL">,
+ Macro<"ELIBEXEC">,
+ Macro<"ESHUTDOWN">,
+ Macro<"ENOKEY">,
+ Macro<"ESTRPIPE">,
+ Macro<"EKEYREJECTED">,
+ Macro<"ESRMNT">,
+ Macro<"EKEYREVOKED">,
+ Macro<"EBADE">,
+ Macro<"ELIBBAD">,
+ Macro<"EISNAM">,
+ Macro<"EBFONT">,
+ Macro<"EPFNOSUPPORT">,
+ Macro<"EREMOTE">,
+ Macro<"EDEADLOCK">,
+ Macro<"ENONET">,
+ Macro<"EDOTDOT">,
+ Macro<"EKEYEXPIRED">,
+ Macro<"ELIBSCN">,
+ Macro<"ERESTART">,
+ Macro<"EBADRQC">,
+ Macro<"EUCLEAN">,
+ Macro<"ENOANO">,
+ Macro<"ELIBACC">,
+ Macro<"EHWPOISON">,
+ Macro<"ELIBMAX">,
+ Macro<"ESOCKTNOSUPPORT">,
+ Macro<"ENOTNAM">,
+ Macro<"ELNRNG">,
+ Macro<"EL2NSYNC">,
+ Macro<"EADV">,
+ Macro<"ECOMM">,
+ ],
+ [], // Types
+ [] // Functions
+ >;
+
+ let Headers = [
+ Errno,
+ ];
+}
--- /dev/null
+def POSIX : StandardSpec<"POSIX"> {
+ HeaderSpec Errno = HeaderSpec<
+ "errno.h",
+ [
+ Macro<"E2BIG">,
+ Macro<"EACCES">,
+ Macro<"EADDRINUSE">,
+ Macro<"EADDRNOTAVAIL">,
+ Macro<"EAFNOSUPPORT">,
+ Macro<"EAGAIN">,
+ Macro<"EALREADY">,
+ Macro<"EBADF">,
+ Macro<"EBADMSG">,
+ Macro<"EBUSY">,
+ Macro<"ECANCELED">,
+ Macro<"ECHILD">,
+ Macro<"ECONNABORTED">,
+ Macro<"ECONNREFUSED">,
+ Macro<"ECONNRESET">,
+ Macro<"EDEADLK">,
+ Macro<"EDESTADDRREQ">,
+ Macro<"EDQUOT">,
+ Macro<"EEXIST">,
+ Macro<"EFAULT">,
+ Macro<"EFBIG">,
+ Macro<"EHOSTUNREACH">,
+ Macro<"EIDRM">,
+ Macro<"EINPROGRESS">,
+ Macro<"EINTR">,
+ Macro<"EINVAL">,
+ Macro<"EIO">,
+ Macro<"EISCONN">,
+ Macro<"EISDIR">,
+ Macro<"ELOOP">,
+ Macro<"EMFILE">,
+ Macro<"EMLINK">,
+ Macro<"EMSGSIZE">,
+ Macro<"EMULTIHOP">,
+ Macro<"ENAMETOOLONG">,
+ Macro<"ENETDOWN">,
+ Macro<"ENETRESET">,
+ Macro<"ENETUNREACH">,
+ Macro<"ENFILE">,
+ Macro<"ENOBUFS">,
+ Macro<"ENODATA">,
+ Macro<"ENODEV">,
+ Macro<"ENOENT">,
+ Macro<"ENOEXEC">,
+ Macro<"ENOLCK">,
+ Macro<"ENOLINK">,
+ Macro<"ENOMEM">,
+ Macro<"ENOMSG">,
+ Macro<"ENOPROTOOPT">,
+ Macro<"ENOSPC">,
+ Macro<"ENOSR">,
+ Macro<"ENOSTR">,
+ Macro<"ENOSYS">,
+ Macro<"ENOTCONN">,
+ Macro<"ENOTDIR">,
+ Macro<"ENOTEMPTY">,
+ Macro<"ENOTRECOVERABLE">,
+ Macro<"ENOTSOCK">,
+ Macro<"ENOTSUP">,
+ Macro<"ENOTTY">,
+ Macro<"ENXIO">,
+ Macro<"EOPNOTSUPP">,
+ Macro<"EOVERFLOW">,
+ Macro<"EOWNERDEAD">,
+ Macro<"EPERM">,
+ Macro<"EPIPE">,
+ Macro<"EPROTO">,
+ Macro<"EPROTONOSUPPORT">,
+ Macro<"EPROTOTYPE">,
+ Macro<"EROFS">,
+ Macro<"ESPIPE">,
+ Macro<"ESRCH">,
+ Macro<"ESTALE">,
+ Macro<"ETIME">,
+ Macro<"ETIMEDOUT">,
+ Macro<"ETXTBSY">,
+ Macro<"EWOULDBLOCK">,
+ Macro<"EXDEV">,
+ ],
+ [], // Types
+ [] // Functions
+ >;
+
+ let Headers = [
+ Errno,
+ ];
+}
]
>;
+ HeaderSpec Errno = HeaderSpec<
+ "errno.h",
+ [
+ Macro<"errno">,
+ Macro<"EDOM">,
+ Macro<"EILSEQ">,
+ Macro<"ERANGE">,
+ ],
+ [], // Types
+ [] // Functions
+ >;
+
let Headers = [
+ Errno,
Math,
String,
StdIO,
-add_subdirectory(string)
+add_subdirectory(errno)
add_subdirectory(math)
+add_subdirectory(string)
add_subdirectory(__support)
--- /dev/null
+add_entrypoint_object(
+ __errno_location
+ SRCS
+ errno_location.cpp
+ HDRS
+ llvmlibc_errno.h
+)
+
+add_custom_target(libc_errno_unittests)
+
+add_libc_unittest(
+ errno_test
+ SUITE
+ libc_errno_unittests
+ SRCS
+ errno_test.cpp
+ DEPENDS
+ __errno_location
+)
--- /dev/null
+//===----------------- Implementation of __errno_location -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/llvmlibc_errno.h"
+
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+static thread_local int __errno = 0;
+
+// __errno_location is not really an entry point but we still want it to behave
+// like an entry point because the errno macro resolves to the C symbol
+// "__errno_location".
+int *LLVM_LIBC_ENTRYPOINT(__errno_location)() { return &__errno; }
+
+} // namespace __llvm_libc
--- /dev/null
+//===---------------------- Unittests for errno --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/llvmlibc_errno.h"
+
+#include "gtest/gtest.h"
+
+TEST(ErrnoTest, Basic) {
+ int test_val = 123;
+ llvmlibc_errno = test_val;
+ ASSERT_EQ(test_val, llvmlibc_errno);
+}
--- /dev/null
+//===------------------ Implementation header for errno -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H
+#define LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H
+
+// Internal code should use this and not use the errno macro from the
+// public header.
+#define llvmlibc_errno (*__llvm_libc::__errno_location())
+
+namespace __llvm_libc {
+
+int *__errno_location();
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H