aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/InitPreprocessor.cpp
diff options
context:
space:
mode:
authorManuel Sainz de Baranda y Goñi <manuel@zxe.io>2025-01-26 16:48:42 +0100
committerGitHub <noreply@github.com>2025-01-26 16:48:42 +0100
commit33ad474c45e6d7a0de7bc75e15e27cf6cb9ff895 (patch)
tree738059880086cc7c6237db277004e8b9bcd51e9d /clang/lib/Frontend/InitPreprocessor.cpp
parent0c784851c50b6b5b844e6a1f21bbe73efac332d4 (diff)
downloadllvm-33ad474c45e6d7a0de7bc75e15e27cf6cb9ff895.zip
llvm-33ad474c45e6d7a0de7bc75e15e27cf6cb9ff895.tar.gz
llvm-33ad474c45e6d7a0de7bc75e15e27cf6cb9ff895.tar.bz2
[Clang] Add predefined macros for integer constants (#123514)
This adds predefined macros for integer constants to implement section 7.18.4 of ISO/IEC 9899:1999 in `<stdint.h>` in a safe way: ``` __INT8_C(c) __INT16_C(c) __INT32_C(c) __INT64_C(c) __INTMAX_C(c) __UINT8_C(c) __UINT16_C(c) __UINT32_C(c) __UINT64_C(c) __UINTMAX_C(c) ``` Which improves compatibility with GCC and makes it trivial to implement section 7.18.4 of ISO/IEC 9899:1999. Clang defines `__INT<N>_C_SUFFIX__`, `__UINT<N>_C_SUFFIX__`, `__INTAX_C_SUFFIX__` and `__UINTMAX_C_SUFFIX__`, but these macros are useless for this purpose. Let's say, for example, that `__INT64_C_SUFFIX__` expands to `L` or `LL`. If the user defines them as a macros, the compiler will produce errors if `INT64_C` is implemented in `<stdint.h>` using `__INT64_C_SUFFIX__`: **minimal-test.c:** ```cpp #if defined(__clang__) & !defined(__INT64_C) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wreserved-identifier" # define __PSTDC_INT_C_(literal, suffix) literal##suffix # define __PSTDC_INT_C(literal, suffix) __PSTDC_INT_C_(literal, suffix) # define INT64_C(literal) __PSTDC_INT_C(literal, __INT64_C_SUFFIX__) # pragma clang diagnostic pop #elif defined(__GNUC__) # define INT64_C __INT64_C #endif typedef __INT64_TYPE__ int64_t; #define L "Make Clang produce an error" #define LL "Make Clang produce an error" int main(int argc, char **argv) { (void)argc; (void)argv; int64_t v = INT64_C(9223372036854775807); (void)v; return 0; } ``` <img width="697" alt="imagen" src="https://github.com/user-attachments/assets/6df97af6-7cfd-4cf9-85b7-d7c854509325" /> **test.c:** ```cpp #if defined(__clang__) && !defined(__INT8_C) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wreserved-identifier" # define __PSTDC_INT_C_(literal, suffix) literal##suffix # define __PSTDC_INT_C(literal, suffix) __PSTDC_INT_C_(literal, suffix) # define INT8_C(literal) __PSTDC_INT_C(literal, __INT8_C_SUFFIX__) # define INT16_C(literal) __PSTDC_INT_C(literal, __INT16_C_SUFFIX__) # define INT32_C(literal) __PSTDC_INT_C(literal, __INT32_C_SUFFIX__) # define INT64_C(literal) __PSTDC_INT_C(literal, __INT64_C_SUFFIX__) # define INTMAX_C(literal) __PSTDC_INT_C(literal, __INTMAX_C_SUFFIX__) # define UINT8_C(literal) __PSTDC_INT_C(literal, __UINT8_C_SUFFIX__) # define UINT16_C(literal) __PSTDC_INT_C(literal, __UINT16_C_SUFFIX__) # define UINT32_C(literal) __PSTDC_INT_C(literal, __UINT32_C_SUFFIX__) # define UINT64_C(literal) __PSTDC_INT_C(literal, __UINT64_C_SUFFIX__) # define UINTMAX_C(literal) __PSTDC_INT_C(literal, __UINTMAX_C_SUFFIX__) # pragma clang diagnostic pop #else # define INT8_C __INT8_C # define INT16_C __INT16_C # define INT32_C __INT32_C # define INT64_C __INT64_C # define INTMAX_C __INTMAX_C # define UINT8_C __UINT8_C # define UINT16_C __UINT16_C # define UINT32_C __UINT32_C # define UINT64_C __UINT64_C # define UINTMAX_C __UINTMAX_C #endif typedef __INT8_TYPE__ int8_t; typedef __INT16_TYPE__ int16_t; typedef __INT32_TYPE__ int32_t; typedef __INT64_TYPE__ int64_t; typedef __INTMAX_TYPE__ intmax_t; typedef __UINT8_TYPE__ uint8_t; typedef __UINT16_TYPE__ uint16_t; typedef __UINT32_TYPE__ uint32_t; typedef __UINT64_TYPE__ uint64_t; typedef __UINTMAX_TYPE__ uintmax_t; #define L "Make Clang produce an error" #define LL "Make Clang produce an error" #define U "Make Clang produce an error" #define UL "Make Clang produce an error" #define ULL "Make Clang produce an error" int main(int argc, char **argv) { (void)argc; (void)argv; int8_t a = INT8_C (127); int16_t b = INT16_C (32767); int32_t c = INT32_C (2147483647); int64_t d = INT64_C (9223372036854775807); intmax_t e = INTMAX_C (9223372036854775807); uint8_t f = UINT8_C (255); uint16_t g = UINT16_C (65535); uint32_t h = UINT32_C (4294967295); uint64_t i = UINT64_C (18446744073709551615); uintmax_t j = UINTMAX_C(18446744073709551615); (void)a; (void)b; (void)c; (void)d; (void)e; (void)f; (void)g; (void)h; (void)i; (void)j; return 0; } ```
Diffstat (limited to 'clang/lib/Frontend/InitPreprocessor.cpp')
-rw-r--r--clang/lib/Frontend/InitPreprocessor.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 29723b5..17f624e 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -253,6 +253,8 @@ static void DefineExactWidthIntType(const LangOptions &LangOpts,
StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty));
Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
+ Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C(c)",
+ ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
}
static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty,
@@ -1164,12 +1166,16 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder);
DefineFmt(LangOpts, "__INTMAX", TI.getIntMaxType(), TI, Builder);
- Builder.defineMacro("__INTMAX_C_SUFFIX__",
- TI.getTypeConstantSuffix(TI.getIntMaxType()));
+ StringRef ConstSuffix(TI.getTypeConstantSuffix(TI.getIntMaxType()));
+ Builder.defineMacro("__INTMAX_C_SUFFIX__", ConstSuffix);
+ Builder.defineMacro("__INTMAX_C(c)",
+ ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
DefineFmt(LangOpts, "__UINTMAX", TI.getUIntMaxType(), TI, Builder);
- Builder.defineMacro("__UINTMAX_C_SUFFIX__",
- TI.getTypeConstantSuffix(TI.getUIntMaxType()));
+ ConstSuffix = TI.getTypeConstantSuffix(TI.getUIntMaxType());
+ Builder.defineMacro("__UINTMAX_C_SUFFIX__", ConstSuffix);
+ Builder.defineMacro("__UINTMAX_C(c)",
+ ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(LangAS::Default), Builder);
DefineFmt(LangOpts, "__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI,
Builder);