FLANG
type-kinds.h
1//===-- include/flang/Common/type-kinds.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#ifndef FORTRAN_COMMON_TYPE_KINDS_H_
10#define FORTRAN_COMMON_TYPE_KINDS_H_
11
12#include "Fortran-consts.h"
13#include "real.h"
14#include <cinttypes>
15
16// Canonical lists of supported Fortran kinds for each intrinsic type.
17#define FORTRAN_INTEGER_KINDS {1, 2, 4, 8, 16}
18#define FORTRAN_UNSIGNED_KINDS FORTRAN_INTEGER_KINDS
19#define FORTRAN_REAL_KINDS {2, 3, 4, 8, 10, 16}
20#define FORTRAN_LOGICAL_KINDS {1, 2, 4, 8}
21#define FORTRAN_CHARACTER_KINDS {1, 2, 4}
22
23namespace Fortran::common {
24
25static constexpr int IntegerKinds[] FORTRAN_INTEGER_KINDS;
26static constexpr int UnsignedKinds[] FORTRAN_UNSIGNED_KINDS;
27static constexpr int RealKinds[] FORTRAN_REAL_KINDS;
28static constexpr int LogicalKinds[] FORTRAN_LOGICAL_KINDS;
29static constexpr int CharacterKinds[] FORTRAN_CHARACTER_KINDS;
30
32template <TypeCategory CAT> struct KindsByType;
33template <> struct KindsByType<TypeCategory::Integer> {
34 static inline constexpr int kinds[] FORTRAN_INTEGER_KINDS;
35};
36template <> struct KindsByType<TypeCategory::Unsigned> {
37 static inline constexpr int kinds[] FORTRAN_UNSIGNED_KINDS;
38};
39template <> struct KindsByType<TypeCategory::Real> {
40 static inline constexpr int kinds[] FORTRAN_REAL_KINDS;
41};
42template <> struct KindsByType<TypeCategory::Complex> {
43 static inline constexpr int kinds[] FORTRAN_REAL_KINDS;
44};
45template <> struct KindsByType<TypeCategory::Logical> {
46 static inline constexpr int kinds[] FORTRAN_LOGICAL_KINDS;
47};
48template <> struct KindsByType<TypeCategory::Character> {
49 static inline constexpr int kinds[] FORTRAN_CHARACTER_KINDS;
50};
51template <> struct KindsByType<TypeCategory::Derived> {
52 static inline constexpr int kinds[]{0};
53};
54
55static constexpr int maxKind{16};
56
57template <typename T, std::size_t N>
58static constexpr bool IsKindInList(const T (&kinds)[N], std::int64_t kind) {
59 for (std::size_t i{0}; i < N; ++i) {
60 if (kinds[i] == kind)
61 return true;
62 }
63 return false;
64}
65
66// A predicate that is true when a kind value is a kind that could possibly
67// be supported for an intrinsic type category on some target instruction
68// set architecture.
69static constexpr bool IsValidKindOfIntrinsicType(
70 TypeCategory category, std::int64_t kind) {
71 switch (category) {
72 case TypeCategory::Integer:
73 case TypeCategory::Unsigned: {
74 constexpr int kinds[] = FORTRAN_INTEGER_KINDS;
75 return IsKindInList(kinds, kind);
76 }
77 case TypeCategory::Real:
78 case TypeCategory::Complex: {
79 constexpr int kinds[] = FORTRAN_REAL_KINDS;
80 return IsKindInList(kinds, kind);
81 }
82 case TypeCategory::Character: {
83 constexpr int kinds[] = FORTRAN_CHARACTER_KINDS;
84 return IsKindInList(kinds, kind);
85 }
86 case TypeCategory::Logical: {
87 constexpr int kinds[] = FORTRAN_LOGICAL_KINDS;
88 return IsKindInList(kinds, kind);
89 }
90 default:
91 return false;
92 }
93}
94
95static constexpr int TypeSizeInBytes(TypeCategory category, std::int64_t kind) {
96 if (IsValidKindOfIntrinsicType(category, kind)) {
97 if (category == TypeCategory::Real || category == TypeCategory::Complex) {
98 int precision{PrecisionOfRealKind(kind)};
99 int bits{BitsForBinaryPrecision(precision)};
100 if (bits == 80) { // x87 is stored in 16-byte containers
101 bits = 128;
102 }
103 if (category == TypeCategory::Complex) {
104 bits *= 2;
105 }
106 return bits >> 3;
107 } else {
108 return kind;
109 }
110 } else {
111 return -1;
112 }
113}
114
115} // namespace Fortran::common
116#endif // FORTRAN_COMMON_TYPE_KINDS_H_
Definition bit-population-count.h:20
Iterable lists of valid kinds for each TypeCategory.
Definition type-kinds.h:32