Manuel Sainz de Baranda y Goñi
33ad474c45
[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;
}
```
2025-01-26 16:48:42 +01:00
John Brawn
78bf8a0a22
[clang] Don't define predefined macros multiple times
...
Fix several instances of macros being defined multiple times
in several targets. Most of these are just simple duplication in a
TargetInfo or OSTargetInfo of things already defined in
InitializePredefinedMacros or InitializeStandardPredefinedMacros,
but there are a few that aren't:
* AArch64 defines a couple of feature macros for armv8.1a that are
handled generically by getTargetDefines.
* CSKY needs to take care when CPUName and ArchName are the same.
* Many os/target combinations result in __ELF__ being defined twice.
Instead define __ELF__ just once in InitPreprocessor based on
the Triple, which already knows what the object format is based
on os and target.
These changes shouldn't change the final result of which macros are
defined, with the exception of the changes to __ELF__ where if you
explicitly specify the object type in the triple then this affects
if __ELF__ is defined, e.g. --target=i686-windows-elf results in it
being defined where it wasn't before, but this is more accurate as an
ELF file is in fact generated.
Differential Revision: https://reviews.llvm.org/D150966
2023-05-24 17:28:41 +01:00
Kazushi (Jam) Marukawa
6036bf5309
[VE] Add clang tests for VE
...
Summary:
Add a preprocessor test to check VE predefinitions. Add a driver test
to check VE toolchain behavior.
Reviewers: simoll, k-ishizaka
Reviewed By: simoll
Subscribers: krytarowski, jfb, ormris, cfe-commits
Tags: #llvm, #ve, #clang
Differential Revision: https://reviews.llvm.org/D82461
2020-06-25 12:03:19 +09:00