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 maxKind{16};
26
27template <typename T, std::size_t N>
28static constexpr bool IsKindInList(const T (&kinds)[N], std::int64_t kind) {
29 for (std::size_t i{0}; i < N; ++i) {
30 if (kinds[i] == kind)
31 return true;
32 }
33 return false;
34}
35
36// A predicate that is true when a kind value is a kind that could possibly
37// be supported for an intrinsic type category on some target instruction
38// set architecture.
39static constexpr bool IsValidKindOfIntrinsicType(
40 TypeCategory category, std::int64_t kind) {
41 switch (category) {
42 case TypeCategory::Integer:
43 case TypeCategory::Unsigned: {
44 constexpr int kinds[] = FORTRAN_INTEGER_KINDS;
45 return IsKindInList(kinds, kind);
46 }
47 case TypeCategory::Real:
48 case TypeCategory::Complex: {
49 constexpr int kinds[] = FORTRAN_REAL_KINDS;
50 return IsKindInList(kinds, kind);
51 }
52 case TypeCategory::Character: {
53 constexpr int kinds[] = FORTRAN_CHARACTER_KINDS;
54 return IsKindInList(kinds, kind);
55 }
56 case TypeCategory::Logical: {
57 constexpr int kinds[] = FORTRAN_LOGICAL_KINDS;
58 return IsKindInList(kinds, kind);
59 }
60 default:
61 return false;
62 }
63}
64
65static constexpr int TypeSizeInBytes(TypeCategory category, std::int64_t kind) {
66 if (IsValidKindOfIntrinsicType(category, kind)) {
67 if (category == TypeCategory::Real || category == TypeCategory::Complex) {
68 int precision{PrecisionOfRealKind(kind)};
69 int bits{BitsForBinaryPrecision(precision)};
70 if (bits == 80) { // x87 is stored in 16-byte containers
71 bits = 128;
72 }
73 if (category == TypeCategory::Complex) {
74 bits *= 2;
75 }
76 return bits >> 3;
77 } else {
78 return kind;
79 }
80 } else {
81 return -1;
82 }
83}
84
85} // namespace Fortran::common
86#endif // FORTRAN_COMMON_TYPE_KINDS_H_
Definition bit-population-count.h:20