1 //===-- include/flang/Runtime/cpp-type.h ------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // Maps Fortran intrinsic types to C++ types used in the runtime. 10 11 #ifndef FORTRAN_RUNTIME_CPP_TYPE_H_ 12 #define FORTRAN_RUNTIME_CPP_TYPE_H_ 13 14 #include "flang/Common/Fortran-consts.h" 15 #include "flang/Common/float128.h" 16 #include "flang/Common/float80.h" 17 #include "flang/Common/uint128.h" 18 #include "flang/Runtime/complex.h" 19 #include <cstdint> 20 #if __cplusplus >= 202302 21 #include <stdfloat> 22 #endif 23 #include <type_traits> 24 25 #if !defined HAS_FP16 && __STDCPP_FLOAT16_T__ 26 #define HAS_FP16 1 27 #endif 28 #if !defined HAS_BF16 && __STDCPP_BFLOAT16_T__ 29 #define HAS_BF16 1 30 #endif 31 32 namespace Fortran::runtime { 33 34 using common::TypeCategory; 35 36 template <TypeCategory CAT, int KIND> struct CppTypeForHelper { 37 using type = void; 38 }; 39 template <TypeCategory CAT, int KIND> 40 using CppTypeFor = typename CppTypeForHelper<CAT, KIND>::type; 41 42 template <TypeCategory CAT, int KIND> 43 constexpr bool HasCppTypeFor{ 44 !std::is_void_v<typename CppTypeForHelper<CAT, KIND>::type>}; 45 46 template <int KIND> struct CppTypeForHelper<TypeCategory::Integer, KIND> { 47 using type = common::HostSignedIntType<8 * KIND>; 48 }; 49 50 template <int KIND> struct CppTypeForHelper<TypeCategory::Unsigned, KIND> { 51 using type = common::HostUnsignedIntType<8 * KIND>; 52 }; 53 54 #if HAS_FP16 55 template <> struct CppTypeForHelper<TypeCategory::Real, 2> { 56 using type = std::float16_t; 57 }; 58 #endif 59 #if HAS_BF16 60 template <> struct CppTypeForHelper<TypeCategory::Real, 3> { 61 using type = std::bfloat16_t; 62 }; 63 #endif 64 template <> struct CppTypeForHelper<TypeCategory::Real, 4> { 65 #if __STDCPP_FLOAT32_T__ 66 using type = std::float32_t; 67 #else 68 using type = float; 69 #endif 70 }; 71 template <> struct CppTypeForHelper<TypeCategory::Real, 8> { 72 #if __STDCPP_FLOAT64_T__ 73 using type = std::float64_t; 74 #else 75 using type = double; 76 #endif 77 }; 78 #if HAS_FLOAT80 79 template <> struct CppTypeForHelper<TypeCategory::Real, 10> { 80 using type = CppFloat80Type; 81 }; 82 #endif 83 #if __STDCPP_FLOAT128_T__ 84 using CppFloat128Type = std::float128_t; 85 #elif HAS_LDBL128 86 using CppFloat128Type = long double; 87 #elif HAS_FLOAT128 88 using CppFloat128Type = __float128; 89 #endif 90 #if __STDCPP_FLOAT128_t || HAS_LDBL128 || HAS_FLOAT128 91 template <> struct CppTypeForHelper<TypeCategory::Real, 16> { 92 using type = CppFloat128Type; 93 }; 94 #endif 95 96 template <int KIND> struct CppTypeForHelper<TypeCategory::Complex, KIND> { 97 using type = rtcmplx::complex<CppTypeFor<TypeCategory::Real, KIND>>; 98 }; 99 100 template <> struct CppTypeForHelper<TypeCategory::Character, 1> { 101 using type = char; 102 }; 103 template <> struct CppTypeForHelper<TypeCategory::Character, 2> { 104 using type = char16_t; 105 }; 106 template <> struct CppTypeForHelper<TypeCategory::Character, 4> { 107 using type = char32_t; 108 }; 109 110 template <int KIND> struct CppTypeForHelper<TypeCategory::Logical, KIND> { 111 using type = common::HostSignedIntType<8 * KIND>; 112 }; 113 template <> struct CppTypeForHelper<TypeCategory::Logical, 1> { 114 using type = bool; 115 }; 116 117 } // namespace Fortran::runtime 118 #endif // FORTRAN_RUNTIME_CPP_TYPE_H_ 119