diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index a4cf4631c8470..836e8a507bd6f 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -134,6 +134,14 @@ add_header( DEPENDS libc.include.llvm-libc-macros.float_macros ) +add_header( + cfloat128 + HDR + cfloat128.h + DEPENDS + libc.include.llvm-libc-macros.float_macros +) +add_header(cfloat16 HDR cfloat16.h) add_header(fsblkcnt_t HDR fsblkcnt_t.h) add_header(fsfilcnt_t HDR fsfilcnt_t.h) add_header( diff --git a/libc/include/llvm-libc-types/cfloat128.h b/libc/include/llvm-libc-types/cfloat128.h new file mode 100644 index 0000000000000..0cc8ed3041d6f --- /dev/null +++ b/libc/include/llvm-libc-types/cfloat128.h @@ -0,0 +1,38 @@ +//===-- Definition of cfloat128 type --------------------------------------===// +// +// 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_TYPES_CFLOAT128_H +#define LLVM_LIBC_TYPES_CFLOAT128_H + +#include "../llvm-libc-macros/float-macros.h" // LDBL_MANT_DIG + +// Currently, the complex variant of C23 `_Float128` type is only defined as a +// built-in type in GCC 7 or later, and only for C. For C++, or for clang, +// the complex variant of `__float128` is defined instead, and only on x86-64 +// targets. +// +// TODO: Update the complex variant of C23 `_Float128` type detection again when +// clang supports it. +// https://github.com/llvm/llvm-project/issues/80195 +#if defined(__STDC_IEC_60559_COMPLEX__) && !defined(__clang__) && \ + !defined(__cplusplus) +#define LIBC_TYPES_HAS_CFLOAT128 +typedef _Complex _Float128 cfloat128; +#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) +// Use _Complex __float128 type. gcc and clang sometime use __SIZEOF_FLOAT128__ +// to notify the availability of __float128. clang also uses __FLOAT128__ macro +// to notify the availability of __float128 type: +// https://reviews.llvm.org/D15120 +#define LIBC_TYPES_HAS_CFLOAT128 +typedef _Complex __float128 cfloat128; +#elif (LDBL_MANT_DIG == 113) +#define LIBC_TYPES_HAS_CFLOAT128 +typedef _Complex long double cfloat128; +#endif + +#endif // LLVM_LIBC_TYPES_CFLOAT128_H diff --git a/libc/include/llvm-libc-types/cfloat16.h b/libc/include/llvm-libc-types/cfloat16.h new file mode 100644 index 0000000000000..e7e5631e02507 --- /dev/null +++ b/libc/include/llvm-libc-types/cfloat16.h @@ -0,0 +1,20 @@ +//===-- Definition of cfloat16 type ---------------------------------------===// +// +// 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_TYPES_CFLOAT16_H +#define LLVM_LIBC_TYPES_CFLOAT16_H + +#if defined(__FLT16_MANT_DIG__) && \ + (!defined(__GNUC__) || __GNUC__ >= 13 || defined(__clang__)) && \ + !defined(__arm__) && !defined(_M_ARM) && !defined(__riscv) && \ + !defined(_WIN32) +#define LIBC_TYPES_HAS_CFLOAT16 +typedef _Complex _Float16 cfloat16; +#endif + +#endif // LLVM_LIBC_TYPES_CFLOAT16_H diff --git a/libc/src/__support/CPP/CMakeLists.txt b/libc/src/__support/CPP/CMakeLists.txt index c1981b827042c..774668be42e56 100644 --- a/libc/src/__support/CPP/CMakeLists.txt +++ b/libc/src/__support/CPP/CMakeLists.txt @@ -126,6 +126,7 @@ add_header_library( type_traits/is_array.h type_traits/is_base_of.h type_traits/is_class.h + type_traits/is_complex.h type_traits/is_const.h type_traits/is_constant_evaluated.h type_traits/is_convertible.h @@ -165,6 +166,7 @@ add_header_library( libc.include.llvm-libc-macros.stdfix_macros libc.src.__support.macros.attributes libc.src.__support.macros.properties.types + libc.src.__support.macros.properties.complex_types ) add_header_library( diff --git a/libc/src/__support/CPP/type_traits.h b/libc/src/__support/CPP/type_traits.h index cef4e5d1f0b13..d50b6612656db 100644 --- a/libc/src/__support/CPP/type_traits.h +++ b/libc/src/__support/CPP/type_traits.h @@ -25,7 +25,6 @@ #include "src/__support/CPP/type_traits/is_array.h" #include "src/__support/CPP/type_traits/is_base_of.h" #include "src/__support/CPP/type_traits/is_class.h" -#include "src/__support/CPP/type_traits/is_complex.h" #include "src/__support/CPP/type_traits/is_const.h" #include "src/__support/CPP/type_traits/is_constant_evaluated.h" #include "src/__support/CPP/type_traits/is_convertible.h" diff --git a/libc/src/__support/CPP/type_traits/is_complex.h b/libc/src/__support/CPP/type_traits/is_complex.h index 4f5ee9abdb33a..23f05c08ccab5 100644 --- a/libc/src/__support/CPP/type_traits/is_complex.h +++ b/libc/src/__support/CPP/type_traits/is_complex.h @@ -10,6 +10,10 @@ #include "src/__support/CPP/type_traits/is_same.h" #include "src/__support/CPP/type_traits/remove_cv.h" +#include "src/__support/macros/attributes.h" +#include "src/__support/macros/config.h" +// LIBC_TYPES_HAS_CFLOAT16 && LIBC_TYPES_HAS_CFLOAT128 +#include "src/__support/macros/properties/complex_types.h" namespace LIBC_NAMESPACE_DECL { namespace cpp { @@ -25,7 +29,16 @@ template struct is_complex { public: LIBC_INLINE_VAR static constexpr bool value = __is_unqualified_any_of(); + _Complex long double +#ifdef LIBC_TYPES_HAS_CFLOAT16 + , + cfloat16 +#endif +#ifdef LIBC_TYPES_HAS_CFLOAT128 + , + cfloat128 +#endif + >(); }; template LIBC_INLINE_VAR constexpr bool is_complex_v = is_complex::value; diff --git a/libc/src/__support/macros/properties/CMakeLists.txt b/libc/src/__support/macros/properties/CMakeLists.txt index c69f3a85d7287..80ed63a2fbcf7 100644 --- a/libc/src/__support/macros/properties/CMakeLists.txt +++ b/libc/src/__support/macros/properties/CMakeLists.txt @@ -37,3 +37,13 @@ add_header_library( libc.include.llvm-libc-macros.float16_macros libc.include.llvm-libc-types.float128 ) + +add_header_library( + complex_types + HDRS + complex_types.h + DEPENDS + .types + libc.include.llvm-libc-types.cfloat16 + libc.include.llvm-libc-types.cfloat128 +) diff --git a/libc/src/__support/macros/properties/complex_types.h b/libc/src/__support/macros/properties/complex_types.h new file mode 100644 index 0000000000000..3f4a7646649c6 --- /dev/null +++ b/libc/src/__support/macros/properties/complex_types.h @@ -0,0 +1,25 @@ +//===-- Complex Types support -----------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// Complex Types detection and support. + +#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H +#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H + +#include "include/llvm-libc-types/cfloat128.h" +#include "include/llvm-libc-types/cfloat16.h" +#include "types.h" + +// -- cfloat16 support -------------------------------------------------------- +// LIBC_TYPES_HAS_CFLOAT16 and 'cfloat16' type is provided by +// "include/llvm-libc-types/cfloat16.h" + +// -- cfloat128 support ------------------------------------------------------- +// LIBC_TYPES_HAS_CFLOAT128 and 'cfloat128' type are provided by +// "include/llvm-libc-types/cfloat128.h" + +#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h index 5220b1245bf3a..07e2cd5df18cb 100644 --- a/libc/test/UnitTest/FPMatcher.h +++ b/libc/test/UnitTest/FPMatcher.h @@ -11,6 +11,7 @@ #include "src/__support/CPP/array.h" #include "src/__support/CPP/type_traits.h" +#include "src/__support/CPP/type_traits/is_complex.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/fpbits_str.h" @@ -128,6 +129,14 @@ template class CFPMatcher : public Matcher { return matchComplex(); else if (cpp::is_complex_type_same()) return matchComplex(); +#ifdef LIBC_TYPES_HAS_CFLOAT16 + else if (cpp::is_complex_type_same) + return matchComplex(); +#endif +#ifdef LIBC_TYPES_HAS_CFLOAT128 + else if (cpp::is_complex_type_same) + return matchComplex(); +#endif } void explainError() override { @@ -137,6 +146,14 @@ template class CFPMatcher : public Matcher { return explainErrorComplex(); else if (cpp::is_complex_type_same()) return explainErrorComplex(); +#ifdef LIBC_TYPES_HAS_CFLOAT16 + else if (cpp::is_complex_type_same) + return explainErrorComplex(); +#endif +#ifdef LIBC_TYPES_HAS_CFLOAT128 + else if (cpp::is_complex_type_same) + return explainErrorComplex(); +#endif } };