xref: /llvm-project/flang/include/flang/Runtime/cpp-type.h (revision fc97d2e68b03bc2979395e84b645e5b3ba35aecd)
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