|
9 | 9 | #include "flang/Runtime/numeric.h"
|
10 | 10 | #include "numeric-templates.h"
|
11 | 11 | #include "terminator.h"
|
| 12 | +#include "tools.h" |
12 | 13 | #include "flang/Common/float128.h"
|
13 | 14 | #include <cfloat>
|
14 | 15 | #include <climits>
|
|
18 | 19 | namespace Fortran::runtime {
|
19 | 20 |
|
20 | 21 | template <typename RES>
|
21 |
| -inline RT_API_ATTRS RES getIntArgValue(const char *source, int line, void *arg, |
22 |
| - int kind, std::int64_t defaultValue, int resKind) { |
| 22 | +inline RT_API_ATTRS RES GetIntArgValue(const char *source, int line, |
| 23 | + const void *arg, int kind, std::int64_t defaultValue, int resKind) { |
23 | 24 | RES res;
|
24 | 25 | if (!arg) {
|
25 | 26 | res = static_cast<RES>(defaultValue);
|
26 | 27 | } else if (kind == 1) {
|
27 | 28 | res = static_cast<RES>(
|
28 |
| - *static_cast<CppTypeFor<TypeCategory::Integer, 1> *>(arg)); |
| 29 | + *static_cast<const CppTypeFor<TypeCategory::Integer, 1> *>(arg)); |
29 | 30 | } else if (kind == 2) {
|
30 | 31 | res = static_cast<RES>(
|
31 |
| - *static_cast<CppTypeFor<TypeCategory::Integer, 2> *>(arg)); |
| 32 | + *static_cast<const CppTypeFor<TypeCategory::Integer, 2> *>(arg)); |
32 | 33 | } else if (kind == 4) {
|
33 | 34 | res = static_cast<RES>(
|
34 |
| - *static_cast<CppTypeFor<TypeCategory::Integer, 4> *>(arg)); |
| 35 | + *static_cast<const CppTypeFor<TypeCategory::Integer, 4> *>(arg)); |
35 | 36 | } else if (kind == 8) {
|
36 | 37 | res = static_cast<RES>(
|
37 |
| - *static_cast<CppTypeFor<TypeCategory::Integer, 8> *>(arg)); |
| 38 | + *static_cast<const CppTypeFor<TypeCategory::Integer, 8> *>(arg)); |
38 | 39 | #ifdef __SIZEOF_INT128__
|
39 | 40 | } else if (kind == 16) {
|
40 | 41 | if (resKind != 16) {
|
41 | 42 | Terminator{source, line}.Crash("Unexpected integer kind in runtime");
|
42 | 43 | }
|
43 | 44 | res = static_cast<RES>(
|
44 |
| - *static_cast<CppTypeFor<TypeCategory::Integer, 16> *>(arg)); |
| 45 | + *static_cast<const CppTypeFor<TypeCategory::Integer, 16> *>(arg)); |
45 | 46 | #endif
|
46 | 47 | } else {
|
47 | 48 | Terminator{source, line}.Crash("Unexpected integer kind in runtime");
|
@@ -112,6 +113,22 @@ inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedIntKind(T x) {
|
112 | 113 | return -1;
|
113 | 114 | }
|
114 | 115 |
|
| 116 | +// SELECTED_LOGICAL_KIND (F'2023 16.9.182) |
| 117 | +template <typename T> |
| 118 | +inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedLogicalKind( |
| 119 | + T x) { |
| 120 | + if (x <= 2) { |
| 121 | + return 1; |
| 122 | + } else if (x <= 4) { |
| 123 | + return 2; |
| 124 | + } else if (x <= 9) { |
| 125 | + return 4; |
| 126 | + } else if (x <= 18) { |
| 127 | + return 8; |
| 128 | + } |
| 129 | + return -1; |
| 130 | +} |
| 131 | + |
115 | 132 | // SELECTED_REAL_KIND (16.9.170)
|
116 | 133 | template <typename P, typename R, typename D>
|
117 | 134 | inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedRealKind(
|
@@ -717,40 +734,72 @@ CppTypeFor<TypeCategory::Real, 10> RTDEF(Scale10)(
|
717 | 734 | }
|
718 | 735 | #endif
|
719 | 736 |
|
| 737 | +// SELECTED_CHAR_KIND |
| 738 | +CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedCharKind)( |
| 739 | + const char *source, int line, const char *x, std::size_t length) { |
| 740 | + static const char *keywords[]{ |
| 741 | + "ASCII", "DEFAULT", "UCS-2", "ISO_10646", "UCS-4", nullptr}; |
| 742 | + switch (IdentifyValue(x, length, keywords)) { |
| 743 | + case 0: // ASCII |
| 744 | + case 1: // DEFAULT |
| 745 | + return 1; |
| 746 | + case 2: // UCS-2 |
| 747 | + return 2; |
| 748 | + case 3: // ISO_10646 |
| 749 | + case 4: // UCS-4 |
| 750 | + return 4; |
| 751 | + default: |
| 752 | + return -1; |
| 753 | + } |
| 754 | +} |
720 | 755 | // SELECTED_INT_KIND
|
721 | 756 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedIntKind)(
|
722 | 757 | const char *source, int line, void *x, int xKind) {
|
723 | 758 | #ifdef __SIZEOF_INT128__
|
724 | 759 | CppTypeFor<TypeCategory::Integer, 16> r =
|
725 |
| - getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>( |
| 760 | + GetIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>( |
726 | 761 | source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 16);
|
727 | 762 | #else
|
728 |
| - std::int64_t r = getIntArgValue<std::int64_t>( |
| 763 | + std::int64_t r = GetIntArgValue<std::int64_t>( |
729 | 764 | source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8);
|
730 | 765 | #endif
|
731 | 766 | return SelectedIntKind(r);
|
732 | 767 | }
|
733 | 768 |
|
| 769 | +// SELECTED_LOGICAL_KIND |
| 770 | +CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedLogicalKind)( |
| 771 | + const char *source, int line, void *x, int xKind) { |
| 772 | +#ifdef __SIZEOF_INT128__ |
| 773 | + CppTypeFor<TypeCategory::Integer, 16> r = |
| 774 | + GetIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>( |
| 775 | + source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 16); |
| 776 | +#else |
| 777 | + std::int64_t r = GetIntArgValue<std::int64_t>( |
| 778 | + source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8); |
| 779 | +#endif |
| 780 | + return SelectedLogicalKind(r); |
| 781 | +} |
| 782 | + |
734 | 783 | // SELECTED_REAL_KIND
|
735 | 784 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedRealKind)(const char *source,
|
736 | 785 | int line, void *precision, int pKind, void *range, int rKind, void *radix,
|
737 | 786 | int dKind) {
|
738 | 787 | #ifdef __SIZEOF_INT128__
|
739 | 788 | CppTypeFor<TypeCategory::Integer, 16> p =
|
740 |
| - getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>( |
| 789 | + GetIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>( |
741 | 790 | source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 16);
|
742 | 791 | CppTypeFor<TypeCategory::Integer, 16> r =
|
743 |
| - getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>( |
| 792 | + GetIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>( |
744 | 793 | source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 16);
|
745 | 794 | CppTypeFor<TypeCategory::Integer, 16> d =
|
746 |
| - getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>( |
| 795 | + GetIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>( |
747 | 796 | source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 16);
|
748 | 797 | #else
|
749 |
| - std::int64_t p = getIntArgValue<std::int64_t>( |
| 798 | + std::int64_t p = GetIntArgValue<std::int64_t>( |
750 | 799 | source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 8);
|
751 |
| - std::int64_t r = getIntArgValue<std::int64_t>( |
| 800 | + std::int64_t r = GetIntArgValue<std::int64_t>( |
752 | 801 | source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 8);
|
753 |
| - std::int64_t d = getIntArgValue<std::int64_t>( |
| 802 | + std::int64_t d = GetIntArgValue<std::int64_t>( |
754 | 803 | source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 8);
|
755 | 804 | #endif
|
756 | 805 | return SelectedRealKind(p, r, d);
|
|
0 commit comments