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.h"
15 #include "flang/Common/uint128.h"
16 #include "flang/Runtime/float128.h"
17 #include <cfloat>
18 #include <complex>
19 #include <cstdint>
20 #include <type_traits>
21 
22 namespace Fortran::runtime {
23 
24 using common::TypeCategory;
25 
26 template <TypeCategory CAT, int KIND> struct CppTypeForHelper {};
27 template <TypeCategory CAT, int KIND>
28 using CppTypeFor = typename CppTypeForHelper<CAT, KIND>::type;
29 
30 template <TypeCategory CAT, int KIND, bool SFINAE = false>
31 constexpr bool HasCppTypeFor{false};
32 template <TypeCategory CAT, int KIND>
33 constexpr bool HasCppTypeFor<CAT, KIND, true>{
34     !std::is_void_v<typename CppTypeForHelper<CAT, KIND>::type>};
35 
36 template <int KIND> struct CppTypeForHelper<TypeCategory::Integer, KIND> {
37   using type = common::HostSignedIntType<8 * KIND>;
38 };
39 
40 // TODO: REAL/COMPLEX(2 & 3)
41 template <> struct CppTypeForHelper<TypeCategory::Real, 4> {
42   using type = float;
43 };
44 template <> struct CppTypeForHelper<TypeCategory::Real, 8> {
45   using type = double;
46 };
47 #if LDBL_MANT_DIG == 64
48 template <> struct CppTypeForHelper<TypeCategory::Real, 10> {
49   using type = long double;
50 };
51 #endif
52 #if LDBL_MANT_DIG == 113
53 using CppFloat128Type = long double;
54 #elif HAS_FLOAT128
55 using CppFloat128Type = __float128;
56 #endif
57 #if LDBL_MANT_DIG == 113 || HAS_FLOAT128
58 template <> struct CppTypeForHelper<TypeCategory::Real, 16> {
59   using type = CppFloat128Type;
60 };
61 #endif
62 
63 template <int KIND> struct CppTypeForHelper<TypeCategory::Complex, KIND> {
64   using type = std::complex<CppTypeFor<TypeCategory::Real, KIND>>;
65 };
66 
67 template <> struct CppTypeForHelper<TypeCategory::Character, 1> {
68   using type = char;
69 };
70 template <> struct CppTypeForHelper<TypeCategory::Character, 2> {
71   using type = char16_t;
72 };
73 template <> struct CppTypeForHelper<TypeCategory::Character, 4> {
74   using type = char32_t;
75 };
76 
77 template <int KIND> struct CppTypeForHelper<TypeCategory::Logical, KIND> {
78   using type = common::HostSignedIntType<8 * KIND>;
79 };
80 template <> struct CppTypeForHelper<TypeCategory::Logical, 1> {
81   using type = bool;
82 };
83 
84 } // namespace Fortran::runtime
85 #endif // FORTRAN_RUNTIME_CPP_TYPE_H_
86