llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Petr Hosek (petrhosek)

<details>
<summary>Changes</summary>

This change expands the stdio support on baremetal to support opaque FILE*. 
This builds on top of the existing baremetal embedding API; we treat the 
standard FILE* streams as pointers that point to the cookie symbols which are a 
part of the embedding API. This also allows users to define their own FILE* 
streams, but we don't (yet) support the API that return FILE* such as fopen or 
fopencookie.

---

Patch is 33.69 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/168931.diff


23 Files Affected:

- (modified) clang/cmake/caches/Fuchsia-stage2.cmake (+4-2) 
- (modified) libc/config/baremetal/aarch64/entrypoints.txt (+8) 
- (modified) libc/config/baremetal/arm/entrypoints.txt (+8) 
- (modified) libc/config/baremetal/riscv/entrypoints.txt (+8) 
- (modified) libc/src/__support/OSUtil/baremetal/io.cpp (+4-38) 
- (modified) libc/src/__support/OSUtil/baremetal/io.h (+39) 
- (modified) libc/src/stdio/baremetal/CMakeLists.txt (+133-18) 
- (added) libc/src/stdio/baremetal/feof.cpp (+24) 
- (added) libc/src/stdio/baremetal/ferror.cpp (+23) 
- (added) libc/src/stdio/baremetal/fgetc.cpp () 
- (added) libc/src/stdio/baremetal/fgets.cpp () 
- (added) libc/src/stdio/baremetal/fprintf.cpp (+34) 
- (added) libc/src/stdio/baremetal/fputc.cpp (+22) 
- (added) libc/src/stdio/baremetal/fputc_internal.h (+29) 
- (added) libc/src/stdio/baremetal/fputs.cpp (+23) 
- (added) libc/src/stdio/baremetal/fputs_internal.h (+29) 
- (added) libc/src/stdio/baremetal/fwrite_internal.h (+27) 
- (modified) libc/src/stdio/baremetal/printf.cpp (+4-42) 
- (modified) libc/src/stdio/baremetal/putchar.cpp (+5-8) 
- (modified) libc/src/stdio/baremetal/puts.cpp (+3-9) 
- (added) libc/src/stdio/baremetal/vfprintf.cpp (+30) 
- (added) libc/src/stdio/baremetal/vfprintf_internal.h (+69) 
- (modified) libc/src/stdio/baremetal/vprintf.cpp (+4-43) 


``````````diff
diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake 
b/clang/cmake/caches/Fuchsia-stage2.cmake
index be3d0cfa2e657..1e7b3e1b71373 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -341,7 +341,7 @@ foreach(target 
armv6m-none-eabi;armv7m-none-eabi;armv7em-none-eabi;armv8m.main-n
   foreach(lang C;CXX;ASM)
     # TODO: The preprocessor defines workaround various issues in libc and 
libc++ integration.
     # These should be addressed and removed over time.
-    set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} 
-Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, 
vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dfputs(string, 
stream)=puts(string)\" -D_LIBCPP_PRINT=1")
+    set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} 
-Wno-atomic-alignment")
     if(NOT ${target} STREQUAL "aarch64-none-elf")
       set(RUNTIMES_${target}_CMAKE_${lang}_local_flags 
"${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mthumb")
     endif()
@@ -372,6 +372,7 @@ foreach(target 
armv6m-none-eabi;armv7m-none-eabi;armv7em-none-eabi;armv8m.main-n
   set(RUNTIMES_${target}_LIBCXX_ENABLE_RTTI OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")
+  set(RUNTIMES_${target}_LIBCXX_HAS_TERMINAL_AVAILABLE OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
   set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "")
@@ -406,7 +407,7 @@ foreach(target riscv32-unknown-elf)
   foreach(lang C;CXX;ASM)
     # TODO: The preprocessor defines workaround various issues in libc and 
libc++ integration.
     # These should be addressed and removed over time.
-    set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} 
-march=rv32imafc -mabi=ilp32f -Wno-atomic-alignment \"-Dvfprintf(stream, 
format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, 
...)=printf(format)\" \"-Dfputs(string, stream)=puts(string)\" 
-D_LIBCPP_PRINT=1" CACHE STRING "")
+    set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} 
-march=rv32imafc -mabi=ilp32f -Wno-atomic-alignment" CACHE STRING "")
   endforeach()
   foreach(type SHARED;MODULE;EXE)
     set(RUNTIMES_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE 
STRING "")
@@ -427,6 +428,7 @@ foreach(target riscv32-unknown-elf)
   set(RUNTIMES_${target}_LIBCXX_ENABLE_RTTI OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")
+  set(RUNTIMES_${target}_LIBCXX_HAS_TERMINAL_AVAILABLE OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
   set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "")
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt 
b/libc/config/baremetal/aarch64/entrypoints.txt
index c69ab3d0bb37c..4c6b6dfc4d669 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -124,8 +124,15 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # stdio.h entrypoints
     libc.src.stdio.asprintf
+    libc.src.stdio.feof
+    libc.src.stdio.ferror
+    libc.src.stdio.fprintf
+    libc.src.stdio.fputc
+    libc.src.stdio.fputs
+    libc.src.stdio.fwrite
     libc.src.stdio.getchar
     libc.src.stdio.printf
+    libc.src.stdio.putc
     libc.src.stdio.putchar
     libc.src.stdio.puts
     libc.src.stdio.remove
@@ -134,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.sprintf
     libc.src.stdio.sscanf
     libc.src.stdio.vasprintf
+    libc.src.stdio.vfprintf
     libc.src.stdio.vprintf
     libc.src.stdio.vscanf
     libc.src.stdio.vsnprintf
diff --git a/libc/config/baremetal/arm/entrypoints.txt 
b/libc/config/baremetal/arm/entrypoints.txt
index c566f8ad08c8e..0847a0905a6f7 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -124,8 +124,15 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # stdio.h entrypoints
     libc.src.stdio.asprintf
+    libc.src.stdio.feof
+    libc.src.stdio.ferror
+    libc.src.stdio.fprintf
+    libc.src.stdio.fputc
+    libc.src.stdio.fputs
+    libc.src.stdio.fwrite
     libc.src.stdio.getchar
     libc.src.stdio.printf
+    libc.src.stdio.putc
     libc.src.stdio.putchar
     libc.src.stdio.puts
     libc.src.stdio.remove
@@ -134,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.sprintf
     libc.src.stdio.sscanf
     libc.src.stdio.vasprintf
+    libc.src.stdio.vfprintf
     libc.src.stdio.vprintf
     libc.src.stdio.vscanf
     libc.src.stdio.vsnprintf
diff --git a/libc/config/baremetal/riscv/entrypoints.txt 
b/libc/config/baremetal/riscv/entrypoints.txt
index a6aef96e91698..9a5c73b81e87f 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -124,8 +124,15 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # stdio.h entrypoints
     libc.src.stdio.asprintf
+    libc.src.stdio.feof
+    libc.src.stdio.ferror
+    libc.src.stdio.fprintf
+    libc.src.stdio.fputc
+    libc.src.stdio.fputs
+    libc.src.stdio.fwrite
     libc.src.stdio.getchar
     libc.src.stdio.printf
+    libc.src.stdio.putc
     libc.src.stdio.putchar
     libc.src.stdio.puts
     libc.src.stdio.remove
@@ -134,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.sprintf
     libc.src.stdio.sscanf
     libc.src.stdio.vasprintf
+    libc.src.stdio.vfprintf
     libc.src.stdio.vprintf
     libc.src.stdio.vscanf
     libc.src.stdio.vsnprintf
diff --git a/libc/src/__support/OSUtil/baremetal/io.cpp 
b/libc/src/__support/OSUtil/baremetal/io.cpp
index 2a9ef6bfa6579..2978d701017a5 100644
--- a/libc/src/__support/OSUtil/baremetal/io.cpp
+++ b/libc/src/__support/OSUtil/baremetal/io.cpp
@@ -8,49 +8,15 @@
 
 #include "io.h"
 
+#include "hdr/types/FILE.h"
 #include "src/__support/CPP/string_view.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
-// These are intended to be provided by the vendor.
-//
-// The signature of these types and functions intentionally match `fopencookie`
-// which allows the following:
-//
-// ```
-// struct __llvm_libc_stdio_cookie { ... };
-// ...
-// struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
-// cookie_io_functions_t stdin_func = { .read = __llvm_libc_stdio_read };
-// FILE *stdin = fopencookie(&__llvm_libc_stdin_cookie, "r", stdin_func);
-// ...
-// struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
-// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write };
-// FILE *stdout = fopencookie(&__llvm_libc_stdout_cookie, "w", stdout_func);
-// ...
-// struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
-// cookie_io_functions_t stderr_func = { .write = __llvm_libc_stdio_write };
-// FILE *stderr = fopencookie(&__llvm_libc_stderr_cookie, "w", stderr_func);
-// ```
-//
-// At the same time, implementation of functions like `printf` and `scanf` can
-// use `__llvm_libc_stdio_read` and `__llvm_libc_stdio_write` directly to avoid
-// the extra indirection.
-//
-// All three symbols `__llvm_libc_stdin_cookie`, `__llvm_libc_stdout_cookie`,
-// and `__llvm_libc_stderr_cookie` must be provided, even if they don't point
-// at anything.
-
-struct __llvm_libc_stdio_cookie;
-
-extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
-extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
-extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
-
-extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t 
size);
-extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf,
-                                           size_t size);
+extern "C" FILE *stdin = reinterpret_cast<FILE *>(&__llvm_libc_stdin_cookie);
+extern "C" FILE *stdout = reinterpret_cast<FILE *>(&__llvm_libc_stdout_cookie);
+extern "C" FILE *stderr = reinterpret_cast<FILE *>(&__llvm_libc_stderr_cookie);
 
 ssize_t read_from_stdin(char *buf, size_t size) {
   return __llvm_libc_stdio_read(static_cast<void *>(&__llvm_libc_stdin_cookie),
diff --git a/libc/src/__support/OSUtil/baremetal/io.h 
b/libc/src/__support/OSUtil/baremetal/io.h
index aed34ec7e62e3..2605fd45776b9 100644
--- a/libc/src/__support/OSUtil/baremetal/io.h
+++ b/libc/src/__support/OSUtil/baremetal/io.h
@@ -16,6 +16,45 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+// These are intended to be provided by the vendor.
+//
+// The signature of these types and functions intentionally match `fopencookie`
+// which allows the following:
+//
+// ```
+// struct __llvm_libc_stdio_cookie { ... };
+// ...
+// struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
+// cookie_io_functions_t stdin_func = { .read = __llvm_libc_stdio_read };
+// FILE *stdin = fopencookie(&__llvm_libc_stdin_cookie, "r", stdin_func);
+// ...
+// struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
+// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write };
+// FILE *stdout = fopencookie(&__llvm_libc_stdout_cookie, "w", stdout_func);
+// ...
+// struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
+// cookie_io_functions_t stderr_func = { .write = __llvm_libc_stdio_write };
+// FILE *stderr = fopencookie(&__llvm_libc_stderr_cookie, "w", stderr_func);
+// ```
+//
+// At the same time, implementation of functions like `printf` and `scanf` can
+// use `__llvm_libc_stdio_read` and `__llvm_libc_stdio_write` directly to avoid
+// the extra indirection.
+//
+// All three symbols `__llvm_libc_stdin_cookie`, `__llvm_libc_stdout_cookie`,
+// and `__llvm_libc_stderr_cookie` must be provided, even if they don't point
+// at anything.
+
+struct __llvm_libc_stdio_cookie;
+
+extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
+extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
+extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
+
+extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t 
size);
+extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf,
+                                           size_t size);
+
 ssize_t read_from_stdin(char *buf, size_t size);
 void write_to_stderr(cpp::string_view msg);
 void write_to_stdout(cpp::string_view msg);
diff --git a/libc/src/stdio/baremetal/CMakeLists.txt 
b/libc/src/stdio/baremetal/CMakeLists.txt
index bfeff0e2b5880..e920b4a1a30f4 100644
--- a/libc/src/stdio/baremetal/CMakeLists.txt
+++ b/libc/src/stdio/baremetal/CMakeLists.txt
@@ -1,3 +1,111 @@
+add_header_library(
+  fputc_internal
+  HDRS
+    fputc_internal.h
+  DEPENDS
+    libc.hdr.types.FILE
+    libc.src.__support.CPP.string_view
+    libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+  fputs_internal
+  HDRS
+    fputs_internal.h
+  DEPENDS
+    libc.hdr.types.FILE
+    libc.src.__support.CPP.string_view
+    libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+  fwrite_internal
+  HDRS
+    fwrite_internal.h
+  DEPENDS
+    libc.hdr.types.FILE
+    libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+  vfprintf_internal
+  HDRS
+    vfprintf_internal.h
+  DEPENDS
+    libc.hdr.types.FILE
+    libc.hdr.stdio_macros
+    libc.src.__support.arg_list
+    libc.src.__support.CPP.limits
+    libc.src.__support.CPP.string_view
+    libc.src.__support.libc_errno
+    libc.src.__support.OSUtil.osutil
+    libc.src.stdio.printf_core.printf_main
+    libc.src.stdio.printf_core.writer
+    libc.src.stdio.printf_core.error_mapper
+    libc.src.stdio.printf_core.core_structs
+)
+
+add_entrypoint_object(
+  feof
+  SRCS
+    feof.cpp
+  HDRS
+    ../feof.h
+  DEPENDS
+    libc.hdr.types.FILE
+)
+
+add_entrypoint_object(
+  ferror
+  SRCS
+    ferror.cpp
+  HDRS
+    ../ferror.h
+  DEPENDS
+    libc.hdr.types.FILE
+)
+
+add_entrypoint_object(
+  fprintf
+  SRCS
+    fprintf.cpp
+  HDRS
+    ../fprintf.h
+  DEPENDS
+    .vfprintf_internal
+    libc.src.__support.arg_list
+)
+
+add_entrypoint_object(
+  fputc
+  SRCS
+    fputc.cpp
+  HDRS
+    ../fputc.h
+  DEPENDS
+    .fputc_internal
+)
+
+add_entrypoint_object(
+  fputs
+  SRCS
+    fputs.cpp
+  HDRS
+    ../fputc.h
+  DEPENDS
+    .fputs_internal
+)
+
+add_entrypoint_object(
+  fwrite
+  SRCS
+    fwrite.cpp
+  HDRS
+    ../fwrite.h
+  DEPENDS
+    .fwrite_internal
+)
+
 add_entrypoint_object(
   getchar
   SRCS
@@ -27,14 +135,8 @@ add_entrypoint_object(
   HDRS
     ../printf.h
   DEPENDS
-    libc.src.stdio.printf_core.printf_main
-    libc.src.stdio.printf_core.writer
-    libc.src.stdio.printf_core.error_mapper
-    libc.src.stdio.printf_core.core_structs
+    .vfprintf_internal
     libc.src.__support.arg_list
-    libc.src.__support.OSUtil.osutil
-    libc.src.__support.libc_errno
-    libc.src.__support.CPP.limits
 )
 
 add_entrypoint_object(
@@ -44,8 +146,17 @@ add_entrypoint_object(
   HDRS
     ../putchar.h
   DEPENDS
-    libc.src.__support.OSUtil.osutil
-    libc.src.__support.CPP.string_view
+    .fputc_internal
+)
+
+add_entrypoint_object(
+  putc
+  SRCS
+    putc.cpp
+  HDRS
+    ../putc.h
+  DEPENDS
+    .fputc_internal
 )
 
 add_entrypoint_object(
@@ -55,8 +166,7 @@ add_entrypoint_object(
   HDRS
     ../puts.h
   DEPENDS
-    libc.src.__support.OSUtil.osutil
-    libc.src.__support.CPP.string_view
+    .fputs_internal
 )
 
 add_header_library(
@@ -82,6 +192,17 @@ add_entrypoint_object(
     libc.src.__support.OSUtil.osutil
 )
 
+add_entrypoint_object(
+  vfprintf
+  SRCS
+    vfprintf.cpp
+  HDRS
+    ../vfprintf.h
+  DEPENDS
+    .vfprintf_internal
+    libc.src.__support.arg_list
+)
+
 add_entrypoint_object(
   vprintf
   SRCS
@@ -89,14 +210,8 @@ add_entrypoint_object(
   HDRS
     ../vprintf.h
   DEPENDS
-    libc.src.stdio.printf_core.printf_main
-    libc.src.stdio.printf_core.writer
-    libc.src.stdio.printf_core.error_mapper
-    libc.src.stdio.printf_core.core_structs
+    .vfprintf_internal
     libc.src.__support.arg_list
-    libc.src.__support.OSUtil.osutil
-    libc.src.__support.libc_errno
-    libc.src.__support.CPP.limits
 )
 
 add_entrypoint_object(
diff --git a/libc/src/stdio/baremetal/feof.cpp 
b/libc/src/stdio/baremetal/feof.cpp
new file mode 100644
index 0000000000000..3c241edeb47f6
--- /dev/null
+++ b/libc/src/stdio/baremetal/feof.cpp
@@ -0,0 +1,24 @@
+//===-- Implementation of feof for baremetal --------------------*- C++ 
-*-===//
+//
+// 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/stdio/feof.h"
+
+#include "hdr/types/FILE.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, feof, (::FILE * stream)) {
+  (void)stream;
+  // TODO: Shall we have an embeddeding API for feof?
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
diff --git a/libc/src/stdio/baremetal/ferror.cpp 
b/libc/src/stdio/baremetal/ferror.cpp
new file mode 100644
index 0000000000000..5af5a1efdcd9a
--- /dev/null
+++ b/libc/src/stdio/baremetal/ferror.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of ferror for baremetal ------------------*- C++ 
-*-===//
+//
+// 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/stdio/ferror.h"
+
+#include "hdr/types/FILE.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, ferror, (::FILE * stream)) {
+  (void)stream;
+  // TODO: Shall we have an embeddeding API for ferror?
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/fgetc.cpp 
b/libc/src/stdio/baremetal/fgetc.cpp
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libc/src/stdio/baremetal/fgets.cpp 
b/libc/src/stdio/baremetal/fgets.cpp
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libc/src/stdio/baremetal/fprintf.cpp 
b/libc/src/stdio/baremetal/fprintf.cpp
new file mode 100644
index 0000000000000..fc96c56ec77ed
--- /dev/null
+++ b/libc/src/stdio/baremetal/fprintf.cpp
@@ -0,0 +1,34 @@
+//===-- Implementation of fprintf for baremetal -----------------*- C++ 
-*-===//
+//
+// 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/stdio/fprintf.h"
+
+#include "hdr/types/FILE.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/baremetal/vfprintf_internal.h"
+
+#include <stdarg.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, fprintf,
+                   (::FILE *__restrict stream, const char *__restrict format,
+                    ...)) {
+  va_list vlist;
+  va_start(vlist, format);
+  internal::ArgList args(vlist); // This holder class allows for easier copying
+                                 // and pointer semantics, as well as handling
+                                 // destruction automatically.
+  va_end(vlist);
+
+  return vfprintf_internal(stream, format, args);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/fputc.cpp 
b/libc/src/stdio/baremetal/fputc.cpp
new file mode 100644
index 0000000000000..1b4086466ee7b
--- /dev/null
+++ b/libc/src/stdio/baremetal/fputc.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of fputc for baremetal -------------------*- C++ 
-*-===//
+//
+// 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/stdio/fputc.h"
+
+#include "hdr/types/FILE.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/baremetal/fputc_internal.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, fputc, (int c, ::FILE *stream)) {
+  return fputc_internal(c, stream);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/baremetal/fputc_internal.h 
b/libc/src/stdio/baremetal/fputc_internal.h
new file mode 100644
index 0000000000000..e578d6584bcfe
--- /dev/null
+++ b/libc/src/stdio/baremetal/fputc_internal.h
@@ -0,0 +1,29 @@
+//===-- Baremetal implementation header of fputc ----------------*- C++ 
-*-===//
+//
+// 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_STDIO_BAREMETAL_FPUTC_INTERNAL_H
+#define LLVM_LIBC_SRC_STDIO_BAREMETAL_FPUTC_INTERNAL_H
+
+#include "hdr/types/FILE.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LIBC_INLINE int fputc_internal(int c, ::FILE *stream) {
+  char ch = static_cast<char>(c);
+  cpp::string_view str_view(&ch, 1);
+  __llvm_libc_stdio_write(stream, str_view.data(), str_view.size());
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDIO_BAREMETAL_FPUTC_INTERNAL_H
diff --git a/libc/src/stdio/baremetal/fputs.cpp 
b/libc/src/stdio/baremetal/fputs.cpp
new file mode 100644
index 0000000000000..daed53182686e
--- /dev/null
+++ b/libc/src/stdio/baremetal/fputs.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of fputs for baremetal -------------------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for li...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/168931
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to