[libc-commits] [libc] ca1da36 - [libc] add inttypes macros (#80726)

via libc-commits libc-commits at lists.llvm.org
Tue Feb 6 06:36:01 PST 2024


Author: Schrodinger ZHU Yifan
Date: 2024-02-06T09:35:56-05:00
New Revision: ca1da36aec963c5504ae7ae2e834b37856c476db

URL: https://github.com/llvm/llvm-project/commit/ca1da36aec963c5504ae7ae2e834b37856c476db
DIFF: https://github.com/llvm/llvm-project/commit/ca1da36aec963c5504ae7ae2e834b37856c476db.diff

LOG: [libc] add inttypes macros (#80726)

Standard file:
https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/

Notice that we are not quite the same as other implementations:
1. MUSL: https://github.com/bminor/musl/blob/master/include/inttypes.h
2. GLIBC:
https://github.com/bminor/glibc/blob/bbd248ac0d75efdef8fe61ea69b1fb25fb95b6e7/stdlib/inttypes.h#L57
3. CheriBSD:
https://github.com/CTSRD-CHERI/cheribsd/blob/698d1636dd1fe2322e5bc7029e415928c80b76b1/sys/arm64/include/_inttypes.h

fixes #80186

Added: 
    libc/include/llvm-libc-macros/inttypes-macros.h

Modified: 
    libc/include/CMakeLists.txt
    libc/include/inttypes.h.def
    libc/include/llvm-libc-macros/CMakeLists.txt
    libc/test/src/stdio/CMakeLists.txt
    libc/test/src/stdio/sprintf_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 4f4d8434757d7..332410453b54d 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -73,6 +73,7 @@ add_gen_header(
   DEPENDS
     .llvm_libc_common_h
     .llvm-libc-types.imaxdiv_t
+    .llvm-libc-macros.inttypes_macros
 )
 
 add_gen_header(

diff  --git a/libc/include/inttypes.h.def b/libc/include/inttypes.h.def
index 94cdc2f21eaf7..a99d4e931f514 100644
--- a/libc/include/inttypes.h.def
+++ b/libc/include/inttypes.h.def
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_INTTYPES_H
 
 #include <__llvm-libc-common.h>
+#include <llvm-libc-macros/inttypes-macros.h>
 #include <stdint.h>
 
 %%public_api()

diff  --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index c5a7e742cadd1..562769a5e84ce 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -221,3 +221,9 @@ add_macro_header(
   HDR
     wchar-macros.h
 )
+
+add_macro_header(
+  inttypes_macros
+  HDR
+    inttypes-macros.h
+)

diff  --git a/libc/include/llvm-libc-macros/inttypes-macros.h b/libc/include/llvm-libc-macros/inttypes-macros.h
new file mode 100644
index 0000000000000..fc3e2517f1947
--- /dev/null
+++ b/libc/include/llvm-libc-macros/inttypes-macros.h
@@ -0,0 +1,289 @@
+//===-- Definition of macros from inttypes.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_MACROS_INTTYPES_MACROS_H
+#define __LLVM_LIBC_MACROS_INTTYPES_MACROS_H
+
+// fprintf/scanf format macros.
+// POSIX.1-2008, Technical Corrigendum 1, XBD/TC1-2008/0050 [211] is applied.
+
+// clang provides these macros, so we don't need to define them.
+// TODO: ISO C23 will provide binary notations.
+
+#ifndef __clang__
+#if __UINTPTR_MAX__ == __UINT64_MAX__
+#define __PRI64 "l"
+#define __PRIPTR "l"
+#elif __UINTPTR_MAX__ == __UINT32_MAX__
+#define __PRI64 "ll"
+#define __PRIPTR ""
+#else
+// CHERI achitecture for example, has 128-bit pointers that use special "P"
+// format.
+#error "Unsupported pointer format"
+#endif
+#define __INT8_FMTd__ "hhd"
+#define __INT16_FMTd__ "hd"
+#define __INT32_FMTd__ "d"
+#define __INT64_FMTd__ __PRI64 "d"
+#define __INT_LEAST8_FMTd__ "hhd"
+#define __INT_LEAST16_FMTd__ "hd"
+#define __INT_LEAST32_FMTd__ "d"
+#define __INT_LEAST64_FMTd__ __PRI64 "d"
+#define __INT_FAST8_FMTd__ "hhd"
+#define __INT_FAST16_FMTd__ "hd"
+#define __INT_FAST32_FMTd__ "d"
+#define __INT_FAST64_FMTd__ __PRI64 "d"
+#define __INTMAX_FMTd__ __PRI64 "d"
+#define __INTPTR_FMTd__ __PRIPTR "d"
+
+#define __INT8_FMTi__ "hhi"
+#define __INT16_FMTi__ "hi"
+#define __INT32_FMTi__ "i"
+#define __INT64_FMTi__ __PRI64 "i"
+#define __INT_LEAST8_FMTi__ "hhi"
+#define __INT_LEAST16_FMTi__ "hi"
+#define __INT_LEAST32_FMTi__ "i"
+#define __INT_LEAST64_FMTi__ __PRI64 "i"
+#define __INT_FAST8_FMTi__ "hhi"
+#define __INT_FAST16_FMTi__ "hi"
+#define __INT_FAST32_FMTi__ "i"
+#define __INT_FAST64_FMTi__ __PRI64 "i"
+#define __INTMAX_FMTi__ __PRI64 "i"
+#define __INTPTR_FMTi__ __PRIPTR "i"
+
+#define __UINT8_FMTo__ "hho"
+#define __UINT16_FMTo__ "ho"
+#define __UINT32_FMTo__ "o"
+#define __UINT64_FMTo__ __PRI64 "o"
+#define __UINT_LEAST8_FMTo__ "hho"
+#define __UINT_LEAST16_FMTo__ "ho"
+#define __UINT_LEAST32_FMTo__ "o"
+#define __UINT_LEAST64_FMTo__ __PRI64 "o"
+#define __UINT_FAST8_FMTo__ "hho"
+#define __UINT_FAST16_FMTo__ "ho"
+#define __UINT_FAST32_FMTo__ "o"
+#define __UINT_FAST64_FMTo__ __PRI64 "o"
+#define __UINTMAX_FMTo__ __PRI64 "o"
+#define __UINTPTR_FMTo__ __PRIPTR "o"
+
+#define __UINT8_FMTu__ "hhu"
+#define __UINT16_FMTu__ "hu"
+#define __UINT32_FMTu__ "u"
+#define __UINT64_FMTu__ __PRI64 "u"
+#define __UINT_LEAST8_FMTu__ "hhu"
+#define __UINT_LEAST16_FMTu__ "hu"
+#define __UINT_LEAST32_FMTu__ "u"
+#define __UINT_LEAST64_FMTu__ __PRI64 "u"
+#define __UINT_FAST8_FMTu__ "hhu"
+#define __UINT_FAST16_FMTu__ "hu"
+#define __UINT_FAST32_FMTu__ "u"
+#define __UINT_FAST64_FMTu__ __PRI64 "u"
+#define __UINTMAX_FMTu__ __PRI64 "u"
+#define __UINTPTR_FMTu__ __PRIPTR "u"
+
+#define __UINT8_FMTx__ "hhx"
+#define __UINT16_FMTx__ "hx"
+#define __UINT32_FMTx__ "x"
+#define __UINT64_FMTx__ __PRI64 "x"
+#define __UINT_LEAST8_FMTx__ "hhx"
+#define __UINT_LEAST16_FMTx__ "hx"
+#define __UINT_LEAST32_FMTx__ "x"
+#define __UINT_LEAST64_FMTx__ __PRI64 "x"
+#define __UINT_FAST8_FMTx__ "hhx"
+#define __UINT_FAST16_FMTx__ "hx"
+#define __UINT_FAST32_FMTx__ "x"
+#define __UINT_FAST64_FMTx__ __PRI64 "x"
+#define __UINTMAX_FMTx__ __PRI64 "x"
+#define __UINTPTR_FMTx__ __PRIPTR "x"
+
+#define __UINT8_FMTX__ "hhX"
+#define __UINT16_FMTX__ "hX"
+#define __UINT32_FMTX__ "X"
+#define __UINT64_FMTX__ __PRI64 "X"
+#define __UINT_LEAST8_FMTX__ "hhX"
+#define __UINT_LEAST16_FMTX__ "hX"
+#define __UINT_LEAST32_FMTX__ "X"
+#define __UINT_LEAST64_FMTX__ __PRI64 "X"
+#define __UINT_FAST8_FMTX__ "hhX"
+#define __UINT_FAST16_FMTX__ "hX"
+#define __UINT_FAST32_FMTX__ "X"
+#define __UINT_FAST64_FMTX__ __PRI64 "X"
+#define __UINTMAX_FMTX__ __PRI64 "X"
+#define __UINTPTR_FMTX__ __PRIPTR "X"
+#endif
+
+// The fprintf() macros for signed integers.
+#define PRId8 __INT8_FMTd__
+#define PRId16 __INT16_FMTd__
+#define PRId32 __INT32_FMTd__
+#define PRId64 __INT64_FMTd__
+#define PRIdLEAST8 __INT_LEAST8_FMTd__
+#define PRIdLEAST16 __INT_LEAST16_FMTd__
+#define PRIdLEAST32 __INT_LEAST32_FMTd__
+#define PRIdLEAST64 __INT_LEAST64_FMTd__
+#define PRIdFAST8 __INT_FAST8_FMTd__
+#define PRIdFAST16 __INT_FAST16_FMTd__
+#define PRIdFAST32 __INT_FAST32_FMTd__
+#define PRIdFAST64 __INT_FAST64_FMTd__
+#define PRIdMAX __INTMAX_FMTd__
+#define PRIdPTR __INTPTR_FMTd__
+
+#define PRIi8 __INT8_FMTi__
+#define PRIi16 __INT16_FMTi__
+#define PRIi32 __INT32_FMTi__
+#define PRIi64 __INT64_FMTi__
+#define PRIiLEAST8 __INT_LEAST8_FMTi__
+#define PRIiLEAST16 __INT_LEAST16_FMTi__
+#define PRIiLEAST32 __INT_LEAST32_FMTi__
+#define PRIiLEAST64 __INT_LEAST64_FMTi__
+#define PRIiFAST8 __INT_FAST8_FMTi__
+#define PRIiFAST16 __INT_FAST16_FMTi__
+#define PRIiFAST32 __INT_FAST32_FMTi__
+#define PRIiFAST64 __INT_FAST64_FMTi__
+#define PRIiMAX __INTMAX_FMTi__
+#define PRIiPTR __INTPTR_FMTi__
+
+// The fprintf() macros for unsigned integers.
+#define PRIo8 __UINT8_FMTo__
+#define PRIo16 __UINT16_FMTo__
+#define PRIo32 __UINT32_FMTo__
+#define PRIo64 __UINT64_FMTo__
+#define PRIoLEAST8 __UINT_LEAST8_FMTo__
+#define PRIoLEAST16 __UINT_LEAST16_FMTo__
+#define PRIoLEAST32 __UINT_LEAST32_FMTo__
+#define PRIoLEAST64 __UINT_LEAST64_FMTo__
+#define PRIoFAST8 __UINT_FAST8_FMTo__
+#define PRIoFAST16 __UINT_FAST16_FMTo__
+#define PRIoFAST32 __UINT_FAST32_FMTo__
+#define PRIoFAST64 __UINT_FAST64_FMTo__
+#define PRIoMAX __UINTMAX_FMTo__
+#define PRIoPTR __UINTPTR_FMTo__
+
+#define PRIu8 __UINT8_FMTu__
+#define PRIu16 __UINT16_FMTu__
+#define PRIu32 __UINT32_FMTu__
+#define PRIu64 __UINT64_FMTu__
+#define PRIuLEAST8 __UINT_LEAST8_FMTu__
+#define PRIuLEAST16 __UINT_LEAST16_FMTu__
+#define PRIuLEAST32 __UINT_LEAST32_FMTu__
+#define PRIuLEAST64 __UINT_LEAST64_FMTu__
+#define PRIuFAST8 __UINT_FAST8_FMTu__
+#define PRIuFAST16 __UINT_FAST16_FMTu__
+#define PRIuFAST32 __UINT_FAST32_FMTu__
+#define PRIuFAST64 __UINT_FAST64_FMTu__
+#define PRIuMAX __UINTMAX_FMTu__
+#define PRIuPTR __UINTPTR_FMTu__
+
+#define PRIx8 __UINT8_FMTx__
+#define PRIx16 __UINT16_FMTx__
+#define PRIx32 __UINT32_FMTx__
+#define PRIx64 __UINT64_FMTx__
+#define PRIxLEAST8 __UINT_LEAST8_FMTx__
+#define PRIxLEAST16 __UINT_LEAST16_FMTx__
+#define PRIxLEAST32 __UINT_LEAST32_FMTx__
+#define PRIxLEAST64 __UINT_LEAST64_FMTx__
+#define PRIxFAST8 __UINT_FAST8_FMTx__
+#define PRIxFAST16 __UINT_FAST16_FMTx__
+#define PRIxFAST32 __UINT_FAST32_FMTx__
+#define PRIxFAST64 __UINT_FAST64_FMTx__
+#define PRIxMAX __UINTMAX_FMTx__
+#define PRIxPTR __UINTPTR_FMTx__
+
+#define PRIX8 __UINT8_FMTX__
+#define PRIX16 __UINT16_FMTX__
+#define PRIX32 __UINT32_FMTX__
+#define PRIX64 __UINT64_FMTX__
+#define PRIXLEAST8 __UINT_LEAST8_FMTX__
+#define PRIXLEAST16 __UINT_LEAST16_FMTX__
+#define PRIXLEAST32 __UINT_LEAST32_FMTX__
+#define PRIXLEAST64 __UINT_LEAST64_FMTX__
+#define PRIXFAST8 __UINT_FAST8_FMTX__
+#define PRIXFAST16 __UINT_FAST16_FMTX__
+#define PRIXFAST32 __UINT_FAST32_FMTX__
+#define PRIXFAST64 __UINT_FAST64_FMTX__
+#define PRIXMAX __UINTMAX_FMTX__
+#define PRIXPTR __UINTPTR_FMTX__
+
+// The fscanf() macros for signed integers.
+#define SCNd8 __INT8_FMTd__
+#define SCNd16 __INT16_FMTd__
+#define SCNd32 __INT32_FMTd__
+#define SCNd64 __INT64_FMTd__
+#define SCNdLEAST8 __INT_LEAST8_FMTd__
+#define SCNdLEAST16 __INT_LEAST16_FMTd__
+#define SCNdLEAST32 __INT_LEAST32_FMTd__
+#define SCNdLEAST64 __INT_LEAST64_FMTd__
+#define SCNdFAST8 __INT_FAST8_FMTd__
+#define SCNdFAST16 __INT_FAST16_FMTd__
+#define SCNdFAST32 __INT_FAST32_FMTd__
+#define SCNdFAST64 __INT_FAST64_FMTd__
+#define SCNdMAX __INTMAX_FMTd__
+#define SCNdPTR __INTPTR_FMTd__
+
+#define SCNi8 __INT8_FMTi__
+#define SCNi16 __INT16_FMTi__
+#define SCNi32 __INT32_FMTi__
+#define SCNi64 __INT64_FMTi__
+#define SCNiLEAST8 __INT_LEAST8_FMTi__
+#define SCNiLEAST16 __INT_LEAST16_FMTi__
+#define SCNiLEAST32 __INT_LEAST32_FMTi__
+#define SCNiLEAST64 __INT_LEAST64_FMTi__
+#define SCNiFAST8 __INT_FAST8_FMTi__
+#define SCNiFAST16 __INT_FAST16_FMTi__
+#define SCNiFAST32 __INT_FAST32_FMTi__
+#define SCNiFAST64 __INT_FAST64_FMTi__
+#define SCNiMAX __INTMAX_FMTi__
+#define SCNiPTR __INTPTR_FMTi__
+
+// The fscanf() macros for unsigned integers.
+#define SCNo8 __UINT8_FMTo__
+#define SCNo16 __UINT16_FMTo__
+#define SCNo32 __UINT32_FMTo__
+#define SCNo64 __UINT64_FMTo__
+#define SCNoLEAST8 __UINT_LEAST8_FMTo__
+#define SCNoLEAST16 __UINT_LEAST16_FMTo__
+#define SCNoLEAST32 __UINT_LEAST32_FMTo__
+#define SCNoLEAST64 __UINT_LEAST64_FMTo__
+#define SCNoFAST8 __UINT_FAST8_FMTo__
+#define SCNoFAST16 __UINT_FAST16_FMTo__
+#define SCNoFAST32 __UINT_FAST32_FMTo__
+#define SCNoFAST64 __UINT_FAST64_FMTo__
+#define SCNoMAX __UINTMAX_FMTo__
+#define SCNoPTR __UINTPTR_FMTo__
+
+#define SCNu8 __UINT8_FMTu__
+#define SCNu16 __UINT16_FMTu__
+#define SCNu32 __UINT32_FMTu__
+#define SCNu64 __UINT64_FMTu__
+#define SCNuLEAST8 __UINT_LEAST8_FMTu__
+#define SCNuLEAST16 __UINT_LEAST16_FMTu__
+#define SCNuLEAST32 __UINT_LEAST32_FMTu__
+#define SCNuLEAST64 __UINT_LEAST64_FMTu__
+#define SCNuFAST8 __UINT_FAST8_FMTu__
+#define SCNuFAST16 __UINT_FAST16_FMTu__
+#define SCNuFAST32 __UINT_FAST32_FMTu__
+#define SCNuFAST64 __UINT_FAST64_FMTu__
+#define SCNuMAX __UINTMAX_FMTu__
+#define SCNuPTR __UINTPTR_FMTu__
+
+#define SCNx8 __UINT8_FMTx__
+#define SCNx16 __UINT16_FMTx__
+#define SCNx32 __UINT32_FMTx__
+#define SCNx64 __UINT64_FMTx__
+#define SCNxLEAST8 __UINT_LEAST8_FMTx__
+#define SCNxLEAST16 __UINT_LEAST16_FMTx__
+#define SCNxLEAST32 __UINT_LEAST32_FMTx__
+#define SCNxLEAST64 __UINT_LEAST64_FMTx__
+#define SCNxFAST8 __UINT_FAST8_FMTx__
+#define SCNxFAST16 __UINT_FAST16_FMTx__
+#define SCNxFAST32 __UINT_FAST32_FMTx__
+#define SCNxFAST64 __UINT_FAST64_FMTx__
+#define SCNxMAX __UINTMAX_FMTx__
+#define SCNxPTR __UINTPTR_FMTx__
+
+#endif // __LLVM_LIBC_MACROS_INTTYPES_MACROS_H

diff  --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt
index ffc238443863b..8db2293ab74a9 100644
--- a/libc/test/src/stdio/CMakeLists.txt
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -132,6 +132,7 @@ add_fp_unittest(
   DEPENDS
     libc.src.stdio.sprintf
     libc.src.__support.FPUtil.fp_bits
+    libc.include.inttypes
   COMPILE_OPTIONS
     ${sprintf_test_copts}
 )

diff  --git a/libc/test/src/stdio/sprintf_test.cpp b/libc/test/src/stdio/sprintf_test.cpp
index 1468bffe2a031..f3614b05a0c3e 100644
--- a/libc/test/src/stdio/sprintf_test.cpp
+++ b/libc/test/src/stdio/sprintf_test.cpp
@@ -11,6 +11,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/RoundingModeUtils.h"
 #include "test/UnitTest/Test.h"
+#include <inttypes.h>
 
 // TODO: Add a comment here explaining the printf format string.
 
@@ -33,6 +34,25 @@ using LIBC_NAMESPACE::fputil::testing::RoundingMode;
   EXPECT_EQ(actual_written, static_cast<int>(sizeof(expected_str) - 1));       \
   EXPECT_STREQ(actual_str, expected_str);
 
+#define macro_test(FMT, X, expected)                                           \
+  do {                                                                         \
+    for (char &c : buff) {                                                     \
+      c = 0;                                                                   \
+    }                                                                          \
+    LIBC_NAMESPACE::sprintf(buff, "%" FMT, X);                                 \
+    ASSERT_STREQ(buff, expected);                                              \
+  } while (0)
+
+TEST(LlvmLibcSPrintfTest, Macros) {
+  char buff[128];
+  macro_test(PRIu8, 1, "1");
+  macro_test(PRIX16, 0xAA, "AA");
+  macro_test(PRId32, -123, "-123");
+  macro_test(PRIX32, 0xFFFFFF85, "FFFFFF85");
+  macro_test(PRIo8, 0xFF, "377");
+  macro_test(PRIo64, 0123, "123");
+}
+
 TEST(LlvmLibcSPrintfTest, SimpleNoConv) {
   char buff[64];
   int written;


        


More information about the libc-commits mailing list