1 //===-- runtime/type-code.cpp ---------------------------------------------===//
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 #include "flang/Runtime/type-code.h"
10 
11 namespace Fortran::runtime {
12 
TypeCode(TypeCategory f,int kind)13 TypeCode::TypeCode(TypeCategory f, int kind) {
14   switch (f) {
15   case TypeCategory::Integer:
16     switch (kind) {
17     case 1:
18       raw_ = CFI_type_int8_t;
19       break;
20     case 2:
21       raw_ = CFI_type_int16_t;
22       break;
23     case 4:
24       raw_ = CFI_type_int32_t;
25       break;
26     case 8:
27       raw_ = CFI_type_int64_t;
28       break;
29     case 16:
30       raw_ = CFI_type_int128_t;
31       break;
32     }
33     break;
34   case TypeCategory::Real:
35     switch (kind) {
36     case 2:
37       raw_ = CFI_type_half_float;
38       break;
39     case 3:
40       raw_ = CFI_type_bfloat;
41       break;
42     case 4:
43       raw_ = CFI_type_float;
44       break;
45     case 8:
46       raw_ = CFI_type_double;
47       break;
48     case 10:
49       raw_ = CFI_type_extended_double;
50       break;
51     case 16:
52       raw_ = CFI_type_float128;
53       break;
54     }
55     break;
56   case TypeCategory::Complex:
57     switch (kind) {
58     case 2:
59       raw_ = CFI_type_half_float_Complex;
60       break;
61     case 3:
62       raw_ = CFI_type_bfloat_Complex;
63       break;
64     case 4:
65       raw_ = CFI_type_float_Complex;
66       break;
67     case 8:
68       raw_ = CFI_type_double_Complex;
69       break;
70     case 10:
71       raw_ = CFI_type_extended_double_Complex;
72       break;
73     case 16:
74       raw_ = CFI_type_long_double_Complex;
75       break;
76     }
77     break;
78   case TypeCategory::Character:
79     switch (kind) {
80     case 1:
81       raw_ = CFI_type_char;
82       break;
83     case 2:
84       raw_ = CFI_type_char16_t;
85       break;
86     case 4:
87       raw_ = CFI_type_char32_t;
88       break;
89     }
90     break;
91   case TypeCategory::Logical:
92     switch (kind) {
93     case 1:
94       raw_ = CFI_type_Bool;
95       break;
96     case 2:
97       raw_ = CFI_type_int_least16_t;
98       break;
99     case 4:
100       raw_ = CFI_type_int_least32_t;
101       break;
102     case 8:
103       raw_ = CFI_type_int_least64_t;
104       break;
105     }
106     break;
107   case TypeCategory::Derived:
108     raw_ = CFI_type_struct;
109     break;
110   }
111 }
112 
113 std::optional<std::pair<TypeCategory, int>>
GetCategoryAndKind() const114 TypeCode::GetCategoryAndKind() const {
115   switch (raw_) {
116   case CFI_type_int8_t:
117     return std::make_pair(TypeCategory::Integer, 1);
118   case CFI_type_int16_t:
119     return std::make_pair(TypeCategory::Integer, 2);
120   case CFI_type_int32_t:
121     return std::make_pair(TypeCategory::Integer, 4);
122   case CFI_type_int64_t:
123     return std::make_pair(TypeCategory::Integer, 8);
124   case CFI_type_int128_t:
125     return std::make_pair(TypeCategory::Integer, 16);
126   case CFI_type_half_float:
127     return std::make_pair(TypeCategory::Real, 2);
128   case CFI_type_bfloat:
129     return std::make_pair(TypeCategory::Real, 3);
130   case CFI_type_float:
131     return std::make_pair(TypeCategory::Real, 4);
132   case CFI_type_double:
133     return std::make_pair(TypeCategory::Real, 8);
134   case CFI_type_extended_double:
135     return std::make_pair(TypeCategory::Real, 10);
136   case CFI_type_long_double:
137     return std::make_pair(TypeCategory::Real, 16);
138   case CFI_type_float128:
139     return std::make_pair(TypeCategory::Real, 16);
140   case CFI_type_half_float_Complex:
141     return std::make_pair(TypeCategory::Complex, 2);
142   case CFI_type_bfloat_Complex:
143     return std::make_pair(TypeCategory::Complex, 3);
144   case CFI_type_float_Complex:
145     return std::make_pair(TypeCategory::Complex, 4);
146   case CFI_type_double_Complex:
147     return std::make_pair(TypeCategory::Complex, 8);
148   case CFI_type_extended_double_Complex:
149     return std::make_pair(TypeCategory::Complex, 10);
150   case CFI_type_long_double_Complex:
151     return std::make_pair(TypeCategory::Complex, 16);
152   case CFI_type_float128_Complex:
153     return std::make_pair(TypeCategory::Complex, 16);
154   case CFI_type_char:
155     return std::make_pair(TypeCategory::Character, 1);
156   case CFI_type_char16_t:
157     return std::make_pair(TypeCategory::Character, 2);
158   case CFI_type_char32_t:
159     return std::make_pair(TypeCategory::Character, 4);
160   case CFI_type_Bool:
161     return std::make_pair(TypeCategory::Logical, 1);
162   case CFI_type_int_least8_t:
163     return std::make_pair(TypeCategory::Logical, 1);
164   case CFI_type_int_least16_t:
165     return std::make_pair(TypeCategory::Logical, 2);
166   case CFI_type_int_least32_t:
167     return std::make_pair(TypeCategory::Logical, 4);
168   case CFI_type_int_least64_t:
169     return std::make_pair(TypeCategory::Logical, 8);
170   case CFI_type_struct:
171     return std::make_pair(TypeCategory::Derived, 0);
172   default:
173     return std::nullopt;
174   }
175 }
176 } // namespace Fortran::runtime
177