[llvm-branch-commits] [flang] [llvm] [Flang] Introduce KindsEnum for strong typing (PR #217828)
Michael Kruse via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Aug 21 00:01:48 PDT 2026
https://github.com/Meinersbur created https://github.com/llvm/llvm-project/pull/217828
Proposed here: https://github.com/llvm/llvm-project/pull/206907#discussion_r3783309935
>From 3aa2a68d9289f4d6f48891f334e60b136edb92d0 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Wed, 19 Aug 2026 21:34:23 +0200
Subject: [PATCH] Conversion to KindsEnum
---
flang-rt/lib/runtime/descriptor.cpp | 3 +-
flang-rt/lib/runtime/iso_fortran_env_impl.cpp | 20 +-
flang/include/flang/Common/type-kinds.h | 114 ++++++--
flang/include/flang/Evaluate/call.h | 16 +-
.../include/flang/Evaluate/character-value.h | 36 +--
flang/include/flang/Evaluate/common.h | 11 +
flang/include/flang/Evaluate/complex-value.h | 19 +-
flang/include/flang/Evaluate/constant.h | 50 ++--
flang/include/flang/Evaluate/expression.h | 97 +++----
.../include/flang/Evaluate/fold-designator.h | 9 +-
flang/include/flang/Evaluate/initial-image.h | 6 +-
flang/include/flang/Evaluate/integer-value.h | 44 ++--
flang/include/flang/Evaluate/logical-value.h | 27 +-
flang/include/flang/Evaluate/real-value.h | 57 ++--
flang/include/flang/Evaluate/rewrite.h | 2 +-
flang/include/flang/Evaluate/shape.h | 2 +-
flang/include/flang/Evaluate/target.h | 29 +-
flang/include/flang/Evaluate/tools.h | 64 ++---
flang/include/flang/Evaluate/type.h | 102 ++++----
.../include/flang/Evaluate/typekind-traits.h | 64 +++--
flang/include/flang/Evaluate/variable.h | 30 +--
flang/include/flang/Frontend/TargetOptions.h | 5 +-
flang/include/flang/Lower/Mangler.h | 6 +-
flang/include/flang/Lower/Support/Utils.h | 4 +-
flang/include/flang/Semantics/expression.h | 14 +-
flang/include/flang/Semantics/semantics.h | 13 +-
flang/include/flang/Semantics/type.h | 3 +-
flang/include/flang/Support/default-kinds.h | 50 ++--
flang/include/flang/Tools/TargetSetup.h | 30 ++-
flang/lib/Evaluate/character-value-impl.cpp | 26 +-
flang/lib/Evaluate/character-value-impl.h | 35 +--
flang/lib/Evaluate/character-value.cpp | 22 +-
flang/lib/Evaluate/character.h | 25 +-
flang/lib/Evaluate/characteristics.cpp | 4 +-
flang/lib/Evaluate/check-expression.cpp | 19 +-
flang/lib/Evaluate/complex-value.cpp | 8 +-
flang/lib/Evaluate/constant.cpp | 23 +-
flang/lib/Evaluate/expression.cpp | 26 +-
flang/lib/Evaluate/fold-character.cpp | 19 +-
flang/lib/Evaluate/fold-complex.cpp | 9 +-
flang/lib/Evaluate/fold-designator.cpp | 9 +-
flang/lib/Evaluate/fold-implementation.h | 183 ++++++-------
flang/lib/Evaluate/fold-integer.cpp | 122 +++++----
flang/lib/Evaluate/fold-logical.cpp | 64 +++--
flang/lib/Evaluate/fold-matmul.h | 2 +-
flang/lib/Evaluate/fold-real.cpp | 52 ++--
flang/lib/Evaluate/fold-reduction.h | 20 +-
flang/lib/Evaluate/formatting.cpp | 11 +-
flang/lib/Evaluate/host.h | 14 +-
flang/lib/Evaluate/initial-image.cpp | 7 +-
flang/lib/Evaluate/int-power.h | 6 +-
flang/lib/Evaluate/integer-value-impl.cpp | 6 +-
flang/lib/Evaluate/integer-value-impl.h | 1 +
flang/lib/Evaluate/integer-value.cpp | 49 ++--
flang/lib/Evaluate/intrinsics-library.cpp | 25 +-
flang/lib/Evaluate/intrinsics.cpp | 60 +++--
flang/lib/Evaluate/real-value-impl.cpp | 31 ++-
flang/lib/Evaluate/real-value-impl.h | 14 +-
flang/lib/Evaluate/real-value.cpp | 79 +++---
flang/lib/Evaluate/shape.cpp | 4 +-
flang/lib/Evaluate/target.cpp | 85 +++---
flang/lib/Evaluate/tools.cpp | 116 ++++----
flang/lib/Evaluate/type.cpp | 70 +++--
flang/lib/Evaluate/variable.cpp | 7 +-
flang/lib/Frontend/CompilerInvocation.cpp | 50 ++--
flang/lib/Lower/Bridge.cpp | 3 +-
flang/lib/Lower/CallInterface.cpp | 28 +-
flang/lib/Lower/ConvertArrayConstructor.cpp | 4 +-
flang/lib/Lower/ConvertConstant.cpp | 18 +-
flang/lib/Lower/ConvertExprToHLFIR.cpp | 25 +-
flang/lib/Lower/ConvertType.cpp | 23 +-
flang/lib/Lower/IO.cpp | 7 +-
flang/lib/Lower/OpenMP/Atomic.cpp | 1 -
flang/lib/Lower/Support/Utils.cpp | 28 +-
flang/lib/Semantics/check-allocate.cpp | 4 +-
flang/lib/Semantics/check-call.cpp | 22 +-
flang/lib/Semantics/check-case.cpp | 22 +-
flang/lib/Semantics/check-data.cpp | 2 +-
flang/lib/Semantics/check-declarations.cpp | 14 +-
flang/lib/Semantics/check-io.cpp | 16 +-
flang/lib/Semantics/check-omp-atomic.cpp | 6 +-
flang/lib/Semantics/check-omp-structure.cpp | 2 +-
flang/lib/Semantics/compute-offsets.cpp | 3 +-
flang/lib/Semantics/data-to-inits.cpp | 8 +-
flang/lib/Semantics/expression.cpp | 162 +++++++-----
flang/lib/Semantics/resolve-names-utils.cpp | 14 +-
flang/lib/Semantics/resolve-names.cpp | 30 ++-
flang/lib/Semantics/runtime-type-info.cpp | 80 +++---
flang/lib/Semantics/semantics.cpp | 10 +-
flang/lib/Semantics/type.cpp | 15 +-
flang/lib/Support/default-kinds.cpp | 21 +-
flang/tools/f18-parse-demo/f18-parse-demo.cpp | 6 +-
.../unittests/Evaluate/CharacterValueTest.cpp | 112 ++++----
flang/unittests/Evaluate/ComplexValueTest.cpp | 114 ++++----
flang/unittests/Evaluate/IntegerValueTest.cpp | 247 +++++++++---------
flang/unittests/Evaluate/LogicalValueTest.cpp | 64 ++---
flang/unittests/Evaluate/RealValueTest.cpp | 238 +++++++++--------
flang/unittests/Evaluate/expression.cpp | 5 +-
flang/unittests/Evaluate/folding.cpp | 10 +-
flang/unittests/Evaluate/intrinsics.cpp | 135 +++++-----
flang/unittests/Evaluate/logical.cpp | 13 +-
101 files changed, 2056 insertions(+), 1686 deletions(-)
diff --git a/flang-rt/lib/runtime/descriptor.cpp b/flang-rt/lib/runtime/descriptor.cpp
index 4aacbf6ae7949..8e142e2c3e443 100644
--- a/flang-rt/lib/runtime/descriptor.cpp
+++ b/flang-rt/lib/runtime/descriptor.cpp
@@ -66,7 +66,8 @@ RT_API_ATTRS void Descriptor::Establish(TypeCode t, std::size_t elementBytes,
RT_API_ATTRS std::size_t Descriptor::BytesFor(TypeCategory category, int kind) {
Terminator terminator{__FILE__, __LINE__};
- int bytes{common::TypeSizeInBytes(category, kind)};
+ int bytes{static_cast<int>(
+ common::TypeSizeInBytes(category, static_cast<common::KindsEnum>(kind)))};
RUNTIME_CHECK(terminator, bytes > 0);
return bytes;
}
diff --git a/flang-rt/lib/runtime/iso_fortran_env_impl.cpp b/flang-rt/lib/runtime/iso_fortran_env_impl.cpp
index 70230d0f16c7a..2572b94a11896 100644
--- a/flang-rt/lib/runtime/iso_fortran_env_impl.cpp
+++ b/flang-rt/lib/runtime/iso_fortran_env_impl.cpp
@@ -230,11 +230,23 @@ extern const std::int32_t FORTRAN_NAMED_CONST(real80){real80};
extern const std::int32_t FORTRAN_NAMED_CONST(real64x2){real64x2};
extern const std::int32_t FORTRAN_NAMED_CONST(real128){real128};
-extern const std::int32_t FORTRAN_NAMED_CONST(
- __builtin_integer_kinds)[] = FORTRAN_INTEGER_KINDS;
+// FORTRAN_INTEGER_KINDS/FORTRAN_LOGICAL_KINDS expand to lists of
+// Fortran::common::KindsEnum values; cast each to std::int32_t for this
+// externally-visible ABI array.
+extern const std::int32_t FORTRAN_NAMED_CONST(__builtin_integer_kinds)[]{
+ static_cast<std::int32_t>(Fortran::common::KindsEnum::Kind1),
+ static_cast<std::int32_t>(Fortran::common::KindsEnum::Kind2),
+ static_cast<std::int32_t>(Fortran::common::KindsEnum::Kind4),
+ static_cast<std::int32_t>(Fortran::common::KindsEnum::Kind8),
+ static_cast<std::int32_t>(Fortran::common::KindsEnum::Kind16),
+};
-extern const std::int32_t FORTRAN_NAMED_CONST(
- __builtin_logical_kinds)[] = FORTRAN_LOGICAL_KINDS;
+extern const std::int32_t FORTRAN_NAMED_CONST(__builtin_logical_kinds)[]{
+ static_cast<std::int32_t>(Fortran::common::KindsEnum::Kind1),
+ static_cast<std::int32_t>(Fortran::common::KindsEnum::Kind2),
+ static_cast<std::int32_t>(Fortran::common::KindsEnum::Kind4),
+ static_cast<std::int32_t>(Fortran::common::KindsEnum::Kind8),
+};
// Target-filtered subset of FORTRAN_REAL_KINDS from type-kinds.h.
extern const std::int32_t FORTRAN_NAMED_CONST(__builtin_real_kinds)[]{
diff --git a/flang/include/flang/Common/type-kinds.h b/flang/include/flang/Common/type-kinds.h
index 926cce6f25909..fdee0279046dd 100644
--- a/flang/include/flang/Common/type-kinds.h
+++ b/flang/include/flang/Common/type-kinds.h
@@ -14,53 +14,126 @@
#include <cinttypes>
// Canonical lists of supported Fortran kinds for each intrinsic type.
-#define FORTRAN_INTEGER_KINDS {1, 2, 4, 8, 16}
+#define FORTRAN_INTEGER_KINDS \
+ {Fortran::common::KindsEnum::Kind1, Fortran::common::KindsEnum::Kind2, \
+ Fortran::common::KindsEnum::Kind4, Fortran::common::KindsEnum::Kind8, \
+ Fortran::common::KindsEnum::Kind16}
#define FORTRAN_UNSIGNED_KINDS FORTRAN_INTEGER_KINDS
-#define FORTRAN_REAL_KINDS {2, 3, 4, 8, 10, 16}
-#define FORTRAN_LOGICAL_KINDS {1, 2, 4, 8}
-#define FORTRAN_CHARACTER_KINDS {1, 2, 4}
+#define FORTRAN_REAL_KINDS \
+ {Fortran::common::KindsEnum::Kind2, Fortran::common::KindsEnum::Kind3, \
+ Fortran::common::KindsEnum::Kind4, Fortran::common::KindsEnum::Kind8, \
+ Fortran::common::KindsEnum::Kind10, Fortran::common::KindsEnum::Kind16}
+#define FORTRAN_LOGICAL_KINDS \
+ {Fortran::common::KindsEnum::Kind1, Fortran::common::KindsEnum::Kind2, \
+ Fortran::common::KindsEnum::Kind4, Fortran::common::KindsEnum::Kind8}
+#define FORTRAN_CHARACTER_KINDS \
+ {Fortran::common::KindsEnum::Kind1, Fortran::common::KindsEnum::Kind2, \
+ Fortran::common::KindsEnum::Kind4}
namespace Fortran::common {
-static constexpr int IntegerKinds[] FORTRAN_INTEGER_KINDS;
-static constexpr int UnsignedKinds[] FORTRAN_UNSIGNED_KINDS;
-static constexpr int RealKinds[] FORTRAN_REAL_KINDS;
-static constexpr int LogicalKinds[] FORTRAN_LOGICAL_KINDS;
-static constexpr int CharacterKinds[] FORTRAN_CHARACTER_KINDS;
+/// All possible kinds. Used to strongly type Fortran KIND values.
+///
+/// Cannot use ENUM_CLASS here because it does not support assigned values.
+enum class KindsEnum : int {
+ InvalidKind = -1,
+ NoKind = 0,
+
+ Kind1 = 1,
+ Kind2 = 2,
+ Kind3 = 3,
+ Kind4 = 4,
+ Kind8 = 8,
+ Kind10 = 10,
+ Kind16 = 16,
+
+ // SpecialKinds
+ AssumedTypeKind = -3,
+ ClassKind = -2,
+ TypelessKind = -1,
+};
+
+inline constexpr bool operator<(KindsEnum a, KindsEnum b) {
+ return static_cast<int>(a) < static_cast<int>(b);
+}
+inline constexpr bool operator<=(KindsEnum a, KindsEnum b) {
+ return static_cast<int>(a) <= static_cast<int>(b);
+}
+inline constexpr bool operator>(KindsEnum a, KindsEnum b) {
+ return static_cast<int>(a) > static_cast<int>(b);
+}
+inline constexpr bool operator>=(KindsEnum a, KindsEnum b) {
+ return static_cast<int>(a) >= static_cast<int>(b);
+}
+
+inline constexpr KindsEnum IntegerKinds[] FORTRAN_INTEGER_KINDS;
+inline constexpr KindsEnum UnsignedKinds[] FORTRAN_UNSIGNED_KINDS;
+inline constexpr KindsEnum RealKinds[] FORTRAN_REAL_KINDS;
+inline constexpr KindsEnum LogicalKinds[] FORTRAN_LOGICAL_KINDS;
+inline constexpr KindsEnum CharacterKinds[] FORTRAN_CHARACTER_KINDS;
+
+/// Iterable lists of valid kinds for each TypeCategory for use by SearchTypes.
+template <TypeCategory CAT> struct KindsByType;
+template <> struct KindsByType<TypeCategory::Integer> {
+ static inline constexpr KindsEnum kinds[] FORTRAN_INTEGER_KINDS;
+};
+template <> struct KindsByType<TypeCategory::Unsigned> {
+ static inline constexpr KindsEnum kinds[] FORTRAN_UNSIGNED_KINDS;
+};
+template <> struct KindsByType<TypeCategory::Real> {
+ static inline constexpr KindsEnum kinds[] FORTRAN_REAL_KINDS;
+};
+template <> struct KindsByType<TypeCategory::Complex> {
+ static inline constexpr KindsEnum kinds[] FORTRAN_REAL_KINDS;
+};
+template <> struct KindsByType<TypeCategory::Logical> {
+ static inline constexpr KindsEnum kinds[] FORTRAN_LOGICAL_KINDS;
+};
+template <> struct KindsByType<TypeCategory::Character> {
+ static inline constexpr KindsEnum kinds[] FORTRAN_CHARACTER_KINDS;
+};
+template <> struct KindsByType<TypeCategory::Derived> {
+ static inline constexpr KindsEnum kinds[]{KindsEnum::NoKind};
+};
static constexpr int maxKind{16};
template <typename T, std::size_t N>
-static constexpr bool IsKindInList(const T (&kinds)[N], std::int64_t kind) {
+static constexpr bool IsKindInList(const T (&kinds)[N], KindsEnum kind) {
for (std::size_t i{0}; i < N; ++i) {
- if (kinds[i] == kind)
+ if (kinds[i] == static_cast<T>(kind))
return true;
}
return false;
}
+inline constexpr bool IsValidKind(KindsEnum kind) {
+ int val{static_cast<int>(kind)};
+ return 1 <= val && val <= maxKind;
+}
+
// A predicate that is true when a kind value is a kind that could possibly
// be supported for an intrinsic type category on some target instruction
// set architecture.
static constexpr bool IsValidKindOfIntrinsicType(
- TypeCategory category, std::int64_t kind) {
+ TypeCategory category, KindsEnum kind) {
switch (category) {
case TypeCategory::Integer:
case TypeCategory::Unsigned: {
- constexpr int kinds[] = FORTRAN_INTEGER_KINDS;
+ constexpr auto &kinds = KindsByType<TypeCategory::Integer>::kinds;
return IsKindInList(kinds, kind);
}
case TypeCategory::Real:
case TypeCategory::Complex: {
- constexpr int kinds[] = FORTRAN_REAL_KINDS;
+ constexpr auto &kinds = KindsByType<TypeCategory::Real>::kinds;
return IsKindInList(kinds, kind);
}
case TypeCategory::Character: {
- constexpr int kinds[] = FORTRAN_CHARACTER_KINDS;
+ constexpr auto &kinds = KindsByType<TypeCategory::Character>::kinds;
return IsKindInList(kinds, kind);
}
case TypeCategory::Logical: {
- constexpr int kinds[] = FORTRAN_LOGICAL_KINDS;
+ constexpr auto &kinds = KindsByType<TypeCategory::Logical>::kinds;
return IsKindInList(kinds, kind);
}
default:
@@ -68,10 +141,11 @@ static constexpr bool IsValidKindOfIntrinsicType(
}
}
-static constexpr int TypeSizeInBytes(TypeCategory category, std::int64_t kind) {
+static constexpr KindsEnum TypeSizeInBytes(
+ TypeCategory category, KindsEnum kind) {
if (IsValidKindOfIntrinsicType(category, kind)) {
if (category == TypeCategory::Real || category == TypeCategory::Complex) {
- int precision{PrecisionOfRealKind(kind)};
+ int precision{PrecisionOfRealKind(static_cast<int>(kind))};
int bits{BitsForBinaryPrecision(precision)};
if (bits == 80) { // x87 is stored in 16-byte containers
bits = 128;
@@ -79,12 +153,12 @@ static constexpr int TypeSizeInBytes(TypeCategory category, std::int64_t kind) {
if (category == TypeCategory::Complex) {
bits *= 2;
}
- return bits >> 3;
+ return static_cast<KindsEnum>(bits >> 3);
} else {
return kind;
}
} else {
- return -1;
+ return KindsEnum::InvalidKind;
}
}
diff --git a/flang/include/flang/Evaluate/call.h b/flang/include/flang/Evaluate/call.h
index 5001fbc85920e..99663379c03f7 100644
--- a/flang/include/flang/Evaluate/call.h
+++ b/flang/include/flang/Evaluate/call.h
@@ -296,9 +296,9 @@ struct SpecificIntrinsic {
};
struct ProcedureDesignator {
- static int kind() {
+ static KindsEnum kind() {
llvm_unreachable("This class has no kind");
- return 0;
+ return NoKind;
}
EVALUATE_UNION_CLASS_BOILERPLATE(ProcedureDesignator)
@@ -338,9 +338,9 @@ using Chevrons = std::vector<Expr<SomeType>>;
class ProcedureRef {
public:
- static int kind() {
+ static KindsEnum kind() {
llvm_unreachable("This class has no kind");
- return 0;
+ return NoKind;
}
CLASS_BOILERPLATE(ProcedureRef)
@@ -403,14 +403,14 @@ class ProcedureRef {
template <typename A> class FunctionRef : public ProcedureRef {
public:
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
using Result = A;
CLASS_BOILERPLATE(FunctionRef)
- explicit FunctionRef(int kind, ProcedureRef &&pr)
+ explicit FunctionRef(KindsEnum kind, ProcedureRef &&pr)
: ProcedureRef{std::move(pr)}, kind_{kind} {}
- FunctionRef(int kind, ProcedureDesignator &&p, ActualArguments &&a)
+ FunctionRef(KindsEnum kind, ProcedureDesignator &&p, ActualArguments &&a)
: ProcedureRef{std::move(p), std::move(a)}, kind_{kind} {}
std::optional<DynamicType> GetType() const {
@@ -429,7 +429,7 @@ template <typename A> class FunctionRef : public ProcedureRef {
}
private:
- int kind_;
+ KindsEnum kind_;
};
} // namespace Fortran::evaluate
#endif // FORTRAN_EVALUATE_CALL_H_
diff --git a/flang/include/flang/Evaluate/character-value.h b/flang/include/flang/Evaluate/character-value.h
index 84fa95818c966..9d08e9fa71d00 100644
--- a/flang/include/flang/Evaluate/character-value.h
+++ b/flang/include/flang/Evaluate/character-value.h
@@ -9,6 +9,7 @@
#ifndef FORTRAN_EVALUATE_CHARACTER_VALUE_H_
#define FORTRAN_EVALUATE_CHARACTER_VALUE_H_
+#include "flang/Common/type-kinds.h"
#include "flang/Evaluate/common.h"
#include "flang/Evaluate/object-sizes.h"
#include "flang/Evaluate/type.h"
@@ -21,6 +22,7 @@
namespace Fortran::evaluate::value {
class CharacterValueImpl;
+using common::KindsEnum;
/// A character string with dynamic character representation with
/// std::basic_string-like API.
@@ -47,18 +49,18 @@ class CharacterValue {
/// operations are supported in this state.
CharacterValue();
- explicit CharacterValue(int kind, std::string s);
- explicit CharacterValue(int kind, std::u16string s);
- explicit CharacterValue(int kind, std::u32string s);
+ explicit CharacterValue(KindsEnum kind, std::string s);
+ explicit CharacterValue(KindsEnum kind, std::u16string s);
+ explicit CharacterValue(KindsEnum kind, std::u32string s);
/// Fill constructor: create a string of n copies of the given character.
- CharacterValue(int kind, std::size_t n, char32_t c);
+ CharacterValue(KindsEnum kind, std::size_t n, char32_t c);
// Named ctors
- static CharacterValue Zero(int kind);
+ static CharacterValue Zero(KindsEnum kind);
static CharacterValue FromRawBytes(
- int kind, const void *raw, size_t byteSize);
+ KindsEnum kind, const void *raw, size_t byteSize);
void print(llvm::raw_ostream &os) const;
@@ -71,14 +73,14 @@ class CharacterValue {
bool IsMonostate() const;
/// The kind of the value currently stored.
- int kind() const;
+ KindsEnum kind() const;
bool empty() const;
std::size_t size() const;
std::size_t length() const { return size(); }
/// Byte size of one character unit (1, 2, or 4).
- std::size_t charSize() const { return kind(); }
+ std::size_t charSize() const { return static_cast<std::size_t>(kind()); }
/// Number of bytes accessed by FromRawBytes/StoreRawBytes
size_t bytesStored() const { return length() * charSize(); }
@@ -119,11 +121,11 @@ class CharacterValue {
bool operator>=(const CharacterValue &y) const { return !(*this < y); }
bool operator>(const CharacterValue &y) const { return y < *this; }
- CharacterValue ToAscii(int kind) const;
+ CharacterValue ToAscii(KindsEnum kind) const;
/// Assign n copies of the given character, fixing the kind from the char
/// type.
- void assign(int kind, std::size_t n, char32_t c);
+ void assign(KindsEnum kind, std::size_t n, char32_t c);
/// Assign from a raw character pointer and length.
void assign(const char *p, std::size_t n);
@@ -194,14 +196,14 @@ class CharacterValue {
void StoreRawBytes(void *dst, size_t size, bool *changed = nullptr) const;
template <typename F>
- static auto withCharProto(int kind, F &&f)
+ static auto withCharProto(KindsEnum kind, F &&f)
-> decltype(std::declval<F>()(std::declval<char>())) {
switch (kind) {
- case 1:
+ case KindsEnum::Kind1:
return f(char{});
- case 2:
+ case KindsEnum::Kind2:
return f(char16_t{});
- case 4:
+ case KindsEnum::Kind4:
return f(char32_t{});
default:
llvm_unreachable("unsupported character kind/monostate");
@@ -210,11 +212,11 @@ class CharacterValue {
template <typename F> decltype(auto) withStdString(F &&f) const {
switch (kind()) {
- case 1:
+ case KindsEnum::Kind1:
return f(*AsStdString());
- case 2:
+ case KindsEnum::Kind2:
return f(*AsU16String());
- case 4:
+ case KindsEnum::Kind4:
return f(*AsU32String());
default:
llvm_unreachable("unsupported kind/monostate");
diff --git a/flang/include/flang/Evaluate/common.h b/flang/include/flang/Evaluate/common.h
index 7368a424b46b1..50e302414a586 100644
--- a/flang/include/flang/Evaluate/common.h
+++ b/flang/include/flang/Evaluate/common.h
@@ -15,6 +15,7 @@
#include "flang/Common/indirection.h"
#include "flang/Common/restorer.h"
#include "flang/Common/target-rounding.h"
+#include "flang/Common/type-kinds.h"
#include "flang/Parser/char-block.h"
#include "flang/Parser/message.h"
#include "flang/Support/FPMaxminBehavior.h"
@@ -26,6 +27,16 @@
#include <set>
#include <string>
+namespace llvm {
+class raw_ostream;
+}
+
+namespace Fortran::common {
+/// Declared here (rather than in flang/Common/type-kinds.h) because
+/// Fortran::common must not depend on LLVM; defined in lib/Evaluate/type.cpp.
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, KindsEnum);
+} // namespace Fortran::common
+
namespace Fortran::semantics {
class DerivedTypeSpec;
}
diff --git a/flang/include/flang/Evaluate/complex-value.h b/flang/include/flang/Evaluate/complex-value.h
index eed00cc503962..7b854627c25fa 100644
--- a/flang/include/flang/Evaluate/complex-value.h
+++ b/flang/include/flang/Evaluate/complex-value.h
@@ -17,6 +17,7 @@ class raw_ostream;
}
namespace Fortran::evaluate::value {
+using common::KindsEnum;
/// A complex floating-point value with dynamic precision.
///
@@ -40,22 +41,22 @@ class ComplexValue {
explicit ComplexValue(const RealValue &r)
: ComplexValue{r, RealValue::Zero(r.kind())} {}
- ComplexValue(int kind, const RealValue &r) : ComplexValue{r} {
+ ComplexValue(KindsEnum kind, const RealValue &r) : ComplexValue{r} {
CHECK(kind == r.kind());
}
- ComplexValue(int kind, const ComplexValue &v) : ComplexValue{v} {
+ ComplexValue(KindsEnum kind, const ComplexValue &v) : ComplexValue{v} {
CHECK(kind == v.kind());
}
- ComplexValue(int kind, ComplexValue &&v) : ComplexValue{std::move(v)} {
+ ComplexValue(KindsEnum kind, ComplexValue &&v) : ComplexValue{std::move(v)} {
CHECK(kind == v.kind());
}
/// Creates a complex value (+0.0 + +0.0i) of a given kind. This is
/// different from the default-ctor which creates a "monostate" that
/// represents zero of unknown kind.
- static ComplexValue Zero(int kind) {
+ static ComplexValue Zero(KindsEnum kind) {
RealValue zero{RealValue::Zero(kind)};
return ComplexValue{zero, zero};
}
@@ -74,7 +75,7 @@ class ComplexValue {
}
/// The kind of the value currently stored.
- int kind() const {
+ KindsEnum kind() const {
CHECK(re_.kind() == im_.kind());
return re_.kind();
}
@@ -83,7 +84,7 @@ class ComplexValue {
std::size_t bytesStored() const {
return re_.bytesStored() + im_.bytesStored();
}
- static constexpr std::size_t bytesStored(int kind) {
+ static constexpr std::size_t bytesStored(KindsEnum kind) {
return 2 * RealValue::bytesStored(kind);
}
@@ -118,7 +119,7 @@ class ComplexValue {
return re_.IsSignalingNaN() || im_.IsSignalingNaN();
}
- static ValueWithRealFlags<ComplexValue> FromInteger(int kind,
+ static ValueWithRealFlags<ComplexValue> FromInteger(KindsEnum kind,
const IntegerValue &n, bool isUnsigned = false,
Rounding rounding = TargetCharacteristics::defaultRounding);
@@ -146,7 +147,7 @@ class ComplexValue {
return ComplexValue{re_.FlushSubnormalToZero(), im_.FlushSubnormalToZero()};
}
- static ComplexValue NotANumber(int kind) {
+ static ComplexValue NotANumber(KindsEnum kind) {
return {RealValue::NotANumber(kind), RealValue::NotANumber(kind)};
}
@@ -157,7 +158,7 @@ class ComplexValue {
void StoreRawBytes(void *dst, size_t size, bool *changed = nullptr) const;
static ComplexValue FromRawBytes(
- int kind, const void *raw, std::size_t expectedSize);
+ KindsEnum kind, const void *raw, std::size_t expectedSize);
// TODO: unit testing
diff --git a/flang/include/flang/Evaluate/constant.h b/flang/include/flang/Evaluate/constant.h
index 530328e1802bb..b8976125e8b64 100644
--- a/flang/include/flang/Evaluate/constant.h
+++ b/flang/include/flang/Evaluate/constant.h
@@ -12,6 +12,7 @@
#include "formatting.h"
#include "type.h"
#include "flang/Common/reference.h"
+#include "flang/Common/type-kinds.h"
#include "flang/Support/default-kinds.h"
#include <map>
#include <vector>
@@ -110,47 +111,49 @@ class ConstantBase : public ConstantBounds {
using Result = RESULT;
using Element = ELEMENT;
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
// Constructor for creating ConstantBase from an actual value (i.e.
// literals, etc.)
template <typename A>
- ConstantBase(int kind, const A &x, Result res)
+ ConstantBase(KindsEnum kind, const A &x, Result res)
: kind_{kind}, result_{res}, values_{A{kind, x}} {
CHECK_KIND(kind, RESULT);
}
- ConstantBase(int kind, ELEMENT &&x)
+ ConstantBase(KindsEnum kind, ELEMENT &&x)
: kind_{kind}, result_{Result{kind}}, values_{std::move(x)} {
CHECK_KIND(kind, RESULT);
}
template <TypeCategory CAT>
- ConstantBase(int kind, const SomeKind<CAT> &x)
+ ConstantBase(KindsEnum kind, const SomeKind<CAT> &x)
: kind_{kind}, result_{Result{kind}}, values_{x} {
CHECK_KIND(kind, RESULT);
}
template <TypeCategory CAT>
- ConstantBase(int kind, SomeKind<CAT> &&x)
+ ConstantBase(KindsEnum kind, SomeKind<CAT> &&x)
: kind_{kind}, result_{Result{kind}}, values_{std::move(x)} {
CHECK_KIND(kind, RESULT);
}
template <typename A>
- ConstantBase(int kind, const A &x)
+ ConstantBase(KindsEnum kind, const A &x)
: kind_{kind}, result_{Result{kind}}, values_{A{kind, x}} {
CHECK_KIND(kind, RESULT);
}
- ConstantBase(int kind, ELEMENT &&x, Result res)
+ ConstantBase(KindsEnum kind, ELEMENT &&x, Result res)
: kind_{kind}, result_{res}, values_{std::move(x)} {
CHECK_KIND(kind, RESULT);
}
- ConstantBase(int kind, std::vector<Element> &&x, ConstantSubscripts &&sh)
+ ConstantBase(
+ KindsEnum kind, std::vector<Element> &&x, ConstantSubscripts &&sh)
: ConstantBase{kind, std::move(x), std::move(sh), Result{kind}} {}
ConstantBase(
- int kind, std::vector<Element> &&, ConstantSubscripts &&, Result);
+ KindsEnum kind, std::vector<Element> &&, ConstantSubscripts &&, Result);
template <typename A, typename B, typename C>
- ConstantBase(int kind, const std::map<A, B, C> &x, Result res = Result{})
+ ConstantBase(
+ KindsEnum kind, const std::map<A, B, C> &x, Result res = Result{})
: kind_{kind}, result_{res}, values_{x} {}
DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(ConstantBase)
@@ -172,7 +175,7 @@ class ConstantBase : public ConstantBounds {
std::size_t CopyFrom(const ConstantBase &source, std::size_t count,
ConstantSubscripts &resultSubscripts, const std::vector<int> *dimOrder);
- int kind_;
+ KindsEnum kind_;
Result result_; // usually empty except for Real & Complex
std::vector<Element> values_;
};
@@ -209,12 +212,12 @@ class Constant<Type<TypeCategory::Character>> : public ConstantBounds {
using Result = Type<TypeCategory::Character>;
using Element = Scalar<Result>;
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
CLASS_BOILERPLATE(Constant)
- explicit Constant(int kind, const Scalar<Result> &);
- explicit Constant(int kind, Scalar<Result> &&);
- Constant(int kind, ConstantSubscript length, std::vector<Element> &&,
+ explicit Constant(KindsEnum kind, const Scalar<Result> &);
+ explicit Constant(KindsEnum kind, Scalar<Result> &&);
+ Constant(KindsEnum kind, ConstantSubscript length, std::vector<Element> &&,
ConstantSubscripts &&);
~Constant();
@@ -252,7 +255,7 @@ class Constant<Type<TypeCategory::Character>> : public ConstantBounds {
ConstantSubscripts &resultSubscripts, const std::vector<int> *dimOrder);
private:
- int kind_;
+ KindsEnum kind_;
Scalar<Result> values_; // one contiguous string
ConstantSubscript length_;
bool wasHollerith_{false};
@@ -275,11 +278,11 @@ class Constant<SomeDerived>
Constant(const StructureConstructor &);
Constant(StructureConstructor &&);
- Constant(int kind, const StructureConstructor &v) : Constant(v) {
- CHECK(kind == 0);
+ Constant(KindsEnum kind, const StructureConstructor &v) : Constant(v) {
+ CHECK(kind == NoKind);
}
- Constant(int kind, StructureConstructor &&v) : Constant(std::move(v)) {
- CHECK(kind == 0);
+ Constant(KindsEnum kind, StructureConstructor &&v) : Constant(std::move(v)) {
+ CHECK(kind == NoKind);
}
Constant(const semantics::DerivedTypeSpec &,
std::vector<StructureConstructorValues> &&, ConstantSubscripts &&);
@@ -313,20 +316,21 @@ inline Constant<LogicalResult> MakeLogicalResultConstant(bool v) {
template <typename T, typename CharT,
typename =
std::enable_if_t<std::is_same_v<T, Type<TypeCategory::Character>>>>
-inline Constant<T> MakeConstant(int kind, const std::basic_string<CharT> &v) {
+inline Constant<T> MakeConstant(
+ KindsEnum kind, const std::basic_string<CharT> &v) {
return Constant<T>{kind, value::CharacterValue{kind, v}};
}
template <typename T, typename CharT,
typename =
std::enable_if_t<std::is_same_v<T, Type<TypeCategory::Character>>>>
-inline Constant<T> MakeConstant(int kind, std::basic_string<CharT> &&v) {
+inline Constant<T> MakeConstant(KindsEnum kind, std::basic_string<CharT> &&v) {
return Constant<T>{kind, value::CharacterValue{kind, std::move(v)}};
}
template <typename T,
typename = std::enable_if_t<std::is_same_v<T, Type<TypeCategory::Integer>>>>
-inline Constant<T> MakeConstant(int kind, int64_t v) {
+inline Constant<T> MakeConstant(KindsEnum kind, int64_t v) {
return Constant<T>{kind, value::IntegerValue{kind, v}};
}
diff --git a/flang/include/flang/Evaluate/expression.h b/flang/include/flang/Evaluate/expression.h
index be7fa33738257..e4bf9dd8b5e2a 100644
--- a/flang/include/flang/Evaluate/expression.h
+++ b/flang/include/flang/Evaluate/expression.h
@@ -60,14 +60,14 @@ using common::RelationalOperator;
// maps to some instantiation of Type<CATEGORY, KIND>, SomeKind<CATEGORY>,
// or SomeType. (Exception: BOZ literal constants in generic Expr<SomeType>.)
template <typename A> using ResultType = typename std::decay_t<A>::Result;
-template <typename A> constexpr int ResultKind = std::decay_t<A>::kind();
+template <typename A> constexpr KindsEnum ResultKind = std::decay_t<A>::kind();
// Common Expr<> behaviors: every Expr<T> derives from ExpressionBase<T>.
template <typename RESULT> class ExpressionBase {
public:
using Result = RESULT;
- int kind() const;
+ KindsEnum kind() const;
private:
using Derived = Expr<Result>;
@@ -128,7 +128,7 @@ class Operation {
(operands == 1 && std::is_same_v<Result, SomeDerived>));
template <int J> using Operand = std::tuple_element_t<J, OperandTypes>;
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
// Unary operations wrap a single Expr with a CopyableIndirection.
// Binary operations wrap a tuple of CopyableIndirections to Exprs.
@@ -139,11 +139,11 @@ class Operation {
public:
CLASS_BOILERPLATE(Operation)
- explicit Operation(int kind, const Expr<OPERANDS> &...x)
+ explicit Operation(KindsEnum kind, const Expr<OPERANDS> &...x)
: kind_{kind}, operand_{x...} {
CHECK_KIND(kind, RESULT);
}
- explicit Operation(int kind, Expr<OPERANDS> &&...x)
+ explicit Operation(KindsEnum kind, Expr<OPERANDS> &&...x)
: kind_{kind}, operand_{std::move(x)...} {
CHECK_KIND(kind, RESULT);
}
@@ -208,7 +208,7 @@ class Operation {
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
private:
- int kind_;
+ KindsEnum kind_;
Container operand_;
};
@@ -415,7 +415,7 @@ template <typename T> class ConditionalExpr {
public:
using Result = T;
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
CLASS_BOILERPLATE(ConditionalExpr)
ConditionalExpr(Expr<LogicalResult> &&cond, Expr<Result> &&thenVal,
@@ -451,7 +451,7 @@ template <typename T> class ConditionalExpr {
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
private:
- int kind_;
+ KindsEnum kind_;
common::CopyableIndirection<Expr<LogicalResult>> condition_;
common::CopyableIndirection<Expr<Result>> thenValue_;
common::CopyableIndirection<Expr<Result>> elseValue_;
@@ -464,7 +464,7 @@ struct ImpliedDoIndex {
using Result = SubscriptInteger;
bool operator==(const ImpliedDoIndex &) const;
- static constexpr int kind() { return SubscriptIntegerKind; }
+ static constexpr KindsEnum kind() { return SubscriptIntegerKind; }
static constexpr DynamicType GetType() {
return {TypeCategory::Integer, kind()};
@@ -541,23 +541,23 @@ class ArrayConstructor : public ArrayConstructorValues<RESULT> {
using Result = RESULT;
using Base = ArrayConstructorValues<Result>;
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(ArrayConstructor)
- explicit ArrayConstructor(int kind, Base &&values)
+ explicit ArrayConstructor(KindsEnum kind, Base &&values)
: Base{std::move(values)}, kind_{kind} {
CHECK_KIND(kind, RESULT);
}
template <typename T>
- explicit ArrayConstructor(int kind, const Expr<T> &) : kind_{kind} {
+ explicit ArrayConstructor(KindsEnum kind, const Expr<T> &) : kind_{kind} {
CHECK_KIND(kind, RESULT);
}
- static constexpr Result result(int kind) { return Result{kind}; }
+ static constexpr Result result(KindsEnum kind) { return Result{kind}; }
DynamicType GetType() const { return {Result::category, kind_}; }
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
private:
- int kind_;
+ KindsEnum kind_;
};
template <>
@@ -567,20 +567,20 @@ class ArrayConstructor<Type<TypeCategory::Character>>
using Result = Type<TypeCategory::Character>;
using Base = ArrayConstructorValues<Result>;
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(ArrayConstructor)
- explicit ArrayConstructor(int kind, Base &&values)
+ explicit ArrayConstructor(KindsEnum kind, Base &&values)
: Base{std::move(values)}, kind_{kind} {
- CHECK(kind != 0);
+ CHECK(kind != NoKind);
}
template <typename T>
- explicit ArrayConstructor(int kind, const Expr<T> &) : kind_{kind} {
- CHECK(kind != 0);
+ explicit ArrayConstructor(KindsEnum kind, const Expr<T> &) : kind_{kind} {
+ CHECK(kind != NoKind);
}
ArrayConstructor &set_LEN(Expr<SubscriptInteger> &&);
bool operator==(const ArrayConstructor &) const;
- static constexpr Result result(int kind) { return Result{kind}; }
+ static constexpr Result result(KindsEnum kind) { return Result{kind}; }
DynamicType GetType() const { return {Result::category, kind()}; }
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
const Expr<SubscriptInteger> *LEN() const {
@@ -588,7 +588,7 @@ class ArrayConstructor<Type<TypeCategory::Character>>
}
private:
- int kind_;
+ KindsEnum kind_;
std::optional<common::CopyableIndirection<Expr<SubscriptInteger>>> length_;
};
@@ -599,7 +599,7 @@ class ArrayConstructor<SomeDerived>
using Result = SomeDerived;
using Base = ArrayConstructorValues<Result>;
- constexpr int kind() const { return 0; }
+ constexpr KindsEnum kind() const { return NoKind; }
CLASS_BOILERPLATE(ArrayConstructor)
@@ -609,9 +609,9 @@ class ArrayConstructor<SomeDerived>
explicit ArrayConstructor(const A &prototype)
: result_{prototype.GetType().value().GetDerivedTypeSpec()} {}
template <typename A>
- explicit ArrayConstructor(int kind, const A &prototype)
+ explicit ArrayConstructor(KindsEnum kind, const A &prototype)
: result_{prototype.GetType().value().GetDerivedTypeSpec()} {
- CHECK(kind == 0);
+ CHECK(kind == NoKind);
}
bool operator==(const ArrayConstructor &) const;
@@ -683,7 +683,7 @@ class Expr<Type<TypeCategory::Real>>
using Result = Type<TypeCategory::Real>;
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
- explicit Expr(int kind, const Scalar<Result> &x)
+ explicit Expr(KindsEnum kind, const Scalar<Result> &x)
: u{Constant<Result>{kind, x}} {}
private:
@@ -709,7 +709,7 @@ class Expr<Type<TypeCategory::Complex>>
public:
using Result = Type<TypeCategory::Complex>;
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
- explicit Expr(int kind, const Scalar<Result> &x)
+ explicit Expr(KindsEnum kind, const Scalar<Result> &x)
: u{Constant<Result>{kind, x}} {}
using Operations = std::variant<Parentheses<Result>, Negate<Result>,
Convert<Result, TypeCategory::Complex>, Add<Result>, Subtract<Result>,
@@ -733,9 +733,9 @@ class Expr<Type<TypeCategory::Character>>
public:
using Result = Type<TypeCategory::Character>;
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
- explicit Expr(int kind, const Scalar<Result> &x)
+ explicit Expr(KindsEnum kind, const Scalar<Result> &x)
: u{Constant<Result>{kind, x}} {}
- explicit Expr(int kind, Scalar<Result> &&x)
+ explicit Expr(KindsEnum kind, Scalar<Result> &&x)
: u{Constant<Result>{kind, std::move(x)}} {}
std::optional<Expr<SubscriptInteger>> LEN() const;
@@ -791,7 +791,7 @@ template <> class Relational<SomeType> {
public:
using Result = LogicalResult;
EVALUATE_UNION_CLASS_BOILERPLATE(Relational)
- int kind() const {
+ KindsEnum kind() const {
return common::visit([](const auto &x) { return x.kind(); }, u);
}
static constexpr DynamicType GetType() {
@@ -823,9 +823,9 @@ class Expr<Type<TypeCategory::Logical>>
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
explicit Expr(const Scalar<Result> &x) : u{Constant<Result>{x.kind(), x}} {}
- explicit Expr(int kind, const Scalar<Result> &x)
+ explicit Expr(KindsEnum kind, const Scalar<Result> &x)
: u{Constant<Result>{kind, x}} {}
- explicit Expr(int kind, bool x)
+ explicit Expr(KindsEnum kind, bool x)
: u{Constant<Result>{kind, Scalar<Result>{kind, x}}} {}
private:
@@ -860,7 +860,7 @@ class StructureConstructor {
public:
using Result = SomeDerived;
- static int kind() { return 0; }
+ static KindsEnum kind() { return NoKind; }
explicit StructureConstructor(const semantics::DerivedTypeSpec &spec)
: result_{spec} {}
@@ -923,8 +923,8 @@ class Expr<SomeKind<CAT>> : public ExpressionBase<SomeKind<CAT>> {
using Result = SomeKind<CAT>;
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
- int kind() const {
- return common::visit([](auto v) -> int { return v.kind(); }, u);
+ KindsEnum kind() const {
+ return common::visit([](auto v) { return v.kind(); }, u);
}
common::MapTemplate<evaluate::Expr, CategoryTypes<CAT>> u;
@@ -947,11 +947,11 @@ using CategoryExpression = common::MapTemplate<Expr, SomeCategory>;
// distinguishable from other integer constants, since they are permitted
// to be used in only a few situations.
using BOZLiteralConstant = typename LargestReal::Scalar::Word;
-static constexpr int BOZLiteralConstantKind = LargestRealKind;
+static constexpr KindsEnum BOZLiteralConstantKind = LargestRealKind;
// Null pointers without MOLD= arguments are typed by context.
struct NullPointer {
- static constexpr int kind() { return 0; }
+ static constexpr KindsEnum kind() { return NoKind; }
constexpr bool operator==(const NullPointer &) const { return true; }
static constexpr int Rank() { return 0; }
@@ -970,7 +970,7 @@ template <> class Expr<SomeType> : public ExpressionBase<SomeType> {
public:
using Result = SomeType;
- static int kind() { return 0; }
+ static KindsEnum kind() { return NoKind; }
EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
@@ -1061,24 +1061,25 @@ FOR_EACH_INTRINSIC_KIND(extern template class ArrayConstructor, )
FOR_EACH_INTRINSIC_KIND(template class ConditionalExpr, )
template <typename T>
-inline Expr<T> MakeConstantExpr(int kind, const Scalar<T> &v) {
+inline Expr<T> MakeConstantExpr(KindsEnum kind, const Scalar<T> &v) {
CHECK(kind == v.kind());
return Expr<T>{Constant<T>{kind, v}};
}
-template <typename T> inline Expr<T> MakeConstantExpr(int kind, Scalar<T> &&v) {
+template <typename T>
+inline Expr<T> MakeConstantExpr(KindsEnum kind, Scalar<T> &&v) {
CHECK(kind == v.kind());
return Expr<T>{Constant<T>{kind, std::move(v)}};
}
template <typename T>
-inline Expr<T> MakeConstantExpr(int kind, const Constant<T> &c) {
+inline Expr<T> MakeConstantExpr(KindsEnum kind, const Constant<T> &c) {
CHECK(kind == c.kind());
return Expr<T>{c};
}
template <typename T>
-inline Expr<T> MakeConstantExpr(int kind, Constant<T> &&c) {
+inline Expr<T> MakeConstantExpr(KindsEnum kind, Constant<T> &&c) {
CHECK(kind == c.kind());
return Expr<T>{std::move(c)};
}
@@ -1086,30 +1087,30 @@ inline Expr<T> MakeConstantExpr(int kind, Constant<T> &&c) {
template <typename T,
typename =
std::enable_if_t<std::is_same_v<T, Type<TypeCategory::Character>>>>
-inline Expr<T> MakeConstantExpr(int kind, const std::string &v) {
+inline Expr<T> MakeConstantExpr(KindsEnum kind, const std::string &v) {
return Expr<T>{MakeConstant<T>(kind, v)};
}
template <typename T,
typename = std::enable_if_t<std::is_same_v<T, Type<TypeCategory::Integer>>>>
-inline Expr<T> MakeConstantExpr(int kind, int64_t v) {
+inline Expr<T> MakeConstantExpr(KindsEnum kind, int64_t v) {
return Expr<T>{Constant<T>{kind, Scalar<T>{kind, v}}};
}
template <typename T,
typename =
std::enable_if_t<std::is_same_v<T, Type<TypeCategory::Unsigned>>>>
-inline Expr<T> MakeConstantExpr(int kind, uint64_t v) {
+inline Expr<T> MakeConstantExpr(KindsEnum kind, uint64_t v) {
return Expr<T>{Constant<T>{kind, Scalar<T>{kind, v}}};
}
template <typename T,
typename = std::enable_if_t<std::is_same_v<T, Type<TypeCategory::Logical>>>>
-inline Expr<T> MakeConstantExpr(int kind, bool v) {
+inline Expr<T> MakeConstantExpr(KindsEnum kind, bool v) {
return Expr<T>{Constant<T>{kind, Scalar<T>{kind, v}}};
}
-template <typename T> inline Expr<T> MakeZeroExpr(int kind) {
+template <typename T> inline Expr<T> MakeZeroExpr(KindsEnum kind) {
return MakeConstantExpr<T>(kind, Scalar<T>::Zero(kind));
}
@@ -1129,6 +1130,10 @@ inline Expr<SubscriptInteger> MakeSubscriptIntExpr(
Constant<SubscriptInteger>{SubscriptIntegerKind, std::move(v)}};
}
+inline Expr<SubscriptInteger> MakeKindExpr(KindsEnum v) {
+ return MakeSubscriptIntExpr(static_cast<int>(v));
+}
+
inline Expr<CInteger> MakeCIntegerExpr(int32_t v) {
return Expr<CInteger>{MakeCIntegerConstant(v)};
}
diff --git a/flang/include/flang/Evaluate/fold-designator.h b/flang/include/flang/Evaluate/fold-designator.h
index 8c1495b41511a..193d629525734 100644
--- a/flang/include/flang/Evaluate/fold-designator.h
+++ b/flang/include/flang/Evaluate/fold-designator.h
@@ -116,7 +116,7 @@ class DesignatorFolder {
std::optional<OffsetSymbol> FoldDesignator(
const Designator<Type<TypeCategory::Character>> &designator,
ConstantSubscript which) {
- const int kind{designator.kind()};
+ const KindsEnum kind{designator.kind()};
return common::visit(
common::visitors{
[&, kind](const Substring &ss) {
@@ -134,9 +134,10 @@ class DesignatorFolder {
if (*start < 1) {
isOutOfRange_ = true;
}
- result->Augment(kind * (*start - 1));
- result->set_size(
- *end >= *start ? kind * (*end - *start + 1) : 0);
+ result->Augment(static_cast<int>(kind) * (*start - 1));
+ result->set_size(*end >= *start
+ ? static_cast<int>(kind) * (*end - *start + 1)
+ : 0);
if (len) {
if (auto lenVal{ToInt64(*len)}) {
if (*end > *lenVal) {
diff --git a/flang/include/flang/Evaluate/initial-image.h b/flang/include/flang/Evaluate/initial-image.h
index c8afa80e71977..f7c656394d1cc 100644
--- a/flang/include/flang/Evaluate/initial-image.h
+++ b/flang/include/flang/Evaluate/initial-image.h
@@ -29,7 +29,7 @@ inline void StoreSerialValues(char *dst, llvm::ArrayRef<SCALAR> values,
}
template <typename SCALAR>
-inline void LoadSerialValues(int kind, const char *src,
+inline void LoadSerialValues(KindsEnum kind, const char *src,
llvm::MutableArrayRef<SCALAR> values, size_t stride) {
for (auto it : llvm::enumerate(values)) {
it.value() = SCALAR::FromRawBytes(
@@ -82,7 +82,7 @@ class InitialImage {
}
Result Add(ConstantSubscript offset, std::size_t bytes,
const Constant<Type<TypeCategory::Character>> &x, FoldingContext &) {
- const int kind{x.kind()};
+ const KindsEnum kind{x.kind()};
if (offset < 0 || offset + bytes > data_.size()) {
return OutOfRange;
} else {
@@ -100,7 +100,7 @@ class InitialImage {
Result result{OkNoChange};
for (auto at{x.lbounds()}; elements-- > 0; x.IncrementSubscripts(at)) {
value::CharacterValue scalar{x.At(at)};
- auto scalarBytes{scalar.size() * kind};
+ auto scalarBytes{scalar.size() * static_cast<size_t>(kind)};
if (scalarBytes != elementBytes) {
result = LengthMismatch;
}
diff --git a/flang/include/flang/Evaluate/integer-value.h b/flang/include/flang/Evaluate/integer-value.h
index d8ddeb39f039d..5e08587e3d88c 100644
--- a/flang/include/flang/Evaluate/integer-value.h
+++ b/flang/include/flang/Evaluate/integer-value.h
@@ -9,6 +9,7 @@
#ifndef FORTRAN_EVALUATE_INTEGER_VALUE_H_
#define FORTRAN_EVALUATE_INTEGER_VALUE_H_
+#include "flang/Common/type-kinds.h"
#include "flang/Common/uint128.h"
#include "flang/Evaluate/common.h"
#include "flang/Evaluate/object-sizes.h"
@@ -23,6 +24,7 @@
namespace Fortran::evaluate::value {
class IntegerValueImpl;
+using common::KindsEnum;
/// A two's-complement integer with dynamic bitwidth.
///
@@ -48,10 +50,10 @@ class IntegerValue {
IntegerValue &operator=(const IntegerValue &);
IntegerValue &operator=(IntegerValue &&);
- IntegerValue(int kind, const IntegerValue &x) : IntegerValue(x) {
+ IntegerValue(KindsEnum kind, const IntegerValue &x) : IntegerValue(x) {
CHECK(x.kind() == kind);
}
- IntegerValue(int kind, IntegerValue &&x) : IntegerValue(std::move(x)) {
+ IntegerValue(KindsEnum kind, IntegerValue &&x) : IntegerValue(std::move(x)) {
CHECK(x.kind() == kind);
}
@@ -64,7 +66,7 @@ class IntegerValue {
// is a class type that never does.
template <typename INT,
typename = std::enable_if_t<std::numeric_limits<INT>::is_integer>>
- IntegerValue(int kind, INT v) {
+ IntegerValue(KindsEnum kind, INT v) {
if constexpr (sizeof(INT) > 8) {
static_assert(sizeof(INT) == 16);
ConstructFromIntegral(kind, static_cast<Fortran::common::uint128_t>(v));
@@ -79,7 +81,7 @@ class IntegerValue {
/// Creates an integer with value 0 of a given kind. This is different from
/// the default-ctor which creates a "monostate" that represents 0 of unknown
/// kind.
- static IntegerValue Zero(int kind);
+ static IntegerValue Zero(KindsEnum kind);
void print(llvm::raw_ostream &os) const;
@@ -92,21 +94,21 @@ class IntegerValue {
bool IsMonostate() const;
/// The kind of the value currently stored.
- int kind() const;
+ KindsEnum kind() const;
int bits() const { return bits(kind()); }
- static constexpr int bits(int kind) { return bytesStored(kind) * 8; }
+ static constexpr int bits(KindsEnum kind) { return bytesStored(kind) * 8; }
/// Number of bytes accessed by FromRawBytes/StoreRawBytes
std::size_t bytesStored() const { return bytesStored(kind()); }
- static constexpr std::size_t bytesStored(int kind) {
+ static constexpr std::size_t bytesStored(KindsEnum kind) {
switch (kind) {
- case 3:
+ case KindsEnum::Kind3:
return 2;
- case 10:
+ case KindsEnum::Kind10:
return 16;
default:
- return kind;
+ return static_cast<std::size_t>(kind);
}
}
@@ -120,13 +122,13 @@ class IntegerValue {
bool operator>(const IntegerValue &y) const { return y < *this; }
/// Left-justified mask (e.g., MASKL(1) has only its sign bit set)
- static IntegerValue MASKL(int kind, int places);
+ static IntegerValue MASKL(KindsEnum kind, int places);
/// Right-justified mask (e.g., MASKR(1) == 1, MASKR(2) == 3, &c.)
- static IntegerValue MASKR(int kind, int places);
+ static IntegerValue MASKR(KindsEnum kind, int places);
static ValueWithOverflow Read(
- int kind, const char *&pp, int base, bool isSigned);
+ KindsEnum kind, const char *&pp, int base, bool isSigned);
/// ZExt or Trunc
static ValueWithOverflow ConvertUnsigned(
@@ -142,18 +144,18 @@ class IntegerValue {
/// Omits a leading "0x".
std::string Hexadecimal() const;
- static constexpr int DIGITS(int kind) {
+ static constexpr int DIGITS(KindsEnum kind) {
// don't count the sign bit
return bits(kind) - 1;
}
- static IntegerValue HUGE(int kind);
+ static IntegerValue HUGE(KindsEnum kind);
- static IntegerValue Least(int kind);
+ static IntegerValue Least(KindsEnum kind);
- static int RANGE(int kind);
+ static int RANGE(KindsEnum kind);
- static int UnsignedRANGE(int kind);
+ static int UnsignedRANGE(KindsEnum kind);
bool IsZero() const;
@@ -312,12 +314,12 @@ class IntegerValue {
PowerWithErrors Power(const IntegerValue &e) const;
static IntegerValue FromRawBytes(
- int kind, const void *raw, std::size_t expectedSize);
+ KindsEnum kind, const void *raw, std::size_t expectedSize);
void StoreRawBytes(void *dst, size_t size, bool *changed = nullptr) const;
private:
- void ConstructFromIntegral(int kind, std::uint64_t n, bool isSigned);
- void ConstructFromIntegral(int kind, Fortran::common::uint128_t n);
+ void ConstructFromIntegral(KindsEnum kind, std::uint64_t n, bool isSigned);
+ void ConstructFromIntegral(KindsEnum kind, Fortran::common::uint128_t n);
static IntegerValue FromImpl(const IntegerValueImpl &x);
static IntegerValue FromImpl(IntegerValueImpl &&x);
diff --git a/flang/include/flang/Evaluate/logical-value.h b/flang/include/flang/Evaluate/logical-value.h
index f313e88cff5a0..e794856d260d8 100644
--- a/flang/include/flang/Evaluate/logical-value.h
+++ b/flang/include/flang/Evaluate/logical-value.h
@@ -14,6 +14,7 @@
#include <utility>
namespace Fortran::evaluate::value {
+using common::KindsEnum;
/// A Fortran LOGICAL value.
///
@@ -32,22 +33,22 @@ class LogicalValue {
LogicalValue &operator=(const LogicalValue &) = default;
LogicalValue &operator=(LogicalValue &&) = default;
- LogicalValue(int kind, const LogicalValue &v) : LogicalValue{v} {
+ LogicalValue(KindsEnum kind, const LogicalValue &v) : LogicalValue{v} {
CHECK(kind == v.kind());
}
- LogicalValue(int kind, LogicalValue &&v) : LogicalValue{std::move(v)} {
+ LogicalValue(KindsEnum kind, LogicalValue &&v) : LogicalValue{std::move(v)} {
CHECK(kind == v.kind());
}
- LogicalValue(int kind, bool truth) : word_(Represent(kind, truth)) {}
+ LogicalValue(KindsEnum kind, bool truth) : word_(Represent(kind, truth)) {}
- LogicalValue(int kind, const Word &w) : word_(kind, w) {}
+ LogicalValue(KindsEnum kind, const Word &w) : word_(kind, w) {}
/// Creates a logical with value 'false' of a given kind. This is in contrast
/// to the default-ctor which creates a "monostate" that represents 'false' of
/// a not-yet-known kind.
- static LogicalValue Zero(int kind) { return LogicalValue{kind, false}; }
+ static LogicalValue Zero(KindsEnum kind) { return LogicalValue{kind, false}; }
void print(llvm::raw_ostream &os) const;
@@ -60,21 +61,21 @@ class LogicalValue {
bool IsMonostate() const { return word_.IsMonostate(); }
/// The kind of the value currently stored.
- int kind() const { return word_.kind(); }
+ KindsEnum kind() const { return word_.kind(); }
int bits() const { return bits(kind()); }
- static constexpr int bits(int kind) { return Word::bits(kind); }
+ static constexpr int bits(KindsEnum kind) { return Word::bits(kind); }
/// Number of bytes accessed by FromRawBytes/StoreRawBytes
std::size_t bytesStored() const { return bytesStored(kind()); }
- static constexpr std::size_t bytesStored(int kind) {
+ static constexpr std::size_t bytesStored(KindsEnum kind) {
return Word::bytesStored(kind);
}
Word word() const { return word_; }
bool IsCanonical() const {
- const int kind{this->kind()};
+ const KindsEnum kind{this->kind()};
return word_ == canonicalFalse(kind) || word_ == canonicalTrue(kind);
}
@@ -119,7 +120,7 @@ class LogicalValue {
}
static LogicalValue FromRawBytes(
- int kind, const void *raw, std::size_t expectedSize) {
+ KindsEnum kind, const void *raw, std::size_t expectedSize) {
Word w{Word::FromRawBytes(kind, raw, expectedSize)};
return LogicalValue{w.kind(), w};
}
@@ -129,11 +130,11 @@ class LogicalValue {
}
private:
- static Word canonicalTrue(int kind) { return Word{kind, 1}; }
+ static Word canonicalTrue(KindsEnum kind) { return Word{kind, 1}; }
- static Word canonicalFalse(int kind) { return Word{kind, 0}; }
+ static Word canonicalFalse(KindsEnum kind) { return Word{kind, 0}; }
- static Word Represent(int kind, bool x) {
+ static Word Represent(KindsEnum kind, bool x) {
return x ? canonicalTrue(kind) : canonicalFalse(kind);
}
diff --git a/flang/include/flang/Evaluate/real-value.h b/flang/include/flang/Evaluate/real-value.h
index f30c65d41478d..1fec1e5f96f76 100644
--- a/flang/include/flang/Evaluate/real-value.h
+++ b/flang/include/flang/Evaluate/real-value.h
@@ -9,6 +9,7 @@
#ifndef FORTRAN_EVALUATE_REAL_VALUE_H_
#define FORTRAN_EVALUATE_REAL_VALUE_H_
+#include "flang/Common/type-kinds.h"
#include "flang/Evaluate/integer-value.h"
#include "flang/Evaluate/object-sizes.h"
#include "flang/Evaluate/target.h"
@@ -20,6 +21,7 @@
namespace Fortran::evaluate::value {
class RealValueImpl;
+using common::KindsEnum;
/// A floating-point value with dynamic precision.
///
@@ -39,33 +41,33 @@ class RealValue {
RealValue &operator=(const RealValue &);
RealValue &operator=(RealValue &&);
- RealValue(int kind, const RealValue &v) : RealValue(v) {
+ RealValue(KindsEnum kind, const RealValue &v) : RealValue(v) {
CHECK(kind == v.kind());
}
- RealValue(int kind, RealValue &&v) : RealValue(std::move(v)) {
+ RealValue(KindsEnum kind, RealValue &&v) : RealValue(std::move(v)) {
CHECK(kind == v.kind());
}
/// Interpret w as the raw bit pattern for the given runtime kind.
- RealValue(int kind, const Word &w);
+ RealValue(KindsEnum kind, const Word &w);
/// Creates a floating-point value of a given kind from a host double,
/// rounded to the target kind's precision (per the default rounding mode).
/// Portable: does not assume that the host "double" shares any bit layout
/// with the target kind, only that <cmath>'s frexp()/ldexp() are available.
- RealValue(int kind, double x);
+ RealValue(KindsEnum kind, double x);
/// Creates a floating-point with value +0.0 of a given kind. In contrast, the
/// default ctor creates a "monostate" that represents +0.0 of unknown kind.
- static RealValue Zero(int kind);
+ static RealValue Zero(KindsEnum kind);
/// Creates a floating-point with value -0.0 of a given kind.
- static RealValue NegativeZero(int kind);
+ static RealValue NegativeZero(KindsEnum kind);
- static RealValue Infinity(int kind, bool negative = false);
+ static RealValue Infinity(KindsEnum kind, bool negative = false);
/// A signaling NaN, as opposed to the quiet NaN returned by NotANumber().
- static RealValue SignalingNaN(int kind);
+ static RealValue SignalingNaN(KindsEnum kind);
void print(llvm::raw_ostream &os) const;
@@ -78,21 +80,21 @@ class RealValue {
bool IsMonostate() const;
/// The kind of the value currently stored.
- int kind() const;
+ KindsEnum kind() const;
int bits() const { return bits(kind()); }
- static constexpr int bits(int kind) { return bytesStored(kind) * 8; }
+ static constexpr int bits(KindsEnum kind) { return bytesStored(kind) * 8; }
/// Number of bytes accessed by FromRawBytes/StoreRawBytes
std::size_t bytesStored() const { return bytesStored(kind()); }
- static constexpr std::size_t bytesStored(int kind) {
+ static constexpr std::size_t bytesStored(KindsEnum kind) {
switch (kind) {
- case 3:
+ case KindsEnum::Kind3:
return 2;
- case 10:
+ case KindsEnum::Kind10:
return 16;
default:
- return kind;
+ return static_cast<std::size_t>(kind);
}
}
@@ -164,21 +166,21 @@ class RealValue {
IntegerValue EXPONENT() const;
- static RealValue EPSILON(int kind);
+ static RealValue EPSILON(KindsEnum kind);
- static RealValue HUGE(int kind);
+ static RealValue HUGE(KindsEnum kind);
- static RealValue TINY(int kind);
+ static RealValue TINY(KindsEnum kind);
- static int DIGITS(int kind);
+ static int DIGITS(KindsEnum kind);
- static int PRECISION(int kind);
+ static int PRECISION(KindsEnum kind);
- static int RANGE(int kind);
+ static int RANGE(KindsEnum kind);
- static int MAXEXPONENT(int kind);
+ static int MAXEXPONENT(KindsEnum kind);
- static int MINEXPONENT(int kind);
+ static int MINEXPONENT(KindsEnum kind);
RealValue RRSPACING() const;
@@ -195,9 +197,9 @@ class RealValue {
RealValue FlushSubnormalToZero() const;
// TODO: Configurable NotANumber representations
- static RealValue NotANumber(int kind);
+ static RealValue NotANumber(KindsEnum kind);
- static ValueWithRealFlags<RealValue> FromInteger(int kind,
+ static ValueWithRealFlags<RealValue> FromInteger(KindsEnum kind,
const IntegerValue &n, bool isUnsigned = false,
Rounding rounding = TargetCharacteristics::defaultRounding);
@@ -210,7 +212,8 @@ class RealValue {
common::RoundingMode mode = common::RoundingMode::ToZero,
int toBits = 0) const;
- static ValueWithRealFlags<RealValue> Convert(int kind, const RealValue &from,
+ static ValueWithRealFlags<RealValue> Convert(KindsEnum kind,
+ const RealValue &from,
Rounding rounding = TargetCharacteristics::defaultRounding);
Word RawBits() const;
@@ -218,7 +221,7 @@ class RealValue {
/// Extracts "raw" biased exponent field.
int Exponent() const;
- static ValueWithRealFlags<RealValue> Read(int kind, const char *&pp,
+ static ValueWithRealFlags<RealValue> Read(KindsEnum kind, const char *&pp,
Rounding rounding = TargetCharacteristics::defaultRounding);
std::string DumpHexadecimal() const;
@@ -229,7 +232,7 @@ class RealValue {
llvm::raw_ostream &o, int kind, bool minimal = false) const;
static RealValue FromRawBytes(
- int kind, const void *raw, std::size_t expectedSize);
+ KindsEnum kind, const void *raw, std::size_t expectedSize);
void StoreRawBytes(void *dst, size_t size, bool *changed = nullptr) const;
diff --git a/flang/include/flang/Evaluate/rewrite.h b/flang/include/flang/Evaluate/rewrite.h
index 92c058b29d792..d69f9e3d6bd35 100644
--- a/flang/include/flang/Evaluate/rewrite.h
+++ b/flang/include/flang/Evaluate/rewrite.h
@@ -126,7 +126,7 @@ template <typename Rewriter> struct Mutator {
template <typename D, size_t... Is>
D MutateOp(D &&op, std::index_sequence<Is...>) const {
- const int kind{op.kind()};
+ const KindsEnum kind{op.kind()};
return D(kind, Mutate(std::move(op.template operand<Is>()))...);
}
diff --git a/flang/include/flang/Evaluate/shape.h b/flang/include/flang/Evaluate/shape.h
index 5bca399c50ef4..cdb7793e1dc10 100644
--- a/flang/include/flang/Evaluate/shape.h
+++ b/flang/include/flang/Evaluate/shape.h
@@ -31,7 +31,7 @@ using ExtentExpr = Expr<ExtentType>;
using MaybeExtentExpr = std::optional<ExtentExpr>;
using Shape = std::vector<MaybeExtentExpr>;
-inline constexpr int ExtentIntKind = Fortran::evaluate::SubscriptIntegerKind;
+inline constexpr KindsEnum ExtentIntKind = SubscriptIntegerKind;
inline Constant<ExtentType> MakeExtentConstant(int64_t v) {
return Constant<ExtentType>{
diff --git a/flang/include/flang/Evaluate/target.h b/flang/include/flang/Evaluate/target.h
index 7b38db2db1956..90df18cdb22f9 100644
--- a/flang/include/flang/Evaluate/target.h
+++ b/flang/include/flang/Evaluate/target.h
@@ -22,6 +22,7 @@
namespace Fortran::evaluate {
+using common::KindsEnum;
using common::Rounding;
ENUM_CLASS(IeeeFeature, Denormal, Divide, Flags, Halting, Inf, Io, NaN,
@@ -50,17 +51,17 @@ class TargetCharacteristics {
void set_areSubnormalsFlushedToZero(bool yes = true);
// Check if a given real kind has flushing control.
- bool hasSubnormalFlushingControl(int kind) const;
+ bool hasSubnormalFlushingControl(KindsEnum kind) const;
// Check if any or all real kinds have flushing control.
bool hasSubnormalFlushingControl(bool any = false) const;
- void set_hasSubnormalFlushingControl(int kind, bool yes = true);
+ void set_hasSubnormalFlushingControl(KindsEnum kind, bool yes = true);
// Check if a given real kind has support for raising a nonstandard
// ieee_denorm exception.
- bool hasSubnormalExceptionSupport(int kind) const;
+ bool hasSubnormalExceptionSupport(KindsEnum kind) const;
// Check if all real kinds have support for the ieee_denorm exception.
bool hasSubnormalExceptionSupport() const;
- void set_hasSubnormalExceptionSupport(int kind, bool yes = true);
+ void set_hasSubnormalExceptionSupport(KindsEnum kind, bool yes = true);
Rounding roundingMode() const { return roundingMode_; }
void set_roundingMode(Rounding);
@@ -83,16 +84,14 @@ class TargetCharacteristics {
std::size_t maxByteSize() const { return maxByteSize_; }
std::size_t maxAlignment() const { return maxAlignment_; }
- static bool CanSupportType(common::TypeCategory, std::int64_t kind);
- bool EnableType(common::TypeCategory category, std::int64_t kind,
+ static bool CanSupportType(common::TypeCategory, KindsEnum kind);
+ bool EnableType(common::TypeCategory category, KindsEnum kind,
std::size_t byteSize, std::size_t align);
- void DisableType(common::TypeCategory category, std::int64_t kind);
+ void DisableType(common::TypeCategory category, KindsEnum kind);
- std::size_t GetByteSize(
- common::TypeCategory category, std::int64_t kind) const;
- std::size_t GetAlignment(
- common::TypeCategory category, std::int64_t kind) const;
- bool IsTypeEnabled(common::TypeCategory category, std::int64_t kind) const;
+ std::size_t GetByteSize(common::TypeCategory category, KindsEnum kind) const;
+ std::size_t GetAlignment(common::TypeCategory category, KindsEnum kind) const;
+ bool IsTypeEnabled(common::TypeCategory category, KindsEnum kind) const;
int SelectedIntKind(std::int64_t precision = 0) const;
int SelectedLogicalKind(std::int64_t bits = 1) const;
@@ -131,8 +130,8 @@ class TargetCharacteristics {
IeeeFeatures &ieeeFeatures() { return ieeeFeatures_; }
const IeeeFeatures &ieeeFeatures() const { return ieeeFeatures_; }
- std::size_t integerKindForPointer() { return integerKindForPointer_; }
- void set_integerKindForPointer(std::size_t newKind) {
+ KindsEnum integerKindForPointer() { return integerKindForPointer_; }
+ void set_integerKindForPointer(KindsEnum newKind) {
integerKindForPointer_ = newKind;
}
@@ -161,7 +160,7 @@ class TargetCharacteristics {
IeeeFeature::Io, IeeeFeature::NaN, IeeeFeature::Rounding,
IeeeFeature::Sqrt, IeeeFeature::Standard, IeeeFeature::Subnormal,
IeeeFeature::UnderflowControl};
- std::size_t integerKindForPointer_{8}; /* For 64 bit pointer */
+ KindsEnum integerKindForPointer_{KindsEnum::Kind8}; /* For 64 bit pointer */
};
} // namespace Fortran::evaluate
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index f50ddb53249fc..b4ee31d5139de 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -196,7 +196,7 @@ auto UnwrapExpr(B &x) -> common::Constify<A, B> * {
return nullptr;
}
template <typename A, typename B>
-auto UnwrapExpr(int kind, B &x) -> common::Constify<A, B> * {
+auto UnwrapExpr(KindsEnum kind, B &x) -> common::Constify<A, B> * {
using Ty = std::decay_t<B>;
if (x.kind() != kind)
return nullptr;
@@ -226,7 +226,7 @@ const A *UnwrapExpr(const std::optional<B> &x) {
}
}
template <typename A, typename B>
-const A *UnwrapExpr(int kind, const std::optional<B> &x) {
+const A *UnwrapExpr(KindsEnum kind, const std::optional<B> &x) {
if (x) {
return UnwrapExpr<A>(kind, *x);
} else {
@@ -241,7 +241,8 @@ template <typename A, typename B> A *UnwrapExpr(std::optional<B> &x) {
return nullptr;
}
}
-template <typename A, typename B> A *UnwrapExpr(int kind, std::optional<B> &x) {
+template <typename A, typename B>
+A *UnwrapExpr(KindsEnum kind, std::optional<B> &x) {
if (x) {
return UnwrapExpr<A>(kind, *x);
} else {
@@ -257,7 +258,8 @@ template <typename A, typename B> const A *UnwrapExpr(const B *x) {
}
}
-template <typename A, typename B> const A *UnwrapExpr(int kind, const B *x) {
+template <typename A, typename B>
+const A *UnwrapExpr(KindsEnum kind, const B *x) {
if (x) {
return UnwrapExpr<A>(kind, *x);
} else {
@@ -273,7 +275,7 @@ template <typename A, typename B> A *UnwrapExpr(B *x) {
}
}
-template <typename A, typename B> A *UnwrapExpr(int kind, B *x) {
+template <typename A, typename B> A *UnwrapExpr(KindsEnum kind, B *x) {
if (x) {
return UnwrapExpr<A>(kind, *x);
} else {
@@ -597,7 +599,7 @@ const Symbol *GetLastPointerSymbol(const evaluate::DataRef &);
// one arbitrary expression to the type of another with ConvertTo(to, from).
template <typename TO, TypeCategory FROMCAT>
-Expr<TO> ConvertToType(int toKind, Expr<SomeKind<FROMCAT>> &&x) {
+Expr<TO> ConvertToType(KindsEnum toKind, Expr<SomeKind<FROMCAT>> &&x) {
static_assert(IsSpecificIntrinsicType<TO>);
if constexpr (FROMCAT == TO::category) {
auto *already{std::get_if<Expr<TO>>(&x.u)};
@@ -627,13 +629,13 @@ Expr<TO> ConvertToType(int toKind, Expr<SomeKind<FROMCAT>> &&x) {
}
template <typename TO, TypeCategory FROMCAT>
-Expr<TO> ConvertToType(int toKind, Expr<Type<FROMCAT>> &&x) {
+Expr<TO> ConvertToType(KindsEnum toKind, Expr<Type<FROMCAT>> &&x) {
return ConvertToType<TO, FROMCAT>(
toKind, Expr<SomeKind<FROMCAT>>{std::move(x)});
}
template <typename TO>
-Expr<TO> ConvertToType(int toKind, BOZLiteralConstant &&x) {
+Expr<TO> ConvertToType(KindsEnum toKind, BOZLiteralConstant &&x) {
static_assert(IsSpecificIntrinsicType<TO>);
if constexpr (TO::category == TypeCategory::Integer ||
TO::category == TypeCategory::Unsigned) {
@@ -666,7 +668,7 @@ std::optional<Expr<SomeType>> ConvertToType(
// Conversions to the type of another expression
template <TypeCategory TC, typename FROM>
common::IfNoLvalue<Expr<Type<TC>>, FROM> ConvertTo(
- int toKind, const Expr<Type<TC>> &to, FROM &&x) {
+ KindsEnum toKind, const Expr<Type<TC>> &to, FROM &&x) {
return ConvertToType<Type<TC>>(toKind, std::move(x));
}
@@ -676,7 +678,7 @@ common::IfNoLvalue<Expr<SomeKind<TC>>, FROM> ConvertTo(
return common::visit(
[&](const auto &toKindExpr) {
using KindExpr = std::decay_t<decltype(toKindExpr)>;
- const int toKind{toKindExpr.kind()};
+ const KindsEnum toKind{toKindExpr.kind()};
return AsCategoryExpr(
ConvertToType<ResultType<KindExpr>>(toKind, std::move(from)));
},
@@ -687,7 +689,7 @@ common::IfNoLvalue<Expr<SomeKind<TC>>, FROM> ConvertTo(
// kind of some category (usually but not necessarily distinct).
template <TypeCategory TOCAT, typename VALUE>
common::IfNoLvalue<Expr<SomeKind<TOCAT>>, VALUE> ConvertToKind(
- int kind, VALUE &&x) {
+ KindsEnum kind, VALUE &&x) {
return AsCategoryExpr(ConvertToType<Type<TOCAT>>(kind, std::move(x)));
}
@@ -710,9 +712,9 @@ template <TypeCategory CAT>
SameKindExprs<CAT, 2> AsSameKindExprs(
Expr<SomeKind<CAT>> &&x, Expr<SomeKind<CAT>> &&y) {
Expr<Type<CAT>> kx{std::get<Expr<Type<CAT>>>(std::move(x.u))};
- int xKind{kx.kind()};
+ KindsEnum xKind{kx.kind()};
Expr<Type<CAT>> ky{std::get<Expr<Type<CAT>>>(std::move(y.u))};
- int yKind{ky.kind()};
+ KindsEnum yKind{ky.kind()};
if (xKind == yKind) {
return {SameExprs<Type<CAT>>{std::move(kx), std::move(ky)}};
} else if (xKind < yKind) {
@@ -736,21 +738,21 @@ SameKindExprs<CAT, 2> AsSameKindExprs(
using ConvertRealOperandsResult =
std::optional<SameKindExprs<TypeCategory::Real, 2>>;
ConvertRealOperandsResult ConvertRealOperands(parser::ContextualMessages &,
- Expr<SomeType> &&, Expr<SomeType> &&, int defaultRealKind);
+ Expr<SomeType> &&, Expr<SomeType> &&, KindsEnum defaultRealKind);
// Per F'2018 R718, if both components are INTEGER, they are both converted
// to default REAL and the result is default COMPLEX. Otherwise, the
// kind of the result is the kind of most precise REAL component, and the other
// component is converted if necessary to its type.
std::optional<Expr<SomeComplex>> ConstructComplex(parser::ContextualMessages &,
- Expr<SomeType> &&, Expr<SomeType> &&, int defaultRealKind);
+ Expr<SomeType> &&, Expr<SomeType> &&, KindsEnum defaultRealKind);
std::optional<Expr<SomeComplex>> ConstructComplex(parser::ContextualMessages &,
std::optional<Expr<SomeType>> &&, std::optional<Expr<SomeType>> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
template <typename A> Expr<TypeOf<A>> ScalarConstantToExpr(const A &x) {
using Ty = TypeOf<A>;
- const int kind{x.kind()};
+ const KindsEnum kind{x.kind()};
static_assert(
std::is_same_v<Scalar<Ty>, std::decay_t<A>>, "TypeOf<> is broken");
return MakeConstantExpr<Ty>(kind, x);
@@ -788,23 +790,23 @@ Expr<SomeKind<CAT>> PromoteAndCombine(
// powers.
template <template <typename> class OPR>
std::optional<Expr<SomeType>> NumericOperation(parser::ContextualMessages &,
- Expr<SomeType> &&, Expr<SomeType> &&, int defaultRealKind);
+ Expr<SomeType> &&, Expr<SomeType> &&, KindsEnum defaultRealKind);
extern template std::optional<Expr<SomeType>> NumericOperation<Power>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
extern template std::optional<Expr<SomeType>> NumericOperation<Multiply>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
extern template std::optional<Expr<SomeType>> NumericOperation<Divide>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
extern template std::optional<Expr<SomeType>> NumericOperation<Add>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
extern template std::optional<Expr<SomeType>> NumericOperation<Subtract>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
std::optional<Expr<SomeType>> Negation(
parser::ContextualMessages &, Expr<SomeType> &&);
@@ -826,7 +828,7 @@ Expr<LogicalResult> PackageRelation(
inline Expr<Type<TypeCategory::Logical>> LogicalNegation(
Expr<Type<TypeCategory::Logical>> &&x) {
- const int kind{x.kind()};
+ const KindsEnum kind{static_cast<KindsEnum>(x.kind())};
return AsExpr(Not{kind, std::move(x)});
}
@@ -907,17 +909,17 @@ struct TypeKindVisitor {
using Result = std::optional<Expr<SomeType>>;
using Types = CategoryTypes<CAT>;
- TypeKindVisitor(int k, VALUE &&x) : kind{k}, value{std::move(x)} {}
- TypeKindVisitor(int k, const VALUE &x) : kind{k}, value{x} {}
+ TypeKindVisitor(KindsEnum k, VALUE &&x) : kind{k}, value{std::move(x)} {}
+ TypeKindVisitor(KindsEnum k, const VALUE &x) : kind{k}, value{x} {}
- template <typename T> Result Test(int k) {
+ template <typename T> Result Test(KindsEnum k) {
if (kind == k) {
return AsGenericExpr(TEMPLATE<T>{k, std::move(value)});
}
return std::nullopt;
}
- int kind;
+ KindsEnum kind;
VALUE value;
};
@@ -927,7 +929,7 @@ struct TypeKindVisitor {
template <TypeCategory CATEGORY, template <typename> typename WRAPPER,
typename WRAPPED>
common::IfNoLvalue<std::optional<Expr<SomeType>>, WRAPPED> WrapperHelper(
- int kind, WRAPPED &&x) {
+ KindsEnum kind, WRAPPED &&x) {
return SearchTypes(
TypeKindVisitor<CATEGORY, WRAPPER, WRAPPED>{kind, std::move(x)});
}
@@ -957,7 +959,7 @@ common::IfNoLvalue<std::optional<Expr<SomeType>>, WRAPPED> TypedWrapper(
dyType.kind(), std::move(x));
case TypeCategory::Derived:
return AsGenericExpr(
- Expr<SomeDerived>{WRAPPER<SomeDerived>{0, std::move(x)}});
+ Expr<SomeDerived>{WRAPPER<SomeDerived>{NoKind, std::move(x)}});
}
}
@@ -1282,7 +1284,7 @@ class ScalarConstantExpander {
// If the type is Character or a derived type, take the length or type
// (resp.) from a another Constant.
template <typename T>
-Constant<T> PackageConstant(int kind, std::vector<Scalar<T>> &&elements,
+Constant<T> PackageConstant(KindsEnum kind, std::vector<Scalar<T>> &&elements,
const Constant<T> &reference, const ConstantSubscripts &shape) {
if constexpr (T::category == TypeCategory::Character) {
return Constant<T>{
diff --git a/flang/include/flang/Evaluate/type.h b/flang/include/flang/Evaluate/type.h
index 0974b87b01650..c3d3f3e2a2bc4 100644
--- a/flang/include/flang/Evaluate/type.h
+++ b/flang/include/flang/Evaluate/type.h
@@ -49,9 +49,20 @@ bool IsPassedViaDescriptor(const Symbol &);
namespace Fortran::evaluate {
+using common::KindsEnum;
using common::TypeCategory;
class TargetCharacteristics;
+inline constexpr KindsEnum InvalidKind{KindsEnum::InvalidKind};
+inline constexpr KindsEnum NoKind{KindsEnum::NoKind};
+inline constexpr KindsEnum Kind1{KindsEnum::Kind1};
+inline constexpr KindsEnum Kind2{KindsEnum::Kind2};
+inline constexpr KindsEnum Kind3{KindsEnum::Kind3};
+inline constexpr KindsEnum Kind4{KindsEnum::Kind4};
+inline constexpr KindsEnum Kind8{KindsEnum::Kind8};
+inline constexpr KindsEnum Kind10{KindsEnum::Kind10};
+inline constexpr KindsEnum Kind16{KindsEnum::Kind16};
+
// Specific intrinsic types are represented by specializations of
// this class template Type<CATEGORY>.
// This used to be Type<CATEGORY,KIND>, but now KIND is passed at runtime.
@@ -60,22 +71,22 @@ class TargetCharacteristics;
template <TypeCategory CATEGORY> class Type;
using SubscriptInteger = Type<TypeCategory::Integer>;
-inline constexpr int SubscriptIntegerKind{8};
+inline constexpr KindsEnum SubscriptIntegerKind{Kind8};
using CInteger = Type<TypeCategory::Integer>;
-inline constexpr int CIntegerKind{4};
+inline constexpr KindsEnum CIntegerKind{Kind4};
using LargestInt = Type<TypeCategory::Integer>;
-inline constexpr int LargestIntKind{16};
+inline constexpr KindsEnum LargestIntKind{Kind16};
using LogicalResult = Type<TypeCategory::Logical>;
-inline constexpr int LogicalResultKind{4};
+inline constexpr KindsEnum LogicalResultKind{Kind4};
using LargestReal = Type<TypeCategory::Real>;
-inline constexpr int LargestRealKind{16};
+inline constexpr KindsEnum LargestRealKind{Kind16};
using Ascii = Type<TypeCategory::Character>;
-inline constexpr int AsciiKind{1};
+inline constexpr KindsEnum AsciiKind{Kind1};
// DynamicType is meant to be suitable for use as the result type for
// GetType() functions and member functions; consequently, it must be
@@ -87,15 +98,16 @@ inline constexpr int AsciiKind{1};
// if one is supplied, or a known integer value.
class DynamicType {
public:
- constexpr DynamicType(TypeCategory cat, int k) : category_{cat}, kind_{k} {
+ constexpr DynamicType(TypeCategory cat, KindsEnum k)
+ : category_{cat}, kind_{k} {
CHECK(common::IsValidKindOfIntrinsicType(category_, kind_));
}
- DynamicType(int charKind, const semantics::ParamValue &len);
+ DynamicType(KindsEnum charKind, const semantics::ParamValue &len);
// When a known length is presented, resolve it to its effective
// length of zero if it is negative.
- constexpr DynamicType(int k, std::int64_t len)
- : category_{TypeCategory::Character}, kind_{k}, knownLength_{
- len >= 0 ? len : 0} {
+ constexpr DynamicType(KindsEnum k, std::int64_t len)
+ : category_{TypeCategory::Character}, kind_{k},
+ knownLength_{len >= 0 ? len : 0} {
CHECK(common::IsValidKindOfIntrinsicType(category_, kind_));
}
explicit constexpr DynamicType(
@@ -139,8 +151,8 @@ class DynamicType {
bool operator!=(const DynamicType &that) const { return !(*this == that); }
constexpr TypeCategory category() const { return category_; }
- constexpr int kind() const {
- CHECK(kind_ > 0);
+ constexpr KindsEnum kind() const {
+ CHECK(kind_ > NoKind);
return kind_;
}
constexpr const semantics::ParamValue *charLengthParamValue() const {
@@ -239,17 +251,23 @@ class DynamicType {
private:
// Special kind codes are used to distinguish the following Fortran types.
- enum SpecialKind {
- TypelessKind = -1, // BOZ actual argument to intrinsic function or pointer
- // argument to ASSOCIATED
- ClassKind = -2, // CLASS(T) or CLASS(*)
- AssumedTypeKind = -3, // TYPE(*)
- };
+ using SpecialKind = KindsEnum;
+
+ // BOZ actual argument to intrinsic function or pointer
+ // argument to ASSOCIATED
+ static inline constexpr SpecialKind TypelessKind{KindsEnum::TypelessKind};
+
+ // CLASS(T) or CLASS(*)
+ static inline constexpr SpecialKind ClassKind{KindsEnum::ClassKind};
+
+ // TYPE(*)
+ static inline constexpr SpecialKind AssumedTypeKind{
+ KindsEnum::AssumedTypeKind};
constexpr DynamicType() {}
TypeCategory category_{TypeCategory::Derived}; // overridable default
- int kind_{0};
+ KindsEnum kind_{NoKind};
const semantics::ParamValue *charLengthParamValue_{nullptr};
#if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE == 7
// GCC 7's optional<> lacks a constexpr operator=
@@ -268,10 +286,10 @@ const semantics::DerivedTypeSpec *GetParentTypeSpec(
const semantics::DerivedTypeSpec &);
template <TypeCategory CATEGORY> struct TypeBase {
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
static constexpr TypeCategory category{CATEGORY};
- explicit constexpr TypeBase(int kind) : kind_{kind} {}
+ explicit constexpr TypeBase(KindsEnum kind) : kind_{kind} {}
constexpr bool operator==(const TypeBase &that) const {
return kind_ == that.kind_;
}
@@ -279,7 +297,7 @@ template <TypeCategory CATEGORY> struct TypeBase {
std::string AsFortran() const { return GetType().AsFortran(); }
private:
- int kind_;
+ KindsEnum kind_;
};
template <>
@@ -417,8 +435,10 @@ template <> class SomeKind<TypeCategory::Derived> {
using Scalar = StructureConstructor;
// Argument provided for having the same signature as Types. Derived types
- // don't have a kind, it is expected to be zero.
- constexpr explicit SomeKind(int kind = 0) { CHECK(kind == 0); }
+ // don't have a kind, it is expected to be NoKind.
+ constexpr explicit SomeKind(KindsEnum kind = NoKind) {
+ CHECK(kind == NoKind);
+ }
constexpr explicit SomeKind(const semantics::DerivedTypeSpec &dts)
: derivedTypeSpec_{&dts} {}
constexpr explicit SomeKind(const DynamicType &dt)
@@ -477,7 +497,7 @@ template <typename CONST> struct TypeOfHelper {
template <typename CONST> using TypeOf = typename TypeOfHelper<CONST>::type;
-int SelectedCharKind(const std::string &, int defaultKind);
+int SelectedCharKind(const std::string &, KindsEnum defaultKind);
// SelectedIntKind and SelectedRealKind are now member functions of
// TargetCharactertics.
@@ -514,14 +534,14 @@ bool AreSameDerivedTypeIgnoringSequence(
if constexpr (std::is_same_v<TY, SomeDerived> || \
std::is_same_v<TY, SomeKind<TypeCategory::Derived>> || \
std::is_same_v<TY, SomeType>) { \
- CHECK((KIND) == 0 && "Type does not have a kind"); \
+ CHECK((KIND) == NoKind && "Type does not have a kind"); \
} else if constexpr (std::is_same_v<TY, Type<TypeCategory::Integer>> || \
std::is_same_v<TY, Type<TypeCategory::Unsigned>> || \
std::is_same_v<TY, Type<TypeCategory::Real>> || \
std::is_same_v<TY, Type<TypeCategory::Complex>> || \
std::is_same_v<TY, Type<TypeCategory::Logical>> || \
std::is_same_v<TY, Type<TypeCategory::Character>>) { \
- CHECK((KIND) != 0 && "Type must come with a kind"); \
+ CHECK((KIND) != NoKind && "Type must come with a kind"); \
} else { \
static_assert(false, "Don't know whether TY should have a kind"); \
} \
@@ -568,30 +588,6 @@ bool AreSameDerivedTypeIgnoringSequence(
FOR_EACH_INTRINSIC_KIND(PREFIX, SUFFIX) \
FOR_EACH_CATEGORY_TYPE(PREFIX, SUFFIX)
-/// Iterable lists of valid kinds for each TypeCategory for use by SearchTypes.
-template <TypeCategory CAT> struct KindsByType;
-template <> struct KindsByType<TypeCategory::Integer> {
- static constexpr int kinds[] = FORTRAN_INTEGER_KINDS;
-};
-template <> struct KindsByType<TypeCategory::Unsigned> {
- static constexpr int kinds[] = FORTRAN_UNSIGNED_KINDS;
-};
-template <> struct KindsByType<TypeCategory::Real> {
- static constexpr int kinds[] = FORTRAN_REAL_KINDS;
-};
-template <> struct KindsByType<TypeCategory::Complex> {
- static constexpr int kinds[] = FORTRAN_REAL_KINDS;
-};
-template <> struct KindsByType<TypeCategory::Logical> {
- static constexpr int kinds[] = FORTRAN_LOGICAL_KINDS;
-};
-template <> struct KindsByType<TypeCategory::Character> {
- static constexpr int kinds[] = FORTRAN_CHARACTER_KINDS;
-};
-template <> struct KindsByType<TypeCategory::Derived> {
- static constexpr int kinds[] = {0};
-};
-
// Given a VISITOR class of the general form
// struct VISITOR {
// using Result = ...;
@@ -609,7 +605,7 @@ common::IfNoLvalue<typename VISITOR::Result, VISITOR> SearchTypesHelper(
using Tuple = typename VISITOR::Types;
if constexpr (J < std::tuple_size_v<Tuple>) {
using TYPE = std::tuple_element_t<J, Tuple>;
- for (int kind : evaluate::KindsByType<TYPE::category>::kinds) {
+ for (KindsEnum kind : common::KindsByType<TYPE::category>::kinds) {
if (auto result{visitor.template Test<TYPE>(kind)}) {
return result;
}
diff --git a/flang/include/flang/Evaluate/typekind-traits.h b/flang/include/flang/Evaluate/typekind-traits.h
index 38aef267d8b61..8d2a2dddabb36 100644
--- a/flang/include/flang/Evaluate/typekind-traits.h
+++ b/flang/include/flang/Evaluate/typekind-traits.h
@@ -46,14 +46,17 @@ template <common::TypeCategory CAT, int KIND> struct TypeKind;
template <int KIND> struct TypeKind<common::TypeCategory::Integer, KIND> {
static constexpr common::TypeCategory category{common::TypeCategory::Integer};
static constexpr int kind{KIND};
- static constexpr int bits{value::IntegerValue::bits(KIND)};
- static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
+ static constexpr KindsEnum kindsEnum{static_cast<KindsEnum>(KIND)};
+ static constexpr int bits{value::IntegerValue::bits(kindsEnum)};
+ static constexpr int bytesStored{value::IntegerValue::bytesStored(kindsEnum)};
using UnsignedT = common::HostUnsignedIntType<bits>;
using SignedT = common::HostSignedIntType<bits>;
using HostT = SignedT;
using Scalar = value::IntegerValue;
using FortranType = Fortran::evaluate::Type<common::TypeCategory::Integer>;
- static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
+ static constexpr DynamicType GetType() {
+ return DynamicType{category, kindsEnum};
+ }
};
using IntegerKindTypes = std::tuple<TypeKind<TypeCategory::Integer, 1>,
@@ -64,14 +67,17 @@ template <int KIND> struct TypeKind<common::TypeCategory::Unsigned, KIND> {
static constexpr common::TypeCategory category{
common::TypeCategory::Unsigned};
static constexpr int kind{KIND};
- static constexpr int bits{value::IntegerValue::bits(KIND)};
- static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
+ static constexpr KindsEnum kindsEnum{static_cast<KindsEnum>(KIND)};
+ static constexpr int bits{value::IntegerValue::bits(kindsEnum)};
+ static constexpr int bytesStored{value::IntegerValue::bytesStored(kindsEnum)};
using UnsignedT = common::HostUnsignedIntType<bits>;
using SignedT = common::HostSignedIntType<bits>;
using HostT = UnsignedT;
using Scalar = value::IntegerValue;
using FortranType = Fortran::evaluate::Type<common::TypeCategory::Unsigned>;
- static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
+ static constexpr DynamicType GetType() {
+ return DynamicType{category, kindsEnum};
+ }
};
using UnsignedKindTypes = std::tuple<TypeKind<TypeCategory::Unsigned, 1>,
@@ -81,14 +87,17 @@ using UnsignedKindTypes = std::tuple<TypeKind<TypeCategory::Unsigned, 1>,
template <int KIND> struct TypeKind<common::TypeCategory::Logical, KIND> {
static constexpr common::TypeCategory category{common::TypeCategory::Logical};
static constexpr int kind{KIND};
- static constexpr int bits{value::LogicalValue::bits(KIND)};
- static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
+ static constexpr KindsEnum kindsEnum{static_cast<KindsEnum>(KIND)};
+ static constexpr int bits{value::LogicalValue::bits(kindsEnum)};
+ static constexpr int bytesStored{value::IntegerValue::bytesStored(kindsEnum)};
using UnsignedT = common::HostUnsignedIntType<bits>;
using SignedT = common::HostSignedIntType<bits>;
using HostT = UnsignedT;
using Scalar = value::LogicalValue;
using FortranType = Fortran::evaluate::Type<common::TypeCategory::Logical>;
- static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
+ static constexpr DynamicType GetType() {
+ return DynamicType{category, kindsEnum};
+ }
};
using LogicalKindTypes = std::tuple<TypeKind<TypeCategory::Logical, 1>,
@@ -111,14 +120,17 @@ template <> struct RealHostType<64> {
template <int KIND> struct TypeKind<common::TypeCategory::Real, KIND> {
static constexpr common::TypeCategory category{common::TypeCategory::Real};
static constexpr int kind{KIND};
- static constexpr int bits{value::RealValue::bits(KIND)};
- static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
+ static constexpr KindsEnum kindsEnum{static_cast<KindsEnum>(KIND)};
+ static constexpr int bits{value::RealValue::bits(kindsEnum)};
+ static constexpr int bytesStored{value::IntegerValue::bytesStored(kindsEnum)};
using UnsignedT = common::HostUnsignedIntType<bits>;
using SignedT = common::HostSignedIntType<bits>;
using HostT = typename detail::RealHostType<bits>::type;
using Scalar = value::RealValue;
using FortranType = Fortran::evaluate::Type<common::TypeCategory::Real>;
- static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
+ static constexpr DynamicType GetType() {
+ return DynamicType{category, kindsEnum};
+ }
};
using RealKindTypes =
@@ -129,10 +141,13 @@ using RealKindTypes =
template <int KIND> struct TypeKind<common::TypeCategory::Complex, KIND> {
static constexpr common::TypeCategory category{common::TypeCategory::Complex};
static constexpr int kind{KIND};
- static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
+ static constexpr KindsEnum kindsEnum{static_cast<KindsEnum>(KIND)};
+ static constexpr int bytesStored{value::IntegerValue::bytesStored(kindsEnum)};
using FortranType = Fortran::evaluate::Type<common::TypeCategory::Complex>;
using Scalar = value::ComplexValue;
- static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
+ static constexpr DynamicType GetType() {
+ return DynamicType{category, kindsEnum};
+ }
using Part = TypeKind<common::TypeCategory::Real, KIND>;
};
@@ -145,39 +160,48 @@ template <> struct TypeKind<common::TypeCategory::Character, 1> {
static constexpr common::TypeCategory category{
common::TypeCategory::Character};
static constexpr int kind{1};
- static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
+ static constexpr KindsEnum kindsEnum{Kind1};
+ static constexpr int bytesStored{value::IntegerValue::bytesStored(kindsEnum)};
using CharT = char;
using StringT = std::basic_string<CharT>;
using HostT = void;
using Scalar = value::CharacterValue;
using FortranType = Fortran::evaluate::Type<common::TypeCategory::Character>;
- static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
+ static constexpr DynamicType GetType() {
+ return DynamicType{category, kindsEnum};
+ }
};
template <> struct TypeKind<common::TypeCategory::Character, 2> {
static constexpr common::TypeCategory category{
common::TypeCategory::Character};
static constexpr int kind{2};
- static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
+ static constexpr KindsEnum kindsEnum{Kind2};
+ static constexpr int bytesStored{value::IntegerValue::bytesStored(kindsEnum)};
using CharT = char16_t;
using StringT = std::basic_string<CharT>;
using HostT = void;
using Scalar = value::CharacterValue;
using FortranType = Fortran::evaluate::Type<common::TypeCategory::Character>;
- static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
+ static constexpr DynamicType GetType() {
+ return DynamicType{category, kindsEnum};
+ }
};
template <> struct TypeKind<common::TypeCategory::Character, 4> {
static constexpr common::TypeCategory category{
common::TypeCategory::Character};
static constexpr int kind{4};
- static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
+ static constexpr KindsEnum kindsEnum{Kind4};
+ static constexpr int bytesStored{value::IntegerValue::bytesStored(kindsEnum)};
using CharT = char32_t;
using StringT = std::basic_string<CharT>;
using HostT = void;
using Scalar = value::CharacterValue;
using FortranType = Fortran::evaluate::Type<common::TypeCategory::Character>;
- static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
+ static constexpr DynamicType GetType() {
+ return DynamicType{category, kindsEnum};
+ }
};
using CharacterKindTypes = std::tuple<TypeKind<TypeCategory::Character, 1>,
diff --git a/flang/include/flang/Evaluate/variable.h b/flang/include/flang/Evaluate/variable.h
index d4b861006ec36..bf3ef0c88e67c 100644
--- a/flang/include/flang/Evaluate/variable.h
+++ b/flang/include/flang/Evaluate/variable.h
@@ -136,8 +136,8 @@ class NamedEntity {
class TypeParamInquiry {
public:
using Result = SubscriptInteger;
- static constexpr int ResultKind{SubscriptIntegerKind};
- constexpr int kind() const { return SubscriptIntegerKind; }
+ static constexpr KindsEnum ResultKind{SubscriptIntegerKind};
+ constexpr KindsEnum kind() const { return ResultKind; }
static constexpr DynamicType GetType() {
return DynamicType{TypeCategory::Integer, SubscriptIntegerKind};
}
@@ -398,38 +398,38 @@ template <typename T> class Designator {
static_assert(
IsSpecificIntrinsicType<Result> || std::is_same_v<Result, SomeDerived>);
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
CLASS_BOILERPLATE(Designator)
template <typename _A>
- explicit Designator(int kind, const _A &x) : u{x}, kind_{kind} {
+ explicit Designator(KindsEnum kind, const _A &x) : u{x}, kind_{kind} {
CHECK_KIND(kind, T);
}
template <typename _A, typename = common::NoLvalue<_A>>
- explicit Designator(int kind, _A &&x) : u(std::move(x)), kind_{kind} {
+ explicit Designator(KindsEnum kind, _A &&x) : u(std::move(x)), kind_{kind} {
CHECK_KIND(kind, T);
}
template <typename _A, typename U = T,
typename = std::enable_if_t<std::is_same_v<U, SomeDerived>>>
- explicit Designator(const _A &x) : Designator(0, x) {}
+ explicit Designator(const _A &x) : Designator(NoKind, x) {}
template <typename _A, typename U = T, typename = common::NoLvalue<_A>,
typename = std::enable_if_t<std::is_same_v<U, SomeDerived>>>
- explicit Designator(_A &&x) : Designator(0, std::move(x)) {}
+ explicit Designator(_A &&x) : Designator(NoKind, std::move(x)) {}
bool operator==(const Designator &) const;
- Designator(int kind, const DataRef &that)
+ Designator(KindsEnum kind, const DataRef &that)
: u{common::CopyVariant<Variant>(that.u)}, kind_{kind} {
CHECK_KIND(kind, T);
}
- Designator(int kind, DataRef &&that)
+ Designator(KindsEnum kind, DataRef &&that)
: u{common::MoveVariant<Variant>(std::move(that.u))}, kind_{kind} {
CHECK_KIND(kind, T);
}
template <typename U = T,
typename = std::enable_if_t<std::is_same_v<U, SomeDerived>>>
- Designator(const DataRef &that) : Designator(0, that) {}
+ Designator(const DataRef &that) : Designator(NoKind, that) {}
template <typename U = T,
typename = std::enable_if_t<std::is_same_v<U, SomeDerived>>>
- Designator(DataRef &&that) : Designator(0, std::move(that)) {}
+ Designator(DataRef &&that) : Designator(NoKind, std::move(that)) {}
std::optional<DynamicType> GetType() const;
int Rank() const;
@@ -442,7 +442,7 @@ template <typename T> class Designator {
Variant u;
private:
- int kind_;
+ KindsEnum kind_;
};
FOR_EACH_CHARACTER_KIND(extern template class Designator, )
@@ -450,7 +450,7 @@ FOR_EACH_CHARACTER_KIND(extern template class Designator, )
class DescriptorInquiry {
public:
using Result = SubscriptInteger;
- static constexpr int kind() { return SubscriptIntegerKind; }
+ static constexpr KindsEnum kind() { return SubscriptIntegerKind; }
static constexpr DynamicType GetType() {
return DynamicType{TypeCategory::Integer, SubscriptIntegerKind};
}
@@ -483,7 +483,7 @@ class DescriptorInquiry {
class RankOneBoundElement {
public:
using Result = SubscriptInteger;
- static constexpr int ResultKind{SubscriptIntegerKind};
+ static constexpr KindsEnum ResultKind{SubscriptIntegerKind};
CLASS_BOILERPLATE(RankOneBoundElement)
RankOneBoundElement(
common::CopyableIndirection<Expr<SubscriptInteger>> &&e, int dim)
@@ -495,7 +495,7 @@ class RankOneBoundElement {
Expr<SubscriptInteger> &base() { return base_.value(); }
int dimension() const { return dimension_; }
- static constexpr int kind() { return ResultKind; }
+ static constexpr KindsEnum kind() { return ResultKind; }
static constexpr int Rank() { return 0; } // always scalar
static constexpr int Corank() { return 0; }
diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h
index f6e5634d5a995..3f079aad688d6 100644
--- a/flang/include/flang/Frontend/TargetOptions.h
+++ b/flang/include/flang/Frontend/TargetOptions.h
@@ -18,6 +18,7 @@
#ifndef FORTRAN_FRONTEND_TARGETOPTIONS_H
#define FORTRAN_FRONTEND_TARGETOPTIONS_H
+#include "flang/Common/type-kinds.h"
#include <string>
#include <vector>
@@ -43,10 +44,10 @@ class TargetOptions {
std::vector<std::string> featuresAsWritten;
/// The real KINDs disabled for this target
- std::vector<int> disabledRealKinds;
+ std::vector<common::KindsEnum> disabledRealKinds;
/// The integer KINDs disabled for this target
- std::vector<int> disabledIntegerKinds;
+ std::vector<common::KindsEnum> disabledIntegerKinds;
/// Extended Altivec ABI on AIX
bool EnableAIXExtendedAltivecABI;
diff --git a/flang/include/flang/Lower/Mangler.h b/flang/include/flang/Lower/Mangler.h
index a243b7824dfcd..e0f2d6a5c1d9f 100644
--- a/flang/include/flang/Lower/Mangler.h
+++ b/flang/include/flang/Lower/Mangler.h
@@ -69,19 +69,17 @@ template <Fortran::common::TypeCategory TC>
std::string mangleArrayLiteral(
mlir::Type,
const Fortran::evaluate::Constant<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
- x.shape(), TC, kind);
+ x.shape(), TC, static_cast<int>(x.kind()));
}
inline std::string mangleArrayLiteral(
mlir::Type,
const Fortran::evaluate::Constant<
Fortran::evaluate::Type<Fortran::common::TypeCategory::Character>> &x) {
- const int kind{x.kind()};
return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
x.shape(), Fortran::common::TypeCategory::Character,
- kind, x.LEN());
+ static_cast<int>(x.kind()), x.LEN());
}
inline std::string mangleArrayLiteral(
diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h
index 555cdec21774e..f9efdc10738e0 100644
--- a/flang/include/flang/Lower/Support/Utils.h
+++ b/flang/include/flang/Lower/Support/Utils.h
@@ -66,7 +66,7 @@ static Fortran::lower::SomeExpr
ignoreEvConvert(const Fortran::evaluate::Convert<
Fortran::evaluate::Type<Fortran::common::TypeCategory::Integer>,
FROM> &x) {
- CHECK(x.kind() == 8);
+ CHECK(x.kind() == Fortran::common::KindsEnum::Kind8);
return toEvExpr(x.left());
}
template <typename A>
@@ -80,7 +80,7 @@ static Fortran::lower::SomeExpr ignoreEvConvert(const A &x) {
inline Fortran::lower::SomeExpr ignoreEvConvert(
const Fortran::evaluate::Expr<
Fortran::evaluate::Type<Fortran::common::TypeCategory::Integer>> &x) {
- CHECK(x.kind() == 8);
+ CHECK(x.kind() == Fortran::common::KindsEnum::Kind8);
return Fortran::common::visit(
[](const auto &v) { return ignoreEvConvert(v); }, x.u);
}
diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h
index 59cd424c4dae9..11a7a3fa84e82 100644
--- a/flang/include/flang/Semantics/expression.h
+++ b/flang/include/flang/Semantics/expression.h
@@ -137,15 +137,15 @@ class ExpressionAnalyzer {
return Say(parser::FindSourceLocation(parsed), std::forward<A>(args)...);
}
- int GetDefaultKind(common::TypeCategory);
+ KindsEnum GetDefaultKind(common::TypeCategory);
DynamicType GetDefaultKindOfType(common::TypeCategory);
// Return false and emit error if these checks fail:
- bool CheckIntrinsicKind(TypeCategory, std::int64_t kind);
+ bool CheckIntrinsicKind(TypeCategory, KindsEnum kind);
bool CheckIntrinsicSize(TypeCategory, std::int64_t size);
// Manage a set of active implied DO loops.
- bool AddImpliedDo(parser::CharBlock, int kind);
+ bool AddImpliedDo(parser::CharBlock, KindsEnum kind);
void RemoveImpliedDo(parser::CharBlock);
// When the argument is the name of an active implied DO index, returns
@@ -272,7 +272,7 @@ class ExpressionAnalyzer {
}
protected:
- int IntegerTypeSpecKind(const parser::IntegerTypeSpec &);
+ KindsEnum IntegerTypeSpecKind(const parser::IntegerTypeSpec &);
private:
// Allows an Expr to be a null pointer.
@@ -329,13 +329,13 @@ class ExpressionAnalyzer {
}
// Analysis subroutines
- int AnalyzeKindParam(
- const std::optional<parser::KindParam> &, int defaultKind);
+ KindsEnum AnalyzeKindParam(
+ const std::optional<parser::KindParam> &, KindsEnum defaultKind);
template <typename PARSED>
MaybeExpr ExprOrVariable(const PARSED &, parser::CharBlock source);
template <typename TYPES, TypeCategory CAT, typename PARSED>
MaybeExpr IntLiteralConstant(const PARSED &, bool isNegated = false);
- MaybeExpr AnalyzeString(std::string &&, int kind);
+ MaybeExpr AnalyzeString(std::string &&, KindsEnum kind);
std::optional<Expr<SubscriptInteger>> AsSubscript(MaybeExpr &&);
std::optional<Expr<SubscriptInteger>> TripletPart(
const std::optional<parser::Subscript> &);
diff --git a/flang/include/flang/Semantics/semantics.h b/flang/include/flang/Semantics/semantics.h
index 28e5ccd9ad409..fb39a08d695be 100644
--- a/flang/include/flang/Semantics/semantics.h
+++ b/flang/include/flang/Semantics/semantics.h
@@ -82,11 +82,13 @@ class SemanticsContext {
const std::string &openAccDefaultNoneScalarsStrictDisableOption() const {
return openAccDefaultNoneScalarsStrictDisableOption_;
}
- int GetDefaultKind(TypeCategory) const;
- int doublePrecisionKind() const {
+ KindsEnum GetDefaultKind(TypeCategory) const;
+ KindsEnum doublePrecisionKind() const {
return defaultKinds_.doublePrecisionKind();
}
- int quadPrecisionKind() const { return defaultKinds_.quadPrecisionKind(); }
+ KindsEnum quadPrecisionKind() const {
+ return defaultKinds_.quadPrecisionKind();
+ }
bool IsEnabled(common::LanguageFeature feature) const {
return languageFeatures_.IsEnabled(feature);
}
@@ -193,8 +195,9 @@ class SemanticsContext {
return *this;
}
- const DeclTypeSpec &MakeNumericType(TypeCategory, int kind = 0);
- const DeclTypeSpec &MakeLogicalType(int kind = 0);
+ const DeclTypeSpec &MakeNumericType(
+ TypeCategory, KindsEnum kind = KindsEnum::NoKind);
+ const DeclTypeSpec &MakeLogicalType(KindsEnum kind = KindsEnum::NoKind);
std::size_t maxErrors() const { return maxErrors_; }
diff --git a/flang/include/flang/Semantics/type.h b/flang/include/flang/Semantics/type.h
index 2f216e3bc0cd6..873f61631cf70 100644
--- a/flang/include/flang/Semantics/type.h
+++ b/flang/include/flang/Semantics/type.h
@@ -45,6 +45,7 @@ class Symbol;
/// i.e. a range of lower-case characters with provenance.
using SourceName = parser::CharBlock;
using TypeCategory = common::TypeCategory;
+using KindsEnum = common::KindsEnum;
using SomeExpr = evaluate::Expr<evaluate::SomeType>;
using MaybeExpr = std::optional<SomeExpr>;
using SomeIntExpr = evaluate::Expr<evaluate::SomeInteger>;
@@ -53,7 +54,7 @@ using SubscriptIntExpr = evaluate::Expr<evaluate::SubscriptInteger>;
using MaybeSubscriptIntExpr = std::optional<SubscriptIntExpr>;
using KindExpr = SubscriptIntExpr;
-KindExpr MakeKindExpr(int v);
+using evaluate::MakeKindExpr;
// An array spec bound: an explicit integer expression, assumed size
// or implied shape(*), or assumed or deferred shape(:). In the absence
diff --git a/flang/include/flang/Support/default-kinds.h b/flang/include/flang/Support/default-kinds.h
index ab1422d63af30..ecd7b4132fc0b 100644
--- a/flang/include/flang/Support/default-kinds.h
+++ b/flang/include/flang/Support/default-kinds.h
@@ -10,6 +10,7 @@
#define FORTRAN_SUPPORT_DEFAULT_KINDS_H_
#include "Fortran.h"
+#include "flang/Common/type-kinds.h"
#include <cstdint>
namespace Fortran::common {
@@ -26,21 +27,21 @@ using ConstantSubscript = std::int64_t;
class IntrinsicTypeDefaultKinds {
public:
IntrinsicTypeDefaultKinds();
- int subscriptIntegerKind() const { return subscriptIntegerKind_; }
- int sizeIntegerKind() const { return sizeIntegerKind_; }
- int doublePrecisionKind() const { return doublePrecisionKind_; }
- int quadPrecisionKind() const { return quadPrecisionKind_; }
-
- IntrinsicTypeDefaultKinds &set_defaultIntegerKind(int);
- IntrinsicTypeDefaultKinds &set_subscriptIntegerKind(int);
- IntrinsicTypeDefaultKinds &set_sizeIntegerKind(int);
- IntrinsicTypeDefaultKinds &set_defaultRealKind(int);
- IntrinsicTypeDefaultKinds &set_doublePrecisionKind(int);
- IntrinsicTypeDefaultKinds &set_quadPrecisionKind(int);
- IntrinsicTypeDefaultKinds &set_defaultCharacterKind(int);
- IntrinsicTypeDefaultKinds &set_defaultLogicalKind(int);
-
- int GetDefaultKind(TypeCategory) const;
+ KindsEnum subscriptIntegerKind() const { return subscriptIntegerKind_; }
+ KindsEnum sizeIntegerKind() const { return sizeIntegerKind_; }
+ KindsEnum doublePrecisionKind() const { return doublePrecisionKind_; }
+ KindsEnum quadPrecisionKind() const { return quadPrecisionKind_; }
+
+ IntrinsicTypeDefaultKinds &set_defaultIntegerKind(KindsEnum);
+ IntrinsicTypeDefaultKinds &set_subscriptIntegerKind(KindsEnum);
+ IntrinsicTypeDefaultKinds &set_sizeIntegerKind(KindsEnum);
+ IntrinsicTypeDefaultKinds &set_defaultRealKind(KindsEnum);
+ IntrinsicTypeDefaultKinds &set_doublePrecisionKind(KindsEnum);
+ IntrinsicTypeDefaultKinds &set_quadPrecisionKind(KindsEnum);
+ IntrinsicTypeDefaultKinds &set_defaultCharacterKind(KindsEnum);
+ IntrinsicTypeDefaultKinds &set_defaultLogicalKind(KindsEnum);
+
+ KindsEnum GetDefaultKind(TypeCategory) const;
private:
// Default REAL just simply has to be IEEE-754 single precision today.
@@ -48,14 +49,17 @@ class IntrinsicTypeDefaultKinds {
// and default LOGICAL intrinsic types also have to occupy one numeric
// storage unit, so their kinds are also forced. Default COMPLEX must always
// comprise two default REAL components.
- int defaultIntegerKind_{4};
- int subscriptIntegerKind_{8};
- int sizeIntegerKind_{4}; // SIZE(), UBOUND(), &c. default KIND=
- int defaultRealKind_{defaultIntegerKind_};
- int doublePrecisionKind_{2 * defaultRealKind_};
- int quadPrecisionKind_{2 * doublePrecisionKind_};
- int defaultCharacterKind_{1};
- int defaultLogicalKind_{defaultIntegerKind_};
+ KindsEnum defaultIntegerKind_{KindsEnum::Kind4};
+ KindsEnum subscriptIntegerKind_{KindsEnum::Kind8};
+ KindsEnum sizeIntegerKind_{
+ KindsEnum::Kind4}; // SIZE(), UBOUND(), &c. default KIND=
+ KindsEnum defaultRealKind_{defaultIntegerKind_};
+ KindsEnum doublePrecisionKind_{
+ static_cast<KindsEnum>(2 * static_cast<int>(defaultRealKind_))};
+ KindsEnum quadPrecisionKind_{
+ static_cast<KindsEnum>(2 * static_cast<int>(doublePrecisionKind_))};
+ KindsEnum defaultCharacterKind_{KindsEnum::Kind1};
+ KindsEnum defaultLogicalKind_{defaultIntegerKind_};
};
} // namespace Fortran::common
#endif // FORTRAN_SUPPORT_DEFAULT_KINDS_H_
diff --git a/flang/include/flang/Tools/TargetSetup.h b/flang/include/flang/Tools/TargetSetup.h
index 47f886141b002..74a4f16421ab0 100644
--- a/flang/include/flang/Tools/TargetSetup.h
+++ b/flang/include/flang/Tools/TargetSetup.h
@@ -15,6 +15,7 @@
#include "llvm/Target/TargetMachine.h"
namespace Fortran::tools {
+using common::KindsEnum;
[[maybe_unused]] inline static void setUpTargetCharacteristics(
Fortran::evaluate::TargetCharacteristics &targetCharacteristics,
@@ -25,13 +26,13 @@ namespace Fortran::tools {
const llvm::Triple &targetTriple{targetMachine.getTargetTriple()};
if (targetTriple.getArch() == llvm::Triple::ArchType::x86_64) {
- targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/3);
- targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/4);
- targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/8);
+ targetCharacteristics.set_hasSubnormalFlushingControl(KindsEnum::Kind3);
+ targetCharacteristics.set_hasSubnormalFlushingControl(KindsEnum::Kind4);
+ targetCharacteristics.set_hasSubnormalFlushingControl(KindsEnum::Kind8);
// ieee_denorm exception support is nonstandard.
- targetCharacteristics.set_hasSubnormalExceptionSupport(/*kind=*/3);
- targetCharacteristics.set_hasSubnormalExceptionSupport(/*kind=*/4);
- targetCharacteristics.set_hasSubnormalExceptionSupport(/*kind=*/8);
+ targetCharacteristics.set_hasSubnormalExceptionSupport(KindsEnum::Kind3);
+ targetCharacteristics.set_hasSubnormalExceptionSupport(KindsEnum::Kind4);
+ targetCharacteristics.set_hasSubnormalExceptionSupport(KindsEnum::Kind8);
}
if (targetTriple.isARM() || targetTriple.isAArch64()) {
@@ -40,9 +41,9 @@ namespace Fortran::tools {
evaluate::IeeeFeature::Halting, false);
targetCharacteristics.set_ieeeFeature(
evaluate::IeeeFeature::Standard, false);
- targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/3);
- targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/4);
- targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/8);
+ targetCharacteristics.set_hasSubnormalFlushingControl(KindsEnum::Kind3);
+ targetCharacteristics.set_hasSubnormalFlushingControl(KindsEnum::Kind4);
+ targetCharacteristics.set_hasSubnormalFlushingControl(KindsEnum::Kind8);
}
switch (targetTriple.getArch()) {
@@ -51,9 +52,9 @@ namespace Fortran::tools {
break;
default:
targetCharacteristics.DisableType(
- Fortran::common::TypeCategory::Real, /*kind=*/10);
+ Fortran::common::TypeCategory::Real, KindsEnum::Kind10);
targetCharacteristics.DisableType(
- Fortran::common::TypeCategory::Complex, /*kind=*/10);
+ Fortran::common::TypeCategory::Complex, KindsEnum::Kind10);
break;
}
@@ -68,9 +69,10 @@ namespace Fortran::tools {
#endif
if constexpr (!f128Support) {
- targetCharacteristics.DisableType(Fortran::common::TypeCategory::Real, 16);
targetCharacteristics.DisableType(
- Fortran::common::TypeCategory::Complex, 16);
+ Fortran::common::TypeCategory::Real, KindsEnum::Kind16);
+ targetCharacteristics.DisableType(
+ Fortran::common::TypeCategory::Complex, KindsEnum::Kind16);
}
for (auto realKind : targetOptions.disabledRealKinds) {
@@ -95,7 +97,7 @@ namespace Fortran::tools {
// Currently the integer kind happens to be the same as the byte size
targetCharacteristics.set_integerKindForPointer(
- targetTriple.getArchPointerBitWidth() / 8);
+ static_cast<KindsEnum>(targetTriple.getArchPointerBitWidth() / 8));
// TODO: use target machine data layout to set-up the target characteristics
// type size and alignment info.
diff --git a/flang/lib/Evaluate/character-value-impl.cpp b/flang/lib/Evaluate/character-value-impl.cpp
index 44f5b1c46d0b5..bd031f9ea0ab1 100644
--- a/flang/lib/Evaluate/character-value-impl.cpp
+++ b/flang/lib/Evaluate/character-value-impl.cpp
@@ -15,14 +15,15 @@
namespace Fortran::evaluate::value {
-CharacterValueImpl::CharacterValueImpl(int kind, std::size_t n, char32_t c) {
+CharacterValueImpl::CharacterValueImpl(
+ KindsEnum kind, std::size_t n, char32_t c) {
withCharProto(kind, [this, n, c](auto ct) {
using CharT = std::decay_t<decltype(ct)>;
storage_ = std::basic_string<CharT>(n, static_cast<CharT>(c));
});
}
-CharacterValueImpl CharacterValueImpl::Zero(int kind) {
+CharacterValueImpl CharacterValueImpl::Zero(KindsEnum kind) {
return withCharProto(kind, [kind](auto c) {
using Char = std::decay_t<decltype(c)>;
return CharacterValueImpl{kind, std::basic_string<Char>{}};
@@ -30,7 +31,7 @@ CharacterValueImpl CharacterValueImpl::Zero(int kind) {
}
CharacterValueImpl CharacterValueImpl::FromRawBytes(
- int kind, const void *raw, size_t size) {
+ KindsEnum kind, const void *raw, size_t size) {
return withCharProto(kind, [kind, raw, size](auto charProto) {
using CharT = decltype(charProto);
CHECK(size % sizeof(CharT) == 0);
@@ -43,7 +44,7 @@ CharacterValueImpl CharacterValueImpl::FromRawBytes(
}
void CharacterValueImpl::print(llvm::raw_ostream &os) const {
- os << kind() << '_';
+ os << static_cast<int>(kind()) << '_';
withStdString(
[&](const auto &s) { os << parser::QuoteCharacterLiteral(s, true); });
}
@@ -178,7 +179,7 @@ bool CharacterValueImpl::operator==(const CharacterValueImpl &y) const {
this->storage_, y.storage_);
}
-void CharacterValueImpl::assign(int kind, std::size_t n, char32_t c) {
+void CharacterValueImpl::assign(KindsEnum kind, std::size_t n, char32_t c) {
return withCharProto(kind, [this, n, c](auto ct) {
using CharT = decltype(ct);
storage_ = std::basic_string<CharT>(n, static_cast<CharT>(c));
@@ -239,7 +240,8 @@ CharacterValueImpl CharacterValueImpl::substr(std::size_t pos) const {
llvm_unreachable("operation not supported on uninitialized value");
} else {
return CharacterValueImpl{
- sizeof(typename StringT::value_type), s.substr(pos)};
+ static_cast<KindsEnum>(sizeof(typename StringT::value_type)),
+ s.substr(pos)};
}
},
storage_);
@@ -255,7 +257,8 @@ CharacterValueImpl CharacterValueImpl::substr(
llvm_unreachable("operation not supported on uninitialized value");
} else {
return CharacterValueImpl{
- sizeof(typename StringT::value_type), s.substr(pos, len)};
+ static_cast<KindsEnum>(sizeof(typename StringT::value_type)),
+ s.substr(pos, len)};
}
},
storage_);
@@ -327,7 +330,7 @@ std::string CharacterValueImpl::ToStdString() const {
storage_);
}
-CharacterValueImpl CharacterValueImpl::ToAscii(int kind) const {
+CharacterValueImpl CharacterValueImpl::ToAscii(KindsEnum kind) const {
if (IsMonostate()) {
return Zero(kind);
}
@@ -341,11 +344,11 @@ CharacterValueImpl CharacterValueImpl::ToAscii(int kind) const {
StringT str;
for (auto iter{s.cbegin()}; iter != s.cend(); ++iter) {
if (static_cast<std::uint64_t>(*iter) > 127) {
- return Zero(sizeof(ct));
+ return Zero(static_cast<KindsEnum>(sizeof(ct)));
}
str.push_back(static_cast<CharT>(*iter));
}
- return CharacterValueImpl{sizeof(CharT), str};
+ return CharacterValueImpl{static_cast<KindsEnum>(sizeof(CharT)), str};
});
});
}
@@ -384,7 +387,8 @@ CharacterValueImpl CharacterValueImpl::operator+(
!std::is_same_v<std::decay_t<decltype(a)>, std::monostate>) {
using StringT = std::decay_t<decltype(a)>;
return CharacterValueImpl{
- sizeof(typename StringT::value_type), a + b};
+ static_cast<KindsEnum>(sizeof(typename StringT::value_type)),
+ a + b};
} else {
llvm_unreachable("operation not supported on uninitialized value or "
"values of different kinds");
diff --git a/flang/lib/Evaluate/character-value-impl.h b/flang/lib/Evaluate/character-value-impl.h
index 9e51587e657c0..3acf977e2ba6c 100644
--- a/flang/lib/Evaluate/character-value-impl.h
+++ b/flang/lib/Evaluate/character-value-impl.h
@@ -9,6 +9,7 @@
#ifndef FORTRAN_EVALUATE_CHARACTER_VALUE_IMPL_H_
#define FORTRAN_EVALUATE_CHARACTER_VALUE_IMPL_H_
+#include "flang/Common/type-kinds.h"
#include "flang/Evaluate/common.h"
#include "llvm/Support/ErrorHandling.h"
#include <cstddef>
@@ -18,6 +19,7 @@
#include <variant>
namespace Fortran::evaluate::value {
+using common::KindsEnum;
class CharacterValueImpl {
using Storage =
@@ -32,7 +34,7 @@ class CharacterValueImpl {
CharacterValueImpl &operator=(CharacterValueImpl &&) = default;
CharacterValueImpl() = default;
- explicit CharacterValueImpl(int kind, std::string s) {
+ explicit CharacterValueImpl(KindsEnum kind, std::string s) {
withCharProto(kind, [&](auto c) {
using CharT = std::decay_t<decltype(c)>;
using StringT = std::basic_string<CharT>;
@@ -51,25 +53,25 @@ class CharacterValueImpl {
CHECK(this->kind() == kind);
}
- explicit CharacterValueImpl(int kind, std::u16string s)
+ explicit CharacterValueImpl(KindsEnum kind, std::u16string s)
: storage_{std::move(s)} {
- CHECK(kind == 2);
+ CHECK(kind == KindsEnum::Kind2);
CHECK(this->kind() == kind);
}
- explicit CharacterValueImpl(int kind, std::u32string s)
+ explicit CharacterValueImpl(KindsEnum kind, std::u32string s)
: storage_{std::move(s)} {
- CHECK(kind == 4);
+ CHECK(kind == KindsEnum::Kind4);
CHECK(this->kind() == kind);
}
/// Fill constructors: create a string of n copies of the given character.
- CharacterValueImpl(int kind, std::size_t n, char32_t c);
+ CharacterValueImpl(KindsEnum kind, std::size_t n, char32_t c);
- static CharacterValueImpl Zero(int kind);
+ static CharacterValueImpl Zero(KindsEnum kind);
static CharacterValueImpl FromRawBytes(
- int kind, const void *raw, size_t byteSize);
+ KindsEnum kind, const void *raw, size_t byteSize);
void print(llvm::raw_ostream &os) const;
@@ -87,8 +89,9 @@ class CharacterValueImpl {
std::string ToStdString() const;
bool IsMonostate() const { return storage_.index() == 0; }
- int kind() const {
- return withCharProto([](auto ct) { return sizeof(ct); });
+ KindsEnum kind() const {
+ return withCharProto(
+ [](auto ct) { return static_cast<KindsEnum>(sizeof(ct)); });
}
/// Byte size of one character unit (1, 2, or 4).
@@ -119,7 +122,7 @@ class CharacterValueImpl {
bool operator>(const CharacterValueImpl &y) const { return y < *this; }
/// Assign n copies of the given character.
- void assign(int kind, std::size_t n, char32_t c);
+ void assign(KindsEnum kind, std::size_t n, char32_t c);
/// Assign from a raw character pointer and length.
void assign(const char *p, std::size_t n) { storage_ = std::string(p, n); }
@@ -146,7 +149,7 @@ class CharacterValueImpl {
/// Return a substring of len characters starting at pos.
CharacterValueImpl substr(std::size_t pos, std::size_t len) const;
- CharacterValueImpl ToAscii(int kind) const;
+ CharacterValueImpl ToAscii(KindsEnum kind) const;
/// Reserve storage for at least n characters.
void reserve(std::size_t n);
@@ -209,14 +212,14 @@ class CharacterValueImpl {
}
template <typename F>
- static auto withCharProto(int kind, F &&f)
+ static auto withCharProto(KindsEnum kind, F &&f)
-> decltype(std::declval<F>()(std::declval<char>())) {
switch (kind) {
- case 1:
+ case KindsEnum::Kind1:
return f(char{});
- case 2:
+ case KindsEnum::Kind2:
return f(char16_t{});
- case 4:
+ case KindsEnum::Kind4:
return f(char32_t{});
default:
llvm_unreachable("unsupported character kind/monostate");
diff --git a/flang/lib/Evaluate/character-value.cpp b/flang/lib/Evaluate/character-value.cpp
index 303fa80b175e6..6e54bbcceea5c 100644
--- a/flang/lib/Evaluate/character-value.cpp
+++ b/flang/lib/Evaluate/character-value.cpp
@@ -41,30 +41,30 @@ CharacterValue &CharacterValue::operator=(CharacterValue &&x) {
return *this;
}
-CharacterValue::CharacterValue(int kind, std::string s) {
+CharacterValue::CharacterValue(KindsEnum kind, std::string s) {
new (this) CharacterValueImpl(kind, std::move(s));
}
-CharacterValue::CharacterValue(int kind, std::u16string s) {
- CHECK(kind == 2);
+CharacterValue::CharacterValue(KindsEnum kind, std::u16string s) {
+ CHECK(kind == KindsEnum::Kind2);
new (this) CharacterValueImpl(kind, std::move(s));
}
-CharacterValue::CharacterValue(int kind, std::u32string s) {
- CHECK(kind == 4);
+CharacterValue::CharacterValue(KindsEnum kind, std::u32string s) {
+ CHECK(kind == KindsEnum::Kind4);
new (this) CharacterValueImpl(kind, std::move(s));
}
-CharacterValue::CharacterValue(int kind, std::size_t n, char32_t c) {
+CharacterValue::CharacterValue(KindsEnum kind, std::size_t n, char32_t c) {
new (this) CharacterValueImpl(kind, n, c);
}
-CharacterValue CharacterValue::Zero(int kind) {
+CharacterValue CharacterValue::Zero(KindsEnum kind) {
return FromImpl(CharacterValueImpl::Zero(kind));
}
CharacterValue CharacterValue::FromRawBytes(
- int kind, const void *raw, size_t byteSize) {
+ KindsEnum kind, const void *raw, size_t byteSize) {
return FromImpl(CharacterValueImpl::FromRawBytes(kind, raw, byteSize));
}
@@ -80,7 +80,7 @@ bool CharacterValue::empty() const { return impl().empty(); }
std::size_t CharacterValue::size() const { return impl().size(); }
-int CharacterValue::kind() const { return impl().kind(); }
+KindsEnum CharacterValue::kind() const { return impl().kind(); }
std::optional<llvm::StringRef> CharacterValue::AsStringRef() const {
return impl().AsStringRef();
@@ -108,11 +108,11 @@ bool CharacterValue::operator==(const CharacterValue &y) const {
return impl() == y.impl();
}
-CharacterValue CharacterValue::ToAscii(int kind) const {
+CharacterValue CharacterValue::ToAscii(KindsEnum kind) const {
return FromImpl(impl().ToAscii(kind));
}
-void CharacterValue::assign(int kind, std::size_t n, char32_t c) {
+void CharacterValue::assign(KindsEnum kind, std::size_t n, char32_t c) {
impl().assign(kind, n, c);
}
diff --git a/flang/lib/Evaluate/character.h b/flang/lib/Evaluate/character.h
index c1a34257e5682..8d95795aeafe4 100644
--- a/flang/lib/Evaluate/character.h
+++ b/flang/lib/Evaluate/character.h
@@ -19,6 +19,8 @@
namespace Fortran::evaluate {
+using common::KindsEnum;
+
class CharacterUtils {
using Character = Scalar<Type<TypeCategory::Character>>;
using CharT = char32_t;
@@ -27,7 +29,7 @@ class CharacterUtils {
// CHAR also implements ACHAR under assumption that character encodings
// contain ASCII
static Character CHAR(int kind, std::uint64_t code) {
- return Character{kind, 1, static_cast<CharT>(code)};
+ return Character{static_cast<KindsEnum>(kind), 1, static_cast<CharT>(code)};
}
// ICHAR also implements IACHAR under assumption that character encodings
@@ -37,20 +39,23 @@ class CharacterUtils {
// Mask to the character kind width to avoid sign extension
auto ch{static_cast<std::uint64_t>(c[0])};
switch (c.kind()) {
- case 1:
+ case Kind1:
return static_cast<std::int64_t>(ch & 0xffu);
- case 2:
+ case Kind2:
return static_cast<std::int64_t>(ch & 0xffffu);
- case 4:
+ case Kind4:
return static_cast<std::int64_t>(ch & 0xffffffffu);
+ default:
+ llvm_unreachable("unsupported character kind");
}
- llvm_unreachable("unsupported character kind");
}
- static Character NEW_LINE(int kind) { return Character{kind, 1, NewLine()}; }
+ static Character NEW_LINE(int kind) {
+ return Character{static_cast<KindsEnum>(kind), 1, NewLine()};
+ }
static Character ADJUSTL(const Character &str) {
- const int kind{str.kind()};
+ const KindsEnum kind{str.kind()};
auto pos{str.find_first_not_of(Space())};
if (pos != Character::npos && pos != 0) {
return Character{str.substr(pos) + Character{kind, pos, Space()}};
@@ -60,7 +65,7 @@ class CharacterUtils {
}
static Character ADJUSTR(const Character &str) {
- const int kind{str.kind()};
+ const KindsEnum kind{str.kind()};
auto pos{str.find_last_not_of(Space())};
if (pos != Character::npos && pos != str.length() - 1) {
auto delta{str.length() - 1 - pos};
@@ -92,7 +97,7 @@ class CharacterUtils {
// Resize adds spaces on the right if the new size is bigger than the
// original, or by trimming the rightmost characters otherwise.
static Character Resize(const Character &str, std::size_t newLength) {
- const int kind{str.kind()};
+ const KindsEnum kind{str.kind()};
auto oldLength{str.length()};
if (newLength > oldLength) {
return str + Character{kind, newLength - oldLength, Space()};
@@ -112,7 +117,7 @@ class CharacterUtils {
}
static Character REPEAT(const Character &str, ConstantSubscript ncopies) {
- const int kind{str.kind()};
+ const KindsEnum kind{str.kind()};
Character result{Character::Zero(kind)};
if (!str.empty() && ncopies > 0) {
result.reserve(ncopies * str.size());
diff --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp
index 4f1c6831e3aeb..ccc87fc61a525 100644
--- a/flang/lib/Evaluate/characteristics.cpp
+++ b/flang/lib/Evaluate/characteristics.cpp
@@ -76,7 +76,7 @@ TypeAndShape &TypeAndShape::Rewrite(FoldingContext &context) {
LEN_ = Fold(context, std::move(LEN_));
if (LEN_) {
if (auto n{ToInt64(*LEN_)}) {
- type_ = DynamicType{type_.kind(), *n};
+ type_ = DynamicType{static_cast<KindsEnum>(type_.kind()), *n};
}
}
shape_ = Fold(context, std::move(shape_));
@@ -940,7 +940,7 @@ std::optional<DummyArgument> DummyArgument::FromActual(std::string &&name,
type->type().GetDerivedTypeSpec(), /*poly=*/false});
}
if (type->type().category() == TypeCategory::Character &&
- type->type().kind() == 1) {
+ type->type().kind() == Kind1) {
type->set_isPossibleSequenceAssociation(true);
} else if (const Symbol * array{IsArrayElement(expr)}) {
type->set_isPossibleSequenceAssociation(
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index d3722c46632f3..925cc173940fe 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -476,26 +476,24 @@ class SuspiciousRealLiteralFinder
: public AnyTraverse<SuspiciousRealLiteralFinder> {
public:
using Base = AnyTraverse<SuspiciousRealLiteralFinder>;
- SuspiciousRealLiteralFinder(int kind, FoldingContext &c)
+ SuspiciousRealLiteralFinder(KindsEnum kind, FoldingContext &c)
: Base{*this}, kind_{kind}, context_{c} {}
using Base::operator();
bool operator()(const Constant<Type<TypeCategory::Real>> &x) const {
- const int kind{x.kind()};
- if (kind_ > kind && x.result().isFromInexactLiteralConversion()) {
+ if (kind_ > x.kind() && x.result().isFromInexactLiteralConversion()) {
context_.Warn(common::UsageWarning::RealConstantWidening,
"Default real literal in REAL(%d) context might need a kind suffix, as its rounded value %s is inexact"_warn_en_US,
- kind_, x.AsFortran());
+ static_cast<int>(kind_), x.AsFortran());
return true;
} else {
return false;
}
}
bool operator()(const Constant<Type<TypeCategory::Complex>> &x) const {
- const int kind{x.kind()};
- if (kind_ > kind && x.result().isFromInexactLiteralConversion()) {
+ if (kind_ > x.kind() && x.result().isFromInexactLiteralConversion()) {
context_.Warn(common::UsageWarning::RealConstantWidening,
"Default real literal in COMPLEX(%d) context might need a kind suffix, as its rounded value %s is inexact"_warn_en_US,
- kind_, x.AsFortran());
+ static_cast<int>(kind_), x.AsFortran());
return true;
} else {
return false;
@@ -503,7 +501,7 @@ class SuspiciousRealLiteralFinder
}
template <TypeCategory TOCAT, TypeCategory FROMCAT>
bool operator()(const Convert<Type<TOCAT>, FROMCAT> &x) const {
- const int toKind{x.kind()};
+ const KindsEnum toKind{x.kind()};
if constexpr ((TOCAT == TypeCategory::Real ||
TOCAT == TypeCategory::Complex) &&
(FROMCAT == TypeCategory::Real || FROMCAT == TypeCategory::Complex)) {
@@ -516,7 +514,7 @@ class SuspiciousRealLiteralFinder
}
private:
- int kind_;
+ KindsEnum kind_;
FoldingContext &context_;
};
@@ -528,7 +526,8 @@ void CheckRealWidening(const Expr<SomeType> &expr, const DynamicType &toType,
if ((fromType->category() == TypeCategory::Real ||
fromType->category() == TypeCategory::Complex) &&
toType.kind() > fromType->kind()) {
- SuspiciousRealLiteralFinder{toType.kind(), context}(expr);
+ SuspiciousRealLiteralFinder{
+ static_cast<KindsEnum>(toType.kind()), context}(expr);
}
}
}
diff --git a/flang/lib/Evaluate/complex-value.cpp b/flang/lib/Evaluate/complex-value.cpp
index 40ba3aeaefa2f..495def8c08052 100644
--- a/flang/lib/Evaluate/complex-value.cpp
+++ b/flang/lib/Evaluate/complex-value.cpp
@@ -13,7 +13,9 @@
namespace Fortran::evaluate::value {
-void ComplexValue::print(llvm::raw_ostream &os) const { AsFortran(os, kind()); }
+void ComplexValue::print(llvm::raw_ostream &os) const {
+ AsFortran(os, static_cast<int>(kind()));
+}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void ComplexValue::dump() const {
@@ -23,7 +25,7 @@ LLVM_DUMP_METHOD void ComplexValue::dump() const {
#endif
ValueWithRealFlags<ComplexValue> ComplexValue::FromInteger(
- int kind, const IntegerValue &n, bool isUnsigned, Rounding rounding) {
+ KindsEnum kind, const IntegerValue &n, bool isUnsigned, Rounding rounding) {
CHECK(!n.IsMonostate());
ValueWithRealFlags<ComplexValue> result;
@@ -171,7 +173,7 @@ void ComplexValue::StoreRawBytes(
}
ComplexValue ComplexValue::FromRawBytes(
- int kind, const void *raw, std::size_t expectedSize) {
+ KindsEnum kind, const void *raw, std::size_t expectedSize) {
CHECK(expectedSize == static_cast<size_t>(-1) ||
expectedSize == bytesStored(kind));
std::size_t partBytes{RealValue::bytesStored(kind)};
diff --git a/flang/lib/Evaluate/constant.cpp b/flang/lib/Evaluate/constant.cpp
index 7a78c1ade352a..5e5963ff02557 100644
--- a/flang/lib/Evaluate/constant.cpp
+++ b/flang/lib/Evaluate/constant.cpp
@@ -143,8 +143,8 @@ bool HasNegativeExtent(const ConstantSubscripts &shape) {
}
template <typename RESULT, typename ELEMENT>
-ConstantBase<RESULT, ELEMENT>::ConstantBase(
- int kind, std::vector<Element> &&x, ConstantSubscripts &&sh, Result res)
+ConstantBase<RESULT, ELEMENT>::ConstantBase(KindsEnum kind,
+ std::vector<Element> &&x, ConstantSubscripts &&sh, Result res)
: ConstantBounds(std::move(sh)), kind_{kind}, result_{res},
values_(std::move(x)) {
CHECK_KIND(kind, RESULT);
@@ -201,7 +201,7 @@ auto Constant<T>::At(const ConstantSubscripts &index) const -> Element {
template <typename T>
auto Constant<T>::Reshape(ConstantSubscripts &&dims) const -> Constant {
- const int kind{Base::kind()};
+ const KindsEnum kind{Base::kind_};
return {kind, Base::Reshape(dims), std::move(dims)};
}
@@ -213,20 +213,20 @@ std::size_t Constant<T>::CopyFrom(const Constant<T> &source, std::size_t count,
// Constant<Type<TypeCategory::Character>> specialization
Constant<Type<TypeCategory::Character>>::Constant(
- int kind, const Scalar<Result> &str)
+ KindsEnum kind, const Scalar<Result> &str)
: kind_{kind}, values_{str},
length_{static_cast<ConstantSubscript>(values_.size())} {
CHECK(str.kind() == kind);
}
Constant<Type<TypeCategory::Character>>::Constant(
- int kind, Scalar<Result> &&str)
+ KindsEnum kind, Scalar<Result> &&str)
: kind_{kind}, values_{std::move(str)},
length_{static_cast<ConstantSubscript>(values_.size())} {
CHECK(str.kind() == kind);
}
-Constant<Type<TypeCategory::Character>>::Constant(int kind,
+Constant<Type<TypeCategory::Character>>::Constant(KindsEnum kind,
ConstantSubscript len, std::vector<Scalar<Result>> &&strings,
ConstantSubscripts &&sh)
: ConstantBounds(std::move(sh)), kind_{kind}, length_{len} {
@@ -319,7 +319,8 @@ std::size_t Constant<Type<TypeCategory::Character>>::CopyFrom(
return count;
} else {
std::size_t copied{0};
- std::size_t elementBytes{static_cast<std::size_t>(length_) * kind()};
+ std::size_t elementBytes{
+ static_cast<std::size_t>(length_) * static_cast<std::size_t>(kind())};
ConstantSubscripts sourceSubscripts{source.lbounds()};
while (copied < count) {
auto *dest{values_.at(SubscriptsToOffset(resultSubscripts) * length_)};
@@ -336,14 +337,14 @@ std::size_t Constant<Type<TypeCategory::Character>>::CopyFrom(
// Constant<SomeDerived> specialization
Constant<SomeDerived>::Constant(const StructureConstructor &x)
- : Base{/*kind=*/0, x.values(), Result{x.derivedTypeSpec()}} {}
+ : Base{NoKind, x.values(), Result{x.derivedTypeSpec()}} {}
Constant<SomeDerived>::Constant(StructureConstructor &&x)
- : Base{/*kind=*/0, std::move(x.values()), Result{x.derivedTypeSpec()}} {}
+ : Base{NoKind, std::move(x.values()), Result{x.derivedTypeSpec()}} {}
Constant<SomeDerived>::Constant(const semantics::DerivedTypeSpec &spec,
std::vector<StructureConstructorValues> &&x, ConstantSubscripts &&s)
- : Base{/*kind=*/0, std::move(x), std::move(s), Result{spec}} {}
+ : Base{NoKind, std::move(x), std::move(s), Result{spec}} {}
static std::vector<StructureConstructorValues> AcquireValues(
std::vector<StructureConstructor> &&x) {
@@ -356,7 +357,7 @@ static std::vector<StructureConstructorValues> AcquireValues(
Constant<SomeDerived>::Constant(const semantics::DerivedTypeSpec &spec,
std::vector<StructureConstructor> &&x, ConstantSubscripts &&shape)
- : Base{/*kind=*/0, AcquireValues(std::move(x)), std::move(shape),
+ : Base{NoKind, AcquireValues(std::move(x)), std::move(shape),
Result{spec}} {}
std::optional<StructureConstructor>
diff --git a/flang/lib/Evaluate/expression.cpp b/flang/lib/Evaluate/expression.cpp
index e8279bb288588..6593cc6454c9d 100644
--- a/flang/lib/Evaluate/expression.cpp
+++ b/flang/lib/Evaluate/expression.cpp
@@ -91,10 +91,10 @@ const typename ExpressionBase<A>::Derived &ExpressionBase<A>::derived() const {
}
#endif
-template <typename A> int ExpressionBase<A>::kind() const {
+template <typename A> KindsEnum ExpressionBase<A>::kind() const {
// Storing/deriving the kind handled by the subclasses
return common::visit(
- [&](const auto &x) -> int { return x.kind(); }, derived().u);
+ [&](const auto &x) -> KindsEnum { return x.kind(); }, derived().u);
}
template <typename A>
@@ -367,45 +367,47 @@ std::optional<Expr<SubscriptInteger>> Expr<SomeCharacter>::LEN() const {
}
Parentheses<SomeDerived>::Parentheses(const Expr<SomeDerived> &x)
- : Base{x.kind(), x} {}
+ : Base{static_cast<KindsEnum>(x.kind()), x} {}
Parentheses<SomeDerived>::Parentheses(Expr<SomeDerived> &&x)
- : Base{x.kind(), std::move(x)} {}
+ : Base{static_cast<KindsEnum>(x.kind()), std::move(x)} {}
ComplexComponent::ComplexComponent(bool isImaginary, const Expr<Operand> &x)
- : Base{x.kind(), x}, isImaginaryPart{isImaginary} {}
+ : Base{static_cast<KindsEnum>(x.kind()), x}, isImaginaryPart{isImaginary} {}
ComplexComponent::ComplexComponent(bool isImaginary, Expr<Operand> &&x)
- : Base{x.kind(), std::move(x)}, isImaginaryPart{isImaginary} {}
+ : Base{static_cast<KindsEnum>(x.kind()), std::move(x)},
+ isImaginaryPart{isImaginary} {}
ComplexConstructor::ComplexConstructor(const Expr<Type<TypeCategory::Real>> &re,
const Expr<Type<TypeCategory::Real>> &im)
- : Base{re.kind(), re, im} {
+ : Base{static_cast<KindsEnum>(re.kind()), re, im} {
CHECK(re.kind() == im.kind());
}
ComplexConstructor::ComplexConstructor(
Expr<Type<TypeCategory::Real>> &&re, Expr<Type<TypeCategory::Real>> &&im)
- : Base{re.kind(), std::move(re), std::move(im)} {
+ : Base{static_cast<KindsEnum>(re.kind()), std::move(re), std::move(im)} {
CHECK(left().kind() == right().kind());
}
LogicalOperation::LogicalOperation(
LogicalOperator opr, const Expr<Operand> &x, const Expr<Operand> &y)
- : Base{x.kind(), x, y}, logicalOperator{opr} {
+ : Base{static_cast<KindsEnum>(x.kind()), x, y}, logicalOperator{opr} {
CHECK(x.kind() == y.kind());
}
LogicalOperation::LogicalOperation(
LogicalOperator opr, Expr<Operand> &&x, Expr<Operand> &&y)
- : Base{x.kind(), std::move(x), std::move(y)}, logicalOperator{opr} {
+ : Base{static_cast<KindsEnum>(x.kind()), std::move(x), std::move(y)},
+ logicalOperator{opr} {
CHECK(x.kind() == y.kind());
}
Concat::Concat(const Expr<Type<TypeCategory::Character>> &x,
const Expr<Type<TypeCategory::Character>> &y)
- : Base{x.kind(), x, y} {
+ : Base{static_cast<KindsEnum>(x.kind()), x, y} {
CHECK(x.kind() == y.kind());
}
Concat::Concat(Expr<Type<TypeCategory::Character>> &&x,
Expr<Type<TypeCategory::Character>> &&y)
- : Base{x.kind(), std::move(x), std::move(y)} {
+ : Base{static_cast<KindsEnum>(x.kind()), std::move(x), std::move(y)} {
CHECK(left().kind() == right().kind());
}
diff --git a/flang/lib/Evaluate/fold-character.cpp b/flang/lib/Evaluate/fold-character.cpp
index 0a23c91df0654..f6dceed2042eb 100644
--- a/flang/lib/Evaluate/fold-character.cpp
+++ b/flang/lib/Evaluate/fold-character.cpp
@@ -47,7 +47,7 @@ Expr<Type<TypeCategory::Character>> FoldIntrinsicFunction(
FunctionRef<Type<TypeCategory::Character>> &&funcRef) {
using T = Type<TypeCategory::Character>;
using StringType = Scalar<T>; // CharacterValue
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
auto *intrinsic{std::get_if<SpecificIntrinsic>(&funcRef.proc().u)};
CHECK(intrinsic);
std::string name{intrinsic->name};
@@ -57,13 +57,15 @@ Expr<Type<TypeCategory::Character>> FoldIntrinsicFunction(
context, std::move(funcRef),
ScalarFunc<T, IntT>([&](const Scalar<IntT> &i) {
if (i.IsNegative() ||
- i.BGE(Scalar<IntT>{SubscriptIntegerKind, 0}.IBSET(8 * kind))) {
+ i.BGE(Scalar<IntT>{SubscriptIntegerKind, 0}.IBSET(
+ 8 * static_cast<int>(kind)))) {
context.Warn(common::UsageWarning::FoldingValueChecks,
"%s(I=%jd) is out of range for CHARACTER(KIND=%d)"_warn_en_US,
parser::ToUpperCaseLetters(name),
- static_cast<std::intmax_t>(i.ToInt64()), kind);
+ static_cast<std::intmax_t>(i.ToInt64()),
+ static_cast<int>(kind));
}
- return CharacterUtils::CHAR(kind, i.ToUInt64());
+ return CharacterUtils::CHAR(static_cast<int>(kind), i.ToUInt64());
}));
} else if (name == "adjustl") {
return FoldElementalIntrinsic<T, T>(
@@ -84,14 +86,15 @@ Expr<Type<TypeCategory::Character>> FoldIntrinsicFunction(
return FoldMINorMAX(context, std::move(funcRef), Ordering::Less);
} else if (name == "minval") {
// Collating sequences correspond to positive integers (3.31)
- StringType most{kind, 1, 0xffffffff >> (8 * (4 - kind))};
+ StringType most{kind, 1, 0xffffffff >> (8 * (4 - static_cast<int>(kind)))};
if (auto identity{
Identity<T>(most, GetConstantLength(context, funcRef, 0))}) {
return FoldMaxvalMinval<T>(
kind, context, std::move(funcRef), RelationalOperator::LT, *identity);
}
} else if (name == "new_line") {
- return MakeConstantExpr<T>(kind, CharacterUtils::NEW_LINE(kind));
+ return MakeConstantExpr<T>(
+ kind, CharacterUtils::NEW_LINE(static_cast<int>(kind)));
} else if (name == "repeat") { // not elemental
if (auto scalars{GetScalarConstantArguments<T, SubscriptInteger>(
{kind, SubscriptIntegerKind}, context, funcRef.arguments(),
@@ -129,7 +132,7 @@ Expr<Type<TypeCategory::Character>> FoldIntrinsicFunction(
Expr<Type<TypeCategory::Character>> FoldOperation(
FoldingContext &context, Concat &&x) {
- const int kind{x.kind()};
+ const KindsEnum kind{static_cast<KindsEnum>(x.kind())};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
@@ -142,7 +145,7 @@ Expr<Type<TypeCategory::Character>> FoldOperation(
Expr<Type<TypeCategory::Character>> FoldOperation(
FoldingContext &context, SetLength &&x) {
- const int kind{x.kind()};
+ const KindsEnum kind{static_cast<KindsEnum>(x.kind())};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
diff --git a/flang/lib/Evaluate/fold-complex.cpp b/flang/lib/Evaluate/fold-complex.cpp
index fda86906d7fb4..59c67b4eefaa9 100644
--- a/flang/lib/Evaluate/fold-complex.cpp
+++ b/flang/lib/Evaluate/fold-complex.cpp
@@ -14,7 +14,7 @@ namespace Fortran::evaluate {
Expr<Type<TypeCategory::Complex>> FoldIntrinsicFunction(FoldingContext &context,
FunctionRef<Type<TypeCategory::Complex>> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
using T = Type<TypeCategory::Complex>;
using Part = typename T::Part;
ActualArguments &args{funcRef.arguments()};
@@ -31,7 +31,7 @@ Expr<Type<TypeCategory::Complex>> FoldIntrinsicFunction(FoldingContext &context,
} else {
context.Warn(common::UsageWarning::FoldingFailure,
"%s(complex(kind=%d)) cannot be folded on host"_warn_en_US, name,
- kind);
+ static_cast<int>(kind));
}
} else if (name == "conjg") {
return FoldElementalIntrinsic<T, T>(
@@ -67,7 +67,8 @@ Expr<Type<TypeCategory::Complex>> FoldIntrinsicFunction(FoldingContext &context,
} else if (name == "matmul") {
return FoldMatmul(context, std::move(funcRef));
} else if (name == "product") {
- auto one{Scalar<Part>::FromInteger(kind, value::IntegerValue{1, 1}).value};
+ auto one{
+ Scalar<Part>::FromInteger(kind, value::IntegerValue{Kind1, 1}).value};
return FoldProduct<T>(context, std::move(funcRef), Scalar<T>{one});
} else if (name == "sum") {
return FoldSum<T>(context, std::move(funcRef));
@@ -77,7 +78,7 @@ Expr<Type<TypeCategory::Complex>> FoldIntrinsicFunction(FoldingContext &context,
Expr<Type<TypeCategory::Complex>> FoldOperation(
FoldingContext &context, ComplexConstructor &&x) {
- const int kind{x.kind()};
+ const KindsEnum kind{x.kind()};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
diff --git a/flang/lib/Evaluate/fold-designator.cpp b/flang/lib/Evaluate/fold-designator.cpp
index 4e0cc1b841194..7f65bafda5121 100644
--- a/flang/lib/Evaluate/fold-designator.cpp
+++ b/flang/lib/Evaluate/fold-designator.cpp
@@ -340,7 +340,7 @@ std::optional<Expr<SomeType>> OffsetToDesignator(FoldingContext &context,
return common::visit(
[&](const auto &z) -> std::optional<Expr<SomeType>> {
using PartType = typename ResultType<decltype(z)>::Part;
- const int kind{z.kind()};
+ const KindsEnum kind{z.kind()};
return AsGenericExpr(Designator<PartType>{kind,
ComplexPart{
ExtractDataRef(std::move(*zExpr)).value(), part}});
@@ -354,12 +354,13 @@ std::optional<Expr<SomeType>> OffsetToDesignator(FoldingContext &context,
return common::visit(
[&](const auto &x) -> std::optional<Expr<SomeType>> {
using T = typename std::decay_t<decltype(x)>::Result;
- const int kind{x.kind()};
+ const KindsEnum kind{x.kind()};
+ const int kindBytes{static_cast<int>(kind)};
return AsGenericExpr(Designator<T>{kind,
Substring{ExtractDataRef(std::move(*cExpr)).value(),
- MakeSubscriptIntExpr(1 + (offset / kind)),
+ MakeSubscriptIntExpr(1 + (offset / kindBytes)),
MakeSubscriptIntExpr(
- 1 + ((offset + size - 1) / kind))}});
+ 1 + ((offset + size - 1) / kindBytes))}});
},
cExpr->u);
}
diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index 24e68fb3e74cd..6a0aab5b4b2e3 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -53,12 +53,13 @@ static constexpr bool useKahanSummation{false};
// Utilities
template <typename T> class Folder {
public:
- explicit Folder(int kind, FoldingContext &c, bool forOptionalArgument = false)
+ explicit Folder(
+ KindsEnum kind, FoldingContext &c, bool forOptionalArgument = false)
: kind_{kind}, context_{c}, forOptionalArgument_{forOptionalArgument} {}
template <typename U = T,
typename = std::enable_if_t<std::is_same_v<U, SomeDerived>>>
explicit Folder(FoldingContext &c, bool forOptionalArgument = false)
- : Folder(0, c, forOptionalArgument) {}
+ : Folder(NoKind, c, forOptionalArgument) {}
std::optional<Constant<T>> GetNamedConstant(const Symbol &);
std::optional<Constant<T>> ApplySubscripts(const Constant<T> &array,
@@ -85,7 +86,7 @@ template <typename T> class Folder {
Expr<T> TRANSFER(FunctionRef<T> &&);
private:
- int kind_;
+ KindsEnum kind_;
FoldingContext &context_;
bool forOptionalArgument_{false};
};
@@ -95,8 +96,8 @@ std::optional<Constant<SubscriptInteger>> GetConstantSubscript(
template <typename TR, typename... TA, std::size_t... I>
static std::optional<std::function<Scalar<TR>(FoldingContext &, Scalar<TA>...)>>
-GetHostRuntimeWrapperHelper(int resultKind,
- std::array<int, sizeof...(TA)> argKinds, const std::string &name,
+GetHostRuntimeWrapperHelper(KindsEnum resultKind,
+ std::array<KindsEnum, sizeof...(TA)> argKinds, const std::string &name,
std::index_sequence<I...>) {
std::vector<DynamicType> argTypes{DynamicType{TA::category, argKinds[I]}...};
if (auto hostWrapper{GetHostRuntimeWrapper(
@@ -116,8 +117,8 @@ GetHostRuntimeWrapperHelper(int resultKind,
// Helper to use host runtime on scalars for folding.
template <typename TR, typename... TA>
static std::optional<std::function<Scalar<TR>(FoldingContext &, Scalar<TA>...)>>
-GetHostRuntimeWrapper(int resultKind, std::array<int, sizeof...(TA)> argKinds,
- const std::string &name) {
+GetHostRuntimeWrapper(KindsEnum resultKind,
+ std::array<KindsEnum, sizeof...(TA)> argKinds, const std::string &name) {
return GetHostRuntimeWrapperHelper<TR, TA...>(
resultKind, argKinds, name, std::index_sequence_for<TA...>{});
}
@@ -154,8 +155,7 @@ template <typename T>
Expr<T> FoldOperation(FoldingContext &, FunctionRef<T> &&);
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, Designator<T> &&designator) {
- const int kind{designator.kind()};
- return Folder<T>{kind, context}.Folding(std::move(designator));
+ return Folder<T>{designator.kind(), context}.Folding(std::move(designator));
}
Expr<TypeParamInquiry::Result> FoldOperation(
FoldingContext &, TypeParamInquiry &&);
@@ -226,7 +226,7 @@ std::optional<Constant<T>> Folder<T>::Folding(DataRef &ref) {
template <typename T>
std::optional<Constant<T>> Folder<T>::ApplySubscripts(const Constant<T> &array,
const std::vector<Constant<SubscriptInteger>> &subscripts) {
- const int kind{array.kind()};
+ const KindsEnum kind{array.kind()};
const auto &shape{array.shape()};
const auto &lbounds{array.lbounds()};
int rank{GetRank(shape)};
@@ -279,7 +279,7 @@ std::optional<Constant<T>> Folder<T>::ApplySubscripts(const Constant<T> &array,
return Constant<T>{
kind, array.LEN(), std::move(values), std::move(resultShape)};
} else if constexpr (std::is_same_v<T, SomeDerived>) {
- CHECK(kind == 0);
+ CHECK(kind == NoKind);
return Constant<T>{array.result().derivedTypeSpec(), std::move(values),
std::move(resultShape)};
} else {
@@ -375,7 +375,7 @@ std::optional<Constant<T>> Folder<T>::GetConstantComponent(Component &component,
}
template <typename T> Expr<T> Folder<T>::Folding(Designator<T> &&designator) {
- const int kind{designator.kind()};
+ const KindsEnum kind{designator.kind()};
if constexpr (T::category == TypeCategory::Character) {
if (auto *substring{common::Unwrap<Substring>(designator.u)}) {
if (std::optional<Expr<SomeCharacter>> folded{
@@ -461,7 +461,7 @@ Constant<T> *Folder<T>::Folding(std::optional<ActualArgument> &arg) {
template <typename... A, std::size_t... I>
std::optional<std::tuple<const Constant<A> *...>> GetConstantArgumentsHelper(
- const std::array<int, sizeof...(A)> &kinds, FoldingContext &context,
+ const std::array<KindsEnum, sizeof...(A)> &kinds, FoldingContext &context,
ActualArguments &arguments, bool hasOptionalArgument,
std::index_sequence<I...>) {
static_assert(sizeof...(A) > 0);
@@ -477,7 +477,7 @@ std::optional<std::tuple<const Constant<A> *...>> GetConstantArgumentsHelper(
template <typename... A>
std::optional<std::tuple<const Constant<A> *...>> GetConstantArguments(
- const std::array<int, sizeof...(A)> &kinds, FoldingContext &context,
+ const std::array<KindsEnum, sizeof...(A)> &kinds, FoldingContext &context,
ActualArguments &args, bool hasOptionalArgument) {
return GetConstantArgumentsHelper<A...>(kinds, context, args,
hasOptionalArgument, std::index_sequence_for<A...>{});
@@ -485,7 +485,7 @@ std::optional<std::tuple<const Constant<A> *...>> GetConstantArguments(
template <typename... A, std::size_t... I>
std::optional<std::tuple<Scalar<A>...>> GetScalarConstantArgumentsHelper(
- const std::array<int, sizeof...(A)> &kinds, FoldingContext &context,
+ const std::array<KindsEnum, sizeof...(A)> &kinds, FoldingContext &context,
ActualArguments &args, bool hasOptionalArgument,
std::index_sequence<I...>) {
if (auto constArgs{GetConstantArguments<A...>(
@@ -499,7 +499,7 @@ std::optional<std::tuple<Scalar<A>...>> GetScalarConstantArgumentsHelper(
template <typename... A>
std::optional<std::tuple<Scalar<A>...>> GetScalarConstantArguments(
- const std::array<int, sizeof...(A)> &kinds, FoldingContext &context,
+ const std::array<KindsEnum, sizeof...(A)> &kinds, FoldingContext &context,
ActualArguments &args, bool hasOptionalArgument) {
return GetScalarConstantArgumentsHelper<A...>(kinds, context, args,
hasOptionalArgument, std::index_sequence_for<A...>{});
@@ -517,12 +517,13 @@ using ScalarFuncWithContext =
template <template <typename, typename...> typename WrapperType, typename TR,
typename... TA, std::size_t... I>
-Expr<TR> FoldElementalIntrinsicHelper(int resultKind,
- const std::array<int, sizeof...(TA)> &argKinds, FoldingContext &context,
- FunctionRef<TR> &&funcRef, WrapperType<TR, TA...> func,
- bool hasOptionalArgument, std::index_sequence<I...>) {
+Expr<TR> FoldElementalIntrinsicHelper(KindsEnum resultKind,
+ const std::array<KindsEnum, sizeof...(TA)> &argKinds,
+ FoldingContext &context, FunctionRef<TR> &&funcRef,
+ WrapperType<TR, TA...> func, bool hasOptionalArgument,
+ std::index_sequence<I...>) {
CHECK(funcRef.kind() == resultKind);
- std::array<int, sizeof...(TA)> kinds{argKinds[I]...};
+ std::array<KindsEnum, sizeof...(TA)> kinds{argKinds[I]...};
if (std::optional<std::tuple<const Constant<TA> *...>> args{
GetConstantArguments<TA...>(
kinds, context, funcRef.arguments(), hasOptionalArgument)}) {
@@ -596,19 +597,19 @@ Expr<TR> FoldElementalIntrinsicHelper(int resultKind,
}
template <typename TR, typename... TA>
-Expr<TR> FoldElementalIntrinsic(int resultKind,
- const std::array<int, sizeof...(TA)> &argKinds, FoldingContext &context,
- FunctionRef<TR> &&funcRef, ScalarFunc<TR, TA...> func,
- bool hasOptionalArgument = false) {
+Expr<TR> FoldElementalIntrinsic(KindsEnum resultKind,
+ const std::array<KindsEnum, sizeof...(TA)> &argKinds,
+ FoldingContext &context, FunctionRef<TR> &&funcRef,
+ ScalarFunc<TR, TA...> func, bool hasOptionalArgument = false) {
return FoldElementalIntrinsicHelper<ScalarFunc, TR, TA...>(resultKind,
argKinds, context, std::move(funcRef), func, hasOptionalArgument,
std::index_sequence_for<TA...>{});
}
template <typename TR, typename... TA>
-Expr<TR> FoldElementalIntrinsic(int resultKind,
- const std::array<int, sizeof...(TA)> &argKinds, FoldingContext &context,
- FunctionRef<TR> &&funcRef, ScalarFuncWithContext<TR, TA...> func,
- bool hasOptionalArgument = false) {
+Expr<TR> FoldElementalIntrinsic(KindsEnum resultKind,
+ const std::array<KindsEnum, sizeof...(TA)> &argKinds,
+ FoldingContext &context, FunctionRef<TR> &&funcRef,
+ ScalarFuncWithContext<TR, TA...> func, bool hasOptionalArgument = false) {
return FoldElementalIntrinsicHelper<ScalarFuncWithContext, TR, TA...>(
resultKind, argKinds, context, std::move(funcRef), func,
hasOptionalArgument, std::index_sequence_for<TA...>{});
@@ -645,7 +646,7 @@ std::optional<std::vector<A>> GetIntegerVector(const B &x) {
// This to prevent generating warnings over and over if the expression
// gets re-folded.
template <typename T> Expr<T> MakeInvalidIntrinsic(FunctionRef<T> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
SpecificIntrinsic invalid{std::get<SpecificIntrinsic>(funcRef.proc().u)};
invalid.name = IntrinsicProcTable::InvalidName;
return Expr<T>{FunctionRef<T>{kind, ProcedureDesignator{std::move(invalid)},
@@ -653,7 +654,7 @@ template <typename T> Expr<T> MakeInvalidIntrinsic(FunctionRef<T> &&funcRef) {
}
template <typename T> Expr<T> Folder<T>::CSHIFT(FunctionRef<T> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
auto args{funcRef.arguments()};
CHECK(args.size() == 3);
const auto *array{UnwrapConstantValue<T>(args[0])};
@@ -733,7 +734,7 @@ template <typename T> Expr<T> Folder<T>::CSHIFT(FunctionRef<T> &&funcRef) {
}
template <typename T> Expr<T> Folder<T>::EOSHIFT(FunctionRef<T> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
auto args{funcRef.arguments()};
CHECK(args.size() == 4);
const auto *array{UnwrapConstantValue<T>(args[0])};
@@ -867,7 +868,7 @@ template <typename T> Expr<T> Folder<T>::EOSHIFT(FunctionRef<T> &&funcRef) {
}
template <typename T> Expr<T> Folder<T>::MERGE(FunctionRef<T> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
return FoldElementalIntrinsic<T, T, T, LogicalResult>(kind,
{kind, kind, LogicalResultKind}, context_, std::move(funcRef),
ScalarFunc<T, T, T, LogicalResult>(
@@ -878,7 +879,7 @@ template <typename T> Expr<T> Folder<T>::MERGE(FunctionRef<T> &&funcRef) {
}
template <typename T> Expr<T> Folder<T>::PACK(FunctionRef<T> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
auto args{funcRef.arguments()};
CHECK(args.size() == 3);
const auto *array{UnwrapConstantValue<T>(args[0])};
@@ -1067,7 +1068,7 @@ template <typename T> Expr<T> Folder<T>::SPREAD(FunctionRef<T> &&funcRef) {
}
template <typename T> Expr<T> Folder<T>::TRANSPOSE(FunctionRef<T> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
auto args{funcRef.arguments()};
CHECK(args.size() == 1);
const auto *matrix{UnwrapConstantValue<T>(args[0])};
@@ -1091,7 +1092,7 @@ template <typename T> Expr<T> Folder<T>::TRANSPOSE(FunctionRef<T> &&funcRef) {
}
template <typename T> Expr<T> Folder<T>::UNPACK(FunctionRef<T> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
auto args{funcRef.arguments()};
CHECK(args.size() == 3);
const auto *vector{UnwrapConstantValue<T>(args[0])};
@@ -1157,7 +1158,7 @@ template <typename T> Expr<T> Folder<T>::TRANSFER(FunctionRef<T> &&funcRef) {
template <typename T>
Expr<T> FoldMINorMAX(
FoldingContext &context, FunctionRef<T> &&funcRef, Ordering order) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
static_assert(T::category == TypeCategory::Integer ||
T::category == TypeCategory::Unsigned ||
T::category == TypeCategory::Real ||
@@ -1273,7 +1274,7 @@ Expr<T> RewriteSpecificMINorMAX(
intrinsic.characteristics.value().functionResult.value().SetType(*resultType);
auto insertConversion{[&](const auto &x) -> Expr<T> {
using TR = ResultType<decltype(x)>;
- const int kind{x.kind()};
+ const KindsEnum kind{x.kind()};
FunctionRef<TR> maxRef{
kind, ProcedureDesignator{funcRef.proc()}, ActualArguments{args}};
return Fold(
@@ -1302,7 +1303,7 @@ Expr<Type<TypeCategory::Logical>> FoldIntrinsicFunction(
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, FunctionRef<T> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
ActualArguments &args{funcRef.arguments()};
const auto *intrinsic{std::get_if<SpecificIntrinsic>(&funcRef.proc().u)};
if (!intrinsic || intrinsic->name != "kind") {
@@ -1388,11 +1389,11 @@ Expr<T> FoldOperation(FoldingContext &context, FunctionRef<T> &&funcRef) {
// Array constructor folding
template <typename T> class ArrayConstructorFolder {
public:
- explicit ArrayConstructorFolder(int kind, FoldingContext &c)
+ explicit ArrayConstructorFolder(KindsEnum kind, FoldingContext &c)
: context_{c}, resultInfo_{kind} {}
Expr<T> FoldArray(ArrayConstructor<T> &&array) {
- const int kind{array.kind()};
+ const KindsEnum kind{array.kind()};
if constexpr (T::category == TypeCategory::Character) {
if (const auto *len{array.LEN()}) {
charLength_ = ToInt64(Fold(context_, common::Clone(*len)));
@@ -1403,7 +1404,7 @@ template <typename T> class ArrayConstructorFolder {
if (FoldArray(array)) {
auto n{static_cast<ConstantSubscript>(elements_.size())};
if constexpr (std::is_same_v<T, SomeDerived>) {
- CHECK(kind == 0);
+ CHECK(kind == NoKind);
return Expr<T>{Constant<T>{array.GetType().GetDerivedTypeSpec(),
std::move(elements_), ConstantSubscripts{n}}};
} else if constexpr (T::category == TypeCategory::Character) {
@@ -1412,7 +1413,7 @@ template <typename T> class ArrayConstructorFolder {
kind, *charLength_, std::move(elements_), ConstantSubscripts{n}}};
}
} else {
- // resultInfo_ is default-constructed (kind 0) and only ever has its
+ // resultInfo_ is default-constructed (NoKind) and only ever has its
// isFromInexactLiteralConversion flag set above; give it the actual
// runtime kind here so that the Constant's result_ carries a valid
// kind (kind_ is a public field of Type<CAT>, not a category with
@@ -1502,7 +1503,7 @@ template <typename T> class ArrayConstructorFolder {
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, ArrayConstructor<T> &&array) {
- const int kind{array.kind()};
+ const KindsEnum kind{array.kind()};
return ArrayConstructorFolder<T>{kind, context}.FoldArray(std::move(array));
}
@@ -1526,7 +1527,7 @@ bool ArrayConstructorIsFlat(const ArrayConstructorValues<T> &values) {
template <typename T>
std::optional<Expr<T>> AsFlatArrayConstructor(const Expr<T> &expr) {
- const int kind{expr.kind()};
+ const KindsEnum kind{static_cast<KindsEnum>(expr.kind())};
if (const auto *c{UnwrapConstantValue<T>(expr)}) {
ArrayConstructor<T> result{kind, expr};
if (!c->empty()) {
@@ -1600,8 +1601,9 @@ std::optional<Expr<T>> FromArrayConstructor(
// Unary case
template <typename RESULT, typename OPERAND>
-std::optional<Expr<RESULT>> MapOperation(int kind, FoldingContext &context,
- std::function<Expr<RESULT>(Expr<OPERAND> &&)> &&f, const Shape &shape,
+std::optional<Expr<RESULT>> MapOperation(KindsEnum kind,
+ FoldingContext &context, std::function<Expr<RESULT>(Expr<OPERAND> &&)> &&f,
+ const Shape &shape,
[[maybe_unused]] std::optional<Expr<SubscriptInteger>> &&length,
Expr<OPERAND> &&values) {
ArrayConstructor<RESULT> result{kind, values};
@@ -1632,8 +1634,8 @@ std::optional<Expr<RESULT>> MapOperation(int kind, FoldingContext &context,
}
template <typename RESULT, typename A>
-ArrayConstructor<RESULT> ArrayConstructorFromMold(int kind, const A &prototype,
- std::optional<Expr<SubscriptInteger>> &&length) {
+ArrayConstructor<RESULT> ArrayConstructorFromMold(KindsEnum kind,
+ const A &prototype, std::optional<Expr<SubscriptInteger>> &&length) {
ArrayConstructor<RESULT> result{kind, prototype};
if constexpr (RESULT::category == TypeCategory::Character) {
if (length) {
@@ -1667,7 +1669,7 @@ bool ShapesMatch(FoldingContext &context,
// array * array case
template <typename RESULT, typename LEFT, typename RIGHT>
-auto MapOperation(int kind, FoldingContext &context,
+auto MapOperation(KindsEnum kind, FoldingContext &context,
std::function<Expr<RESULT>(Expr<LEFT> &&, Expr<RIGHT> &&)> &&f,
const Shape &shape, std::optional<Expr<SubscriptInteger>> &&length,
Expr<LEFT> &&leftValues, Expr<RIGHT> &&rightValues)
@@ -1719,7 +1721,7 @@ auto MapOperation(int kind, FoldingContext &context,
// array * scalar case
template <typename RESULT, typename LEFT, typename RIGHT>
-auto MapOperation(int kind, FoldingContext &context,
+auto MapOperation(KindsEnum kind, FoldingContext &context,
std::function<Expr<RESULT>(Expr<LEFT> &&, Expr<RIGHT> &&)> &&f,
const Shape &shape, std::optional<Expr<SubscriptInteger>> &&length,
Expr<LEFT> &&leftValues, const Expr<RIGHT> &rightScalar)
@@ -1737,7 +1739,7 @@ auto MapOperation(int kind, FoldingContext &context,
// scalar * array case
template <typename RESULT, typename LEFT, typename RIGHT>
-auto MapOperation(int kind, FoldingContext &context,
+auto MapOperation(KindsEnum kind, FoldingContext &context,
std::function<Expr<RESULT>(Expr<LEFT> &&, Expr<RIGHT> &&)> &&f,
const Shape &shape, std::optional<Expr<SubscriptInteger>> &&length,
const Expr<LEFT> &leftScalar, Expr<RIGHT> &&rightValues)
@@ -1786,7 +1788,7 @@ auto ApplyElementwise(FoldingContext &context,
Operation<DERIVED, RESULT, OPERAND> &operation,
std::function<Expr<RESULT>(Expr<OPERAND> &&)> &&f)
-> std::optional<Expr<RESULT>> {
- const int kind{operation.kind()};
+ const KindsEnum kind{operation.kind()};
auto &expr{operation.left()};
expr = Fold(context, std::move(expr));
if (expr.Rank() > 0) {
@@ -1804,7 +1806,7 @@ template <typename DERIVED, typename RESULT, typename OPERAND>
auto ApplyElementwise(
FoldingContext &context, Operation<DERIVED, RESULT, OPERAND> &operation)
-> std::optional<Expr<RESULT>> {
- const int kind{operation.kind()};
+ const KindsEnum kind{operation.kind()};
return ApplyElementwise(context, operation,
std::function<Expr<RESULT>(Expr<OPERAND> &&)>{
[kind](Expr<OPERAND> &&operand) {
@@ -1817,7 +1819,7 @@ auto ApplyElementwise(FoldingContext &context,
Operation<DERIVED, RESULT, LEFT, RIGHT> &operation,
std::function<Expr<RESULT>(Expr<LEFT> &&, Expr<RIGHT> &&)> &&f)
-> std::optional<Expr<RESULT>> {
- const int kind{operation.kind()};
+ const KindsEnum kind{operation.kind()};
auto resultLength{ComputeResultLength(operation)};
auto &leftExpr{operation.left()};
auto &rightExpr{operation.right()};
@@ -1869,7 +1871,7 @@ template <typename DERIVED, typename RESULT, typename LEFT, typename RIGHT>
auto ApplyElementwise(
FoldingContext &context, Operation<DERIVED, RESULT, LEFT, RIGHT> &operation)
-> std::optional<Expr<RESULT>> {
- const int kind{operation.kind()};
+ const KindsEnum kind{operation.kind()};
return ApplyElementwise(context, operation,
std::function<Expr<RESULT>(Expr<LEFT> &&, Expr<RIGHT> &&)>{
[kind](Expr<LEFT> &&left, Expr<RIGHT> &&right) {
@@ -1882,9 +1884,8 @@ auto ApplyElementwise(
template <typename TO, typename FROM>
common::IfNoLvalue<std::optional<TO>, FROM> ConvertString(
- int toKind, FROM &&s) {
- const int fromKind{s.kind()};
- if (std::is_same_v<TO, FROM> && toKind == fromKind) {
+ KindsEnum toKind, FROM &&s) {
+ if (std::is_same_v<TO, FROM> && toKind == s.kind()) {
return std::make_optional<TO>(std::move(s));
} else if (auto result{s.ToAscii(toKind)}; !result.IsMonostate()) {
return result;
@@ -1896,19 +1897,19 @@ common::IfNoLvalue<std::optional<TO>, FROM> ConvertString(
template <typename TO, TypeCategory FROMCAT>
Expr<TO> FoldOperation(
FoldingContext &context, Convert<TO, FROMCAT> &&convert) {
- const int toKind{convert.kind()};
+ const KindsEnum toKind{convert.kind()};
if (auto array{ApplyElementwise(context, convert)}) {
return *array;
}
struct {
FoldingContext &context;
Convert<TO, FROMCAT> &convert;
- int toKind;
+ KindsEnum toKind;
} msvcWorkaround{context, convert, toKind};
return common::visit(
[&msvcWorkaround](auto &kindExpr) -> Expr<TO> {
using Operand = ResultType<decltype(kindExpr)>;
- const int toKind{msvcWorkaround.toKind};
+ const KindsEnum toKind{msvcWorkaround.toKind};
// This variable is a workaround for msvc which emits an error when
// using the FROMCAT template parameter below.
TypeCategory constexpr FromCat{FROMCAT};
@@ -1916,7 +1917,7 @@ Expr<TO> FoldOperation(
auto &convert{msvcWorkaround.convert};
if (auto value{GetScalarConstantValue<Operand>(kindExpr)}) {
FoldingContext &ctx{msvcWorkaround.context};
- const int fromKind{value->kind()};
+ const KindsEnum fromKind{value->kind()};
if constexpr (TO::category == TypeCategory::Integer) {
if constexpr (FromCat == TypeCategory::Integer) {
auto converted{
@@ -1924,8 +1925,8 @@ Expr<TO> FoldOperation(
if (converted.overflow) {
ctx.Warn(common::UsageWarning::FoldingException,
"conversion of %s_%d to INTEGER(%d) overflowed; result is %s"_warn_en_US,
- value->SignedDecimal(), fromKind, toKind,
- converted.value.SignedDecimal());
+ value->SignedDecimal(), static_cast<int>(fromKind),
+ static_cast<int>(toKind), converted.value.SignedDecimal());
}
return MakeConstantExpr<TO>(toKind, std::move(converted.value));
} else if constexpr (FromCat == TypeCategory::Unsigned) {
@@ -1934,8 +1935,8 @@ Expr<TO> FoldOperation(
if ((converted.overflow || converted.value.IsNegative())) {
ctx.Warn(common::UsageWarning::FoldingException,
"conversion of %s_U%d to INTEGER(%d) overflowed; result is %s"_warn_en_US,
- value->UnsignedDecimal(), fromKind, toKind,
- converted.value.SignedDecimal());
+ value->UnsignedDecimal(), static_cast<int>(fromKind),
+ static_cast<int>(toKind), converted.value.SignedDecimal());
}
return MakeConstantExpr<TO>(toKind, std::move(converted.value));
} else if constexpr (FromCat == TypeCategory::Real) {
@@ -1944,11 +1945,11 @@ Expr<TO> FoldOperation(
if (converted.flags.test(RealFlag::InvalidArgument)) {
ctx.Warn(common::UsageWarning::FoldingException,
"REAL(%d) to INTEGER(%d) conversion: invalid argument"_warn_en_US,
- fromKind, toKind);
+ static_cast<int>(fromKind), static_cast<int>(toKind));
} else if (converted.flags.test(RealFlag::Overflow)) {
ctx.Warn(common::UsageWarning::FoldingException,
"REAL(%d) to INTEGER(%d) conversion overflowed"_warn_en_US,
- fromKind, toKind);
+ static_cast<int>(fromKind), static_cast<int>(toKind));
}
return MakeConstantExpr<TO>(toKind, std::move(converted.value));
}
@@ -1973,7 +1974,8 @@ Expr<TO> FoldOperation(
if (!converted.flags.empty()) {
char buffer[64];
std::snprintf(buffer, sizeof buffer,
- "INTEGER(%d) to REAL(%d) conversion", fromKind, toKind);
+ "INTEGER(%d) to REAL(%d) conversion",
+ static_cast<int>(fromKind), static_cast<int>(toKind));
ctx.RealFlagWarnings(converted.flags, buffer);
}
return MakeConstantExpr<TO>(toKind, std::move(converted.value));
@@ -1982,7 +1984,8 @@ Expr<TO> FoldOperation(
char buffer[64];
if (!converted.flags.empty()) {
std::snprintf(buffer, sizeof buffer,
- "REAL(%d) to REAL(%d) conversion", fromKind, toKind);
+ "REAL(%d) to REAL(%d) conversion",
+ static_cast<int>(fromKind), static_cast<int>(toKind));
ctx.RealFlagWarnings(converted.flags, buffer);
}
if (ctx.targetCharacteristics().areSubnormalsFlushedToZero()) {
@@ -2035,9 +2038,11 @@ Expr<TO> FoldOperation(
// match the outer target for the round trip to be a no-op.
auto intermediateTy{kindExpr.GetType()};
auto xTy{x->GetType()};
- int intermediateKind{
- intermediateTy ? intermediateTy->kind() : 0};
- int xKind{xTy ? xTy->kind() : 0};
+ KindsEnum intermediateKind{intermediateTy
+ ? static_cast<KindsEnum>(intermediateTy->kind())
+ : NoKind};
+ KindsEnum xKind{
+ xTy ? static_cast<KindsEnum>(xTy->kind()) : NoKind};
if constexpr (TO::category == TypeCategory::Logical) {
return std::move(*x); // no-op Logical conversion pair
} else { // Integer
@@ -2063,7 +2068,7 @@ Expr<TO> FoldOperation(
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, Parentheses<T> &&x) {
- const int kind{x.kind()};
+ const KindsEnum kind{x.kind()};
auto &operand{x.left()};
operand = Fold(context, std::move(operand));
if (auto value{GetScalarConstantValue<T>(operand)}) {
@@ -2079,7 +2084,7 @@ Expr<T> FoldOperation(FoldingContext &context, Parentheses<T> &&x) {
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, Negate<T> &&x) {
- const int kind{x.kind()};
+ const auto kind{static_cast<KindsEnum>(x.kind())};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
@@ -2130,7 +2135,7 @@ std::optional<std::pair<Scalar<LEFT>, Scalar<RIGHT>>> OperandsAreConstants(
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, Add<T> &&x) {
- const int kind{x.kind()};
+ const auto kind{static_cast<KindsEnum>(x.kind())};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
@@ -2179,7 +2184,7 @@ Expr<T> FoldOperation(FoldingContext &context, Add<T> &&x) {
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, Subtract<T> &&x) {
- const int kind{x.kind()};
+ const auto kind{static_cast<KindsEnum>(x.kind())};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
@@ -2221,7 +2226,7 @@ Expr<T> FoldOperation(FoldingContext &context, Subtract<T> &&x) {
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, Multiply<T> &&x) {
- const int kind{x.kind()};
+ const auto kind{static_cast<KindsEnum>(x.kind())};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
@@ -2272,7 +2277,7 @@ Expr<T> FoldOperation(FoldingContext &context, Multiply<T> &&x) {
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, Divide<T> &&x) {
- const int kind{x.kind()};
+ const auto kind{static_cast<KindsEnum>(x.kind())};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
@@ -2309,8 +2314,8 @@ Expr<T> FoldOperation(FoldingContext &context, Divide<T> &&x) {
using IntType = typename T::Scalar::Word;
auto intNumerator{folded->first.ToInteger()};
isCanonicalNaNOrInf = intNumerator.flags == RealFlags{} &&
- intNumerator.value >= IntType{16, -1} &&
- intNumerator.value <= IntType{16, 1};
+ intNumerator.value >= IntType{Kind16, -1} &&
+ intNumerator.value <= IntType{Kind16, 1};
}
}
if (!isCanonicalNaNOrInf) {
@@ -2327,7 +2332,7 @@ Expr<T> FoldOperation(FoldingContext &context, Divide<T> &&x) {
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, Power<T> &&x) {
- const int kind{x.kind()};
+ const KindsEnum kind{x.kind()};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
@@ -2352,8 +2357,8 @@ Expr<T> FoldOperation(FoldingContext &context, Power<T> &&x) {
context.Warn(common::UsageWarning::FoldingException,
"REAL/COMPLEX 0**0 is not defined"_warn_en_US);
} else {
- return Expr<T>(
- Constant<T>{kind, folded->first}); // 0. ** nonzero -> 0.
+ return Expr<T>{
+ Constant<T>{kind, folded->first}}; // 0. ** nonzero -> 0.
}
} else if (auto callable{GetHostRuntimeWrapper<T, T, T>(
kind, {kind, kind}, "pow")}) {
@@ -2371,7 +2376,7 @@ Expr<T> FoldOperation(FoldingContext &context, Power<T> &&x) {
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, RealToIntPower<T> &&x) {
- const int kind{x.kind()};
+ const auto kind{static_cast<KindsEnum>(x.kind())};
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
@@ -2404,7 +2409,7 @@ Expr<T> FoldOperation(FoldingContext &context, ConditionalExpr<T> &&x) {
template <typename T>
Expr<T> FoldOperation(FoldingContext &context, Extremum<T> &&x) {
- const int kind{x.kind()};
+ const auto kind{static_cast<KindsEnum>(x.kind())};
if (auto array{ApplyElementwise(context, x,
std::function<Expr<T>(Expr<T> &&, Expr<T> &&)>{[=](Expr<T> &&l,
Expr<T> &&r) {
@@ -2445,7 +2450,7 @@ Expr<T> FoldOperation(FoldingContext &context, Extremum<T> &&x) {
}
inline Expr<Type<TypeCategory::Real>> ToReal(
- int kind, FoldingContext &context, Expr<SomeType> &&expr) {
+ KindsEnum kind, FoldingContext &context, Expr<SomeType> &&expr) {
using Result = Type<TypeCategory::Real>;
std::optional<Expr<Result>> result;
common::visit(
@@ -2477,7 +2482,7 @@ inline Expr<Type<TypeCategory::Real>> ToReal(
// REAL(z) and AIMAG(z)
inline Expr<Type<TypeCategory::Real>> FoldOperation(
FoldingContext &context, ComplexComponent &&x) {
- const int kind{x.kind()};
+ const auto kind{x.kind()};
using Operand = Type<TypeCategory::Complex>;
using Result = Type<TypeCategory::Real>;
if (auto array{ApplyElementwise(context, x,
diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index 2545f4b4210b5..6b079260cb82c 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -18,7 +18,7 @@ namespace Fortran::evaluate {
// Return scalar value if asScalar == true and shape-dim array otherwise.
template <typename T>
Expr<T> PackageConstantBounds(
- int kind, const ConstantSubscripts &&bounds, bool asScalar = false) {
+ KindsEnum kind, const ConstantSubscripts &&bounds, bool asScalar = false) {
if (asScalar) {
return MakeConstantExpr<T>(kind, bounds.at(0));
} else {
@@ -101,7 +101,7 @@ class GetConstantArrayBoundHelper {
public:
template <typename T>
static Expr<T> GetLbound(
- int kind, const Expr<SomeType> &array, std::optional<int> dim) {
+ KindsEnum kind, const Expr<SomeType> &array, std::optional<int> dim) {
return PackageConstantBounds<T>(kind,
GetConstantArrayBoundHelper(dim, /*getLbound=*/true).Get(array),
dim.has_value());
@@ -109,7 +109,7 @@ class GetConstantArrayBoundHelper {
template <typename T>
static Expr<T> GetUbound(
- int kind, const Expr<SomeType> &array, std::optional<int> dim) {
+ KindsEnum kind, const Expr<SomeType> &array, std::optional<int> dim) {
return PackageConstantBounds<T>(kind,
GetConstantArrayBoundHelper(dim, /*getLbound=*/false).Get(array),
dim.has_value());
@@ -178,7 +178,7 @@ class GetConstantArrayBoundHelper {
Expr<Type<TypeCategory::Integer>> LBOUND(FoldingContext &context,
FunctionRef<Type<TypeCategory::Integer>> &&funcRef) {
using T = Type<TypeCategory::Integer>;
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
ActualArguments &args{funcRef.arguments()};
if (const auto *array{UnwrapExpr<Expr<SomeType>>(args[0])}) {
std::optional<int> dim;
@@ -229,7 +229,7 @@ Expr<Type<TypeCategory::Integer>> LBOUND(FoldingContext &context,
Expr<Type<TypeCategory::Integer>> UBOUND(FoldingContext &context,
FunctionRef<Type<TypeCategory::Integer>> &&funcRef) {
using T = Type<TypeCategory::Integer>;
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
ActualArguments &args{funcRef.arguments()};
if (auto *array{UnwrapExpr<Expr<SomeType>>(args[0])}) {
std::optional<int> dim;
@@ -294,7 +294,7 @@ Expr<Type<TypeCategory::Integer>> UBOUND(FoldingContext &context,
Expr<Type<TypeCategory::Integer>> COBOUND(FoldingContext &context,
FunctionRef<Type<TypeCategory::Integer>> &&funcRef, bool isUCOBOUND) {
using T = Type<TypeCategory::Integer>;
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
ActualArguments &args{funcRef.arguments()};
if (const Symbol * coarray{UnwrapWholeSymbolOrComponentDataRef(args[0])}) {
std::optional<int> dim;
@@ -327,9 +327,9 @@ template <typename T> class CountAccumulator {
using MaskT = Type<TypeCategory::Logical>;
public:
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
- CountAccumulator(int kind, const Constant<MaskT> &mask)
+ CountAccumulator(KindsEnum kind, const Constant<MaskT> &mask)
: kind_{kind}, mask_{mask} {}
void operator()(
Scalar<T> &element, const ConstantSubscripts &at, bool /*first*/) {
@@ -344,7 +344,7 @@ template <typename T> class CountAccumulator {
void Done(Scalar<T> &) const {}
private:
- int kind_;
+ KindsEnum kind_;
const Constant<MaskT> &mask_;
bool overflow_{false};
};
@@ -353,7 +353,7 @@ template <typename T>
static Expr<T> FoldCount(FoldingContext &context, FunctionRef<T> &&ref) {
using KindLogical = Type<TypeCategory::Logical>;
static_assert(T::category == TypeCategory::Integer);
- const int kind{ref.kind()};
+ const auto kind{ref.kind()};
std::optional<int> dim;
if (std::optional<ArrayAndMask<KindLogical>> arrayAndMask{
ProcessReductionArgs<KindLogical>(LogicalResultKind, context,
@@ -381,7 +381,7 @@ template <WhichLocation WHICH> class LocationHelper {
using Types = std::conditional_t<WHICH == WhichLocation::Findloc,
AllIntrinsicTypes, RelationalTypes>;
- template <typename T> Result Test(int kind) const {
+ template <typename T> Result Test(KindsEnum kind) const {
if (T::category != type_.category() || kind != type_.kind()) {
return std::nullopt;
}
@@ -408,8 +408,8 @@ template <WhichLocation WHICH> class LocationHelper {
}
bool back{false};
if (arg_[backArg]) {
- const auto *backConst{Folder<LogicalResult>{
- LogicalResultKind, context_, /*forOptionalArgument=*/true}
+ const auto *backConst{Folder<LogicalResult>{LogicalResultKind, context_,
+ /*forOptionalArgument=*/true}
.Folding(arg_[backArg])};
if (backConst) {
back = backConst->GetScalarValue().value().IsTrue();
@@ -510,7 +510,7 @@ template <WhichLocation WHICH> class LocationHelper {
std::optional<Constant<T>> &value,
[[maybe_unused]] RelationalOperator relation,
[[maybe_unused]] bool back) const {
- const int kind{element.kind()};
+ const KindsEnum kind{element.kind()};
std::optional<Expr<LogicalResult>> cmp;
bool result{true};
if (value) {
@@ -584,7 +584,7 @@ static std::optional<Constant<SubscriptInteger>> FoldLocationCall(
template <WhichLocation which, typename T>
static Expr<T> FoldLocation(FoldingContext &context, FunctionRef<T> &&ref) {
static_assert(T::category == TypeCategory::Integer);
- const int kind{ref.kind()};
+ const KindsEnum kind{ref.kind()};
if (std::optional<Constant<SubscriptInteger>> found{
FoldLocationCall<which>(ref.arguments(), context)}) {
return Expr<T>{Fold(context,
@@ -599,7 +599,7 @@ template <typename T>
static Expr<T> FoldBitReduction(FoldingContext &context, FunctionRef<T> &&ref,
Scalar<T> (Scalar<T>::*operation)(const Scalar<T> &) const,
Scalar<T> identity) {
- const int kind{ref.kind()};
+ const auto kind{ref.kind()};
static_assert(T::category == TypeCategory::Integer ||
T::category == TypeCategory::Unsigned);
std::optional<int> dim;
@@ -617,7 +617,7 @@ static Expr<T> FoldBitReduction(FoldingContext &context, FunctionRef<T> &&ref,
template <typename T>
std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
FoldingContext &context, FunctionRef<T> &funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
ActualArguments &args{funcRef.arguments()};
auto *intrinsic{std::get_if<SpecificIntrinsic>(&funcRef.proc().u)};
CHECK(intrinsic);
@@ -665,9 +665,8 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
// than BIT_SIZE. It can be converted to Int4 to simplify.
if (const auto *argCon{Folder<T>(kind, context).Folding(args[0])};
argCon && argCon->empty()) {
- } else if (const auto *shiftCon{Folder<Int4>(
- /*kind=*/4, context)
- .Folding(args[2])}) {
+ } else if (const auto *shiftCon{
+ Folder<Int4>(Kind4, context).Folding(args[2])}) {
for (const auto &scalar : shiftCon->values()) {
std::int64_t shiftVal{scalar.ToInt64()};
if (shiftVal < 0) {
@@ -682,8 +681,8 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
}
}
}
- return FoldElementalIntrinsic<T, T, T, Int4>(kind, {kind, kind, 4}, context,
- std::move(funcRef),
+ return FoldElementalIntrinsic<T, T, T, Int4>(kind, {kind, kind, Kind4},
+ context, std::move(funcRef),
ScalarFunc<T, T, T, Int4>(
[&fptr](const Scalar<T> &i, const Scalar<T> &j,
const Scalar<Int4> &shift) -> Scalar<T> {
@@ -719,7 +718,8 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
}
if (const auto *argCon{Folder<T>(kind, context).Folding(args[0])};
argCon && argCon->empty()) {
- } else if (const auto *posCon{Folder<Int4>(4, context).Folding(args[1])}) {
+ } else if (const auto *posCon{
+ Folder<Int4>(Kind4, context).Folding(args[1])}) {
for (const auto &scalar : posCon->values()) {
std::int64_t posVal{scalar.ToInt64()};
if (posVal < 0) {
@@ -735,15 +735,15 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
}
}
}
- return FoldElementalIntrinsic<T, T, Int4>(kind, {kind, 4}, context,
+ return FoldElementalIntrinsic<T, T, Int4>(kind, {kind, Kind4}, context,
std::move(funcRef),
ScalarFunc<T, T, Int4>(
[&](const Scalar<T> &i, const Scalar<Int4> &pos) -> Scalar<T> {
return std::invoke(fptr, i, static_cast<int>(pos.ToInt64()));
}));
} else if (name == "ibits") {
- const auto *posCon{Folder<Int4>(4, context).Folding(args[1])};
- const auto *lenCon{Folder<Int4>(4, context).Folding(args[2])};
+ const auto *posCon{Folder<Int4>(Kind4, context).Folding(args[1])};
+ const auto *lenCon{Folder<Int4>(Kind4, context).Folding(args[2])};
if (const auto *argCon{Folder<T>(kind, context).Folding(args[0])};
argCon && argCon->empty()) {
} else {
@@ -775,8 +775,8 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
}
}
}
- return FoldElementalIntrinsic<T, T, Int4, Int4>(kind, {kind, 4, 4}, context,
- std::move(funcRef),
+ return FoldElementalIntrinsic<T, T, Int4, Int4>(kind, {kind, Kind4, Kind4},
+ context, std::move(funcRef),
ScalarFunc<T, T, Int4, Int4>(
[&](const Scalar<T> &i, const Scalar<Int4> &pos,
const Scalar<Int4> &len) -> Scalar<T> {
@@ -818,12 +818,12 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
context, std::move(funcRef), &Scalar<T>::IEOR, Scalar<T>{kind, 0});
} else if (name == "ishft" || name == "ishftc") {
const auto *argCon{Folder<T>(kind, context).Folding(args[0])};
- const auto *shiftCon{Folder<Int4>(4, context).Folding(args[1])};
+ const auto *shiftCon{Folder<Int4>(Kind4, context).Folding(args[1])};
const auto *shiftVals{shiftCon ? &shiftCon->values() : nullptr};
- const auto *sizeCon{args.size() == 3
- ? Folder<Int4>{4, context, /*forOptionalArgument=*/true}.Folding(
- args[2])
- : nullptr};
+ const auto *sizeCon{args.size() == 3 ? Folder<Int4>{Kind4, context,
+ /*forOptionalArgument=*/true}
+ .Folding(args[2])
+ : nullptr};
const auto *sizeVals{sizeCon ? &sizeCon->values() : nullptr};
if ((argCon && argCon->empty()) || !shiftVals || shiftVals->empty() ||
(sizeVals && sizeVals->empty())) {
@@ -877,22 +877,22 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
}
}
if (name == "ishft") {
- return FoldElementalIntrinsic<T, T, Int4>(kind, {kind, 4}, context,
+ return FoldElementalIntrinsic<T, T, Int4>(kind, {kind, Kind4}, context,
std::move(funcRef),
ScalarFunc<T, T, Int4>(
[&](const Scalar<T> &i, const Scalar<Int4> &shift) -> Scalar<T> {
return i.ISHFT(static_cast<int>(shift.ToInt64()));
}));
} else if (!args.at(2)) { // ISHFTC(no SIZE=)
- return FoldElementalIntrinsic<T, T, Int4>(kind, {kind, 4}, context,
+ return FoldElementalIntrinsic<T, T, Int4>(kind, {kind, Kind4}, context,
std::move(funcRef),
ScalarFunc<T, T, Int4>(
[&](const Scalar<T> &i, const Scalar<Int4> &shift) -> Scalar<T> {
return i.ISHFTC(static_cast<int>(shift.ToInt64()));
}));
} else { // ISHFTC(with SIZE=)
- return FoldElementalIntrinsic<T, T, Int4, Int4>(kind, {kind, 4, 4},
- context, std::move(funcRef),
+ return FoldElementalIntrinsic<T, T, Int4, Int4>(kind,
+ {kind, Kind4, Kind4}, context, std::move(funcRef),
ScalarFunc<T, T, Int4, Int4>(
[&](const Scalar<T> &i, const Scalar<Int4> &shift,
const Scalar<Int4> &size) -> Scalar<T> {
@@ -920,7 +920,7 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
// It can be safely converted to Int4 to simplify.
const auto fptr{name == "maskl" || name == "umaskl" ? &Scalar<T>::MASKL
: &Scalar<T>::MASKR};
- return FoldElementalIntrinsic<T, Int4>(kind, {4}, context,
+ return FoldElementalIntrinsic<T, Int4>(kind, {Kind4}, context,
std::move(funcRef),
ScalarFunc<T, Int4>(
[&fptr, kind](const Scalar<Int4> &places) -> Scalar<T> {
@@ -967,7 +967,7 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
if (const auto *argCon{Folder<T>(kind, context).Folding(args[0])};
argCon && argCon->empty()) {
} else if (const auto *shiftCon{
- Folder<Int4>(4, context).Folding(args[1])}) {
+ Folder<Int4>(Kind4, context).Folding(args[1])}) {
for (const auto &scalar : shiftCon->values()) {
std::int64_t shiftVal{scalar.ToInt64()};
if (shiftVal < 0) {
@@ -982,7 +982,7 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
}
}
}
- return FoldElementalIntrinsic<T, T, Int4>(kind, {kind, 4}, context,
+ return FoldElementalIntrinsic<T, T, Int4>(kind, {kind, Kind4}, context,
std::move(funcRef),
ScalarFunc<T, T, Int4>(
[&](const Scalar<T> &i, const Scalar<Int4> &shift) -> Scalar<T> {
@@ -997,7 +997,7 @@ std::optional<Expr<T>> FoldIntrinsicFunctionCommon(
Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
FunctionRef<Type<TypeCategory::Integer>> &&funcRef) {
using T = Type<TypeCategory::Integer>;
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
if (auto foldedCommon{FoldIntrinsicFunctionCommon(context, funcRef)}) {
return std::move(*foldedCommon);
}
@@ -1024,7 +1024,8 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
typename Scalar<T>::ValueWithOverflow j{i.ABS()};
if (j.overflow) {
context.Warn(common::UsageWarning::FoldingException,
- "abs(integer(kind=%d)) folding overflowed"_warn_en_US, kind);
+ "abs(integer(kind=%d)) folding overflowed"_warn_en_US,
+ static_cast<int>(kind));
}
return j.value;
}));
@@ -1068,8 +1069,9 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
return common::visit(
[&funcRef, &context, kind](const auto &x) -> Expr<T> {
using TR = typename std::decay_t<decltype(x)>::Result;
- return FoldElementalIntrinsic<T, TR>(kind, {x.kind()}, context,
- std::move(funcRef), &Scalar<TR>::EXPONENT);
+ return FoldElementalIntrinsic<T, TR>(kind,
+ {static_cast<KindsEnum>(x.kind())}, context, std::move(funcRef),
+ &Scalar<TR>::EXPONENT);
},
sx->u);
} else {
@@ -1097,8 +1099,9 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
return common::visit(
[&funcRef, &context, &FromInt64, kind](const auto &str) -> Expr<T> {
using Char = typename std::decay_t<decltype(str)>::Result;
- return FoldElementalIntrinsic<T, Char>(kind, {str.kind()},
- context, std::move(funcRef),
+ return FoldElementalIntrinsic<T, Char>(kind,
+ {static_cast<KindsEnum>(str.kind())}, context,
+ std::move(funcRef),
ScalarFunc<T, Char>(
#ifndef _MSC_VER
[&FromInt64](const Scalar<Char> &c) {
@@ -1127,7 +1130,7 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
return common::visit(
[&](const auto &kch) -> Expr<T> {
using TC = typename std::decay_t<decltype(kch)>::Result;
- const int kchKind{kch.kind()};
+ const KindsEnum kchKind{static_cast<KindsEnum>(kch.kind())};
if (UnwrapExpr<Expr<SomeLogical>>(args[2])) { // BACK=
return FoldElementalIntrinsic<T, TC, TC, LogicalResult>(kind,
{kchKind, kchKind, LogicalResultKind}, context,
@@ -1179,7 +1182,7 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
}
}
} else if (auto dyType{expr->GetType()}) {
- return MakeConstantExpr<T>(kind, dyType->kind());
+ return MakeConstantExpr<T>(kind, static_cast<int>(dyType->kind()));
}
}
} else if (name == "lbound") {
@@ -1192,8 +1195,9 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
return common::visit(
[&funcRef, &context, &name, kind](const auto &n) -> Expr<T> {
using TI = typename std::decay_t<decltype(n)>::Result;
+ const KindsEnum nKind{static_cast<KindsEnum>(n.kind())};
if (name == "poppar") {
- return FoldElementalIntrinsic<T, TI>(kind, {n.kind()}, context,
+ return FoldElementalIntrinsic<T, TI>(kind, {nKind}, context,
std::move(funcRef),
ScalarFunc<T, TI>([kind](const Scalar<TI> &i) -> Scalar<T> {
return Scalar<T>{kind, i.POPPAR() ? 1 : 0};
@@ -1209,7 +1213,7 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
common::die(
"missing case to fold intrinsic function %s", name.c_str());
}
- return FoldElementalIntrinsic<T, TI>(kind, {n.kind()}, context,
+ return FoldElementalIntrinsic<T, TI>(kind, {nKind}, context,
std::move(funcRef),
// `i` should be declared as `const Scalar<TI>&`.
// We declare it as `auto` to workaround an msvc bug:
@@ -1245,7 +1249,8 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
return common::visit(
[&](const auto &kch) -> Expr<T> {
using TC = typename std::decay_t<decltype(kch)>::Result;
- return FoldElementalIntrinsic<T, TC>(kind, {kch.kind()}, context,
+ return FoldElementalIntrinsic<T, TC>(kind,
+ {static_cast<KindsEnum>(kch.kind())}, context,
std::move(funcRef),
ScalarFunc<T, TC>{[&FromInt64](const Scalar<TC> &str) {
return FromInt64(CharacterUtils::LEN_TRIM(str));
@@ -1262,7 +1267,8 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
return common::visit(
[&](const auto &x) {
using TR = typename std::decay_t<decltype(x)>::Result;
- return MakeConstantExpr<T>(kind, Scalar<TR>::MAXEXPONENT(x.kind()));
+ return MakeConstantExpr<T>(kind,
+ Scalar<TR>::MAXEXPONENT(static_cast<KindsEnum>(x.kind())));
},
sx->u);
}
@@ -1275,7 +1281,8 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
return common::visit(
[&](const auto &x) {
using TR = typename std::decay_t<decltype(x)>::Result;
- return MakeConstantExpr<T>(kind, Scalar<TR>::MINEXPONENT(x.kind()));
+ return MakeConstantExpr<T>(kind,
+ Scalar<TR>::MINEXPONENT(static_cast<KindsEnum>(x.kind())));
},
sx->u);
}
@@ -1402,7 +1409,7 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
UnwrapExpr<Constant<Type<TypeCategory::Character>>>(args[0])}) {
if (std::optional<value::CharacterValue> charVal{
chCon->GetScalarValue()}) {
- int defaultKind{
+ KindsEnum defaultKind{
context.defaults().GetDefaultKind(TypeCategory::Character)};
return MakeConstantExpr<T>(
kind, SelectedCharKind(*charVal->AsStdString(), defaultKind));
@@ -1442,7 +1449,8 @@ Expr<Type<TypeCategory::Integer>> FoldIntrinsicFunction(FoldingContext &context,
typename Scalar<T>::ValueWithOverflow result{j.SIGN(k)};
if (result.overflow) {
context.Warn(common::UsageWarning::FoldingException,
- "sign(integer(kind=%d)) folding overflowed"_warn_en_US, kind);
+ "sign(integer(kind=%d)) folding overflowed"_warn_en_US,
+ static_cast<int>(kind));
}
return result.value;
}));
@@ -1518,7 +1526,7 @@ Expr<Type<TypeCategory::Unsigned>> FoldIntrinsicFunction(
FoldingContext &context,
FunctionRef<Type<TypeCategory::Unsigned>> &&funcRef) {
using T = Type<TypeCategory::Unsigned>;
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
if (auto foldedCommon{FoldIntrinsicFunctionCommon(context, funcRef)}) {
return std::move(*foldedCommon);
}
@@ -1628,7 +1636,7 @@ Expr<RankOneBoundElement::Result> FoldOperation(
ConstantSubscripts at{c->lbounds()};
at[0] = c->lbounds()[0] + x.dimension();
return MakeConstantExpr<ResultType>(
- RankOneBoundElement::ResultKind, c->At(at));
+ static_cast<KindsEnum>(RankOneBoundElement::ResultKind), c->At(at));
}
return Expr<ResultType>{
RankOneBoundElement{std::move(folded), x.dimension()}};
diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp
index f8fe642f38536..5e9a307b695a9 100644
--- a/flang/lib/Evaluate/fold-logical.cpp
+++ b/flang/lib/Evaluate/fold-logical.cpp
@@ -28,7 +28,7 @@ static std::optional<Expr<SomeType>> ZeroExtend(const Constant<T> &c) {
// for ALL, ANY & PARITY
template <typename T>
-static Expr<T> FoldAllAnyParity(int kind, FoldingContext &context,
+static Expr<T> FoldAllAnyParity(KindsEnum kind, FoldingContext &context,
FunctionRef<T> &&ref,
Scalar<T> (Scalar<T>::*operation)(const Scalar<T> &) const,
Scalar<T> identity) {
@@ -50,7 +50,7 @@ static Expr<T> FoldAllAnyParity(int kind, FoldingContext &context,
// TODO: unsigned
static Expr<SomeReal> RealToIntBound(
- int xRKind, int moldIKind, bool round, bool negate) {
+ KindsEnum xRKind, KindsEnum moldIKind, bool round, bool negate) {
using RealType = Scalar<Type<TypeCategory::Real>>;
using IntType = Scalar<Type<TypeCategory::Integer>>;
RealType result{RealType::Zero(xRKind)}; // 0.
@@ -96,9 +96,9 @@ class RealToIntLimitHelper {
RealToIntLimitHelper(
FoldingContext &context, Expr<SomeReal> &&hi, Expr<SomeReal> &lo)
: context_{context}, hi_{std::move(hi)}, lo_{lo} {}
- template <typename T> Result Test(int kind) {
+ template <typename T> Result Test(KindsEnum kind) {
if (UnwrapExpr<Expr<T>>(kind, hi_)) {
- bool promote{kind < 16};
+ bool promote{kind < Kind16};
Result constResult;
if (auto hiV{GetScalarConstantValue<T>(hi_)}) {
auto loV{GetScalarConstantValue<T>(lo_)};
@@ -110,7 +110,9 @@ class RealToIntLimitHelper {
constResult = AsCategoryExpr(Constant<T>{kind, std::move(diff.value)});
}
if (promote) {
- int nextKind{kind < 4 ? 4 : kind == 4 ? 8 : 16};
+ KindsEnum nextKind{kind < Kind4 ? Kind4
+ : kind == Kind4 ? Kind8
+ : Kind16};
using T2 = Type<TypeCategory::Real>;
hi_ = Expr<SomeReal>{
Fold(context_, ConvertToType<T2>(nextKind, std::move(hi_)))};
@@ -145,7 +147,7 @@ static std::optional<Expr<SomeReal>> RealToIntLimit(
// RealToRealBounds() returns a pair (HUGE(x),REAL(HUGE(mold),KIND(x)))
// when REAL(HUGE(x),KIND(mold)) overflows, and std::nullopt otherwise.
static std::optional<std::pair<Expr<SomeReal>, Expr<SomeReal>>>
-RealToRealBounds(int xRKind, int moldRKind) {
+RealToRealBounds(KindsEnum xRKind, KindsEnum moldRKind) {
using RType = Type<TypeCategory::Real>;
using RealType = Scalar<Type<TypeCategory::Real>>;
using MoldRealType = Scalar<Type<TypeCategory::Real>>;
@@ -161,7 +163,7 @@ RealToRealBounds(int xRKind, int moldRKind) {
}
static std::optional<Expr<SomeInteger>> IntToRealBoundHelper(
- int xIKind, int moldRKind, bool negate) {
+ KindsEnum xIKind, KindsEnum moldRKind, bool negate) {
using IType = Type<TypeCategory::Integer>;
using IntType = Scalar<Type<TypeCategory::Integer>>;
using RealType = Scalar<Type<TypeCategory::Real>>;
@@ -200,12 +202,12 @@ static std::optional<Expr<SomeInteger>> IntToRealBoundHelper(
}
static std::optional<Expr<SomeInteger>> IntToRealBound(
- int xIKind, int moldRKind, bool negate) {
+ KindsEnum xIKind, KindsEnum moldRKind, bool negate) {
return IntToRealBoundHelper(xIKind, moldRKind, negate);
}
static std::optional<Expr<SomeInteger>> IntToIntBoundHelper(
- int xIKind, int moldIKind) {
+ KindsEnum xIKind, KindsEnum moldIKind) {
if (xIKind <= moldIKind) {
return std::nullopt;
} else {
@@ -221,7 +223,7 @@ static std::optional<Expr<SomeInteger>> IntToIntBoundHelper(
}
static std::optional<Expr<SomeInteger>> IntToIntBound(
- int xIKind, int moldIKind) {
+ KindsEnum xIKind, KindsEnum moldIKind) {
return IntToIntBoundHelper(xIKind, moldIKind);
}
@@ -237,10 +239,10 @@ class IntrinsicCallHelper {
}
using Result = std::optional<Expr<SomeType>>;
using Types = LengthlessIntrinsicTypes;
- template <typename T> Result Test(int kind) {
+ template <typename T> Result Test(KindsEnum kind) {
if (T::category == typeAndShape_->type().category() &&
kind == typeAndShape_->type().kind()) {
- return AsGenericExpr(FunctionRef<T>{typeAndShape_->type().kind(),
+ return AsGenericExpr(FunctionRef<T>{kind,
ProcedureDesignator{std::move(call_.specificIntrinsic)},
std::move(call_.arguments)});
} else {
@@ -277,8 +279,8 @@ static Expr<LogicalResult> CompareUnsigned(FoldingContext &context,
static Expr<SomeType> IntTransferMold(
const TargetCharacteristics &target, DynamicType realType, bool asVector) {
CHECK(realType.category() == TypeCategory::Real);
- int rKind{realType.kind()};
- int iKind{std::max<int>(target.GetAlignment(TypeCategory::Real, rKind),
+ KindsEnum rKind{realType.kind()};
+ KindsEnum iKind{std::max<int>(target.GetAlignment(TypeCategory::Real, rKind),
target.GetByteSize(TypeCategory::Real, rKind))};
CHECK(target.CanSupportType(TypeCategory::Integer, iKind));
DynamicType iType{TypeCategory::Integer, iKind};
@@ -309,7 +311,7 @@ static Expr<Type<TypeCategory::Logical>> RewriteOutOfRange(
FoldingContext &context,
FunctionRef<Type<TypeCategory::Logical>> &&funcRef) {
using ResultType = Type<TypeCategory::Logical>;
- const int resultKind{funcRef.kind()};
+ const KindsEnum resultKind{funcRef.kind()};
ActualArguments &args{funcRef.arguments()};
// Fold x= and round= unconditionally
if (auto *x{UnwrapExpr<Expr<SomeType>>(args[0])}) {
@@ -328,10 +330,11 @@ static Expr<Type<TypeCategory::Logical>> RewriteOutOfRange(
std::optional<Expr<LogicalResult>> result;
bool alwaysFalse{false};
if (auto *iXExpr{UnwrapExpr<Expr<SomeInteger>>(*x)}) {
- int iXKind{iXExpr->GetType().value().kind()};
+ auto iXKind{static_cast<KindsEnum>(iXExpr->GetType().value().kind())};
if (auto *iMoldExpr{UnwrapExpr<Expr<SomeInteger>>(*mold)}) {
// INTEGER -> INTEGER
- int iMoldKind{iMoldExpr->GetType().value().kind()};
+ auto iMoldKind{
+ static_cast<KindsEnum>(iMoldExpr->GetType().value().kind())};
if (auto hi{IntToIntBound(iXKind, iMoldKind)}) {
// 'hi' is INT(HUGE(mold), KIND(x))
// OUT_OF_RANGE(x,mold) = (x + (hi + 1)) .UGT. (2*hi + 1)
@@ -349,7 +352,8 @@ static Expr<Type<TypeCategory::Logical>> RewriteOutOfRange(
}
} else if (auto *rMoldExpr{UnwrapExpr<Expr<SomeReal>>(*mold)}) {
// INTEGER -> REAL
- int rMoldKind{rMoldExpr->GetType().value().kind()};
+ auto rMoldKind{
+ static_cast<KindsEnum>(rMoldExpr->GetType().value().kind())};
if (auto hi{IntToRealBound(iXKind, rMoldKind, /*negate=*/false)}) {
// OUT_OF_RANGE(x,mold) = (x - lo) .UGT. (hi - lo)
auto lo{IntToRealBound(iXKind, rMoldKind, /*negate=*/true)};
@@ -363,10 +367,11 @@ static Expr<Type<TypeCategory::Logical>> RewriteOutOfRange(
}
}
} else if (auto *rXExpr{UnwrapExpr<Expr<SomeReal>>(*x)}) {
- int rXKind{rXExpr->GetType().value().kind()};
+ auto rXKind{static_cast<KindsEnum>(rXExpr->GetType().value().kind())};
if (auto *iMoldExpr{UnwrapExpr<Expr<SomeInteger>>(*mold)}) {
// REAL -> INTEGER
- int iMoldKind{iMoldExpr->GetType().value().kind()};
+ auto iMoldKind{
+ static_cast<KindsEnum>(iMoldExpr->GetType().value().kind())};
auto hi{RealToIntBound(rXKind, iMoldKind, false, false)};
auto lo{RealToIntBound(rXKind, iMoldKind, false, true)};
if (args.size() >= 3) {
@@ -416,7 +421,8 @@ static Expr<Type<TypeCategory::Logical>> RewriteOutOfRange(
// TRANSFER(HUGE(mold), int)
// Note that OUT_OF_RANGE(+/-Inf or NaN,mold) =
// TRANSFER(+Inf or Nan, int) - 1 .ULT. TRANSFER(HUGE(mold), int)
- int rMoldKind{rMoldExpr->GetType().value().kind()};
+ auto rMoldKind{
+ static_cast<KindsEnum>(rMoldExpr->GetType().value().kind())};
if (auto bounds{RealToRealBounds(rXKind, rMoldKind)}) {
auto &[moldHuge, xHuge]{*bounds};
Expr<SomeType> abs{ApplyIntrinsic(context, "abs",
@@ -481,7 +487,7 @@ static std::optional<common::RoundingMode> GetRoundingMode(
Expr<Type<TypeCategory::Logical>> FoldIntrinsicFunction(FoldingContext &context,
FunctionRef<Type<TypeCategory::Logical>> &&funcRef) {
using T = Type<TypeCategory::Logical>;
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
ActualArguments &args{funcRef.arguments()};
auto *intrinsic{std::get_if<SpecificIntrinsic>(&funcRef.proc().u)};
CHECK(intrinsic);
@@ -613,7 +619,7 @@ Expr<Type<TypeCategory::Logical>> FoldIntrinsicFunction(FoldingContext &context,
IsActuallyConstant(*args[0]->UnwrapExpr())) {
auto restorer{context.messages().DiscardMessages()};
using DefaultReal = Type<TypeCategory::Real>;
- constexpr int DefaultRealKind{4};
+ constexpr KindsEnum DefaultRealKind{Kind4};
return FoldElementalIntrinsic<T, DefaultReal>(kind, {DefaultRealKind},
context, std::move(funcRef),
ScalarFunc<T, DefaultReal>([kind](const Scalar<DefaultReal> &x) {
@@ -623,7 +629,7 @@ Expr<Type<TypeCategory::Logical>> FoldIntrinsicFunction(FoldingContext &context,
} else if (name == "__builtin_ieee_is_negative") {
auto restorer{context.messages().DiscardMessages()};
using DefaultReal = Type<TypeCategory::Real>;
- constexpr int DefaultRealKind{4};
+ constexpr KindsEnum DefaultRealKind{Kind4};
if (args[0] && args[0]->UnwrapExpr() &&
IsActuallyConstant(*args[0]->UnwrapExpr())) {
return FoldElementalIntrinsic<T, DefaultReal>(kind, {DefaultRealKind},
@@ -635,7 +641,7 @@ Expr<Type<TypeCategory::Logical>> FoldIntrinsicFunction(FoldingContext &context,
} else if (name == "__builtin_ieee_is_normal") {
auto restorer{context.messages().DiscardMessages()};
using DefaultReal = Type<TypeCategory::Real>;
- constexpr int DefaultRealKind = 4;
+ constexpr KindsEnum DefaultRealKind{Kind4};
if (args[0] && args[0]->UnwrapExpr() &&
IsActuallyConstant(*args[0]->UnwrapExpr())) {
return FoldElementalIntrinsic<T, DefaultReal>(kind, {DefaultRealKind},
@@ -669,7 +675,7 @@ Expr<Type<TypeCategory::Logical>> FoldIntrinsicFunction(FoldingContext &context,
// Int64 used to be Type<Integer,8>; force the argument to that kind as
// before.
using Int64 = Type<TypeCategory::Integer>;
- constexpr int Int64Kind{8};
+ constexpr KindsEnum Int64Kind{Kind8};
return FoldElementalIntrinsic<T, Int64>(kind, {Int64Kind}, context,
std::move(funcRef),
ScalarFunc<T, Int64>([kind](const Scalar<Int64> &x) {
@@ -680,7 +686,7 @@ Expr<Type<TypeCategory::Logical>> FoldIntrinsicFunction(FoldingContext &context,
if (args[0] && args[0]->UnwrapExpr() &&
IsActuallyConstant(*args[0]->UnwrapExpr())) {
using Int64 = Type<TypeCategory::Integer>;
- constexpr int Int64Kind{8};
+ constexpr KindsEnum Int64Kind{Kind8};
return FoldElementalIntrinsic<T, Int64>(kind, {Int64Kind}, context,
std::move(funcRef),
ScalarFunc<T, Int64>([kind](const Scalar<Int64> &x) {
@@ -872,7 +878,7 @@ Expr<Type<TypeCategory::Logical>> FoldOperation(
return *array;
}
using Ty = Type<TypeCategory::Logical>;
- const int kind{x.kind()};
+ const KindsEnum kind{x.kind()};
auto &operand{x.left()};
if (auto value{GetScalarConstantValue<Ty>(operand)}) {
return MakeConstantExpr<Ty>(kind, !value->IsTrue());
@@ -883,7 +889,7 @@ Expr<Type<TypeCategory::Logical>> FoldOperation(
Expr<Type<TypeCategory::Logical>> FoldOperation(
FoldingContext &context, LogicalOperation &&operation) {
using LOGICAL = Type<TypeCategory::Logical>;
- const int kind{operation.kind()};
+ const KindsEnum kind{operation.kind()};
if (auto array{ApplyElementwise(context, operation,
std::function<Expr<LOGICAL>(Expr<LOGICAL> &&, Expr<LOGICAL> &&)>{
[=](Expr<LOGICAL> &&x, Expr<LOGICAL> &&y) {
diff --git a/flang/lib/Evaluate/fold-matmul.h b/flang/lib/Evaluate/fold-matmul.h
index e0c58acdbb4bc..2fc655cb3e1a9 100644
--- a/flang/lib/Evaluate/fold-matmul.h
+++ b/flang/lib/Evaluate/fold-matmul.h
@@ -15,7 +15,7 @@ namespace Fortran::evaluate {
template <typename T>
static Expr<T> FoldMatmul(FoldingContext &context, FunctionRef<T> &&funcRef) {
- const int kind{funcRef.kind()};
+ const auto kind{static_cast<KindsEnum>(funcRef.kind())};
using Element = typename Constant<T>::Element;
auto args{funcRef.arguments()};
CHECK(args.size() == 2);
diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp
index 57b935ac05799..d16282917746e 100644
--- a/flang/lib/Evaluate/fold-real.cpp
+++ b/flang/lib/Evaluate/fold-real.cpp
@@ -15,17 +15,17 @@ namespace Fortran::evaluate {
template <typename T>
static Expr<T> FoldTransformationalBessel(
FunctionRef<T> &&funcRef, FoldingContext &context) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
CHECK(funcRef.arguments().size() == 3);
/// Bessel runtime functions use `int` integer arguments. Convert integer
/// arguments to Int4, any overflow error will be reported during the
/// conversion folding.
using Int4 = Type<TypeCategory::Integer>;
- if (auto args{GetConstantArguments<Int4, Int4, T>({4, 4, kind}, context,
- funcRef.arguments(), /*hasOptionalArgument=*/false)}) {
+ if (auto args{GetConstantArguments<Int4, Int4, T>({Kind4, Kind4, kind},
+ context, funcRef.arguments(), /*hasOptionalArgument=*/false)}) {
const std::string &name{std::get<SpecificIntrinsic>(funcRef.proc().u).name};
if (auto elementalBessel{
- GetHostRuntimeWrapper<T, Int4, T>(kind, {4, kind}, name)}) {
+ GetHostRuntimeWrapper<T, Int4, T>(kind, {Kind4, kind}, name)}) {
std::vector<Scalar<T>> results;
int n1{static_cast<int>(
std::get<0>(*args)->GetScalarValue().value().ToInt64())};
@@ -34,14 +34,14 @@ static Expr<T> FoldTransformationalBessel(
Scalar<T> x{std::get<2>(*args)->GetScalarValue().value()};
for (int i{n1}; i <= n2; ++i) {
results.emplace_back(
- (*elementalBessel)(context, value::IntegerValue{4, i}, x));
+ (*elementalBessel)(context, value::IntegerValue{Kind4, i}, x));
}
return Expr<T>{Constant<T>{kind, std::move(results),
ConstantSubscripts{std::max(n2 - n1 + 1, 0)}}};
} else {
context.Warn(common::UsageWarning::FoldingFailure,
"%s(integer(kind=4), real(kind=%d)) cannot be folded on host"_warn_en_US,
- name, kind);
+ name, static_cast<int>(kind));
}
}
return Expr<T>{std::move(funcRef)};
@@ -111,7 +111,7 @@ class Norm2Accumulator {
ConstantSubscripts maxAbsAt_{maxAbs_.lbounds()};
};
-static Expr<Type<TypeCategory::Real>> FoldNorm2(int kind,
+static Expr<Type<TypeCategory::Real>> FoldNorm2(KindsEnum kind,
FoldingContext &context, FunctionRef<Type<TypeCategory::Real>> &&funcRef) {
using T = Type<TypeCategory::Real>;
using Element = typename Constant<T>::Element;
@@ -130,7 +130,8 @@ static Expr<Type<TypeCategory::Real>> FoldNorm2(int kind,
arrayAndMask->mask, dim, identity, norm2Accumulator)};
if (norm2Accumulator.overflow()) {
context.Warn(common::UsageWarning::FoldingException,
- "NORM2() of REAL(%d) data overflowed"_warn_en_US, kind);
+ "NORM2() of REAL(%d) data overflowed"_warn_en_US,
+ static_cast<int>(kind));
}
return Expr<T>{std::move(result)};
}
@@ -139,7 +140,7 @@ static Expr<Type<TypeCategory::Real>> FoldNorm2(int kind,
Expr<Type<TypeCategory::Real>> FoldIntrinsicFunction(
FoldingContext &context, FunctionRef<Type<TypeCategory::Real>> &&funcRef) {
- const int kind{funcRef.kind()};
+ const KindsEnum kind{funcRef.kind()};
using T = Type<TypeCategory::Real>;
using ComplexT = Type<TypeCategory::Complex>;
using Int4 = Type<TypeCategory::Integer>;
@@ -161,7 +162,8 @@ Expr<Type<TypeCategory::Real>> FoldIntrinsicFunction(
kind, {kind}, context, std::move(funcRef), *callable);
} else {
context.Warn(common::UsageWarning::FoldingFailure,
- "%s(real(kind=%d)) cannot be folded on host"_warn_en_US, name, kind);
+ "%s(real(kind=%d)) cannot be folded on host"_warn_en_US, name,
+ static_cast<int>(kind));
}
} else if (name == "amax0" || name == "amin0" || name == "amin1" ||
name == "amax1" || name == "dmin1" || name == "dmax1") {
@@ -176,19 +178,19 @@ Expr<Type<TypeCategory::Real>> FoldIntrinsicFunction(
} else {
context.Warn(common::UsageWarning::FoldingFailure,
"%s(real(kind=%d), real(kind%d)) cannot be folded on host"_warn_en_US,
- name, kind, kind);
+ name, static_cast<int>(kind), static_cast<int>(kind));
}
} else if (name == "bessel_jn" || name == "bessel_yn") {
if (args.size() == 2) { // elemental
// runtime functions use int arg
if (auto callable{
- GetHostRuntimeWrapper<T, Int4, T>(kind, {4, kind}, name)}) {
+ GetHostRuntimeWrapper<T, Int4, T>(kind, {Kind4, kind}, name)}) {
return FoldElementalIntrinsic<T, Int4, T>(
- kind, {4, kind}, context, std::move(funcRef), *callable);
+ kind, {Kind4, kind}, context, std::move(funcRef), *callable);
} else {
context.Warn(common::UsageWarning::FoldingFailure,
"%s(integer(kind=4), real(kind=%d)) cannot be folded on host"_warn_en_US,
- name, kind);
+ name, static_cast<int>(kind));
}
} else {
return FoldTransformationalBessel<T>(std::move(funcRef), context);
@@ -352,8 +354,9 @@ Expr<Type<TypeCategory::Real>> FoldIntrinsicFunction(
sConst->IsZero() ? "zero" : "NaN");
badSConst = true;
}
- return FoldElementalIntrinsic<T, T, TS>(kind, {kind, sVal.kind()},
- context, std::move(funcRef),
+ return FoldElementalIntrinsic<T, T, TS>(kind,
+ {kind, static_cast<KindsEnum>(sVal.kind())}, context,
+ std::move(funcRef),
ScalarFunc<T, T, TS>([&](const Scalar<T> &x,
const Scalar<TS> &s) -> Scalar<T> {
if (!badSConst && (s.IsZero() || s.IsNotANumber())) {
@@ -374,7 +377,7 @@ Expr<Type<TypeCategory::Real>> FoldIntrinsicFunction(
} else if (name == "norm2") {
return FoldNorm2(kind, context, std::move(funcRef));
} else if (name == "product") {
- auto one{Scalar<T>::FromInteger(kind, value::IntegerValue{1, 1}).value};
+ auto one{Scalar<T>::FromInteger(kind, value::IntegerValue{Kind1, 1}).value};
return FoldProduct<T>(context, std::move(funcRef), one);
} else if (name == "real" || name == "dble") {
if (auto *expr{args[0].value().UnwrapExpr()}) {
@@ -390,8 +393,9 @@ Expr<Type<TypeCategory::Real>> FoldIntrinsicFunction(
return common::visit(
[&](const auto &byVal) {
using TBY = ResultType<decltype(byVal)>;
- return FoldElementalIntrinsic<T, T, TBY>(kind, {kind, byVal.kind()},
- context, std::move(funcRef),
+ return FoldElementalIntrinsic<T, T, TBY>(kind,
+ {kind, static_cast<KindsEnum>(byVal.kind())}, context,
+ std::move(funcRef),
ScalarFunc<T, T, TBY>(
[&](const Scalar<T> &x, const Scalar<TBY> &y) -> Scalar<T> {
ValueWithRealFlags<Scalar<T>> result{x.SCALE(y)};
@@ -409,8 +413,9 @@ Expr<Type<TypeCategory::Real>> FoldIntrinsicFunction(
return common::visit(
[&](const auto &iVal) {
using TY = ResultType<decltype(iVal)>;
- return FoldElementalIntrinsic<T, T, TY>(kind, {kind, iVal.kind()},
- context, std::move(funcRef),
+ return FoldElementalIntrinsic<T, T, TY>(kind,
+ {kind, static_cast<KindsEnum>(iVal.kind())}, context,
+ std::move(funcRef),
ScalarFunc<T, T, TY>(
[&](const Scalar<T> &x, const Scalar<TY> &i) -> Scalar<T> {
return x.SET_EXPONENT(i.ToInt64());
@@ -448,8 +453,9 @@ Expr<Type<TypeCategory::Real>> FoldIntrinsicFunction(
return common::visit(
[&](const auto &yVal) {
using TY = ResultType<decltype(yVal)>;
- return FoldElementalIntrinsic<T, T, TY>(kind, {kind, yVal.kind()},
- context, std::move(funcRef),
+ return FoldElementalIntrinsic<T, T, TY>(kind,
+ {kind, static_cast<KindsEnum>(yVal.kind())}, context,
+ std::move(funcRef),
ScalarFunc<T, T, TY>([&](const Scalar<T> &x,
const Scalar<TY> &y) -> Scalar<T> {
auto xBig{
diff --git a/flang/lib/Evaluate/fold-reduction.h b/flang/lib/Evaluate/fold-reduction.h
index 0acc731fd58b1..26dd9cd6a3a00 100644
--- a/flang/lib/Evaluate/fold-reduction.h
+++ b/flang/lib/Evaluate/fold-reduction.h
@@ -18,7 +18,7 @@ template <typename T>
static Expr<T> FoldDotProduct(
FoldingContext &context, FunctionRef<T> &&funcRef) {
using Element = typename Constant<T>::Element;
- const int kind{funcRef.kind()};
+ const auto kind{static_cast<KindsEnum>(funcRef.kind())};
auto args{funcRef.arguments()};
CHECK(args.size() == 2);
Folder<T> folder{kind, context};
@@ -133,7 +133,7 @@ template <typename T> struct ArrayAndMask {
Constant<LogicalResult> mask;
};
template <typename T>
-static std::optional<ArrayAndMask<T>> ProcessReductionArgs(int kind,
+static std::optional<ArrayAndMask<T>> ProcessReductionArgs(KindsEnum kind,
FoldingContext &context, ActualArguments &arg, std::optional<int> &dim,
int arrayIndex, std::optional<int> dimIndex = std::nullopt,
std::optional<int> maskIndex = std::nullopt) {
@@ -176,7 +176,7 @@ static std::optional<ArrayAndMask<T>> ProcessReductionArgs(int kind,
// operator()(Scalar<T> &, const ConstantSubscripts &, bool first)
// and Done(Scalar<T> &).
template <typename T, typename ACCUMULATOR, typename ARRAY>
-static Constant<T> DoReduction(int kind, const Constant<ARRAY> &array,
+static Constant<T> DoReduction(KindsEnum kind, const Constant<ARRAY> &array,
const Constant<LogicalResult> &mask, std::optional<int> &dim,
const Scalar<T> &identity, ACCUMULATOR &accumulator) {
ConstantSubscripts at{array.lbounds()};
@@ -232,9 +232,9 @@ static Constant<T> DoReduction(int kind, const Constant<ARRAY> &array,
// MAXVAL & MINVAL
template <typename T, bool ABS = false> class MaxvalMinvalAccumulator {
public:
- constexpr int kind() const { return kind_; }
+ constexpr KindsEnum kind() const { return kind_; }
- MaxvalMinvalAccumulator(int kind, RelationalOperator opr,
+ MaxvalMinvalAccumulator(KindsEnum kind, RelationalOperator opr,
FoldingContext &context, const Constant<T> &array)
: kind_{kind}, opr_{opr}, context_{context}, array_{array} {};
void operator()(Scalar<T> &element, const ConstantSubscripts &at,
@@ -264,14 +264,14 @@ template <typename T, bool ABS = false> class MaxvalMinvalAccumulator {
void Done(Scalar<T> &) const {}
private:
- int kind_;
+ KindsEnum kind_;
RelationalOperator opr_;
FoldingContext &context_;
const Constant<T> &array_;
};
template <typename T>
-static Expr<T> FoldMaxvalMinval(int kind, FoldingContext &context,
+static Expr<T> FoldMaxvalMinval(KindsEnum kind, FoldingContext &context,
FunctionRef<T> &&ref, RelationalOperator opr, const Scalar<T> &identity) {
static_assert(T::category == TypeCategory::Integer ||
T::category == TypeCategory::Unsigned ||
@@ -322,7 +322,7 @@ static Expr<T> FoldProduct(
T::category == TypeCategory::Unsigned ||
T::category == TypeCategory::Real ||
T::category == TypeCategory::Complex);
- const int kind{ref.kind()};
+ const auto kind{static_cast<KindsEnum>(ref.kind())};
std::optional<int> dim;
if (std::optional<ArrayAndMask<T>> arrayAndMask{
ProcessReductionArgs<T>(kind, context, ref.arguments(), dim,
@@ -373,7 +373,7 @@ template <typename T> class SumAccumulator {
}
private:
- int kind_;
+ KindsEnum kind_;
const Constant<T> &array_;
Rounding rounding_;
bool overflow_{false};
@@ -387,7 +387,7 @@ static Expr<T> FoldSum(FoldingContext &context, FunctionRef<T> &&ref) {
T::category == TypeCategory::Real ||
T::category == TypeCategory::Complex);
using Element = typename Constant<T>::Element;
- const int kind{ref.kind()};
+ const auto kind{static_cast<KindsEnum>(ref.kind())};
std::optional<int> dim;
Element identity{Element::Zero(kind)};
if (std::optional<ArrayAndMask<T>> arrayAndMask{
diff --git a/flang/lib/Evaluate/formatting.cpp b/flang/lib/Evaluate/formatting.cpp
index 7ee14e37baee6..18a1e4069e11a 100644
--- a/flang/lib/Evaluate/formatting.cpp
+++ b/flang/lib/Evaluate/formatting.cpp
@@ -78,7 +78,7 @@ llvm::raw_ostream &ConstantBase<RESULT, VALUE>::AsFortran(
o << value.UnsignedDecimal() << "U_" << kind_;
} else if constexpr (Result::category == TypeCategory::Real ||
Result::category == TypeCategory::Complex) {
- value.AsFortran(o, kind_);
+ value.AsFortran(o, static_cast<int>(kind_));
} else if constexpr (Result::category == TypeCategory::Character) {
o << value.kind() << '_';
value.withStdString(
@@ -126,7 +126,7 @@ llvm::raw_ostream &Constant<Type<TypeCategory::Character>>::AsFortran(
if (j > 0) {
o << ',';
}
- if (kind_ != 1) {
+ if (kind_ != Kind1) {
o << kind_ << '_';
}
value.withStdString(
@@ -718,7 +718,8 @@ std::string DynamicType::AsFortran() const {
}
return result;
} else if (charLengthParamValue_ || knownLength()) {
- std::string result{"CHARACTER(KIND="s + std::to_string(kind_) + ",LEN="};
+ std::string result{
+ "CHARACTER(KIND="s + std::to_string(static_cast<int>(kind_)) + ",LEN="};
if (knownLength()) {
result += std::to_string(*knownLength()) + "_8";
} else if (charLengthParamValue_->isAssumed()) {
@@ -737,13 +738,13 @@ std::string DynamicType::AsFortran() const {
return "(typeless intrinsic function argument)";
} else {
return parser::ToUpperCaseLetters(EnumToString(category_)) + '(' +
- std::to_string(kind_) + ')';
+ std::to_string(static_cast<int>(kind_)) + ')';
}
}
std::string DynamicType::AsFortran(std::string &&charLenExpr) const {
if (!charLenExpr.empty() && category_ == TypeCategory::Character) {
- return "CHARACTER(KIND=" + std::to_string(kind_) +
+ return "CHARACTER(KIND=" + std::to_string(static_cast<int>(kind_)) +
",LEN=" + std::move(charLenExpr) + ')';
} else {
return AsFortran();
diff --git a/flang/lib/Evaluate/host.h b/flang/lib/Evaluate/host.h
index 6d3f61a5536b2..a084623c56686 100644
--- a/flang/lib/Evaluate/host.h
+++ b/flang/lib/Evaluate/host.h
@@ -73,16 +73,16 @@ template <typename... T> constexpr inline bool HostTypeExists() {
template <typename FTN_T>
inline constexpr Scalar<FTN_T> CastHostToFortran(const HostType<FTN_T> &x) {
static_assert(HostTypeExists<FTN_T>());
+ constexpr KindsEnum kind{static_cast<KindsEnum>(FTN_T::kind)};
if constexpr (FTN_T::category == TypeCategory::Complex &&
- Scalar<FTN_T>::bytesStored(FTN_T::kind) != sizeof(HostType<FTN_T>)) {
+ Scalar<FTN_T>::bytesStored(kind) != sizeof(HostType<FTN_T>)) {
// X87 is usually padded to 12 or 16bytes. Need to cast piecewise for
// complex
return Scalar<FTN_T>{CastHostToFortran<typename FTN_T::Part>(std::real(x)),
CastHostToFortran<typename FTN_T::Part>(std::imag(x))};
} else {
- static_assert(
- Scalar<FTN_T>::bytesStored(FTN_T::kind) == sizeof(HostType<FTN_T>));
- return Scalar<FTN_T>::FromRawBytes(FTN_T::kind, &x, sizeof(x));
+ static_assert(Scalar<FTN_T>::bytesStored(kind) == sizeof(HostType<FTN_T>));
+ return Scalar<FTN_T>::FromRawBytes(kind, &x, sizeof(x));
}
}
@@ -90,14 +90,14 @@ inline constexpr Scalar<FTN_T> CastHostToFortran(const HostType<FTN_T> &x) {
template <typename FTN_T>
inline constexpr HostType<FTN_T> CastFortranToHost(const Scalar<FTN_T> &x) {
static_assert(HostTypeExists<FTN_T>());
+ constexpr KindsEnum kind{static_cast<KindsEnum>(FTN_T::kind)};
if constexpr (FTN_T::category == TypeCategory::Complex &&
- Scalar<FTN_T>::bytesStored(FTN_T::kind) != sizeof(HostType<FTN_T>)) {
+ Scalar<FTN_T>::bytesStored(kind) != sizeof(HostType<FTN_T>)) {
using FortranPartType = typename FTN_T::Part;
return HostType<FTN_T>{CastFortranToHost<FortranPartType>(x.REAL()),
CastFortranToHost<FortranPartType>(x.AIMAG())};
} else {
- static_assert(
- Scalar<FTN_T>::bytesStored(FTN_T::kind) == sizeof(HostType<FTN_T>));
+ static_assert(Scalar<FTN_T>::bytesStored(kind) == sizeof(HostType<FTN_T>));
HostType<FTN_T> result;
x.StoreRawBytes(&result, sizeof(result));
return result;
diff --git a/flang/lib/Evaluate/initial-image.cpp b/flang/lib/Evaluate/initial-image.cpp
index 6c82726d63774..776fb165b59df 100644
--- a/flang/lib/Evaluate/initial-image.cpp
+++ b/flang/lib/Evaluate/initial-image.cpp
@@ -96,7 +96,7 @@ class AsConstantHelper {
extents_{extents}, padWithZero_{padWithZero}, offset_{offset} {
CHECK(!type.IsPolymorphic());
}
- template <typename T> Result Test(int kind) {
+ template <typename T> Result Test(KindsEnum kind) {
if (T::category != type_.category()) {
return std::nullopt;
}
@@ -160,12 +160,13 @@ class AsConstantHelper {
return AsGenericExpr(
Const{derived, std::move(typedValue), std::move(extents_)});
} else if constexpr (T::category == TypeCategory::Character) {
- auto length{static_cast<ConstantSubscript>(stride) / kind};
+ auto length{
+ static_cast<ConstantSubscript>(stride) / static_cast<int>(kind)};
llvm::SmallVector<char, 256> buffer;
const char *data{GetTailPaddedData(offset_, elements * stride, buffer)};
for (std::size_t j{0}; j < elements; ++j) {
typedValue[j] = value::CharacterValue::FromRawBytes(
- kind, data + j * stride, length * kind);
+ kind, data + j * stride, length * static_cast<int>(kind));
}
return AsGenericExpr(
Const{kind, length, std::move(typedValue), std::move(extents_)});
diff --git a/flang/lib/Evaluate/int-power.h b/flang/lib/Evaluate/int-power.h
index 3acdec06286f7..2df35fcadc333 100644
--- a/flang/lib/Evaluate/int-power.h
+++ b/flang/lib/Evaluate/int-power.h
@@ -19,7 +19,7 @@ template <typename REAL, typename INT>
ValueWithRealFlags<REAL> TimesIntPowerOf(const REAL &factor, const REAL &base,
const INT &power,
Rounding rounding = TargetCharacteristics::defaultRounding) {
- const int realKind{base.kind()};
+ const KindsEnum realKind{base.kind()};
CHECK(factor.kind() == base.kind());
ValueWithRealFlags<REAL> result{factor};
if (base.IsNotANumber()) {
@@ -56,8 +56,8 @@ ValueWithRealFlags<REAL> TimesIntPowerOf(const REAL &factor, const REAL &base,
template <typename REAL, typename INT>
ValueWithRealFlags<REAL> IntPower(const REAL &base, const INT &power,
Rounding rounding = TargetCharacteristics::defaultRounding) {
- const int realKind{base.kind()};
- const int intKind{power.kind()};
+ const KindsEnum realKind{base.kind()};
+ const KindsEnum intKind{power.kind()};
REAL one{REAL::FromInteger(realKind, INT{intKind, 1}).value};
return TimesIntPowerOf(one, base, power, rounding);
}
diff --git a/flang/lib/Evaluate/integer-value-impl.cpp b/flang/lib/Evaluate/integer-value-impl.cpp
index bc1a1d1c8cf73..0b41e1cea30b3 100644
--- a/flang/lib/Evaluate/integer-value-impl.cpp
+++ b/flang/lib/Evaluate/integer-value-impl.cpp
@@ -21,10 +21,12 @@ IntegerValueImpl IntegerValueImpl::Zero(int kind) {
IntegerValueImpl IntegerValueImpl::FromRawBytes(
int kind, const void *raw, std::size_t expectedSize) {
- CHECK(expectedSize == IntegerValue::bytesStored(kind));
+ CHECK(
+ expectedSize == IntegerValue::bytesStored(static_cast<KindsEnum>(kind)));
return withWordProto(kind, [&](auto proto) {
- assert(IntegerValue::bytesStored(kind) == sizeof(proto));
+ assert(IntegerValue::bytesStored(static_cast<KindsEnum>(kind)) ==
+ sizeof(proto));
std::decay_t<decltype(proto)> t{};
memcpy(&t, raw, sizeof(proto));
return FromWord(t);
diff --git a/flang/lib/Evaluate/integer-value-impl.h b/flang/lib/Evaluate/integer-value-impl.h
index 0ad4608619046..c3e8928c55b73 100644
--- a/flang/lib/Evaluate/integer-value-impl.h
+++ b/flang/lib/Evaluate/integer-value-impl.h
@@ -22,6 +22,7 @@
#undef HUGE
namespace Fortran::evaluate::value {
+using common::KindsEnum;
class IntegerValueImpl {
public:
diff --git a/flang/lib/Evaluate/integer-value.cpp b/flang/lib/Evaluate/integer-value.cpp
index 2ec567a0423ac..d079bdf194fce 100644
--- a/flang/lib/Evaluate/integer-value.cpp
+++ b/flang/lib/Evaluate/integer-value.cpp
@@ -38,13 +38,15 @@ IntegerValue &IntegerValue::operator=(IntegerValue &&x) {
return *this;
}
-IntegerValue IntegerValue::Zero(int kind) {
- return FromImpl(IntegerValueImpl::Zero(kind));
+IntegerValue IntegerValue::Zero(KindsEnum kind) {
+ return FromImpl(IntegerValueImpl::Zero(static_cast<int>(kind)));
}
bool IntegerValue::IsMonostate() const { return impl().IsMonostate(); }
-int IntegerValue::kind() const { return impl().kind(); }
+KindsEnum IntegerValue::kind() const {
+ return static_cast<KindsEnum>(impl().kind());
+}
void IntegerValue::print(llvm::raw_ostream &os) const { impl().print(os); }
@@ -56,17 +58,17 @@ bool IntegerValue::operator==(const IntegerValue &y) const {
return impl() == y.impl();
}
-IntegerValue IntegerValue::MASKL(int kind, int places) {
- return FromImpl(IntegerValueImpl::MASKL(kind, places));
+IntegerValue IntegerValue::MASKL(KindsEnum kind, int places) {
+ return FromImpl(IntegerValueImpl::MASKL(static_cast<int>(kind), places));
}
-IntegerValue IntegerValue::MASKR(int kind, int places) {
- return FromImpl(IntegerValueImpl::MASKR(kind, places));
+IntegerValue IntegerValue::MASKR(KindsEnum kind, int places) {
+ return FromImpl(IntegerValueImpl::MASKR(static_cast<int>(kind), places));
}
IntegerValue::ValueWithOverflow IntegerValue::Read(
- int kind, const char *&pp, int base, bool isSigned) {
- auto r{IntegerValueImpl::Read(kind, pp, base, isSigned)};
+ KindsEnum kind, const char *&pp, int base, bool isSigned) {
+ auto r{IntegerValueImpl::Read(static_cast<int>(kind), pp, base, isSigned)};
return {FromImpl(std::move(r.value)), r.overflow};
}
@@ -92,17 +94,21 @@ std::string IntegerValue::SignedDecimal() const {
std::string IntegerValue::Hexadecimal() const { return impl().Hexadecimal(); }
-IntegerValue IntegerValue::HUGE(int kind) {
- return FromImpl(IntegerValueImpl::HUGE(kind));
+IntegerValue IntegerValue::HUGE(KindsEnum kind) {
+ return FromImpl(IntegerValueImpl::HUGE(static_cast<int>(kind)));
}
-IntegerValue IntegerValue::Least(int kind) {
- return FromImpl(IntegerValueImpl::Least(kind));
+IntegerValue IntegerValue::Least(KindsEnum kind) {
+ return FromImpl(IntegerValueImpl::Least(static_cast<int>(kind)));
}
-int IntegerValue::RANGE(int kind) { return DecimalRange(kind * 8 - 1); }
+int IntegerValue::RANGE(KindsEnum kind) {
+ return DecimalRange(static_cast<int>(kind) * 8 - 1);
+}
-int IntegerValue::UnsignedRANGE(int kind) { return DecimalRange(kind * 8); }
+int IntegerValue::UnsignedRANGE(KindsEnum kind) {
+ return DecimalRange(static_cast<int>(kind) * 8);
+}
bool IntegerValue::IsZero() const { return impl().IsZero(); }
@@ -282,8 +288,9 @@ typename IntegerValue::PowerWithErrors IntegerValue::Power(
}
IntegerValue IntegerValue::FromRawBytes(
- int kind, const void *raw, std::size_t expectedSize) {
- return FromImpl(IntegerValueImpl::FromRawBytes(kind, raw, expectedSize));
+ KindsEnum kind, const void *raw, std::size_t expectedSize) {
+ return FromImpl(IntegerValueImpl::FromRawBytes(
+ static_cast<int>(kind), raw, expectedSize));
}
void IntegerValue::StoreRawBytes(void *dst, size_t size, bool *changed) const {
@@ -291,13 +298,13 @@ void IntegerValue::StoreRawBytes(void *dst, size_t size, bool *changed) const {
}
void IntegerValue::ConstructFromIntegral(
- int kind, std::uint64_t v, bool isSigned) {
- new (this) IntegerValueImpl(kind, v, isSigned);
+ KindsEnum kind, std::uint64_t v, bool isSigned) {
+ new (this) IntegerValueImpl(static_cast<int>(kind), v, isSigned);
}
void IntegerValue::ConstructFromIntegral(
- int kind, Fortran::common::uint128_t v) {
- new (this) IntegerValueImpl(kind, v);
+ KindsEnum kind, Fortran::common::uint128_t v) {
+ new (this) IntegerValueImpl(static_cast<int>(kind), v);
}
IntegerValue IntegerValue::FromImpl(const IntegerValueImpl &x) {
diff --git a/flang/lib/Evaluate/intrinsics-library.cpp b/flang/lib/Evaluate/intrinsics-library.cpp
index adfc295b97a2c..264f145edf268 100644
--- a/flang/lib/Evaluate/intrinsics-library.cpp
+++ b/flang/lib/Evaluate/intrinsics-library.cpp
@@ -152,7 +152,7 @@ template <typename FuncType, typename TR, typename... TA, size_t... I>
static Expr<SomeType> ApplyHostFunctionHelper(FuncType func,
FoldingContext &context, std::vector<Expr<SomeType>> &&args,
std::index_sequence<I...>) {
- const int kind{TR::kind};
+ const KindsEnum kind{static_cast<KindsEnum>(TR::kind)};
host::HostFloatingPointEnvironment hostFPE;
hostFPE.SetUpHostFloatingPointEnvironment(context);
host::HostType<TR> hostResult{};
@@ -787,13 +787,18 @@ static DynamicType BiggerType(DynamicType type) {
if (type.category() == TypeCategory::Real ||
type.category() == TypeCategory::Complex) {
// 16 bits floats to IEEE 32 bits float
- if (type.kind() == common::RealKindForPrecision(11) ||
- type.kind() == common::RealKindForPrecision(8)) {
- return {type.category(), common::RealKindForPrecision(24)};
+ if (type.kind() ==
+ static_cast<KindsEnum>(common::RealKindForPrecision(11)) ||
+ type.kind() ==
+ static_cast<KindsEnum>(common::RealKindForPrecision(8))) {
+ return {type.category(),
+ static_cast<KindsEnum>(common::RealKindForPrecision(24))};
}
// x87 float to IEEE 128 bits float
- if (type.kind() == common::RealKindForPrecision(64)) {
- return {type.category(), common::RealKindForPrecision(113)};
+ if (type.kind() ==
+ static_cast<KindsEnum>(common::RealKindForPrecision(64))) {
+ return {type.category(),
+ static_cast<KindsEnum>(common::RealKindForPrecision(113))};
}
}
return type;
@@ -825,12 +830,12 @@ static const Expr<SomeType> &GetArg(
template <typename T>
static bool IsInRange(const Expr<T> &expr, int lb, int ub) {
- const int kind{expr.kind()};
+ const auto kind{static_cast<KindsEnum>(expr.kind())};
if (auto scalar{GetScalarConstantValue<T>(expr)}) {
auto lbValue{
- Scalar<T>::FromInteger(kind, value::IntegerValue{1, lb}).value};
+ Scalar<T>::FromInteger(kind, value::IntegerValue{Kind1, lb}).value};
auto ubValue{
- Scalar<T>::FromInteger(kind, value::IntegerValue{1, ub}).value};
+ Scalar<T>::FromInteger(kind, value::IntegerValue{Kind1, ub}).value};
return Satisfies(RelationalOperator::LE, lbValue.Compare(*scalar)) &&
Satisfies(RelationalOperator::LE, scalar->Compare(ubValue));
}
@@ -864,7 +869,7 @@ static bool VerifyStrictlyPositiveIfReal(
const bool isStrictlyPositive{std::visit(
[&](const auto &x) -> bool {
using T = typename std::decay_t<decltype(x)>::Result;
- const int kind{x.kind()};
+ const auto kind{static_cast<KindsEnum>(x.kind())};
auto scalar{GetScalarConstantValue<T>(x)};
return Satisfies(
RelationalOperator::LT, Scalar<T>::Zero(kind).Compare(*scalar));
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 748c6e0d14402..85ee4011a1024 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -9,6 +9,7 @@
#include "flang/Evaluate/intrinsics.h"
#include "flang/Common/enum-set.h"
#include "flang/Common/idioms.h"
+#include "flang/Common/type-kinds.h"
#include "flang/Evaluate/check-expression.h"
#include "flang/Evaluate/common.h"
#include "flang/Evaluate/expression.h"
@@ -1821,7 +1822,7 @@ static DynamicType GetBuiltinDerivedType(
return DynamicType{derived};
}
-static std::int64_t GetBuiltinKind(
+static KindsEnum GetBuiltinKind(
const semantics::Scope *builtinsScope, const char *which) {
if (!builtinsScope) {
common::die("INTERNAL: The __fortran_builtins module was not found, and "
@@ -1839,12 +1840,12 @@ static std::int64_t GetBuiltinKind(
const auto &details{
DEREF(symbol.detailsIf<semantics::ObjectEntityDetails>())};
if (const auto kind{ToInt64(details.init())}) {
- return *kind;
+ return static_cast<KindsEnum>(*kind);
} else {
common::die(
"INTERNAL: The __fortran_builtins module does not define the kind '%s'",
which);
- return -1;
+ return KindsEnum::InvalidKind;
}
}
@@ -2279,10 +2280,10 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
argOk = true;
break;
case KindCode::exactKind:
- argOk = type->kind() == d.typePattern.kindValue;
+ argOk = type->kind() == static_cast<KindsEnum>(d.typePattern.kindValue);
break;
case KindCode::greaterOrEqualToKind:
- argOk = type->kind() >= d.typePattern.kindValue;
+ argOk = type->kind() >= static_cast<KindsEnum>(d.typePattern.kindValue);
break;
case KindCode::sameAtom:
if (!sameArg) {
@@ -2546,7 +2547,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
messages.Say(
"%s(KIND=%jd) type not supported on this target."_err_en_US,
parser::ToUpperCaseLetters(EnumToString(*category)),
- defaults.quadPrecisionKind());
+ static_cast<std::intmax_t>(defaults.quadPrecisionKind()));
}
break;
case KindCode::defaultLogicalKind:
@@ -2567,7 +2568,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
if (result.categorySet.test(aType->category())) {
if (const auto *sameChar{UnwrapExpr<Expr<SomeCharacter>>(*sameArg)}) {
if (auto len{ToInt64(Fold(context, sameChar->LEN()))}) {
- resultType = DynamicType{aType->kind(), *len};
+ resultType =
+ DynamicType{static_cast<KindsEnum>(aType->kind()), *len};
} else {
resultType = *aType;
}
@@ -2575,14 +2577,16 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
resultType = *aType;
}
} else {
- resultType = DynamicType{*category, aType->kind()};
+ resultType =
+ DynamicType{*category, static_cast<KindsEnum>(aType->kind())};
}
}
break;
case KindCode::sameKind:
CHECK(sameArg);
if (std::optional<DynamicType> aType{sameArg->GetType()}) {
- resultType = DynamicType{*category, aType->kind()};
+ resultType =
+ DynamicType{*category, static_cast<KindsEnum>(aType->kind())};
}
break;
case KindCode::operand:
@@ -2599,11 +2603,12 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
CHECK(expr->Rank() == 0);
if (auto code{ToInt64(Fold(context, common::Clone(*expr)))}) {
if (context.targetCharacteristics().IsTypeEnabled(
- *category, *code)) {
+ *category, static_cast<KindsEnum>(*code))) {
if (*category == TypeCategory::Character) { // ACHAR & CHAR
- resultType = DynamicType{static_cast<int>(*code), 1};
+ resultType = DynamicType{static_cast<KindsEnum>(*code), 1};
} else {
- resultType = DynamicType{*category, static_cast<int>(*code)};
+ resultType =
+ DynamicType{*category, static_cast<KindsEnum>(*code)};
}
break;
}
@@ -2631,7 +2636,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
CHECK(kindDummyArg->flags.test(ArgFlag::defaultsToDefaultForResult));
}
if (!resultType) {
- int kind{defaults.GetDefaultKind(*category)};
+ KindsEnum kind{defaults.GetDefaultKind(*category)};
if (*category == TypeCategory::Character) { // ACHAR & CHAR
resultType = DynamicType{kind, 1};
} else {
@@ -2649,14 +2654,14 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
case KindCode::subscript:
CHECK(result.categorySet == IntType);
CHECK(*category == TypeCategory::Integer);
- resultType =
- DynamicType{TypeCategory::Integer, defaults.subscriptIntegerKind()};
+ resultType = DynamicType{TypeCategory::Integer,
+ static_cast<KindsEnum>(defaults.subscriptIntegerKind())};
break;
case KindCode::size:
CHECK(result.categorySet == IntType);
CHECK(*category == TypeCategory::Integer);
- resultType =
- DynamicType{TypeCategory::Integer, defaults.sizeIntegerKind()};
+ resultType = DynamicType{TypeCategory::Integer,
+ static_cast<KindsEnum>(defaults.sizeIntegerKind())};
break;
case KindCode::teamType:
CHECK(result.categorySet == DerivedType);
@@ -2666,7 +2671,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
break;
case KindCode::greaterOrEqualToKind:
case KindCode::exactKind:
- resultType = DynamicType{*category, result.kindValue};
+ resultType =
+ DynamicType{*category, static_cast<KindsEnum>(result.kindValue)};
break;
case KindCode::typeless:
case KindCode::any:
@@ -3262,7 +3268,8 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer(
}
if (dummies.size() == 2) {
// Handle SHAPE
- DynamicType shapeType{TypeCategory::Integer, defaults_.sizeIntegerKind()};
+ DynamicType shapeType{TypeCategory::Integer,
+ static_cast<KindsEnum>(defaults_.sizeIntegerKind())};
if (arguments.size() >= 3 && arguments[2]) {
if (auto type{arguments[2]->GetType()}) {
if (type->category() == TypeCategory::Integer) {
@@ -3277,7 +3284,8 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer(
dummies.emplace_back("shape"s, std::move(shape));
// Handle LOWER
- DynamicType lowerType{TypeCategory::Integer, defaults_.sizeIntegerKind()};
+ DynamicType lowerType{TypeCategory::Integer,
+ static_cast<KindsEnum>(defaults_.sizeIntegerKind())};
if (arguments.size() >= 4 && arguments[3]) {
if (auto type{arguments[3]->GetType()}) {
if (type->category() == TypeCategory::Integer) {
@@ -3331,7 +3339,8 @@ IntrinsicProcTable::Implementation::HandleC_F_Strpointer(
if (CheckAndRearrangeArguments(arguments, context.messages(), keywords, 1)) {
CHECK(arguments.size() == 3);
const bool hasNchars{arguments[2].has_value()};
- const int cCharKind = defaults_.GetDefaultKind(TypeCategory::Character);
+ const KindsEnum cCharKind{
+ defaults_.GetDefaultKind(TypeCategory::Character)};
// Check first argument (CSTRARRAY or CSTRPTR) and optional third argument
// (NCHARS)
@@ -3477,7 +3486,8 @@ IntrinsicProcTable::Implementation::HandleC_F_Strpointer(
}
if (dummies.size() == 2) {
// Add NCHARS dummy
- DynamicType ncharsType{TypeCategory::Integer, defaults_.sizeIntegerKind()};
+ DynamicType ncharsType{TypeCategory::Integer,
+ static_cast<KindsEnum>(defaults_.sizeIntegerKind())};
if (arguments.size() >= 3 && arguments[2]) {
if (const auto type{arguments[2]->GetType()}) {
if (type->category() == TypeCategory::Integer) {
@@ -3554,7 +3564,7 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::HandleC_Loc(
} else if (typeAndShape->type().category() != TypeCategory::Derived &&
!IsInteroperableIntrinsicType(typeAndShape->type()).value_or(true)) {
if (typeAndShape->type().category() == TypeCategory::Character &&
- typeAndShape->type().kind() == 1) {
+ typeAndShape->type().kind() == Kind1) {
// Default character kind, but length is not known to be 1
context.Warn(common::UsageWarning::CharacterInteroperability,
arguments[0]->sourceLocation(),
@@ -3624,7 +3634,7 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::HandleC_Devloc(
} else if (typeAndShape->type().category() != TypeCategory::Derived &&
!IsInteroperableIntrinsicType(typeAndShape->type()).value_or(true)) {
if (typeAndShape->type().category() == TypeCategory::Character &&
- typeAndShape->type().kind() == 1) {
+ typeAndShape->type().kind() == Kind1) {
// Default character kind, but length is not known to be 1
context.Warn(common::UsageWarning::CharacterInteroperability,
arguments[0]->sourceLocation(),
@@ -3805,7 +3815,7 @@ static DynamicType GetReturnType(const SpecificIntrinsicInterface &interface,
default:
CRASH_NO_CASE;
}
- int kind{interface.result.kindCode == KindCode::doublePrecision
+ KindsEnum kind{interface.result.kindCode == KindCode::doublePrecision
? defaults.doublePrecisionKind()
: interface.result.kindCode == KindCode::quadPrecision
? defaults.quadPrecisionKind()
diff --git a/flang/lib/Evaluate/real-value-impl.cpp b/flang/lib/Evaluate/real-value-impl.cpp
index 738f461af2d88..3d682a780d1a9 100644
--- a/flang/lib/Evaluate/real-value-impl.cpp
+++ b/flang/lib/Evaluate/real-value-impl.cpp
@@ -38,7 +38,7 @@ RealValueImpl::RealValueImpl(int kind, double x) {
storage_ = std::signbit(x) ? RealValueImpl::NegativeZero(kind).storage_
: RealValueImpl::Zero(kind).storage_;
} else if (std::isnan(x)) {
- storage_ = RealValueImpl::NotANumber(kind).storage_;
+ storage_ = RealValueImpl::NotANumber(static_cast<KindsEnum>(kind)).storage_;
} else if (std::isinf(x)) {
storage_ = RealValueImpl::Infinity(kind, x < 0).storage_;
} else {
@@ -54,9 +54,11 @@ RealValueImpl::RealValueImpl(int kind, double x) {
// Convert() then applies the target kind's own IEEE rounding/overflow
// semantics for the final narrowing (or widening).
constexpr int wideKind{8};
- RealValueImpl magnitude{
- RealValueImpl::FromInteger(wideKind, IntegerValue{8, mantissa}).value};
- magnitude = magnitude.SCALE(IntegerValue{4, exp - fracBits}).value;
+ RealValueImpl magnitude{RealValueImpl::FromInteger(
+ wideKind, IntegerValue{KindsEnum::Kind8, mantissa})
+ .value};
+ magnitude =
+ magnitude.SCALE(IntegerValue{KindsEnum::Kind4, exp - fracBits}).value;
if (negative) {
magnitude = magnitude.SetSign(true);
}
@@ -74,12 +76,13 @@ RealValueImpl RealValueImpl::Zero(int kind) {
RealValueImpl RealValueImpl::FromRawBytes(
int kind, const void *raw, std::size_t expectedSize) {
- return RealValueImpl{
- kind, IntegerValue::FromRawBytes(kind, raw, expectedSize)};
+ return RealValueImpl{kind,
+ IntegerValue::FromRawBytes(
+ static_cast<KindsEnum>(kind), raw, expectedSize)};
}
void RealValueImpl::print(llvm::raw_ostream &os) const {
- AsFortran(os, kind());
+ AsFortran(os, static_cast<int>(kind()));
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -89,17 +92,17 @@ LLVM_DUMP_METHOD void RealValueImpl::dump() const {
}
#endif
-int RealValueImpl::kind() const {
+KindsEnum RealValueImpl::kind() const {
if (IsMonostate()) {
llvm_unreachable("uninitialized value has not a defined kind");
}
- return withWord([](const auto &v) -> int {
+ return withWord([](const auto &v) -> KindsEnum {
using R = std::decay_t<decltype(v)>;
if constexpr (std::is_same_v<R, R3>) {
- return 3;
+ return KindsEnum::Kind3;
}
- return R::bits / 8;
+ return static_cast<KindsEnum>(R::bits / 8);
});
}
@@ -166,9 +169,9 @@ RealValueImpl RealValueImpl::TINY(int kind) {
kind, [](auto p) { return FromWord(decltype(p)::TINY()); });
}
-RealValueImpl RealValueImpl::NotANumber(int kind) {
- return withWordProto(
- kind, [](auto p) { return FromWord(decltype(p)::NotANumber()); });
+RealValueImpl RealValueImpl::NotANumber(KindsEnum kind) {
+ return withWordProto(static_cast<int>(kind),
+ [](auto p) { return FromWord(decltype(p)::NotANumber()); });
}
RealValueImpl RealValueImpl::SignalingNaN(int kind) {
diff --git a/flang/lib/Evaluate/real-value-impl.h b/flang/lib/Evaluate/real-value-impl.h
index 15f4dae3ded47..b1b670cb65e01 100644
--- a/flang/lib/Evaluate/real-value-impl.h
+++ b/flang/lib/Evaluate/real-value-impl.h
@@ -9,6 +9,7 @@
#ifndef FORTRAN_EVALUATE_REAL_VALUE_IMPL_H_
#define FORTRAN_EVALUATE_REAL_VALUE_IMPL_H_
+#include "flang/Common/type-kinds.h"
#include "flang/Evaluate/real.h"
#include "llvm/Support/ErrorHandling.h"
#include <type_traits>
@@ -25,6 +26,7 @@ class raw_ostream;
namespace Fortran::evaluate::value {
class IntegerValue;
+using common::KindsEnum;
class RealValueImpl {
public:
@@ -78,19 +80,19 @@ class RealValueImpl {
#endif
bool IsMonostate() const { return storage_.index() == 0; }
- int kind() const;
+ KindsEnum kind() const;
int bits() const;
std::size_t bytesStored() const { return bytesStored(kind()); }
- static constexpr std::size_t bytesStored(int kind) {
+ static constexpr std::size_t bytesStored(KindsEnum kind) {
switch (kind) {
- case 3:
+ case KindsEnum::Kind3:
return 2;
- case 10:
+ case KindsEnum::Kind10:
return 16;
default:
- return kind;
+ return static_cast<std::size_t>(kind);
}
}
@@ -111,7 +113,7 @@ class RealValueImpl {
static RealValueImpl HUGE(int kind);
static RealValueImpl EPSILON(int kind);
static RealValueImpl TINY(int kind);
- static RealValueImpl NotANumber(int kind);
+ static RealValueImpl NotANumber(KindsEnum kind);
static RealValueImpl SignalingNaN(int kind);
static RealValueImpl Infinity(int kind, bool negative = false);
static RealValueImpl NegativeZero(int kind);
diff --git a/flang/lib/Evaluate/real-value.cpp b/flang/lib/Evaluate/real-value.cpp
index 8f8f9bbaefd99..b6aec10be12ba 100644
--- a/flang/lib/Evaluate/real-value.cpp
+++ b/flang/lib/Evaluate/real-value.cpp
@@ -38,31 +38,33 @@ RealValue &RealValue::operator=(RealValue &&x) {
return *this;
}
-RealValue::RealValue(int kind, const Word &w) {
- new (this) RealValueImpl(kind, w);
+RealValue::RealValue(KindsEnum kind, const Word &w) {
+ new (this) RealValueImpl(static_cast<int>(kind), w);
}
-RealValue::RealValue(int kind, double x) { new (this) RealValueImpl(kind, x); }
+RealValue::RealValue(KindsEnum kind, double x) {
+ new (this) RealValueImpl(static_cast<int>(kind), x);
+}
-RealValue RealValue::Zero(int kind) {
- return FromImpl(RealValueImpl::Zero(kind));
+RealValue RealValue::Zero(KindsEnum kind) {
+ return FromImpl(RealValueImpl::Zero(static_cast<int>(kind)));
}
-RealValue RealValue::NegativeZero(int kind) {
- return FromImpl(RealValueImpl::NegativeZero(kind));
+RealValue RealValue::NegativeZero(KindsEnum kind) {
+ return FromImpl(RealValueImpl::NegativeZero(static_cast<int>(kind)));
}
-RealValue RealValue::Infinity(int kind, bool negative) {
- return FromImpl(RealValueImpl::Infinity(kind, negative));
+RealValue RealValue::Infinity(KindsEnum kind, bool negative) {
+ return FromImpl(RealValueImpl::Infinity(static_cast<int>(kind), negative));
}
-RealValue RealValue::SignalingNaN(int kind) {
- return FromImpl(RealValueImpl::SignalingNaN(kind));
+RealValue RealValue::SignalingNaN(KindsEnum kind) {
+ return FromImpl(RealValueImpl::SignalingNaN(static_cast<int>(kind)));
}
bool RealValue::IsMonostate() const { return impl().IsMonostate(); }
-int RealValue::kind() const { return impl().kind(); }
+KindsEnum RealValue::kind() const { return impl().kind(); }
void RealValue::print(llvm::raw_ostream &os) const { impl().print(os); }
@@ -149,30 +151,36 @@ ValueWithRealFlags<RealValue> RealValue::KahanSummation(
IntegerValue RealValue::EXPONENT() const { return impl().EXPONENT(); }
-RealValue RealValue::EPSILON(int kind) {
- return FromImpl(RealValueImpl::EPSILON(kind));
+RealValue RealValue::EPSILON(KindsEnum kind) {
+ return FromImpl(RealValueImpl::EPSILON(static_cast<int>(kind)));
}
-RealValue RealValue::HUGE(int kind) {
- return FromImpl(RealValueImpl::HUGE(kind));
+RealValue RealValue::HUGE(KindsEnum kind) {
+ return FromImpl(RealValueImpl::HUGE(static_cast<int>(kind)));
}
-RealValue RealValue::TINY(int kind) {
- return FromImpl(RealValueImpl::TINY(kind));
+RealValue RealValue::TINY(KindsEnum kind) {
+ return FromImpl(RealValueImpl::TINY(static_cast<int>(kind)));
}
-int RealValue::DIGITS(int kind) { return RealValueImpl::DIGITS(kind); }
+int RealValue::DIGITS(KindsEnum kind) {
+ return RealValueImpl::DIGITS(static_cast<int>(kind));
+}
-int RealValue::PRECISION(int kind) { return RealValueImpl::PRECISION(kind); }
+int RealValue::PRECISION(KindsEnum kind) {
+ return RealValueImpl::PRECISION(static_cast<int>(kind));
+}
-int RealValue::RANGE(int kind) { return RealValueImpl::RANGE(kind); }
+int RealValue::RANGE(KindsEnum kind) {
+ return RealValueImpl::RANGE(static_cast<int>(kind));
+}
-int RealValue::MAXEXPONENT(int kind) {
- return RealValueImpl::MAXEXPONENT(kind);
+int RealValue::MAXEXPONENT(KindsEnum kind) {
+ return RealValueImpl::MAXEXPONENT(static_cast<int>(kind));
}
-int RealValue::MINEXPONENT(int kind) {
- return RealValueImpl::MINEXPONENT(kind);
+int RealValue::MINEXPONENT(KindsEnum kind) {
+ return RealValueImpl::MINEXPONENT(static_cast<int>(kind));
}
RealValue RealValue::RRSPACING() const { return FromImpl(impl().RRSPACING()); }
@@ -194,13 +202,14 @@ RealValue RealValue::FlushSubnormalToZero() const {
return FromImpl(impl().FlushSubnormalToZero());
}
-RealValue RealValue::NotANumber(int kind) {
+RealValue RealValue::NotANumber(KindsEnum kind) {
return FromImpl(RealValueImpl::NotANumber(kind));
}
ValueWithRealFlags<RealValue> RealValue::FromInteger(
- int kind, const IntegerValue &n, bool isUnsigned, Rounding rounding) {
- return FromImpl(RealValueImpl::FromInteger(kind, n, isUnsigned, rounding));
+ KindsEnum kind, const IntegerValue &n, bool isUnsigned, Rounding rounding) {
+ return FromImpl(RealValueImpl::FromInteger(
+ static_cast<int>(kind), n, isUnsigned, rounding));
}
ValueWithRealFlags<RealValue> RealValue::ToWholeNumber(
@@ -213,8 +222,9 @@ ValueWithRealFlags<IntegerValue> RealValue::ToInteger(
}
ValueWithRealFlags<RealValue> RealValue::Convert(
- int kind, const RealValue &from, Rounding rounding) {
- return FromImpl(RealValueImpl::Convert(kind, from.impl(), rounding));
+ KindsEnum kind, const RealValue &from, Rounding rounding) {
+ return FromImpl(
+ RealValueImpl::Convert(static_cast<int>(kind), from.impl(), rounding));
}
IntegerValue RealValue::RawBits() const { return impl().RawBits(); }
@@ -222,8 +232,8 @@ IntegerValue RealValue::RawBits() const { return impl().RawBits(); }
int RealValue::Exponent() const { return impl().Exponent(); }
ValueWithRealFlags<RealValue> RealValue::Read(
- int kind, const char *&pp, Rounding rounding) {
- return FromImpl(RealValueImpl::Read(kind, pp, rounding));
+ KindsEnum kind, const char *&pp, Rounding rounding) {
+ return FromImpl(RealValueImpl::Read(static_cast<int>(kind), pp, rounding));
}
std::string RealValue::DumpHexadecimal() const {
@@ -236,8 +246,9 @@ llvm::raw_ostream &RealValue::AsFortran(
}
RealValue RealValue::FromRawBytes(
- int kind, const void *raw, std::size_t expectedSize) {
- return FromImpl(RealValueImpl::FromRawBytes(kind, raw, expectedSize));
+ KindsEnum kind, const void *raw, std::size_t expectedSize) {
+ return FromImpl(
+ RealValueImpl::FromRawBytes(static_cast<int>(kind), raw, expectedSize));
}
void RealValue::StoreRawBytes(void *dst, size_t size, bool *changed) const {
diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp
index 4d10951fe6501..a0cb21a543987 100644
--- a/flang/lib/Evaluate/shape.cpp
+++ b/flang/lib/Evaluate/shape.cpp
@@ -1087,8 +1087,8 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result {
}
} else {
// Non-scalar MASK= -> [COUNT(mask, KIND=extent_kind)]
- ActualArgument kindArg{
- AsGenericExpr(MakeExtentConstant(ExtentIntKind))};
+ ActualArgument kindArg{AsGenericExpr(
+ MakeExtentConstant(static_cast<int64_t>(ExtentIntKind)))};
kindArg.set_keyword(context_->SaveTempName("kind"));
ActualArguments toCount{
ActualArgument{common::Clone(
diff --git a/flang/lib/Evaluate/target.cpp b/flang/lib/Evaluate/target.cpp
index 47442634355c2..3698fbf8aa3a4 100644
--- a/flang/lib/Evaluate/target.cpp
+++ b/flang/lib/Evaluate/target.cpp
@@ -18,15 +18,16 @@ Rounding TargetCharacteristics::defaultRounding;
TargetCharacteristics::TargetCharacteristics() {
auto enableCategoryKinds{[this](TypeCategory category) {
- for (int kind{1}; kind <= maxKind; ++kind) {
+ for (int i{1}; i <= maxKind; ++i) {
+ KindsEnum kind{static_cast<KindsEnum>(i)};
if (CanSupportType(category, kind)) {
- auto byteSize{
- static_cast<std::size_t>(common::TypeSizeInBytes(category, kind))};
+ auto byteSize{static_cast<std::size_t>(
+ common::TypeSizeInBytes(category, static_cast<KindsEnum>(kind)))};
std::size_t align{byteSize};
if (category == TypeCategory::Complex) {
align /= 2;
}
- EnableType(category, kind, byteSize, align);
+ EnableType(category, static_cast<KindsEnum>(kind), byteSize, align);
}
}
}};
@@ -43,15 +44,15 @@ TargetCharacteristics::TargetCharacteristics() {
}
bool TargetCharacteristics::CanSupportType(
- TypeCategory category, std::int64_t kind) {
+ TypeCategory category, KindsEnum kind) {
return common::IsValidKindOfIntrinsicType(category, kind);
}
bool TargetCharacteristics::EnableType(common::TypeCategory category,
- std::int64_t kind, std::size_t byteSize, std::size_t align) {
+ KindsEnum kind, std::size_t byteSize, std::size_t align) {
if (CanSupportType(category, kind)) {
- byteSize_[static_cast<int>(category)][kind] = byteSize;
- align_[static_cast<int>(category)][kind] = align;
+ byteSize_[static_cast<int>(category)][static_cast<int>(kind)] = byteSize;
+ align_[static_cast<int>(category)][static_cast<int>(kind)] = align;
maxByteSize_ = std::max(maxByteSize_, byteSize);
maxAlignment_ = std::max(maxAlignment_, align);
return true;
@@ -61,32 +62,32 @@ bool TargetCharacteristics::EnableType(common::TypeCategory category,
}
void TargetCharacteristics::DisableType(
- common::TypeCategory category, std::int64_t kind) {
- if (kind > 0 && kind <= maxKind) {
- align_[static_cast<int>(category)][kind] = 0;
+ common::TypeCategory category, KindsEnum kind) {
+ if (IsValidKind(kind)) {
+ align_[static_cast<int>(category)][static_cast<int>(kind)] = 0;
}
}
std::size_t TargetCharacteristics::GetByteSize(
- common::TypeCategory category, std::int64_t kind) const {
- if (kind > 0 && kind <= maxKind) {
- return byteSize_[static_cast<int>(category)][kind];
+ common::TypeCategory category, KindsEnum kind) const {
+ if (IsValidKind(kind)) {
+ return byteSize_[static_cast<int>(category)][static_cast<int>(kind)];
} else {
return 0;
}
}
std::size_t TargetCharacteristics::GetAlignment(
- common::TypeCategory category, std::int64_t kind) const {
- if (kind > 0 && kind <= maxKind) {
- return align_[static_cast<int>(category)][kind];
+ common::TypeCategory category, KindsEnum kind) const {
+ if (IsValidKind(kind)) {
+ return align_[static_cast<int>(category)][static_cast<int>(kind)];
} else {
return 0;
}
}
bool TargetCharacteristics::IsTypeEnabled(
- common::TypeCategory category, std::int64_t kind) const {
+ common::TypeCategory category, KindsEnum kind) const {
return GetAlignment(category, kind) > 0;
}
@@ -102,16 +103,16 @@ void TargetCharacteristics::set_areSubnormalsFlushedToZero(bool yes) {
}
// Check if a given real kind has flushing control.
-bool TargetCharacteristics::hasSubnormalFlushingControl(int kind) const {
- CHECK(kind > 0 && kind <= maxKind);
+bool TargetCharacteristics::hasSubnormalFlushingControl(KindsEnum kind) const {
+ CHECK(IsValidKind(kind));
CHECK(CanSupportType(TypeCategory::Real, kind));
- return hasSubnormalFlushingControl_[kind];
+ return hasSubnormalFlushingControl_[static_cast<int>(kind)];
}
// Check if any or all real kinds have flushing control.
bool TargetCharacteristics::hasSubnormalFlushingControl(bool any) const {
for (int kind{1}; kind <= maxKind; ++kind) {
- if (CanSupportType(TypeCategory::Real, kind) &&
+ if (CanSupportType(TypeCategory::Real, static_cast<KindsEnum>(kind)) &&
hasSubnormalFlushingControl_[kind] == any) {
return any;
}
@@ -120,22 +121,22 @@ bool TargetCharacteristics::hasSubnormalFlushingControl(bool any) const {
}
void TargetCharacteristics::set_hasSubnormalFlushingControl(
- int kind, bool yes) {
- CHECK(kind > 0 && kind <= maxKind);
- hasSubnormalFlushingControl_[kind] = yes;
+ KindsEnum kind, bool yes) {
+ CHECK(IsValidKind(kind));
+ hasSubnormalFlushingControl_[static_cast<int>(kind)] = yes;
}
// Check if a given real kind has (nonstandard) ieee_denorm exception control.
-bool TargetCharacteristics::hasSubnormalExceptionSupport(int kind) const {
- CHECK(kind > 0 && kind <= maxKind);
+bool TargetCharacteristics::hasSubnormalExceptionSupport(KindsEnum kind) const {
+ CHECK(IsValidKind(kind));
CHECK(CanSupportType(TypeCategory::Real, kind));
- return hasSubnormalExceptionSupport_[kind];
+ return hasSubnormalExceptionSupport_[static_cast<int>(kind)];
}
// Check if all real kinds have support for the ieee_denorm exception.
bool TargetCharacteristics::hasSubnormalExceptionSupport() const {
for (int kind{1}; kind <= maxKind; ++kind) {
- if (CanSupportType(TypeCategory::Real, kind) &&
+ if (CanSupportType(TypeCategory::Real, static_cast<KindsEnum>(kind)) &&
!hasSubnormalExceptionSupport_[kind]) {
return false;
}
@@ -144,9 +145,9 @@ bool TargetCharacteristics::hasSubnormalExceptionSupport() const {
}
void TargetCharacteristics::set_hasSubnormalExceptionSupport(
- int kind, bool yes) {
- CHECK(kind > 0 && kind <= maxKind);
- hasSubnormalExceptionSupport_[kind] = yes;
+ KindsEnum kind, bool yes) {
+ CHECK(IsValidKind(kind));
+ hasSubnormalExceptionSupport_[static_cast<int>(kind)] = yes;
}
void TargetCharacteristics::set_roundingMode(Rounding rounding) {
@@ -160,9 +161,9 @@ class SelectedIntKindVisitor {
SelectedIntKindVisitor(
const TargetCharacteristics &targetCharacteristics, std::int64_t p)
: targetCharacteristics_{targetCharacteristics}, precision_{p} {}
- using Result = std::optional<int>;
+ using Result = std::optional<KindsEnum>;
using Types = IntegerTypes;
- template <typename T> Result Test(int kind) const {
+ template <typename T> Result Test(KindsEnum kind) const {
if (Scalar<T>::RANGE(kind) >= precision_ &&
targetCharacteristics_.IsTypeEnabled(T::category, kind)) {
return kind;
@@ -178,7 +179,7 @@ class SelectedIntKindVisitor {
int TargetCharacteristics::SelectedIntKind(std::int64_t precision) const {
if (auto kind{SearchTypes(SelectedIntKindVisitor{*this, precision})}) {
- return *kind;
+ return static_cast<int>(*kind);
} else {
return -1;
}
@@ -190,9 +191,9 @@ class SelectedLogicalKindVisitor {
SelectedLogicalKindVisitor(
const TargetCharacteristics &targetCharacteristics, std::int64_t bits)
: targetCharacteristics_{targetCharacteristics}, bits_{bits} {}
- using Result = std::optional<int>;
+ using Result = std::optional<KindsEnum>;
using Types = LogicalTypes;
- template <typename T> Result Test(int kind) const {
+ template <typename T> Result Test(KindsEnum kind) const {
if (Scalar<T>::bits(kind) >= bits_ &&
targetCharacteristics_.IsTypeEnabled(T::category, kind)) {
return kind;
@@ -208,7 +209,7 @@ class SelectedLogicalKindVisitor {
int TargetCharacteristics::SelectedLogicalKind(std::int64_t bits) const {
if (auto kind{SearchTypes(SelectedLogicalKindVisitor{*this, bits})}) {
- return *kind;
+ return static_cast<int>(*kind);
} else {
return -1;
}
@@ -221,13 +222,13 @@ class SelectedRealKindVisitor {
std::int64_t p, std::int64_t r)
: targetCharacteristics_{targetCharacteristics}, precision_{p}, range_{
r} {}
- using Result = std::optional<int>;
+ using Result = std::optional<KindsEnum>;
using Types = RealTypes;
- template <typename T> Result Test(int kind) const {
+ template <typename T> Result Test(KindsEnum kind) const {
if (Scalar<T>::PRECISION(kind) >= precision_ &&
Scalar<T>::RANGE(kind) >= range_ &&
targetCharacteristics_.IsTypeEnabled(T::category, kind)) {
- return {kind};
+ return kind;
} else {
return std::nullopt;
}
@@ -245,7 +246,7 @@ int TargetCharacteristics::SelectedRealKind(
}
if (auto kind{
SearchTypes(SelectedRealKindVisitor{*this, precision, range})}) {
- return *kind;
+ return static_cast<int>(*kind);
}
// No kind has both sufficient precision and sufficient range.
// The negative return value encodes whether any kinds exist that
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index 85d2a8f752d0f..0d0381be5dfda 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -116,7 +116,8 @@ auto IsVariableHelper::operator()(const ProcedureDesignator &x) const
// Conversions of COMPLEX component expressions to REAL.
ConvertRealOperandsResult ConvertRealOperands(
parser::ContextualMessages &messages, Expr<SomeType> &&x,
- Expr<SomeType> &&y, int defaultRealKind) {
+ Expr<SomeType> &&y, KindsEnum defaultRealKind) {
+ const KindsEnum defaultRealKindEnum{defaultRealKind};
return common::visit(
common::visitors{
[&](Expr<SomeInteger> &&ix,
@@ -125,33 +126,33 @@ ConvertRealOperandsResult ConvertRealOperands(
// both integer operands are converted to default REAL.
return {AsSameKindExprs<TypeCategory::Real>(
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(ix)),
+ defaultRealKindEnum, std::move(ix)),
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(iy)))};
+ defaultRealKindEnum, std::move(iy)))};
},
[&](Expr<SomeInteger> &&ix,
Expr<SomeUnsigned> &&iy) -> ConvertRealOperandsResult {
return {AsSameKindExprs<TypeCategory::Real>(
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(ix)),
+ defaultRealKindEnum, std::move(ix)),
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(iy)))};
+ defaultRealKindEnum, std::move(iy)))};
},
[&](Expr<SomeUnsigned> &&ix,
Expr<SomeInteger> &&iy) -> ConvertRealOperandsResult {
return {AsSameKindExprs<TypeCategory::Real>(
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(ix)),
+ defaultRealKindEnum, std::move(ix)),
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(iy)))};
+ defaultRealKindEnum, std::move(iy)))};
},
[&](Expr<SomeUnsigned> &&ix,
Expr<SomeUnsigned> &&iy) -> ConvertRealOperandsResult {
return {AsSameKindExprs<TypeCategory::Real>(
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(ix)),
+ defaultRealKindEnum, std::move(ix)),
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(iy)))};
+ defaultRealKindEnum, std::move(iy)))};
},
[&](Expr<SomeInteger> &&ix,
Expr<SomeReal> &&ry) -> ConvertRealOperandsResult {
@@ -186,33 +187,33 @@ ConvertRealOperandsResult ConvertRealOperands(
BOZLiteralConstant &&by) -> ConvertRealOperandsResult {
return {AsSameKindExprs<TypeCategory::Real>(
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(ix)),
+ defaultRealKindEnum, std::move(ix)),
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(by)))};
+ defaultRealKindEnum, std::move(by)))};
},
[&](Expr<SomeUnsigned> &&ix,
BOZLiteralConstant &&by) -> ConvertRealOperandsResult {
return {AsSameKindExprs<TypeCategory::Real>(
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(ix)),
+ defaultRealKindEnum, std::move(ix)),
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(by)))};
+ defaultRealKindEnum, std::move(by)))};
},
[&](BOZLiteralConstant &&bx,
Expr<SomeInteger> &&iy) -> ConvertRealOperandsResult {
return {AsSameKindExprs<TypeCategory::Real>(
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(bx)),
+ defaultRealKindEnum, std::move(bx)),
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(iy)))};
+ defaultRealKindEnum, std::move(iy)))};
},
[&](BOZLiteralConstant &&bx,
Expr<SomeUnsigned> &&iy) -> ConvertRealOperandsResult {
return {AsSameKindExprs<TypeCategory::Real>(
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(bx)),
+ defaultRealKindEnum, std::move(bx)),
ConvertToKind<TypeCategory::Real>(
- defaultRealKind, std::move(iy)))};
+ defaultRealKindEnum, std::move(iy)))};
},
[&](Expr<SomeReal> &&rx,
BOZLiteralConstant &&by) -> ConvertRealOperandsResult {
@@ -265,7 +266,7 @@ std::optional<Expr<SomeType>> MixedRealLeft(
return Package(common::visit(
[&](auto &&rxk) -> Expr<SomeReal> {
using resultType = ResultType<decltype(rxk)>;
- const int resultKind = rxk.kind();
+ const KindsEnum resultKind{rxk.kind()};
if constexpr (std::is_same_v<OPR<resultType>, Power<resultType>>) {
return AsCategoryExpr(RealToIntPower<resultType>{
resultKind, std::move(rxk), std::move(iy)});
@@ -286,7 +287,7 @@ static Expr<SomeComplex> MakeComplex(
std::optional<Expr<SomeComplex>> ConstructComplex(
parser::ContextualMessages &messages, Expr<SomeType> &&real,
- Expr<SomeType> &&imaginary, int defaultRealKind) {
+ Expr<SomeType> &&imaginary, KindsEnum defaultRealKind) {
if (auto converted{ConvertRealOperands(
messages, std::move(real), std::move(imaginary), defaultRealKind)}) {
return {common::visit(
@@ -300,7 +301,7 @@ std::optional<Expr<SomeComplex>> ConstructComplex(
std::optional<Expr<SomeComplex>> ConstructComplex(
parser::ContextualMessages &messages, std::optional<Expr<SomeType>> &&real,
- std::optional<Expr<SomeType>> &&imaginary, int defaultRealKind) {
+ std::optional<Expr<SomeType>> &&imaginary, KindsEnum defaultRealKind) {
if (auto parts{common::AllPresent(std::move(real), std::move(imaginary))}) {
return ConstructComplex(messages, std::get<0>(std::move(*parts)),
std::get<1>(std::move(*parts)), defaultRealKind);
@@ -332,7 +333,7 @@ Expr<SomeComplex> PromoteRealToComplex(Expr<SomeReal> &&someX) {
return common::visit(
[](auto &&x) {
using RT = ResultType<decltype(x)>;
- int rtKind{x.kind()};
+ auto rtKind{x.kind()};
return AsCategoryExpr(ComplexConstructor{std::move(x),
AsExpr(
Constant<RT>{rtKind, Scalar<RT>::Zero(rtKind), RT{rtKind}})});
@@ -346,13 +347,14 @@ Expr<SomeComplex> PromoteRealToComplex(Expr<SomeReal> &&someX) {
template <template <typename> class OPR, TypeCategory RCAT>
std::optional<Expr<SomeType>> MixedComplexLeft(
parser::ContextualMessages &messages, const Expr<SomeComplex> &zx,
- const Expr<SomeKind<RCAT>> &iry, [[maybe_unused]] int defaultRealKind) {
+ const Expr<SomeKind<RCAT>> &iry,
+ [[maybe_unused]] KindsEnum defaultRealKind) {
if constexpr (RCAT == TypeCategory::Integer &&
std::is_same_v<OPR<LargestReal>, Power<LargestReal>>) {
// COMPLEX**INTEGER is a special case that doesn't convert the exponent.
return Package(common::visit(
[&](const auto &zxk) {
- const int zxkKind{zxk.kind()};
+ const KindsEnum zxkKind{static_cast<KindsEnum>(zxk.kind())};
using Ty = ResultType<decltype(zxk)>;
return AsCategoryExpr(AsExpr(RealToIntPower<Ty>{
zxkKind, common::Clone(zxk), common::Clone(iry)}));
@@ -398,7 +400,7 @@ std::optional<Expr<SomeType>> MixedComplexLeft(
template <template <typename> class OPR, TypeCategory LCAT>
std::optional<Expr<SomeType>> MixedComplexRight(
parser::ContextualMessages &messages, const Expr<SomeKind<LCAT>> &irx,
- const Expr<SomeComplex> &zy, [[maybe_unused]] int defaultRealKind) {
+ const Expr<SomeComplex> &zy, [[maybe_unused]] KindsEnum defaultRealKind) {
if constexpr (std::is_same_v<OPR<LargestReal>, Add<LargestReal>>) {
// x + (a,b) -> (a,b) + x -> (a+x, b)
return MixedComplexLeft<OPR, LCAT>(messages, zy, irx, defaultRealKind);
@@ -432,7 +434,7 @@ Expr<SomeComplex> PromoteMixedComplexReal(
static_assert(XCAT == TypeCategory::Real || YCAT == TypeCategory::Real);
return common::visit(
[&](const auto &kx, const auto &ky) {
- int maxKind{std::max(kx.kind(), ky.kind())};
+ KindsEnum maxKind{std::max(kx.kind(), ky.kind())};
using ZTy = Type<TypeCategory::Complex>;
auto cx{ConvertToType<ZTy>(maxKind, std::move(x))};
auto cy{ConvertToType<ZTy>(maxKind, std::move(y))};
@@ -448,7 +450,7 @@ Expr<SomeComplex> PromoteMixedComplexReal(
template <template <typename> class OPR>
std::optional<Expr<SomeType>> NumericOperation(
parser::ContextualMessages &messages, Expr<SomeType> &&x,
- Expr<SomeType> &&y, int defaultRealKind) {
+ Expr<SomeType> &&y, KindsEnum defaultRealKind) {
return common::visit(
common::visitors{
[](Expr<SomeInteger> &&ix, Expr<SomeInteger> &&iy) {
@@ -471,7 +473,7 @@ std::optional<Expr<SomeType>> NumericOperation(
return Package(common::visit(
[&](auto &&ryk) -> Expr<SomeReal> {
using resultType = ResultType<decltype(ryk)>;
- const int resultKind{ryk.kind()};
+ const KindsEnum resultKind{ryk.kind()};
auto converted{
ConvertToType<resultType>(resultKind, std::move(ix))};
return AsCategoryExpr(OPR<resultType>{
@@ -577,19 +579,19 @@ std::optional<Expr<SomeType>> NumericOperation(
template std::optional<Expr<SomeType>> NumericOperation<Power>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
template std::optional<Expr<SomeType>> NumericOperation<Multiply>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
template std::optional<Expr<SomeType>> NumericOperation<Divide>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
template std::optional<Expr<SomeType>> NumericOperation<Add>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
template std::optional<Expr<SomeType>> NumericOperation<Subtract>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
- int defaultRealKind);
+ KindsEnum defaultRealKind);
std::optional<Expr<SomeType>> Negation(
parser::ContextualMessages &messages, Expr<SomeType> &&x) {
@@ -771,9 +773,9 @@ std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
auto makeIntCall =
[&](Expr<SomeDerived> &&operand) -> Expr<SomeType> {
using IntType = Type<TypeCategory::Integer>;
- constexpr int intKind{4};
+ constexpr KindsEnum intKind{Kind4};
DynamicType enumType{*xDerived};
- DynamicType intResultType{TypeCategory::Integer, 4};
+ DynamicType intResultType{TypeCategory::Integer, Kind4};
characteristics::DummyDataObject ddo{
characteristics::TypeAndShape{enumType}};
ddo.intent = common::Intent::In;
@@ -821,7 +823,8 @@ Expr<SomeLogical> BinaryLogicalOperation(
}
template <TypeCategory TO>
-std::optional<Expr<SomeType>> ConvertToNumeric(int kind, Expr<SomeType> &&x) {
+std::optional<Expr<SomeType>> ConvertToNumeric(
+ KindsEnum kind, Expr<SomeType> &&x) {
static_assert(common::IsNumericTypeCategory(TO));
return common::visit(
[=](auto &&cx) -> std::optional<Expr<SomeType>> {
@@ -841,42 +844,44 @@ std::optional<Expr<SomeType>> ConvertToType(
if (type.IsTypelessIntrinsicArgument()) {
return std::nullopt;
}
+ const bool hasKind{type.category() != TypeCategory::Derived};
+ const KindsEnum kind{hasKind ? static_cast<KindsEnum>(type.kind()) : NoKind};
switch (type.category()) {
case TypeCategory::Integer:
if (auto *boz{std::get_if<BOZLiteralConstant>(&x.u)}) {
// Extension to C7109: allow BOZ literals to appear in integer contexts
// when the type is unambiguous.
return Expr<SomeType>{
- ConvertToKind<TypeCategory::Integer>(type.kind(), std::move(*boz))};
+ ConvertToKind<TypeCategory::Integer>(kind, std::move(*boz))};
}
- return ConvertToNumeric<TypeCategory::Integer>(type.kind(), std::move(x));
+ return ConvertToNumeric<TypeCategory::Integer>(kind, std::move(x));
case TypeCategory::Unsigned:
if (auto *boz{std::get_if<BOZLiteralConstant>(&x.u)}) {
return Expr<SomeType>{
- ConvertToKind<TypeCategory::Unsigned>(type.kind(), std::move(*boz))};
+ ConvertToKind<TypeCategory::Unsigned>(kind, std::move(*boz))};
}
if (auto *cx{UnwrapExpr<Expr<SomeUnsigned>>(x)}) {
return Expr<SomeType>{
- ConvertToKind<TypeCategory::Unsigned>(type.kind(), std::move(*cx))};
+ ConvertToKind<TypeCategory::Unsigned>(kind, std::move(*cx))};
}
break;
case TypeCategory::Real:
if (auto *boz{std::get_if<BOZLiteralConstant>(&x.u)}) {
return Expr<SomeType>{
- ConvertToKind<TypeCategory::Real>(type.kind(), std::move(*boz))};
+ ConvertToKind<TypeCategory::Real>(kind, std::move(*boz))};
}
- return ConvertToNumeric<TypeCategory::Real>(type.kind(), std::move(x));
+ return ConvertToNumeric<TypeCategory::Real>(kind, std::move(x));
case TypeCategory::Complex:
- return ConvertToNumeric<TypeCategory::Complex>(type.kind(), std::move(x));
+ return ConvertToNumeric<TypeCategory::Complex>(kind, std::move(x));
case TypeCategory::Character:
if (auto *cx{UnwrapExpr<Expr<SomeCharacter>>(x)}) {
auto converted{
- ConvertToKind<TypeCategory::Character>(type.kind(), std::move(*cx))};
+ ConvertToKind<TypeCategory::Character>(kind, std::move(*cx))};
if (auto length{type.GetCharLength()}) {
converted = common::visit(
[&](auto &&x) {
using CharacterType = ResultType<decltype(x)>;
- const int characterKind{x.kind()};
+ const KindsEnum characterKind{x.kind()};
return Expr<SomeCharacter>{Expr<CharacterType>{
SetLength{characterKind, std::move(x), std::move(*length)}}};
},
@@ -888,7 +893,7 @@ std::optional<Expr<SomeType>> ConvertToType(
case TypeCategory::Logical:
if (auto *cx{UnwrapExpr<Expr<SomeLogical>>(x)}) {
return Expr<SomeType>{
- ConvertToKind<TypeCategory::Logical>(type.kind(), std::move(*cx))};
+ ConvertToKind<TypeCategory::Logical>(kind, std::move(*cx))};
}
break;
case TypeCategory::Derived:
@@ -1351,14 +1356,14 @@ template <common::TypeCategory CAT> using Numeric = Type<CAT>;
template <common::TypeCategory CAT> using NumericExpr = Expr<Numeric<CAT>>;
template <common::TypeCategory CAT> struct SignedNumericTerm {
- int kind() const { return expr.kind(); };
+ KindsEnum kind() const { return static_cast<KindsEnum>(expr.kind()); };
NumericExpr<CAT> expr;
bool isPositive;
};
template <common::TypeCategory CAT> struct SignedNumericExpr {
- int kind() const { return expr.kind(); };
+ KindsEnum kind() const { return static_cast<KindsEnum>(expr.kind()); };
NumericExpr<CAT> expr;
bool isPositive;
@@ -1387,7 +1392,7 @@ template <common::TypeCategory CAT>
static SignedNumericExpr<CAT> buildRightAssociatedSignedFold(
llvm::MutableArrayRef<SignedNumericTerm<CAT>> terms) {
assert(!terms.empty() && "cannot build empty signed fold");
- const int kind{terms.front().kind()};
+ const KindsEnum kind{terms.front().kind()};
const bool isPositive{terms.front().isPositive};
NumericExpr<CAT> result{std::move(terms.back().expr)};
for (std::size_t i{terms.size() - 1}; i > 0; --i) {
@@ -1407,7 +1412,7 @@ template <common::TypeCategory CAT>
static SignedNumericExpr<CAT> buildSignedAdd(
SignedNumericExpr<CAT> left, SignedNumericExpr<CAT> right) {
CHECK(left.kind() == right.kind());
- const int kind{left.kind()};
+ const KindsEnum kind{left.kind()};
if (left.isPositive == right.isPositive) {
return SignedNumericExpr<CAT>{
NumericExpr<CAT>{Add<Numeric<CAT>>{
@@ -1730,17 +1735,18 @@ template <TypeCategory TO, TypeCategory FROM>
static std::optional<Expr<SomeType>> DataConstantConversionHelper(
FoldingContext &context, const DynamicType &toType,
const Expr<SomeType> &expr) {
- if (!common::IsValidKindOfIntrinsicType(FROM, toType.kind())) {
+ if (!common::IsValidKindOfIntrinsicType(
+ FROM, static_cast<KindsEnum>(toType.kind()))) {
return std::nullopt;
}
- DynamicType sizedType{FROM, toType.kind()};
+ DynamicType sizedType{FROM, static_cast<KindsEnum>(toType.kind())};
if (auto sized{
Fold(context, ConvertToType(sizedType, Expr<SomeType>{expr}))}) {
if (const auto *someExpr{UnwrapExpr<Expr<SomeKind<FROM>>>(*sized)}) {
return common::visit(
[](const auto &w) -> std::optional<Expr<SomeType>> {
using FromType = ResultType<decltype(w)>;
- const int kind{w.kind()};
+ const KindsEnum kind{static_cast<KindsEnum>(w.kind())};
if (IsValidKindOfIntrinsicType(TO, kind)) {
if (const auto *fromConst{UnwrapExpr<Constant<FromType>>(w)}) {
using LogicalType = value::LogicalValue;
@@ -1854,7 +1860,7 @@ std::optional<Expr<SomeType>> HollerithToBOZ(FoldingContext &context,
template <typename T> const Symbol *GetBoundSymbol(const Expr<T> &);
const Symbol *GetBoundSymbol(const Expr<Type<TypeCategory::Integer>> &expr) {
using T = Type<TypeCategory::Integer>;
- const int kind{expr.kind()};
+ const KindsEnum kind{static_cast<KindsEnum>(expr.kind())};
return common::visit(
common::visitors{
[](const Extremum<T> &max) -> const Symbol * {
@@ -1875,7 +1881,9 @@ const Symbol *GetBoundSymbol(const Expr<Type<TypeCategory::Integer>> &expr) {
[kind](const Convert<T, TypeCategory::Integer> &x) {
return common::visit(
[kind](const auto &y) -> const Symbol * {
- int yKind{y.GetType() ? y.GetType()->kind() : 0};
+ KindsEnum yKind{y.GetType()
+ ? static_cast<KindsEnum>(y.GetType()->kind())
+ : NoKind};
if (yKind <= kind) {
return GetBoundSymbol(y);
} else {
diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp
index b9ed5305ad75c..ff050d8782c58 100644
--- a/flang/lib/Evaluate/type.cpp
+++ b/flang/lib/Evaluate/type.cpp
@@ -21,6 +21,14 @@
#include <optional>
#include <string>
+using Fortran::common::KindsEnum;
+
+namespace Fortran::common {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &os, KindsEnum kind) {
+ return os << static_cast<int>(kind);
+}
+} // namespace Fortran::common
+
// IsDescriptor() predicate: true when a symbol is implemented
// at runtime with a descriptor.
namespace Fortran::semantics {
@@ -117,7 +125,7 @@ bool IsPassedViaDescriptor(const Symbol &symbol) {
namespace Fortran::evaluate {
-DynamicType::DynamicType(int k, const semantics::ParamValue &pv)
+DynamicType::DynamicType(KindsEnum k, const semantics::ParamValue &pv)
: category_{TypeCategory::Character}, kind_{k} {
CHECK(common::IsValidKindOfIntrinsicType(category_, kind_));
if (auto n{ToInt64(pv.GetExplicit())}) {
@@ -252,7 +260,8 @@ bool DynamicType::IsNonConstantLengthCharacter() const {
}
bool DynamicType::IsTypelessIntrinsicArgument() const {
- return category_ == TypeCategory::Integer && kind_ == TypelessKind;
+ return category_ == TypeCategory::Integer &&
+ kind_ == static_cast<KindsEnum>(TypelessKind);
}
bool DynamicType::IsLengthlessIntrinsicType() const {
@@ -703,12 +712,13 @@ std::optional<DynamicType> DynamicType::From(
if (const auto *intrinsic{type.AsIntrinsic()}) {
if (auto kind{ToInt64(intrinsic->kind())}) {
TypeCategory category{intrinsic->category()};
- if (common::IsValidKindOfIntrinsicType(category, *kind)) {
+ auto kindsEnum{static_cast<KindsEnum>(*kind)};
+ if (common::IsValidKindOfIntrinsicType(category, kindsEnum)) {
if (category == TypeCategory::Character) {
const auto &charType{type.characterTypeSpec()};
- return DynamicType{static_cast<int>(*kind), charType.length()};
+ return DynamicType{kindsEnum, charType.length()};
} else {
- return DynamicType{category, static_cast<int>(*kind)};
+ return DynamicType{category, kindsEnum};
}
}
}
@@ -734,7 +744,8 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
case TypeCategory::Integer:
switch (that.category_) {
case TypeCategory::Integer:
- return DynamicType{TypeCategory::Integer, std::max(kind(), that.kind())};
+ return DynamicType{TypeCategory::Integer,
+ static_cast<KindsEnum>(std::max(kind(), that.kind()))};
case TypeCategory::Real:
case TypeCategory::Complex:
return that;
@@ -745,7 +756,8 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
case TypeCategory::Unsigned:
switch (that.category_) {
case TypeCategory::Unsigned:
- return DynamicType{TypeCategory::Unsigned, std::max(kind(), that.kind())};
+ return DynamicType{TypeCategory::Unsigned,
+ static_cast<KindsEnum>(std::max(kind(), that.kind()))};
default:
CRASH_NO_CASE;
}
@@ -755,9 +767,11 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
case TypeCategory::Integer:
return *this;
case TypeCategory::Real:
- return DynamicType{TypeCategory::Real, std::max(kind(), that.kind())};
+ return DynamicType{TypeCategory::Real,
+ static_cast<KindsEnum>(std::max(kind(), that.kind()))};
case TypeCategory::Complex:
- return DynamicType{TypeCategory::Complex, std::max(kind(), that.kind())};
+ return DynamicType{TypeCategory::Complex,
+ static_cast<KindsEnum>(std::max(kind(), that.kind()))};
default:
CRASH_NO_CASE;
}
@@ -768,7 +782,8 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
return *this;
case TypeCategory::Real:
case TypeCategory::Complex:
- return DynamicType{TypeCategory::Complex, std::max(kind(), that.kind())};
+ return DynamicType{TypeCategory::Complex,
+ static_cast<KindsEnum>(std::max(kind(), that.kind()))};
default:
CRASH_NO_CASE;
}
@@ -776,7 +791,8 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
case TypeCategory::Logical:
switch (that.category_) {
case TypeCategory::Logical:
- return DynamicType{TypeCategory::Logical, std::max(kind(), that.kind())};
+ return DynamicType{TypeCategory::Logical,
+ static_cast<KindsEnum>(std::max(kind(), that.kind()))};
default:
CRASH_NO_CASE;
}
@@ -821,7 +837,8 @@ bool SomeKind<TypeCategory::Derived>::operator==(
return PointeeComparison(derivedTypeSpec_, that.derivedTypeSpec_);
}
-int SelectedCharKind(const std::string &s, int defaultKind) { // F'2023 16.9.180
+int SelectedCharKind(
+ const std::string &s, KindsEnum defaultKind) { // F'2023 16.9.180
auto lower{parser::ToLowerCaseLetters(s)};
auto n{lower.size()};
while (n > 0 && lower[0] == ' ') {
@@ -838,7 +855,7 @@ int SelectedCharKind(const std::string &s, int defaultKind) { // F'2023 16.9.180
} else if (lower == "iso_10646" || lower == "ucs-4") {
return 4;
} else if (lower == "default") {
- return defaultKind;
+ return static_cast<int>(defaultKind);
} else {
return -1;
}
@@ -850,7 +867,8 @@ std::optional<DynamicType> ComparisonType(
case TypeCategory::Integer:
switch (t2.category()) {
case TypeCategory::Integer:
- return DynamicType{TypeCategory::Integer, std::max(t1.kind(), t2.kind())};
+ return DynamicType{TypeCategory::Integer,
+ static_cast<KindsEnum>(std::max(t1.kind(), t2.kind()))};
case TypeCategory::Real:
case TypeCategory::Complex:
return t2;
@@ -863,7 +881,8 @@ std::optional<DynamicType> ComparisonType(
return t1;
case TypeCategory::Real:
case TypeCategory::Complex:
- return DynamicType{t2.category(), std::max(t1.kind(), t2.kind())};
+ return DynamicType{t2.category(),
+ static_cast<KindsEnum>(std::max(t1.kind(), t2.kind()))};
default:
return std::nullopt;
}
@@ -873,15 +892,16 @@ std::optional<DynamicType> ComparisonType(
return t1;
case TypeCategory::Real:
case TypeCategory::Complex:
- return DynamicType{TypeCategory::Complex, std::max(t1.kind(), t2.kind())};
+ return DynamicType{TypeCategory::Complex,
+ static_cast<KindsEnum>(std::max(t1.kind(), t2.kind()))};
default:
return std::nullopt;
}
case TypeCategory::Character:
switch (t2.category()) {
case TypeCategory::Character:
- return DynamicType{
- TypeCategory::Character, std::max(t1.kind(), t2.kind())};
+ return DynamicType{TypeCategory::Character,
+ static_cast<KindsEnum>(std::max(t1.kind(), t2.kind()))};
default:
return std::nullopt;
}
@@ -908,12 +928,12 @@ std::optional<bool> IsInteroperableIntrinsicType(const DynamicType &type,
// KIND=2 is IEEE-754 binary16, interoperable with C _Float16.
// KIND=3 (bfloat16) has no standard interoperable C type, so it is
// accepted only under CUDA (or when reading a module file).
- return type.kind() == 2 || type.kind() >= 4 || !features ||
+ return type.kind() == Kind2 || type.kind() >= Kind4 || !features ||
features->IsEnabled(common::LanguageFeature::CUDA);
case TypeCategory::Logical:
- return type.kind() == 1; // C_BOOL
+ return type.kind() == Kind1; // C_BOOL
case TypeCategory::Character:
- if (type.kind() != 1) { // C_CHAR
+ if (type.kind() != Kind1) { // C_CHAR
return false;
} else if (checkCharLength) {
if (type.knownLength()) {
@@ -934,13 +954,13 @@ bool IsCUDAIntrinsicType(const DynamicType &type) {
switch (type.category()) {
case TypeCategory::Integer:
case TypeCategory::Logical:
- return type.kind() <= 8;
+ return type.kind() <= Kind8;
case TypeCategory::Real:
- return type.kind() >= 2 && type.kind() <= 8;
+ return type.kind() >= Kind2 && type.kind() <= Kind8;
case TypeCategory::Complex:
- return type.kind() == 2 || type.kind() == 4 || type.kind() == 8;
+ return type.kind() == Kind2 || type.kind() == Kind4 || type.kind() == Kind8;
case TypeCategory::Character:
- return type.kind() == 1;
+ return type.kind() == Kind1;
default:
// Derived types are tested in Semantics/check-declarations.cpp
return false;
diff --git a/flang/lib/Evaluate/variable.cpp b/flang/lib/Evaluate/variable.cpp
index 7ea509efdd5ca..4dd6a059be7e1 100644
--- a/flang/lib/Evaluate/variable.cpp
+++ b/flang/lib/Evaluate/variable.cpp
@@ -647,16 +647,17 @@ template <typename T> const Symbol *Designator<T>::GetLastSymbol() const {
template <typename T>
std::optional<DynamicType> Designator<T>::GetType() const {
if constexpr (IsLengthlessIntrinsicType<Result>) {
- return DynamicType{Result::category, kind()};
+ return DynamicType{Result::category, static_cast<KindsEnum>(kind())};
}
if constexpr (Result::category == TypeCategory::Character) {
if (std::holds_alternative<Substring>(u)) {
if (auto len{LEN()}) {
if (auto n{ToInt64(*len)}) {
- return DynamicType{kind(), *n};
+ return DynamicType{static_cast<KindsEnum>(kind()), *n};
}
}
- return DynamicType{TypeCategory::Character, kind()};
+ return DynamicType{
+ TypeCategory::Character, static_cast<KindsEnum>(kind())};
}
}
if (const Symbol * symbol{GetLastSymbol()}) {
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index b57bc4583be38..69c1aad1d03b4 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -589,16 +589,16 @@ static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) {
opts.featuresAsWritten.emplace_back(currentArg->getValue());
if (args.hasArg(clang::options::OPT_fdisable_real_10))
- opts.disabledRealKinds.push_back(10);
+ opts.disabledRealKinds.push_back(Fortran::common::KindsEnum::Kind10);
if (args.hasArg(clang::options::OPT_fdisable_real_3))
- opts.disabledRealKinds.push_back(3);
+ opts.disabledRealKinds.push_back(Fortran::common::KindsEnum::Kind3);
if (args.hasArg(clang::options::OPT_fdisable_integer_2))
- opts.disabledIntegerKinds.push_back(2);
+ opts.disabledIntegerKinds.push_back(Fortran::common::KindsEnum::Kind2);
if (args.hasArg(clang::options::OPT_fdisable_integer_16))
- opts.disabledIntegerKinds.push_back(16);
+ opts.disabledIntegerKinds.push_back(Fortran::common::KindsEnum::Kind16);
if (const llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_mabi_EQ)) {
opts.abi = a->getValue();
@@ -1176,11 +1176,15 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
clang::options::OPT_fdefault_real_4)) {
const llvm::opt::Option &opt = arg->getOption();
if (opt.matches(clang::options::OPT_fdefault_real_8)) {
- res.getDefaultKinds().set_defaultRealKind(8);
- res.getDefaultKinds().set_doublePrecisionKind(16);
+ res.getDefaultKinds().set_defaultRealKind(
+ Fortran::common::KindsEnum::Kind8);
+ res.getDefaultKinds().set_doublePrecisionKind(
+ Fortran::common::KindsEnum::Kind16);
} else if (opt.matches(clang::options::OPT_fdefault_real_4)) {
- res.getDefaultKinds().set_defaultRealKind(4);
- res.getDefaultKinds().set_doublePrecisionKind(8);
+ res.getDefaultKinds().set_defaultRealKind(
+ Fortran::common::KindsEnum::Kind4);
+ res.getDefaultKinds().set_doublePrecisionKind(
+ Fortran::common::KindsEnum::Kind8);
}
}
if (const llvm::opt::Arg *arg =
@@ -1188,17 +1192,25 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
clang::options::OPT_fdefault_integer_4)) {
const llvm::opt::Option &opt = arg->getOption();
if (opt.matches(clang::options::OPT_fdefault_integer_8)) {
- res.getDefaultKinds().set_defaultIntegerKind(8);
- res.getDefaultKinds().set_subscriptIntegerKind(8);
- res.getDefaultKinds().set_sizeIntegerKind(8);
- res.getDefaultKinds().set_defaultLogicalKind(8);
+ res.getDefaultKinds().set_defaultIntegerKind(
+ Fortran::common::KindsEnum::Kind8);
+ res.getDefaultKinds().set_subscriptIntegerKind(
+ Fortran::common::KindsEnum::Kind8);
+ res.getDefaultKinds().set_sizeIntegerKind(
+ Fortran::common::KindsEnum::Kind8);
+ res.getDefaultKinds().set_defaultLogicalKind(
+ Fortran::common::KindsEnum::Kind8);
} else if (opt.matches(clang::options::OPT_fdefault_integer_4)) {
// Note that the subscript integer kind is set to 8 here. If a
// default-integer-kind is not provided, it is also set to 8.
- res.getDefaultKinds().set_defaultIntegerKind(4);
- res.getDefaultKinds().set_subscriptIntegerKind(8);
- res.getDefaultKinds().set_sizeIntegerKind(4);
- res.getDefaultKinds().set_defaultLogicalKind(4);
+ res.getDefaultKinds().set_defaultIntegerKind(
+ Fortran::common::KindsEnum::Kind4);
+ res.getDefaultKinds().set_subscriptIntegerKind(
+ Fortran::common::KindsEnum::Kind8);
+ res.getDefaultKinds().set_sizeIntegerKind(
+ Fortran::common::KindsEnum::Kind4);
+ res.getDefaultKinds().set_defaultLogicalKind(
+ Fortran::common::KindsEnum::Kind4);
}
}
if (args.hasArg(clang::options::OPT_fdefault_double_8)) {
@@ -1211,10 +1223,12 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
diags.Report(diagID);
}
// https://gcc.gnu.org/onlinedocs/gfortran/Fortran-Dialect-Options.html
- res.getDefaultKinds().set_doublePrecisionKind(8);
+ res.getDefaultKinds().set_doublePrecisionKind(
+ Fortran::common::KindsEnum::Kind8);
}
if (args.hasArg(clang::options::OPT_flarge_sizes))
- res.getDefaultKinds().set_sizeIntegerKind(8);
+ res.getDefaultKinds().set_sizeIntegerKind(
+ Fortran::common::KindsEnum::Kind8);
// -x cuda
auto language = args.getLastArgValue(clang::options::OPT_x);
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 4759ad9b6fb3c..1ef864fc8a52d 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -875,7 +875,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
mlir::Type genType(Fortran::common::TypeCategory tc) override final {
return Fortran::lower::getFIRType(
- &getMLIRContext(), tc, bridge.getDefaultKinds().GetDefaultKind(tc), {});
+ &getMLIRContext(), tc,
+ static_cast<int>(bridge.getDefaultKinds().GetDefaultKind(tc)), {});
}
Fortran::lower::TypeConstructionStack &
diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp
index 4d1f8c29dc9f7..25c5bfb035ad4 100644
--- a/flang/lib/Lower/CallInterface.cpp
+++ b/flang/lib/Lower/CallInterface.cpp
@@ -1066,8 +1066,8 @@ class Fortran::lower::CallInterfaceImpl {
} else {
// All result other than characters/derived are simply returned by value
// in implicit interfaces
- mlir::Type mlirType =
- getConverter().genType(dynamicType.category(), dynamicType.kind());
+ mlir::Type mlirType = getConverter().genType(
+ dynamicType.category(), static_cast<int>(dynamicType.kind()));
addFirResult(mlirType, FirPlaceHolder::resultEntityPosition,
Property::Value);
}
@@ -1081,9 +1081,10 @@ class Fortran::lower::CallInterfaceImpl {
std::optional<std::int64_t> constantLen = type.knownLength();
fir::CharacterType::LenType len =
constantLen ? *constantLen : fir::CharacterType::unknownLen();
- mlir::Type charRefTy = fir::ReferenceType::get(
- fir::CharacterType::get(&mlirContext, type.kind(), len));
- mlir::Type boxCharTy = fir::BoxCharType::get(&mlirContext, type.kind());
+ mlir::Type charRefTy = fir::ReferenceType::get(fir::CharacterType::get(
+ &mlirContext, static_cast<int>(type.kind()), len));
+ mlir::Type boxCharTy =
+ fir::BoxCharType::get(&mlirContext, static_cast<int>(type.kind()));
addFirOperand(charRefTy, resultPosition, Property::CharAddress);
addFirOperand(lenTy, resultPosition, Property::CharLength);
/// For now, also return it by boxchar
@@ -1145,8 +1146,8 @@ class Fortran::lower::CallInterfaceImpl {
}
}
if (dynamicType.category() == Fortran::common::TypeCategory::Character) {
- mlir::Type boxCharTy =
- fir::BoxCharType::get(&mlirContext, dynamicType.kind());
+ mlir::Type boxCharTy = fir::BoxCharType::get(
+ &mlirContext, static_cast<int>(dynamicType.kind()));
addFirOperand(boxCharTy, nextPassedArgPosition(), Property::BoxChar,
dummyNameAttr(entity));
addPassedArg(PassEntityBy::BoxChar, entity, characteristics);
@@ -1179,9 +1180,10 @@ class Fortran::lower::CallInterfaceImpl {
if (cat == Fortran::common::TypeCategory::Character)
if (std::optional<std::int64_t> constantLen =
toInt64(dynamicType.GetCharLength()))
- return getConverter().genType(cat, dynamicType.kind(), {*constantLen});
+ return getConverter().genType(cat, static_cast<int>(dynamicType.kind()),
+ {*constantLen});
// INTEGER, REAL, LOGICAL, COMPLEX, and CHARACTER with dynamic length.
- return getConverter().genType(cat, dynamicType.kind());
+ return getConverter().genType(cat, static_cast<int>(dynamicType.kind()));
}
void handleExplicitDummy(
@@ -1259,14 +1261,14 @@ class Fortran::lower::CallInterfaceImpl {
Fortran::common::TypeCategory::Character) {
if (isValueAttr && isBindC) {
// Pass as fir.char<1>
- mlir::Type charTy =
- fir::CharacterType::getSingleton(&mlirContext, dynamicType.kind());
+ mlir::Type charTy = fir::CharacterType::getSingleton(
+ &mlirContext, static_cast<int>(dynamicType.kind()));
addFirOperand(charTy, nextPassedArgPosition(), Property::Value, attrs);
addPassedArg(PassEntityBy::Value, entity, characteristics);
} else {
// Pass as fir.box_char
- mlir::Type boxCharTy =
- fir::BoxCharType::get(&mlirContext, dynamicType.kind());
+ mlir::Type boxCharTy = fir::BoxCharType::get(
+ &mlirContext, static_cast<int>(dynamicType.kind()));
addFirOperand(boxCharTy, nextPassedArgPosition(), Property::BoxChar,
attrs);
addPassedArg(isValueAttr ? PassEntityBy::CharBoxValueAttribute
diff --git a/flang/lib/Lower/ConvertArrayConstructor.cpp b/flang/lib/Lower/ConvertArrayConstructor.cpp
index a76527b4e7454..c840355fc1783 100644
--- a/flang/lib/Lower/ConvertArrayConstructor.cpp
+++ b/flang/lib/Lower/ConvertArrayConstructor.cpp
@@ -508,7 +508,7 @@ struct LengthAndTypeCollector {
const Fortran::evaluate::ArrayConstructor<T> &arrayCtorExpr,
Fortran::lower::SymMap &, Fortran::lower::StatementContext &,
mlir::SmallVectorImpl<mlir::Value> &) {
- const int kind{arrayCtorExpr.kind()};
+ const int kind{static_cast<int>(arrayCtorExpr.kind())};
// Numerical and Logical types.
return Fortran::lower::getFIRType(&converter.getMLIRContext(), T::category,
kind,
@@ -541,7 +541,7 @@ struct LengthAndTypeCollector<Character> {
Fortran::lower::SymMap &symMap,
Fortran::lower::StatementContext &stmtCtx,
mlir::SmallVectorImpl<mlir::Value> &lengths) {
- const int kind{arrayCtorExpr.kind()};
+ const int kind{static_cast<int>(arrayCtorExpr.kind())};
llvm::SmallVector<Fortran::lower::LenParameterTy> typeLengths;
if (const Fortran::evaluate::ExtentExpr *lenExpr = arrayCtorExpr.LEN()) {
lengths.push_back(
diff --git a/flang/lib/Lower/ConvertConstant.cpp b/flang/lib/Lower/ConvertConstant.cpp
index 31f706803de3e..49faf2460d443 100644
--- a/flang/lib/Lower/ConvertConstant.cpp
+++ b/flang/lib/Lower/ConvertConstant.cpp
@@ -54,7 +54,7 @@ static mlir::Attribute convertToAttribute(
fir::FirOpBuilder &builder,
const Fortran::evaluate::Scalar<Fortran::evaluate::Type<TC>> &value,
mlir::Type type) {
- const int kind{value.kind()};
+ const int kind{static_cast<int>(value.kind())};
if constexpr (TC == Fortran::common::TypeCategory::Integer) {
if (kind <= 8)
return builder.getIntegerAttr(type, value.ToInt64());
@@ -154,7 +154,7 @@ class DenseGlobalBuilder {
static_assert(TC != Fortran::common::TypeCategory::Character,
"must be numerical or logical");
- const int kind = constant.kind();
+ const int kind = static_cast<int>(constant.kind());
auto attrTc = TC == Fortran::common::TypeCategory::Logical
? Fortran::common::TypeCategory::Integer
: TC;
@@ -253,7 +253,7 @@ template <Fortran::common::TypeCategory TC>
static mlir::Value genScalarLit(
fir::FirOpBuilder &builder, mlir::Location loc,
const Fortran::evaluate::Scalar<Fortran::evaluate::Type<TC>> &value) {
- int kind = value.kind();
+ int kind = static_cast<int>(value.kind());
if constexpr (TC == Fortran::common::TypeCategory::Integer ||
TC == Fortran::common::TypeCategory::Unsigned) {
// MLIR requires constants to be signless
@@ -325,15 +325,15 @@ createStringLitOp(fir::FirOpBuilder &builder, mlir::Location loc,
const Fortran::evaluate::Scalar<Fortran::evaluate::Type<
Fortran::common::TypeCategory::Character>> &value,
[[maybe_unused]] int64_t len) {
- int kind = value.kind();
- if (kind == 1) {
+ Fortran::common::KindsEnum kind = value.kind();
+ if (kind == Fortran::common::KindsEnum::Kind1) {
assert(value.size() == static_cast<std::uint64_t>(len));
return builder.createStringLitOp(loc, *value.AsStringRef());
} else {
return value.withStdString([&](const auto &value) -> fir::StringLitOp {
using ET = typename std::decay_t<decltype(value)>::value_type;
- fir::CharacterType type =
- fir::CharacterType::get(builder.getContext(), kind, len);
+ fir::CharacterType type = fir::CharacterType::get(
+ builder.getContext(), static_cast<int>(kind), len);
mlir::MLIRContext *context = builder.getContext();
std::int64_t size = static_cast<std::int64_t>(value.size());
mlir::ShapedType shape = mlir::RankedTensorType::get(
@@ -359,7 +359,7 @@ genScalarLit(fir::FirOpBuilder &builder, mlir::Location loc,
const Fortran::evaluate::Scalar<Fortran::evaluate::Type<
Fortran::common::TypeCategory::Character>> &value,
int64_t len, bool outlineInReadOnlyMemory) {
- int kind = value.kind();
+ int kind = static_cast<int>(value.kind());
// When in an initializer context, construct the literal op itself and do
// not construct another constant object in rodata.
if (!outlineInReadOnlyMemory)
@@ -751,7 +751,7 @@ static fir::ExtendedValue
genArrayLit(Fortran::lower::AbstractConverter &converter, mlir::Location loc,
const Fortran::evaluate::Constant<T> &con,
bool outlineInReadOnlyMemory) {
- const int kind{con.kind()};
+ const int kind{static_cast<int>(con.kind())};
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
Fortran::evaluate::ConstantSubscript size =
Fortran::evaluate::GetSize(con.shape());
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index fd46a4b721563..9797ac35a220f 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -1198,7 +1198,7 @@ struct BinaryOp<Fortran::evaluate::Divide<
fir::FirOpBuilder &builder,
const Op &op, hlfir::Entity lhs,
hlfir::Entity rhs) {
- const int kind = op.kind();
+ const int kind = static_cast<int>(op.kind());
mlir::Type ty = Fortran::lower::getFIRType(
builder.getContext(), Fortran::common::TypeCategory::Complex, kind,
/*params=*/{});
@@ -1223,7 +1223,7 @@ struct BinaryOp<Fortran::evaluate::Power<Fortran::evaluate::Type<TC>>> {
fir::FirOpBuilder &builder,
const Op &op, hlfir::Entity lhs,
hlfir::Entity rhs) {
- const int kind = op.kind();
+ const int kind = static_cast<int>(op.kind());
mlir::Type ty = Fortran::lower::getFIRType(builder.getContext(), TC, kind,
/*params=*/{});
return hlfir::EntityWithAttributes{fir::genPow(builder, loc, ty, lhs, rhs)};
@@ -1238,7 +1238,7 @@ struct BinaryOp<
fir::FirOpBuilder &builder,
const Op &op, hlfir::Entity lhs,
hlfir::Entity rhs) {
- const int kind = op.kind();
+ const int kind = static_cast<int>(op.kind());
mlir::Type ty = Fortran::lower::getFIRType(builder.getContext(), TC, kind,
/*params=*/{});
return hlfir::EntityWithAttributes{fir::genPow(builder, loc, ty, lhs, rhs)};
@@ -1327,7 +1327,7 @@ struct BinaryOp<Fortran::evaluate::Relational<
fir::FirOpBuilder &builder,
const Op &op, hlfir::Entity lhs,
hlfir::Entity rhs) {
- int bits = 8 * op.left().GetType().value().kind();
+ int bits = 8 * static_cast<int>(op.left().GetType().value().kind());
auto signlessType = mlir::IntegerType::get(
builder.getContext(), bits,
mlir::IntegerType::SignednessSemantics::Signless);
@@ -1535,7 +1535,7 @@ struct UnaryOp<Fortran::evaluate::Negate<
static hlfir::EntityWithAttributes gen(mlir::Location loc,
fir::FirOpBuilder &builder,
const Op &op, hlfir::Entity lhs) {
- const int kind = op.kind();
+ const int kind = static_cast<int>(op.kind());
// Like LLVM, integer negation is the binary op "0 - value"
mlir::Type type = Fortran::lower::getFIRType(
builder.getContext(), Fortran::common::TypeCategory::Integer, kind,
@@ -1554,9 +1554,9 @@ struct UnaryOp<Fortran::evaluate::Negate<
static hlfir::EntityWithAttributes gen(mlir::Location loc,
fir::FirOpBuilder &builder,
const Op &op, hlfir::Entity lhs) {
- const int kind = op.kind();
- int bits = Fortran::evaluate::Type<
- Fortran::common::TypeCategory::Integer>::Scalar::bits(kind);
+ const int kind = static_cast<int>(op.kind());
+ int bits = Fortran::evaluate::Type<Fortran::common::TypeCategory::Integer>::
+ Scalar::bits(static_cast<Fortran::common::KindsEnum>(kind));
mlir::Type signlessType = mlir::IntegerType::get(
builder.getContext(), bits,
mlir::IntegerType::SignednessSemantics::Signless);
@@ -1633,7 +1633,7 @@ struct UnaryOp<Fortran::evaluate::Convert<Fortran::evaluate::Type<TC1>, TC2>> {
static hlfir::EntityWithAttributes gen(mlir::Location loc,
fir::FirOpBuilder &builder,
const Op &op, hlfir::Entity lhs) {
- int kind = op.kind();
+ int kind = static_cast<int>(op.kind());
if constexpr (TC1 == Fortran::common::TypeCategory::Character &&
TC2 == TC1) {
return hlfir::convertCharacterKind(loc, builder, lhs, kind);
@@ -1765,7 +1765,7 @@ class HlfirBuilder {
template <typename D, typename R, typename O>
hlfir::EntityWithAttributes
gen(const Fortran::evaluate::Operation<D, R, O> &op) {
- const int rKind = op.kind();
+ const int rKind = static_cast<int>(op.kind());
auto &builder = getBuilder();
mlir::Location loc = getLoc();
const int rank = op.Rank();
@@ -1811,7 +1811,7 @@ class HlfirBuilder {
template <typename D, typename R, typename LO, typename RO>
hlfir::EntityWithAttributes
gen(const Fortran::evaluate::Operation<D, R, LO, RO> &op) {
- const int rKind = op.kind();
+ const int rKind = static_cast<int>(op.kind());
auto &builder = getBuilder();
mlir::Location loc = getLoc();
const int rank = op.Rank();
@@ -1910,7 +1910,8 @@ class HlfirBuilder {
getStmtCtx())
.genNamedEntity(desc.base());
using ResTy = Fortran::evaluate::DescriptorInquiry::Result;
- const int resKind = Fortran::evaluate::DescriptorInquiry::kind();
+ const int resKind =
+ static_cast<int>(Fortran::evaluate::DescriptorInquiry::kind());
mlir::Type resultType = getConverter().genType(ResTy::category, resKind);
auto castResult = [&](mlir::Value v) {
return hlfir::EntityWithAttributes{
diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index a2c10f0bd821f..0f1fac1a84574 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -34,7 +34,8 @@ using Fortran::common::VectorElementCategory;
static mlir::Type genRealType(mlir::MLIRContext *context, int kind) {
if (Fortran::common::IsValidKindOfIntrinsicType(
- Fortran::common::TypeCategory::Real, kind)) {
+ Fortran::common::TypeCategory::Real,
+ static_cast<Fortran::common::KindsEnum>(kind))) {
switch (kind) {
case 2:
return mlir::Float16Type::get(context);
@@ -54,13 +55,14 @@ static mlir::Type genRealType(mlir::MLIRContext *context, int kind) {
}
static int getIntegerBits(int kind) {
- return Fortran::evaluate::Type<
- Fortran::common::TypeCategory::Integer>::Scalar::bits(kind);
+ return Fortran::evaluate::Type<Fortran::common::TypeCategory::Integer>::
+ Scalar::bits(static_cast<Fortran::common::KindsEnum>(kind));
}
static mlir::Type genIntegerType(mlir::MLIRContext *context, int kind,
bool isUnsigned = false) {
if (Fortran::common::IsValidKindOfIntrinsicType(
- Fortran::common::TypeCategory::Integer, kind)) {
+ Fortran::common::TypeCategory::Integer,
+ static_cast<Fortran::common::KindsEnum>(kind))) {
mlir::IntegerType::SignednessSemantics signedness =
(isUnsigned ? mlir::IntegerType::SignednessSemantics::Unsigned
: mlir::IntegerType::SignednessSemantics::Signless);
@@ -72,7 +74,8 @@ static mlir::Type genIntegerType(mlir::MLIRContext *context, int kind,
static mlir::Type genLogicalType(mlir::MLIRContext *context, int KIND) {
if (Fortran::common::IsValidKindOfIntrinsicType(
- Fortran::common::TypeCategory::Logical, KIND))
+ Fortran::common::TypeCategory::Logical,
+ static_cast<Fortran::common::KindsEnum>(KIND)))
return fir::LogicalType::get(context, KIND);
return {};
}
@@ -81,7 +84,8 @@ static mlir::Type genCharacterType(
mlir::MLIRContext *context, int KIND,
Fortran::lower::LenParameterTy len = fir::CharacterType::unknownLen()) {
if (Fortran::common::IsValidKindOfIntrinsicType(
- Fortran::common::TypeCategory::Character, KIND))
+ Fortran::common::TypeCategory::Character,
+ static_cast<Fortran::common::KindsEnum>(KIND)))
return fir::CharacterType::get(context, KIND, len);
return {};
}
@@ -152,7 +156,8 @@ struct TypeBuilderImpl {
// INTEGER, UNSIGNED, REAL, COMPLEX, CHARACTER, LOGICAL
llvm::SmallVector<Fortran::lower::LenParameterTy> params;
translateLenParameters(params, category, expr);
- baseType = genFIRType(context, category, dynamicType->kind(), params);
+ baseType = genFIRType(context, category,
+ static_cast<int>(dynamicType->kind()), params);
}
std::optional<Fortran::evaluate::Shape> shapeExpr =
Fortran::evaluate::GetShape(converter.getFoldingContext(), expr);
@@ -487,8 +492,8 @@ struct TypeBuilderImpl {
Fortran::evaluate::Type<Fortran::common::TypeCategory::Character>;
auto designator = Fortran::evaluate::Fold(
converter.getFoldingContext(),
- Fortran::evaluate::Expr<TC>{
- Fortran::evaluate::Designator<TC>{kind, symbol}});
+ Fortran::evaluate::Expr<TC>{Fortran::evaluate::Designator<TC>{
+ static_cast<Fortran::common::KindsEnum>(kind), symbol}});
if (auto len = toInt64(designator.LEN()))
return *len;
return fir::SequenceType::getUnknownExtent();
diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index 490db8cc1d1ba..f3222b42472c3 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -1116,7 +1116,7 @@ lowerStringLit(Fortran::lower::AbstractConverter &converter, mlir::Location loc,
auto [buff, len] = genBuffer(converter, loc, *expr, strTy, lenTy, stmtCtx);
mlir::Value kind;
if (ty2) {
- auto kindVal = expr->GetType().value().kind();
+ auto kindVal = static_cast<std::int64_t>(expr->GetType().value().kind());
kind = mlir::arith::ConstantOp::create(
builder, loc, builder.getIntegerAttr(ty2, kindVal));
}
@@ -1954,8 +1954,9 @@ genNewunitSpec(Fortran::lower::AbstractConverter &converter, mlir::Location loc,
mlir::Value addr = builder.createConvert(
loc, ioFuncTy.getInput(1),
fir::getBase(converter.genExprAddr(loc, var, stmtCtx)));
- auto kind = builder.createIntegerConstant(loc, ioFuncTy.getInput(2),
- var->GetType().value().kind());
+ auto kind = builder.createIntegerConstant(
+ loc, ioFuncTy.getInput(2),
+ static_cast<std::int64_t>(var->GetType().value().kind()));
llvm::SmallVector<mlir::Value> ioArgs = {cookie, addr, kind};
return fir::CallOp::create(builder, loc, ioFunc, ioArgs).getResult(0);
}
diff --git a/flang/lib/Lower/OpenMP/Atomic.cpp b/flang/lib/Lower/OpenMP/Atomic.cpp
index c2ac17c21c34d..0d876e66abdcd 100644
--- a/flang/lib/Lower/OpenMP/Atomic.cpp
+++ b/flang/lib/Lower/OpenMP/Atomic.cpp
@@ -678,7 +678,6 @@ void Fortran::lower::omp::lowerAtomic(
*cond)) {
common::visit(
[&](const auto &kindLogical) {
- using LogicalExpr = std::decay_t<decltype(kindLogical)>;
if (const auto *logOp =
std::get_if<evaluate::LogicalOperation>(&kindLogical.u)) {
if (logOp->logicalOperator == common::LogicalOperator::Eqv ||
diff --git a/flang/lib/Lower/Support/Utils.cpp b/flang/lib/Lower/Support/Utils.cpp
index b54bb9b3886dd..c5277c0eda08a 100644
--- a/flang/lib/Lower/Support/Utils.cpp
+++ b/flang/lib/Lower/Support/Utils.cpp
@@ -101,12 +101,12 @@ class HashEvaluateExpr {
Fortran::common::TypeCategory TC2>
static unsigned getHashValue(
const Fortran::evaluate::Convert<Fortran::evaluate::Type<TC1>, TC2> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return getHashValue(x.left()) - (static_cast<unsigned>(TC1) + 2u) -
(static_cast<unsigned>(kind) + 5u);
}
static unsigned getHashValue(const Fortran::evaluate::ComplexComponent &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return getHashValue(x.left()) -
(static_cast<unsigned>(x.isImaginaryPart) + 1u) * 3u +
static_cast<unsigned>(kind);
@@ -118,49 +118,49 @@ class HashEvaluateExpr {
template <Fortran::common::TypeCategory TC>
static unsigned getHashValue(
const Fortran::evaluate::Negate<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return getHashValue(x.left()) - (static_cast<unsigned>(TC) + 5u) -
(static_cast<unsigned>(kind) + 7u);
}
template <Fortran::common::TypeCategory TC>
static unsigned
getHashValue(const Fortran::evaluate::Add<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) + getHashValue(x.right())) * 23u +
static_cast<unsigned>(TC) + static_cast<unsigned>(kind);
}
template <Fortran::common::TypeCategory TC>
static unsigned getHashValue(
const Fortran::evaluate::Subtract<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) - getHashValue(x.right())) * 19u +
static_cast<unsigned>(TC) + static_cast<unsigned>(kind);
}
template <Fortran::common::TypeCategory TC>
static unsigned getHashValue(
const Fortran::evaluate::Multiply<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) + getHashValue(x.right())) * 29u +
static_cast<unsigned>(TC) + static_cast<unsigned>(kind);
}
template <Fortran::common::TypeCategory TC>
static unsigned getHashValue(
const Fortran::evaluate::Divide<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) - getHashValue(x.right())) * 31u +
static_cast<unsigned>(TC) + static_cast<unsigned>(kind);
}
template <Fortran::common::TypeCategory TC>
static unsigned
getHashValue(const Fortran::evaluate::Power<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) - getHashValue(x.right())) * 37u +
static_cast<unsigned>(TC) + static_cast<unsigned>(kind);
}
template <Fortran::common::TypeCategory TC>
static unsigned getHashValue(
const Fortran::evaluate::Extremum<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) + getHashValue(x.right())) * 41u +
static_cast<unsigned>(TC) + static_cast<unsigned>(kind) +
static_cast<unsigned>(x.ordering) * 7u;
@@ -173,22 +173,22 @@ class HashEvaluateExpr {
template <Fortran::common::TypeCategory TC>
static unsigned getHashValue(
const Fortran::evaluate::RealToIntPower<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) - getHashValue(x.right())) * 43u +
static_cast<unsigned>(TC) + static_cast<unsigned>(kind);
}
static unsigned getHashValue(const Fortran::evaluate::ComplexConstructor &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) - getHashValue(x.right())) * 47u +
static_cast<unsigned>(kind);
}
static unsigned getHashValue(const Fortran::evaluate::Concat &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) - getHashValue(x.right())) * 53u +
static_cast<unsigned>(kind);
}
static unsigned getHashValue(const Fortran::evaluate::SetLength &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) - getHashValue(x.right())) * 59u +
static_cast<unsigned>(kind);
}
@@ -267,7 +267,7 @@ class HashEvaluateExpr {
template <Fortran::common::TypeCategory TC>
static unsigned getHashValue(
const Fortran::evaluate::Relational<Fortran::evaluate::Type<TC>> &x) {
- const int kind{x.kind()};
+ const Fortran::common::KindsEnum kind{x.kind()};
return (getHashValue(x.left()) + getHashValue(x.right())) * 71u +
static_cast<unsigned>(TC) + static_cast<unsigned>(kind) +
static_cast<unsigned>(x.opr) * 11u;
diff --git a/flang/lib/Semantics/check-allocate.cpp b/flang/lib/Semantics/check-allocate.cpp
index 2ac242abd5788..2532106498744 100644
--- a/flang/lib/Semantics/check-allocate.cpp
+++ b/flang/lib/Semantics/check-allocate.cpp
@@ -422,7 +422,9 @@ static bool HaveCompatibleTypeParameters(
return true;
}
if (const IntrinsicTypeSpec * intrinsicType1{type1.AsIntrinsic()}) {
- return evaluate::ToInt64(intrinsicType1->kind()).value() == type2.kind();
+ return static_cast<KindsEnum>(
+ evaluate::ToInt64(intrinsicType1->kind()).value()) ==
+ type2.kind();
} else if (type2.IsUnlimitedPolymorphic()) {
return false;
} else if (const DerivedTypeSpec * derivedType1{type1.AsDerived()}) {
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 7f9095159183a..2e3cad90ddc80 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -199,15 +199,16 @@ static void CheckCharacterActual(evaluate::Expr<evaluate::SomeType> &actual,
.value_or(false)) {
// If substring, take rest of substring
if (*actualLength > 0) {
- actualChars -=
- (actualOffset->offset() / actualType.type().kind()) %
+ actualChars -= (actualOffset->offset() /
+ static_cast<std::int64_t>(
+ actualType.type().kind())) %
*actualLength;
}
} else {
actualChars = (static_cast<std::int64_t>(
actualOffset->symbol().size()) -
actualOffset->offset()) /
- actualType.type().kind();
+ static_cast<std::int64_t>(actualType.type().kind());
}
if (actualChars < dummyChars) {
if (extentErrors) {
@@ -303,12 +304,14 @@ static void ConvertIntegerActual(evaluate::Expr<evaluate::SomeType> &actual,
common::LanguageFeature::ActualIntegerConvertedToSmallerKind)) {
messages.Say(
"Actual argument scalar expression of type INTEGER(%d) cannot be implicitly converted to smaller dummy argument type INTEGER(%d)"_err_en_US,
- actualType.type().kind(), dummyType.type().kind());
+ static_cast<int>(actualType.type().kind()),
+ static_cast<int>(dummyType.type().kind()));
} else {
semanticsContext.Warn(messages,
common::LanguageFeature::ActualIntegerConvertedToSmallerKind,
"Actual argument scalar expression of type INTEGER(%d) was converted to smaller dummy argument type INTEGER(%d)"_port_en_US,
- actualType.type().kind(), dummyType.type().kind());
+ static_cast<int>(actualType.type().kind()),
+ static_cast<int>(dummyType.type().kind()));
}
}
actualType = dummyType;
@@ -633,7 +636,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
bool actualIsArrayElement{IsArrayElement(actual) != nullptr};
bool actualIsCKindCharacter{
actualType.type().category() == TypeCategory::Character &&
- actualType.type().kind() == 1};
+ actualType.type().kind() == KindsEnum::Kind1};
if (!actualIsCKindCharacter) {
if (!actualIsArrayElement && !dummyIsAssumedRank &&
!dummy.ignoreTKR.test(common::IgnoreTKR::Rank)) {
@@ -2075,19 +2078,20 @@ static void CheckEvent_Query(evaluate::ActualArguments &arguments,
}
if (arguments.size() > 1 && arguments[1]) {
if (auto dyType{arguments[1]->GetType()}) {
- int defaultInt{
+ KindsEnum defaultInt{
foldingContext.defaults().GetDefaultKind(TypeCategory::Integer)};
if (dyType->category() == TypeCategory::Integer &&
dyType->kind() < defaultInt) {
foldingContext.messages().Say(arguments[1]->sourceLocation(),
"COUNT= argument to EVENT_QUERY must be an integer with kind >= %d"_err_en_US,
- defaultInt);
+ static_cast<int>(defaultInt));
}
}
}
if (arguments.size() > 2 && arguments[2]) {
if (auto dyType{arguments[2]->GetType()}) {
- if (dyType->category() == TypeCategory::Integer && dyType->kind() < 2) {
+ if (dyType->category() == TypeCategory::Integer &&
+ dyType->kind() < KindsEnum::Kind2) {
foldingContext.messages().Say(arguments[2]->sourceLocation(),
"STAT= argument to EVENT_QUERY must be an integer with kind >= 2 when present"_err_en_US);
}
diff --git a/flang/lib/Semantics/check-case.cpp b/flang/lib/Semantics/check-case.cpp
index 38eab344ed48f..4f358ce5ba677 100644
--- a/flang/lib/Semantics/check-case.cpp
+++ b/flang/lib/Semantics/check-case.cpp
@@ -22,7 +22,8 @@ namespace Fortran::semantics {
template <typename T> class CaseValues {
public:
- CaseValues(int kind, SemanticsContext &c, const evaluate::DynamicType &t)
+ CaseValues(
+ KindsEnum kind, SemanticsContext &c, const evaluate::DynamicType &t)
: kind_{kind}, context_{c}, caseExprType_{t} {}
void Check(const std::list<parser::CaseConstruct::Case> &cases) {
@@ -87,7 +88,8 @@ template <typename T> class CaseValues {
auto folded{evaluate::Fold(foldingContext, SomeExpr{*x->v})};
if (auto converted{evaluate::Fold(foldingContext,
evaluate::ConvertToType(
- {T::category, kind_}, SomeExpr{folded}))}) {
+ evaluate::DynamicType{T::category, kind_},
+ SomeExpr{folded}))}) {
if (auto value{evaluate::GetScalarConstantValue<T>(*converted)}) {
auto back{evaluate::Fold(foldingContext,
evaluate::ConvertToType(*type, SomeExpr{*converted}))};
@@ -144,7 +146,7 @@ template <typename T> class CaseValues {
}
struct Case {
- explicit Case(int kind, const parser::Statement<parser::CaseStmt> &s)
+ explicit Case(KindsEnum kind, const parser::Statement<parser::CaseStmt> &s)
: kind_{kind}, stmt{s} {}
bool IsDefault() const { return !lower && !upper; }
std::string AsFortran() const {
@@ -168,7 +170,7 @@ template <typename T> class CaseValues {
return result;
}
- int kind_;
+ KindsEnum kind_;
const parser::Statement<parser::CaseStmt> &stmt;
std::optional<Value> lower, upper;
};
@@ -218,7 +220,7 @@ template <typename T> class CaseValues {
}
}
- int kind_;
+ KindsEnum kind_;
SemanticsContext &context_;
const evaluate::DynamicType &caseExprType_;
std::list<Case> cases_;
@@ -228,7 +230,7 @@ template <typename T> class CaseValues {
template <TypeCategory CAT> struct TypeVisitor {
using Result = bool;
using Types = evaluate::CategoryTypes<CAT>;
- template <typename T> Result Test(int kind) {
+ template <typename T> Result Test(KindsEnum kind) {
if (kind == exprType.kind()) {
CaseValues<T>(kind, context, exprType).Check(caseList);
return true;
@@ -353,7 +355,8 @@ void CaseChecker::Enter(const parser::CaseConstruct &construct) {
TypeVisitor<TypeCategory::Unsigned>{context_, *exprType, caseList});
return;
case TypeCategory::Logical:
- CaseValues<evaluate::Type<TypeCategory::Logical>>{1, context_, *exprType}
+ CaseValues<evaluate::Type<TypeCategory::Logical>>{
+ KindsEnum::Kind1, context_, *exprType}
.Check(caseList);
return;
case TypeCategory::Character:
@@ -364,9 +367,10 @@ void CaseChecker::Enter(const parser::CaseConstruct &construct) {
if (const auto *derived{evaluate::GetDerivedTypeSpec(*exprType)}) {
if (derived->IsEnumerationType()) {
if (ConvertEnumCaseValues(context_, caseList, *derived)) {
- evaluate::DynamicType intType{TypeCategory::Integer, 4};
+ evaluate::DynamicType intType{
+ TypeCategory::Integer, KindsEnum::Kind4};
CaseValues<evaluate::Type<TypeCategory::Integer>>{
- 4, context_, intType}
+ KindsEnum::Kind4, context_, intType}
.Check(caseList);
}
return;
diff --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp
index 8adf758e319af..bc503ea85fc83 100644
--- a/flang/lib/Semantics/check-data.cpp
+++ b/flang/lib/Semantics/check-data.cpp
@@ -25,7 +25,7 @@ namespace Fortran::semantics {
void DataChecker::Enter(const parser::DataImpliedDo &x) {
const auto &name{parser::UnwrapRef<parser::Name>(
std::get<parser::DataImpliedDo::Bounds>(x.t).Name())};
- int kind{evaluate::ResultKind<evaluate::ImpliedDoIndex>};
+ KindsEnum kind{evaluate::ResultKind<evaluate::ImpliedDoIndex>};
if (const auto dynamicType{evaluate::DynamicType::From(DEREF(name.symbol))}) {
if (dynamicType->category() == TypeCategory::Integer) {
kind = dynamicType->kind();
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 07c6b88f0562a..a127a055542c4 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -1603,7 +1603,7 @@ bool CheckHelper::IsResultOkToDiffer(const FunctionResult &result) {
category == TypeCategory::Derived) {
return false;
}
- int kind{typeAndShape->type().kind()};
+ KindsEnum kind{typeAndShape->type().kind()};
return kind == context_.GetDefaultKind(category) ||
(category == TypeCategory::Real &&
kind == context_.doublePrecisionKind());
@@ -3295,7 +3295,7 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
component.name(),
"A LOGICAL component of an interoperable type should have the interoperable KIND=C_BOOL"_port_en_US);
} else if (type->category() == DeclTypeSpec::Character && dyType &&
- dyType->kind() == 1) {
+ dyType->kind() == KindsEnum::Kind1) {
context().Warn(msgs, common::UsageWarning::BindCCharLength,
component.name(),
"A CHARACTER component of an interoperable type should have length 1"_port_en_US);
@@ -3712,7 +3712,10 @@ void CheckHelper::CheckDioDummyIsDefaultInteger(
if (const DeclTypeSpec *type{arg.GetType()};
type && type->IsNumeric(TypeCategory::Integer)) {
if (const auto kind{evaluate::ToInt64(type->numericTypeSpec().kind())};
- kind && *kind == context_.GetDefaultKind(TypeCategory::Integer)) {
+ kind &&
+ *kind ==
+ static_cast<std::int64_t>(
+ context_.GetDefaultKind(TypeCategory::Integer))) {
return;
}
}
@@ -3799,8 +3802,9 @@ void CheckHelper::CheckDioAssumedLenCharacterArg(const Symbol &subp,
if (!IsAssumedLengthCharacter(*arg) ||
(!kind ||
*kind !=
- context_.defaultKinds().GetDefaultKind(
- TypeCategory::Character))) {
+ static_cast<std::int64_t>(
+ context_.defaultKinds().GetDefaultKind(
+ TypeCategory::Character)))) {
messages_.Say(arg->name(),
"Dummy argument '%s' of a defined input/output procedure must be assumed-length CHARACTER of default kind"_err_en_US,
arg->name());
diff --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp
index 5a5bee2b80e3c..e4dd309469bf1 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -71,20 +71,20 @@ void IoChecker::Enter(
FormatErrorReporter reporter{context_, reporterCharBlock};
auto reporterWrapper{[&](const auto &msg) { return reporter.Say(msg); }};
switch (context_.GetDefaultKind(TypeCategory::Character)) {
- case 1: {
+ case KindsEnum::Kind1: {
common::FormatValidator<char> validator{formatStart,
stmt.source.size() - (formatStart - stmt.source.begin()),
reporterWrapper};
validator.Check();
break;
}
- case 2: { // TODO: Get this to work.
+ case KindsEnum::Kind2: { // TODO: Get this to work.
common::FormatValidator<char16_t> validator{
/*???*/ nullptr, /*???*/ 0, reporterWrapper};
validator.Check();
break;
}
- case 4: { // TODO: Get this to work.
+ case KindsEnum::Kind4: { // TODO: Get this to work.
common::FormatValidator<char32_t> validator{
/*???*/ nullptr, /*???*/ 0, reporterWrapper};
validator.Check();
@@ -277,20 +277,20 @@ void IoChecker::Enter(const parser::Format &spec) {
auto reporterWrapper{
[&](const auto &msg) { return reporter.Say(msg); }};
switch (context_.GetDefaultKind(TypeCategory::Character)) {
- case 1: {
+ case KindsEnum::Kind1: {
common::FormatValidator<char> validator{constantFormat->c_str(),
constantFormat->length(), reporterWrapper, stmt_};
validator.Check();
break;
}
- case 2: {
+ case KindsEnum::Kind2: {
// TODO: Get this to work. (Maybe combine with earlier instance?)
common::FormatValidator<char16_t> validator{
/*???*/ nullptr, /*???*/ 0, reporterWrapper, stmt_};
validator.Check();
break;
}
- case 4: {
+ case KindsEnum::Kind4: {
// TODO: Get this to work. (Maybe combine with earlier instance?)
common::FormatValidator<char32_t> validator{
/*???*/ nullptr, /*???*/ 0, reporterWrapper, stmt_};
@@ -314,8 +314,8 @@ void IoChecker::Enter(const parser::IdVariable &spec) {
return;
}
CheckForDefinableVariable(spec, "ID");
- int kind{expr->GetType()->kind()};
- int defaultKind{context_.GetDefaultKind(TypeCategory::Integer)};
+ KindsEnum kind{expr->GetType()->kind()};
+ KindsEnum defaultKind{context_.GetDefaultKind(TypeCategory::Integer)};
if (kind < defaultKind) {
context_.Say(
"ID kind (%d) is smaller than default INTEGER kind (%d)"_err_en_US,
diff --git a/flang/lib/Semantics/check-omp-atomic.cpp b/flang/lib/Semantics/check-omp-atomic.cpp
index aa0ac59ac8bdf..eac84a685c8b6 100644
--- a/flang/lib/Semantics/check-omp-atomic.cpp
+++ b/flang/lib/Semantics/check-omp-atomic.cpp
@@ -202,7 +202,7 @@ struct ReassocRewriter : public evaluate::rewrite::Identity {
evaluate::Expr<T> Reconstruct(const S &op, evaluate::Expr<T> atom,
evaluate::Expr<T> op1, evaluate::Expr<T> op2) {
using TypeS = llvm::remove_cvref_t<decltype(op)>;
- const int KindS{op.kind()};
+ const auto KindS{op.kind()};
// This function has to be semantically correct for all possible types
// of S even though at runtime s will only be one of the matched types.
// Limit the construction to the operation types that we tried to match
@@ -211,7 +211,7 @@ struct ReassocRewriter : public evaluate::rewrite::Identity {
return evaluate::Expr<T>(TypeS(op));
} else if constexpr (is_logical_v<T>) {
CHECK(op1.kind() == op2.kind());
- const int K{op1.kind()};
+ const KindsEnum K{op1.kind()};
if constexpr (std::is_same_v<TypeS, evaluate::LogicalOperation>) {
CHECK(K == KindS);
// Logical operators take an extra argument in their constructor,
@@ -1739,7 +1739,7 @@ struct MinMaxRewriter : public evaluate::rewrite::Identity {
template <typename T>
evaluate::Expr<T> operator()(
evaluate::Expr<T> &&x, const evaluate::FunctionRef<T> &f) {
- const int kind{f.kind()};
+ const KindsEnum kind{f.kind()};
const evaluate::ProcedureDesignator &proc = f.proc();
if (!IsMinMax(proc) || f.arguments().size() <= 2) {
return Id::operator()(std::move(x), f);
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 8826ba617d397..7af3013883341 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -6518,7 +6518,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPInteropConstruct &x) {
// The interop-var must be a scalar integer of omp_interop_kind
// (c_intptr_t): the runtime uses its storage as a pointer-sized handle.
std::optional<evaluate::DynamicType> type{expr->GetType()};
- int interopKind{static_cast<int>(
+ KindsEnum interopKind{static_cast<KindsEnum>(
context_.targetCharacteristics().integerKindForPointer())};
if (!type || type->category() != evaluate::TypeCategory::Integer ||
type->kind() != interopKind) {
diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp
index f72bc844e89b6..8cdb05118c49f 100644
--- a/flang/lib/Semantics/compute-offsets.cpp
+++ b/flang/lib/Semantics/compute-offsets.cpp
@@ -381,7 +381,8 @@ std::size_t ComputeOffsetsHelper::ComputeOffset(
}
auto result{offset * GetSizeAndAlignment(object.symbol, false).size};
if (object.substringStart) {
- int kind{context_.defaultKinds().GetDefaultKind(TypeCategory::Character)};
+ int kind{static_cast<int>(
+ context_.defaultKinds().GetDefaultKind(TypeCategory::Character))};
if (const DeclTypeSpec * type{object.symbol.GetType()}) {
if (const IntrinsicTypeSpec * intrinsic{type->AsIntrinsic()}) {
kind = ToInt64(intrinsic->kind()).value_or(kind);
diff --git a/flang/lib/Semantics/data-to-inits.cpp b/flang/lib/Semantics/data-to-inits.cpp
index ad893735eae6c..952466ac040fd 100644
--- a/flang/lib/Semantics/data-to-inits.cpp
+++ b/flang/lib/Semantics/data-to-inits.cpp
@@ -207,7 +207,7 @@ bool DataInitializationCompiler<DSV>::Scan(const parser::DataImpliedDo &ido) {
auto foldedUpper{evaluate::Fold(context, SomeExpr{*upperExpr})};
auto upper{ToInt64(foldedUpper)};
if (lower && upper) {
- int kind{evaluate::ResultKind<evaluate::ImpliedDoIndex>};
+ KindsEnum kind{evaluate::ResultKind<evaluate::ImpliedDoIndex>};
if (const auto dynamicType{evaluate::DynamicType::From(*name.symbol)}) {
if (dynamicType->category() == TypeCategory::Integer) {
kind = dynamicType->kind();
@@ -824,12 +824,12 @@ static bool CombineEquivalencedInitialization(
std::size_t minElementBytes{
ComputeMinElementBytes(associated, foldingContext)};
if (!exprAnalyzer.GetFoldingContext().targetCharacteristics().IsTypeEnabled(
- TypeCategory::Integer, minElementBytes) ||
+ TypeCategory::Integer, static_cast<KindsEnum>(minElementBytes)) ||
(bytes % minElementBytes) != 0) {
minElementBytes = 1;
}
- const DeclTypeSpec &typeSpec{scope.MakeNumericType(
- TypeCategory::Integer, MakeKindExpr(minElementBytes))};
+ const DeclTypeSpec &typeSpec{scope.MakeNumericType(TypeCategory::Integer,
+ MakeKindExpr(static_cast<KindsEnum>(minElementBytes)))};
details.set_type(typeSpec);
ArraySpec arraySpec;
arraySpec.emplace_back(ShapeSpec::MakeExplicit(Bound{
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index d007d990514ca..df5b00f315a02 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -74,7 +74,7 @@ static std::optional<DynamicTypeWithLength> AnalyzeTypeSpec(
typeSpec->AsIntrinsic()}) {
TypeCategory category{intrinsic->category()};
if (auto optKind{ToInt64(intrinsic->kind())}) {
- int kind{static_cast<int>(*optKind)};
+ KindsEnum kind{static_cast<KindsEnum>(*optKind)};
if (category == TypeCategory::Character) {
const semantics::CharacterTypeSpec &cts{
typeSpec->characterTypeSpec()};
@@ -698,8 +698,8 @@ template <typename A> MaybeExpr AsMaybeExpr(std::optional<A> &&x) {
}
// Type kind parameter values for literal constants.
-int ExpressionAnalyzer::AnalyzeKindParam(
- const std::optional<parser::KindParam> &kindParam, int defaultKind) {
+KindsEnum ExpressionAnalyzer::AnalyzeKindParam(
+ const std::optional<parser::KindParam> &kindParam, KindsEnum defaultKind) {
if (!kindParam) {
return defaultKind;
}
@@ -709,7 +709,8 @@ int ExpressionAnalyzer::AnalyzeKindParam(
[&](const parser::Scalar<
parser::Integer<parser::Constant<parser::Name>>> &n) {
if (MaybeExpr ie{Analyze(n)}) {
- return ToInt64(*ie).value_or(defaultKind);
+ return ToInt64(*ie).value_or(
+ static_cast<std::int64_t>(defaultKind));
}
return static_cast<std::int64_t>(defaultKind);
},
@@ -718,9 +719,9 @@ int ExpressionAnalyzer::AnalyzeKindParam(
if (kind != static_cast<int>(kind)) {
Say("Unsupported type kind value (%jd)"_err_en_US,
static_cast<std::intmax_t>(kind));
- kind = defaultKind;
+ kind = static_cast<std::int64_t>(defaultKind);
}
- return static_cast<int>(kind);
+ return static_cast<KindsEnum>(kind);
}
// Common handling of parser::IntLiteralConstant, SignedIntLiteralConstant,
@@ -728,7 +729,7 @@ int ExpressionAnalyzer::AnalyzeKindParam(
template <typename TYPES, TypeCategory CAT> struct IntTypeVisitor {
using Result = MaybeExpr;
using Types = TYPES;
- template <typename T> Result Test(int testKind) {
+ template <typename T> Result Test(KindsEnum testKind) {
if (testKind >= kind) {
const char *p{digits.begin()};
using Int = typename T::Scalar;
@@ -776,7 +777,7 @@ template <typename TYPES, TypeCategory CAT> struct IntTypeVisitor {
}
ExpressionAnalyzer &analyzer;
parser::CharBlock digits;
- std::int64_t kind;
+ KindsEnum kind;
bool isDefaultKind;
bool isNegated;
};
@@ -786,7 +787,7 @@ MaybeExpr ExpressionAnalyzer::IntLiteralConstant(
const PARSED &x, bool isNegated) {
const auto &kindParam{std::get<std::optional<parser::KindParam>>(x.t)};
bool isDefaultKind{!kindParam};
- int kind{AnalyzeKindParam(kindParam, GetDefaultKind(CAT))};
+ KindsEnum kind{AnalyzeKindParam(kindParam, GetDefaultKind(CAT))};
const char *typeName{CAT == TypeCategory::Integer ? "INTEGER" : "UNSIGNED"};
if (CheckIntrinsicKind(CAT, kind)) {
auto digits{std::get<parser::CharBlock>(x.t)};
@@ -831,7 +832,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(
}
template <typename TYPE>
-Constant<TYPE> ReadRealLiteral(int kind, parser::CharBlock source,
+Constant<TYPE> ReadRealLiteral(KindsEnum kind, parser::CharBlock source,
FoldingContext &context, bool isDefaultKind) {
const char *p{source.begin()};
auto valWithFlags{Scalar<TYPE>::Read(
@@ -853,10 +854,10 @@ struct RealTypeVisitor {
using Types = RealTypes;
RealTypeVisitor(
- int k, parser::CharBlock lit, FoldingContext &ctx, bool isDeftKind)
+ KindsEnum k, parser::CharBlock lit, FoldingContext &ctx, bool isDeftKind)
: kind{k}, literal{lit}, context{ctx}, isDefaultKind{isDeftKind} {}
- template <typename T> Result Test(int testKind) {
+ template <typename T> Result Test(KindsEnum testKind) {
if (kind == testKind) {
return {AsCategoryExpr(
ReadRealLiteral<T>(testKind, literal, context, isDefaultKind))};
@@ -864,7 +865,7 @@ struct RealTypeVisitor {
return std::nullopt;
}
- int kind;
+ KindsEnum kind;
parser::CharBlock literal;
FoldingContext &context;
bool isDefaultKind;
@@ -881,10 +882,10 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::RealLiteralConstant &x) {
// "6.02214E+23"). In the absence of an explicit kind parameter, any
// exponent letter determines the kind. Otherwise, defaults apply.
auto &defaults{context_.defaultKinds()};
- int defaultKind{defaults.GetDefaultKind(TypeCategory::Real)};
+ KindsEnum defaultKind{defaults.GetDefaultKind(TypeCategory::Real)};
const char *end{xreal.source.end()};
char expoLetter{' '};
- std::optional<int> letterKind;
+ std::optional<KindsEnum> letterKind;
for (const char *p{xreal.source.begin()}; p < end; ++p) {
if (parser::IsLetter(*p)) {
expoLetter = *p;
@@ -920,7 +921,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::RealLiteralConstant &x) {
"Explicit kind parameter together with non-'E' exponent letter is not standard"_port_en_US);
}
}
- bool isDefaultKind{!xkind && letterKind.value_or('e') == 'e'};
+ bool isDefaultKind{!xkind && !letterKind.has_value()};
auto result{SearchTypes(
RealTypeVisitor{kind, xreal.source, GetFoldingContext(), isDefaultKind})};
if (!result) { // C717
@@ -965,38 +966,42 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::ComplexLiteralConstant &z) {
}
// CHARACTER literal processing.
-MaybeExpr ExpressionAnalyzer::AnalyzeString(std::string &&string, int kind) {
+MaybeExpr ExpressionAnalyzer::AnalyzeString(
+ std::string &&string, KindsEnum kind) {
if (!CheckIntrinsicKind(TypeCategory::Character, kind)) {
return std::nullopt;
}
switch (kind) {
- case 1:
- return AsGenericExpr(MakeConstant<Type<TypeCategory::Character>>(1,
- parser::DecodeString<std::string, parser::Encoding::LATIN_1>(
- string, true)));
- case 2:
- return AsGenericExpr(MakeConstant<Type<TypeCategory::Character>>(2,
- parser::DecodeString<std::u16string, parser::Encoding::UTF_8>(
- string, true)));
- case 4:
- return AsGenericExpr(MakeConstant<Type<TypeCategory::Character>>(4,
- parser::DecodeString<std::u32string, parser::Encoding::UTF_8>(
- string, true)));
+ case KindsEnum::Kind1:
+ return AsGenericExpr(
+ MakeConstant<Type<TypeCategory::Character>>(KindsEnum::Kind1,
+ parser::DecodeString<std::string, parser::Encoding::LATIN_1>(
+ string, true)));
+ case KindsEnum::Kind2:
+ return AsGenericExpr(
+ MakeConstant<Type<TypeCategory::Character>>(KindsEnum::Kind2,
+ parser::DecodeString<std::u16string, parser::Encoding::UTF_8>(
+ string, true)));
+ case KindsEnum::Kind4:
+ return AsGenericExpr(
+ MakeConstant<Type<TypeCategory::Character>>(KindsEnum::Kind4,
+ parser::DecodeString<std::u32string, parser::Encoding::UTF_8>(
+ string, true)));
default:
CRASH_NO_CASE;
}
}
MaybeExpr ExpressionAnalyzer::Analyze(const parser::CharLiteralConstant &x) {
- int kind{
- AnalyzeKindParam(std::get<std::optional<parser::KindParam>>(x.t), 1)};
+ KindsEnum kind{AnalyzeKindParam(
+ std::get<std::optional<parser::KindParam>>(x.t), KindsEnum::Kind1)};
auto value{std::get<std::string>(x.t)};
return AnalyzeString(std::move(value), kind);
}
MaybeExpr ExpressionAnalyzer::Analyze(
const parser::HollerithLiteralConstant &x) {
- int kind{GetDefaultKind(TypeCategory::Character)};
+ KindsEnum kind{GetDefaultKind(TypeCategory::Character)};
auto result{AnalyzeString(std::string{x.v}, kind)};
if (auto *constant{UnwrapConstantValue<Ascii>(result)}) {
constant->set_wasHollerith(true);
@@ -1011,7 +1016,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::LogicalLiteralConstant &x) {
bool value{std::get<bool>(x.t)};
auto result{SearchTypes(
TypeKindVisitor<TypeCategory::Logical, Constant, value::LogicalValue>{
- kind, value::LogicalValue{kind, value}})};
+ static_cast<KindsEnum>(kind),
+ value::LogicalValue{static_cast<KindsEnum>(kind), value}})};
if (!result) {
Say("unsupported LOGICAL(KIND=%d)"_err_en_US, kind); // C728
}
@@ -1057,7 +1063,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
auto restorer{GetContextualMessages().SetLocation(n.source)};
if (std::optional<int> kind{IsImpliedDo(n.source)}) {
return AsMaybeExpr(ConvertToKind<TypeCategory::Integer>(
- *kind, AsExpr(ImpliedDoIndex{n.source})));
+ static_cast<KindsEnum>(*kind), AsExpr(ImpliedDoIndex{n.source})));
}
if (context_.HasError(n.symbol)) { // includes case of no symbol
return std::nullopt;
@@ -1074,14 +1080,15 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
// while processing other specification expressions in the PDT
// definition; the right kind value will be used later in each of its
// instantiations.
- int kind{SubscriptIntegerKind};
+ KindsEnum kind{SubscriptIntegerKind};
if (const auto *typeSpec{ultimate.GetType()}) {
if (const semantics::IntrinsicTypeSpec *
intrinType{typeSpec->AsIntrinsic()}) {
if (auto k{ToInt64(Fold(semantics::KindExpr{intrinType->kind()}))};
k &&
- common::IsValidKindOfIntrinsicType(TypeCategory::Integer, *k)) {
- kind = *k;
+ common::IsValidKindOfIntrinsicType(
+ TypeCategory::Integer, static_cast<KindsEnum>(*k))) {
+ kind = static_cast<KindsEnum>(*k);
}
}
}
@@ -1236,7 +1243,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Substring &ss) {
return std::nullopt;
}
return WrapperHelper<TypeCategory::Character, Designator,
- Substring>(dynamicType->kind(),
+ Substring>(static_cast<KindsEnum>(dynamicType->kind()),
Substring{std::move(checked.value()), std::move(first),
std::move(last)});
}
@@ -1271,7 +1278,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(
return common::visit(
[&](auto &&ckExpr) -> MaybeExpr {
using Result = ResultType<decltype(ckExpr)>;
- const int resultKind{ckExpr.kind()};
+ const int resultKind{static_cast<int>(ckExpr.kind())};
auto *cp{std::get_if<Constant<Result>>(&ckExpr.u)};
CHECK(DEREF(cp).size() == 1);
StaticDataObject::Pointer staticData{StaticDataObject::Create()};
@@ -1281,8 +1288,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(
foldingContext_.targetCharacteristics().isBigEndian());
Substring substring{std::move(staticData), std::move(lower.value()),
std::move(upper.value())};
- return AsGenericExpr(Expr<Result>{
- Designator<Result>{resultKind, std::move(substring)}});
+ return AsGenericExpr(Expr<Result>{Designator<Result>{
+ static_cast<KindsEnum>(resultKind), std::move(substring)}});
},
std::move(charExpr->u));
}
@@ -1552,8 +1559,9 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
auto part{kind == MiscKind::ComplexPartRe
? ComplexPart::Part::RE
: ComplexPart::Part::IM};
- return AsCategoryExpr(Designator<PartType>{
- z.kind(), ComplexPart{std::move(*dataRef), part}});
+ return AsCategoryExpr(
+ Designator<PartType>{static_cast<KindsEnum>(z.kind()),
+ ComplexPart{std::move(*dataRef), part}});
},
zExpr->u)};
return AsGenericExpr(std::move(realExpr));
@@ -1661,12 +1669,12 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::CoindexedNamedObject &x) {
return std::nullopt;
}
-int ExpressionAnalyzer::IntegerTypeSpecKind(
+KindsEnum ExpressionAnalyzer::IntegerTypeSpecKind(
const parser::IntegerTypeSpec &spec) {
Expr<SubscriptInteger> value{
AnalyzeKindSelector(TypeCategory::Integer, spec.v)};
if (auto kind{ToInt64(value)}) {
- return static_cast<int>(*kind);
+ return static_cast<KindsEnum>(*kind);
}
SayAt(spec, "Constant INTEGER kind value required here"_err_en_US);
return GetDefaultKind(TypeCategory::Integer);
@@ -1713,7 +1721,7 @@ class ArrayConstructorContext {
// expression in ToExpr().
using Result = MaybeExpr;
using Types = AllTypes;
- template <typename T> Result Test(int kind) {
+ template <typename T> Result Test(KindsEnum kind) {
if (type_ && type_->category() == T::category) {
if constexpr (T::category == TypeCategory::Derived) {
if (!type_->IsUnlimitedPolymorphic()) {
@@ -1748,7 +1756,7 @@ class ArrayConstructorContext {
private:
using ImpliedDoIntType = ResultType<ImpliedDoIndex>;
- static constexpr int ImpliedDoIntKind = ResultKind<ImpliedDoIndex>;
+ static constexpr KindsEnum ImpliedDoIntKind = ResultKind<ImpliedDoIndex>;
std::optional<Expr<SubscriptInteger>> LengthIfGood() const {
if (type_) {
@@ -1810,7 +1818,8 @@ void ArrayConstructorContext::Push(MaybeExpr &&x) {
exprAnalyzer_.Warn(common::LanguageFeature::BOZAsDefaultInteger,
"BOZ literal in array constructor without explicit type is assumed to be default INTEGER"_port_en_US);
x = AsGenericExpr(ConvertToKind<TypeCategory::Integer>(
- exprAnalyzer_.GetDefaultKind(TypeCategory::Integer),
+ static_cast<KindsEnum>(
+ exprAnalyzer_.GetDefaultKind(TypeCategory::Integer)),
std::move(*boz)));
}
}
@@ -1822,7 +1831,8 @@ void ArrayConstructorContext::Push(MaybeExpr &&x) {
exprAnalyzer_.Warn(common::LanguageFeature::BOZAsDefaultInteger,
"BOZ literal in array constructor without explicit type is assumed to be default INTEGER"_port_en_US);
x = AsGenericExpr(ConvertToKind<TypeCategory::Integer>(
- exprAnalyzer_.GetDefaultKind(TypeCategory::Integer),
+ static_cast<KindsEnum>(
+ exprAnalyzer_.GetDefaultKind(TypeCategory::Integer)),
std::move(*boz)));
dyType = x.value().GetType();
} else if (auto cast{ConvertToType(*type_, std::move(*x))}) {
@@ -1948,7 +1958,7 @@ void ArrayConstructorContext::Add(const parser::AcValue::Triplet &triplet) {
auto upperType{upperExpr->GetType()};
auto strideType{strideExpr ? strideExpr->GetType() : lowerType};
if (lowerType && upperType && strideType) {
- int kind{lowerType->kind()};
+ KindsEnum kind{lowerType->kind()};
if (upperType->kind() > kind) {
kind = upperType->kind();
}
@@ -1962,7 +1972,7 @@ void ArrayConstructorContext::Add(const parser::AcValue::Triplet &triplet) {
if (!stride) {
stride = MakeConstantExpr<ImpliedDoIntType>(ImpliedDoIntKind, 1);
}
- DynamicType type{TypeCategory::Integer, kind};
+ DynamicType type{TypeCategory::Integer, static_cast<KindsEnum>(kind)};
if (!type_) {
type_ = DynamicTypeWithLength{type};
}
@@ -1994,7 +2004,7 @@ void ArrayConstructorContext::Add(const parser::AcImpliedDo &impliedDo) {
exprAnalyzer_.Analyze(bounds.Name());
const auto &parsedName{parser::UnwrapRef<parser::Name>(bounds.Name())};
parser::CharBlock name{parsedName.source};
- int kind{ImpliedDoIntKind};
+ KindsEnum kind{ImpliedDoIntKind};
if (const Symbol *symbol{parsedName.symbol}) {
if (auto dynamicType{DynamicType::From(symbol)}) {
if (dynamicType->category() == TypeCategory::Integer) {
@@ -4373,7 +4383,8 @@ MaybeExpr RelationHelper(ExpressionAnalyzer &context, RelationalOperator opr,
if (auto cmp{Relate(context.GetContextualMessages(), opr,
analyzer.MoveExpr(0), analyzer.MoveExpr(1))}) {
return AsMaybeExpr(ConvertToKind<TypeCategory::Logical>(
- context.GetDefaultKind(TypeCategory::Logical),
+ static_cast<KindsEnum>(
+ context.GetDefaultKind(TypeCategory::Logical)),
AsExpr(std::move(*cmp))));
}
} else {
@@ -4729,16 +4740,17 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::PointerObject &x) {
Expr<SubscriptInteger> ExpressionAnalyzer::AnalyzeKindSelector(
TypeCategory category,
const std::optional<parser::KindSelector> &selector) {
- int defaultKind{GetDefaultKind(category)};
+ KindsEnum defaultKind{GetDefaultKind(category)};
if (!selector) {
- return MakeSubscriptIntExpr(defaultKind);
+ return MakeKindExpr(defaultKind);
}
return common::visit(
common::visitors{
[&](const parser::ScalarIntConstantExpr &x) {
if (MaybeExpr kind{Analyze(x)}) {
if (std::optional<std::int64_t> code{ToInt64(*kind)}) {
- if (CheckIntrinsicKind(category, *code)) {
+ if (CheckIntrinsicKind(
+ category, static_cast<KindsEnum>(*code))) {
return MakeSubscriptIntExpr(*code);
}
} else if (auto *intExpr{UnwrapExpr<Expr<SomeInteger>>(*kind)}) {
@@ -4746,12 +4758,12 @@ Expr<SubscriptInteger> ExpressionAnalyzer::AnalyzeKindSelector(
SubscriptIntegerKind, std::move(*intExpr));
}
}
- return MakeSubscriptIntExpr(defaultKind);
+ return MakeKindExpr(defaultKind);
},
[&](const parser::KindSelector::StarSize &x) {
std::intmax_t size = x.v;
if (!CheckIntrinsicSize(category, size)) {
- size = defaultKind;
+ size = static_cast<int>(defaultKind);
} else if (category == TypeCategory::Complex) {
size /= 2;
}
@@ -4761,7 +4773,7 @@ Expr<SubscriptInteger> ExpressionAnalyzer::AnalyzeKindSelector(
selector->u);
}
-int ExpressionAnalyzer::GetDefaultKind(common::TypeCategory category) {
+KindsEnum ExpressionAnalyzer::GetDefaultKind(common::TypeCategory category) {
return context_.GetDefaultKind(category);
}
@@ -4771,7 +4783,7 @@ DynamicType ExpressionAnalyzer::GetDefaultKindOfType(
}
bool ExpressionAnalyzer::CheckIntrinsicKind(
- TypeCategory category, std::int64_t kind) {
+ TypeCategory category, KindsEnum kind) {
if (foldingContext_.targetCharacteristics().IsTypeEnabled(
category, kind)) { // C712, C714, C715, C727
return true;
@@ -4786,12 +4798,13 @@ bool ExpressionAnalyzer::CheckIntrinsicKind(
// compilation with a disabled REAL kind.
} else {
Say("%s(KIND=%jd) is not an enabled type for this target"_err_en_US,
- ToUpperCase(EnumToString(category)), kind);
+ ToUpperCase(EnumToString(category)),
+ static_cast<std::intmax_t>(kind));
}
return true;
} else {
Say("%s(KIND=%jd) is not a supported type"_err_en_US,
- ToUpperCase(EnumToString(category)), kind);
+ ToUpperCase(EnumToString(category)), static_cast<std::intmax_t>(kind));
return false;
}
}
@@ -4808,11 +4821,12 @@ bool ExpressionAnalyzer::CheckIntrinsicSize(
return false;
}
}
- return CheckIntrinsicKind(category, kind);
+ return CheckIntrinsicKind(category, static_cast<KindsEnum>(kind));
}
-bool ExpressionAnalyzer::AddImpliedDo(parser::CharBlock name, int kind) {
- return impliedDos_.insert(std::make_pair(name, kind)).second;
+bool ExpressionAnalyzer::AddImpliedDo(parser::CharBlock name, KindsEnum kind) {
+ return impliedDos_.insert(std::make_pair(name, static_cast<int>(kind)))
+ .second;
}
void ExpressionAnalyzer::RemoveImpliedDo(parser::CharBlock name) {
@@ -4842,7 +4856,7 @@ bool ExpressionAnalyzer::EnforceTypeConstraint(parser::CharBlock at,
ToUpperCase(type->AsFortran()));
return false;
} else if (defaultKind) {
- int kind{context_.GetDefaultKind(category)};
+ KindsEnum kind{context_.GetDefaultKind(category)};
if (type->kind() != kind) {
Say(at, "Must have default kind(%d) of %s type, but is %s"_err_en_US,
kind, ToUpperCase(EnumToString(category)),
@@ -5856,7 +5870,8 @@ void ArgumentAnalyzer::ConvertBOZOperand(std::optional<DynamicType> *thisType,
Expr<SomeType> &&argExpr{MoveExpr(i)};
auto *boz{std::get_if<BOZLiteralConstant>(&argExpr.u)};
if (otherType && otherType->category() == TypeCategory::Real) {
- int kind{context_.context().GetDefaultKind(TypeCategory::Real)};
+ KindsEnum kind{static_cast<KindsEnum>(
+ context_.context().GetDefaultKind(TypeCategory::Real))};
MaybeExpr realExpr{
ConvertToKind<TypeCategory::Real>(kind, std::move(*boz))};
actuals_[i] = std::move(realExpr.value());
@@ -5864,7 +5879,8 @@ void ArgumentAnalyzer::ConvertBOZOperand(std::optional<DynamicType> *thisType,
thisType->emplace(TypeCategory::Real, kind);
}
} else if (otherType && otherType->category() == TypeCategory::Unsigned) {
- int kind{context_.context().GetDefaultKind(TypeCategory::Unsigned)};
+ KindsEnum kind{static_cast<KindsEnum>(
+ context_.context().GetDefaultKind(TypeCategory::Unsigned))};
MaybeExpr unsignedExpr{
ConvertToKind<TypeCategory::Unsigned>(kind, std::move(*boz))};
actuals_[i] = std::move(unsignedExpr.value());
@@ -5872,7 +5888,8 @@ void ArgumentAnalyzer::ConvertBOZOperand(std::optional<DynamicType> *thisType,
thisType->emplace(TypeCategory::Unsigned, kind);
}
} else {
- int kind{context_.context().GetDefaultKind(TypeCategory::Integer)};
+ KindsEnum kind{static_cast<KindsEnum>(
+ context_.context().GetDefaultKind(TypeCategory::Integer))};
MaybeExpr intExpr{
ConvertToKind<TypeCategory::Integer>(kind, std::move(*boz))};
actuals_[i] = std::move(*intExpr);
@@ -5893,7 +5910,7 @@ void ArgumentAnalyzer::ConvertBOZAssignmentRHS(const DynamicType &lhsType) {
if (const auto *boz{std::get_if<BOZLiteralConstant>(&rhs.u)}; boz &&
evaluate::value::IntegerValue::bits(BOZLiteralConstantKind) -
boz->LEADZ() >
- lhsType.kind() * 8) {
+ static_cast<int>(lhsType.kind()) * 8) {
context_.Warn(common::UsageWarning::BOZLiteralTruncation,
"BOZ literal constant is too large for %s(KIND=%d) assignment target; truncated"_warn_en_US,
lhsType.category() == TypeCategory::Unsigned ? "UNSIGNED"
@@ -5955,7 +5972,8 @@ std::string ArgumentAnalyzer::TypeAsFortran(std::size_t i) {
? type->AsFortran()
: "TYPE("s + type->AsFortran() + ')')
: type->category() == TypeCategory::Character
- ? "CHARACTER(KIND="s + std::to_string(type->kind()) + ')'
+ ? "CHARACTER(KIND="s + std::to_string(static_cast<int>(type->kind())) +
+ ')'
: ToUpperCase(type->AsFortran());
} else {
return "untyped";
@@ -6045,7 +6063,7 @@ bool ExprChecker::Pre(const parser::DataImpliedDo &ido) {
parser::Walk(std::get<parser::DataImpliedDo::Bounds>(ido.t), *this);
const auto &bounds{std::get<parser::DataImpliedDo::Bounds>(ido.t)};
const auto &name{parser::UnwrapRef<parser::Name>(bounds.Name())};
- int kind{evaluate::ResultKind<evaluate::ImpliedDoIndex>};
+ KindsEnum kind{evaluate::ResultKind<evaluate::ImpliedDoIndex>};
if (const auto dynamicType{evaluate::DynamicType::From(DEREF(name.symbol))}) {
if (dynamicType->category() == TypeCategory::Integer) {
kind = dynamicType->kind();
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index deb11bdeb96fb..45abb0ab2130c 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -933,7 +933,9 @@ bool EquivalenceSets::IsCharacterSequenceType(const DeclTypeSpec *type) {
return IsSequenceType(type, [&](const IntrinsicTypeSpec &type) {
auto kind{evaluate::ToInt64(type.kind())};
return type.category() == TypeCategory::Character && kind &&
- kind.value() == context_.GetDefaultKind(TypeCategory::Character);
+ kind.value() ==
+ static_cast<std::int64_t>(
+ context_.GetDefaultKind(TypeCategory::Character));
});
}
@@ -943,11 +945,15 @@ bool EquivalenceSets::IsDefaultKindNumericType(const IntrinsicTypeSpec &type) {
switch (type.category()) {
case TypeCategory::Integer:
case TypeCategory::Logical:
- return *kind == context_.GetDefaultKind(TypeCategory::Integer);
+ return *kind ==
+ static_cast<std::int64_t>(
+ context_.GetDefaultKind(TypeCategory::Integer));
case TypeCategory::Real:
case TypeCategory::Complex:
- return *kind == context_.GetDefaultKind(TypeCategory::Real) ||
- *kind == context_.doublePrecisionKind();
+ return *kind ==
+ static_cast<std::int64_t>(
+ context_.GetDefaultKind(TypeCategory::Real)) ||
+ *kind == static_cast<std::int64_t>(context_.doublePrecisionKind());
default:
return false;
}
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index bd3a6222710b4..0525728196e66 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2777,14 +2777,17 @@ void DeclTypeSpecVisitor::Post(const parser::TypeSpec &typeSpec) {
void DeclTypeSpecVisitor::Post(
const parser::IntrinsicTypeSpec::DoublePrecision &) {
- MakeNumericType(TypeCategory::Real, context().doublePrecisionKind());
+ MakeNumericType(
+ TypeCategory::Real, static_cast<int>(context().doublePrecisionKind()));
}
void DeclTypeSpecVisitor::Post(
const parser::IntrinsicTypeSpec::DoubleComplex &) {
- MakeNumericType(TypeCategory::Complex, context().doublePrecisionKind());
+ MakeNumericType(
+ TypeCategory::Complex, static_cast<int>(context().doublePrecisionKind()));
}
void DeclTypeSpecVisitor::MakeNumericType(TypeCategory category, int kind) {
- SetDeclTypeSpec(context().MakeNumericType(category, kind));
+ SetDeclTypeSpec(
+ context().MakeNumericType(category, static_cast<KindsEnum>(kind)));
}
void DeclTypeSpecVisitor::CheckForAbstractType(const Symbol &typeSymbol) {
@@ -3572,7 +3575,9 @@ bool ScopeHandler::ImplicitlyTypeForwardRef(Symbol &symbol) {
return false;
}
auto kind{evaluate::ToInt64(type->numericTypeSpec().kind())};
- if (!kind || *kind != context().GetDefaultKind(TypeCategory::Integer)) {
+ if (!kind ||
+ static_cast<KindsEnum>(*kind) !=
+ context().GetDefaultKind(TypeCategory::Integer)) {
return false;
}
}
@@ -3706,7 +3711,7 @@ const DeclTypeSpec &ScopeHandler::MakeNumericType(
const DeclTypeSpec &ScopeHandler::MakeNumericType(
TypeCategory category, int kind) {
- return context().MakeNumericType(category, kind);
+ return context().MakeNumericType(category, static_cast<KindsEnum>(kind));
}
const DeclTypeSpec &ScopeHandler::MakeLogicalType(
@@ -3720,7 +3725,7 @@ const DeclTypeSpec &ScopeHandler::MakeLogicalType(
}
const DeclTypeSpec &ScopeHandler::MakeLogicalType(int kind) {
- return context().MakeLogicalType(kind);
+ return context().MakeLogicalType(static_cast<KindsEnum>(kind));
}
void ScopeHandler::NotePossibleBadForwardRef(const parser::Name &name) {
@@ -6326,8 +6331,8 @@ void DeclarationVisitor::Post(const parser::EnumerationTypeStmt &x) {
std::string{DerivedTypeDetails::ordinalComponentName})};
Symbol &ordinalSym{MakeSymbol(currScope(), ordinalName, Attrs{})};
ordinalSym.set_details(ObjectEntityDetails{});
- ordinalSym.SetType(
- currScope().MakeNumericType(TypeCategory::Integer, MakeKindExpr(4)));
+ ordinalSym.SetType(currScope().MakeNumericType(
+ TypeCategory::Integer, MakeKindExpr(KindsEnum::Kind4)));
ordinalSym.set(Symbol::Flag::CompilerCreated);
symbol.get<DerivedTypeDetails>().add_component(ordinalSym);
}
@@ -6773,8 +6778,8 @@ void DeclarationVisitor::Post(const parser::CharSelector::LengthAndKind &x) {
charInfo_.kind = EvaluateSubscriptIntExpr(kind);
std::optional<std::int64_t> intKind{ToInt64(charInfo_.kind)};
if (intKind &&
- !context().targetCharacteristics().IsTypeEnabled(
- TypeCategory::Character, *intKind)) { // C715, C719
+ !context().targetCharacteristics().IsTypeEnabled(TypeCategory::Character,
+ static_cast<KindsEnum>(*intKind))) { // C715, C719
Say(currStmtSource().value(),
"KIND value (%jd) not valid for CHARACTER"_err_en_US, *intKind);
charInfo_.kind = std::nullopt; // prevent further errors
@@ -7875,7 +7880,8 @@ void DeclarationVisitor::Post(const parser::BasedPointer &bp) {
}
pointer->set(Symbol::Flag::CrayPointer);
const DeclTypeSpec &pointerType{MakeNumericType(TypeCategory::Integer,
- context().targetCharacteristics().integerKindForPointer())};
+ static_cast<int>(
+ context().targetCharacteristics().integerKindForPointer()))};
const auto *type{pointer->GetType()};
if (!type) {
pointer->SetType(pointerType);
@@ -8167,7 +8173,7 @@ bool DeclarationVisitor::HandleUnrestrictedSpecificIntrinsicFunction(
DEREF(interface->functionResult->GetTypeAndShape()).type()};
CHECK(common::IsNumericTypeCategory(dyType.category()));
const DeclTypeSpec &typeSpec{
- MakeNumericType(dyType.category(), dyType.kind())};
+ MakeNumericType(dyType.category(), static_cast<int>(dyType.kind()))};
ProcEntityDetails details;
details.set_type(typeSpec);
symbol.set_details(std::move(details));
diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp
index ef56ce90ff0a7..a47e715430bee 100644
--- a/flang/lib/Semantics/runtime-type-info.cpp
+++ b/flang/lib/Semantics/runtime-type-info.cpp
@@ -312,15 +312,15 @@ static int GetIntegerKind(const Symbol &symbol, bool canBeUninstantiated) {
auto dyType{evaluate::DynamicType::From(symbol)};
CHECK((dyType && dyType->category() == TypeCategory::Integer) ||
symbol.owner().context().HasError(symbol) || canBeUninstantiated);
- return dyType && dyType->category() == TypeCategory::Integer
- ? dyType->kind()
- : symbol.owner().context().GetDefaultKind(TypeCategory::Integer);
+ return static_cast<int>(dyType && dyType->category() == TypeCategory::Integer
+ ? dyType->kind()
+ : symbol.owner().context().GetDefaultKind(TypeCategory::Integer));
}
// Save a rank-1 array constant of some numeric type as an
// initialized data object in a scope.
template <typename T>
-static SomeExpr SaveNumericPointerTarget(int kind, Scope &scope,
+static SomeExpr SaveNumericPointerTarget(KindsEnum kind, Scope &scope,
SourceName name, std::vector<typename T::Scalar> &&x) {
if (x.empty()) {
return SomeExpr{evaluate::NullPointer{}};
@@ -357,10 +357,10 @@ static SomeExpr SaveObjectInit(
CHECK(symbol.get<ObjectEntityDetails>().init().has_value());
SetReadOnlyCompilerCreatedFlags(symbol);
return evaluate::AsGenericExpr(
- evaluate::Designator<evaluate::SomeDerived>{0, symbol});
+ evaluate::Designator<evaluate::SomeDerived>{KindsEnum::NoKind, symbol});
}
-static SomeExpr IntExpr(int kind, std::int64_t n) {
+static SomeExpr IntExpr(KindsEnum kind, std::int64_t n) {
return evaluate::AsGenericExpr(
evaluate::MakeConstant<evaluate::Type<TypeCategory::Integer>>(kind, n));
}
@@ -514,20 +514,20 @@ const Symbol *RuntimeTableBuilder::DescribeType(
}
}
}
- kinds.emplace_back(8, value);
+ kinds.emplace_back(KindsEnum::Kind8, value);
} else { // LEN= parameter
- lenKinds.emplace_back(
- 1, GetIntegerKind(*inst, isPDTDefinitionWithKindParameters));
+ lenKinds.emplace_back(KindsEnum::Kind1,
+ GetIntegerKind(*inst, isPDTDefinitionWithKindParameters));
}
}
}
}
AddValue(dtValues, derivedTypeSchema_, "kindparameter"s,
- SaveNumericPointerTarget<Int8>(8, scope,
+ SaveNumericPointerTarget<Int8>(KindsEnum::Kind8, scope,
SaveObjectName((fir::kKindParameterSeparator + distinctName).str()),
std::move(kinds)));
AddValue(dtValues, derivedTypeSchema_, "lenparameterkind"s,
- SaveNumericPointerTarget<Int1>(1, scope,
+ SaveNumericPointerTarget<Int1>(KindsEnum::Kind1, scope,
SaveObjectName((fir::kLenKindSeparator + distinctName).str()),
std::move(lenKinds)));
// Traverse the components of the derived type
@@ -645,28 +645,29 @@ const Symbol *RuntimeTableBuilder::DescribeType(
static_cast<evaluate::ConstantSubscript>(specials.size())}));
}
AddValue(dtValues, derivedTypeSchema_, "specialbitset"s,
- IntExpr(4, specialBitSet));
+ IntExpr(KindsEnum::Kind4, specialBitSet));
// Note the presence/absence of a parent component
AddValue(dtValues, derivedTypeSchema_, "hasparent"s,
- IntExpr(1, dtScope.GetDerivedTypeParent() != nullptr));
+ IntExpr(KindsEnum::Kind1, dtScope.GetDerivedTypeParent() != nullptr));
// To avoid wasting run time attempting to initialize derived type
// instances without any initialized components, analyze the type
// and set a flag if there's nothing to do for it at run time.
AddValue(dtValues, derivedTypeSchema_, "noinitializationneeded"s,
- IntExpr(1,
+ IntExpr(KindsEnum::Kind1,
derivedTypeSpec &&
!derivedTypeSpec->HasDefaultInitialization(false, false)));
// Similarly, a flag to short-circuit destruction when not needed.
AddValue(dtValues, derivedTypeSchema_, "nodestructionneeded"s,
- IntExpr(1, derivedTypeSpec && !derivedTypeSpec->HasDestruction()));
+ IntExpr(KindsEnum::Kind1,
+ derivedTypeSpec && !derivedTypeSpec->HasDestruction()));
// Similarly, a flag to short-circuit finalization when not needed.
AddValue(dtValues, derivedTypeSchema_, "nofinalizationneeded"s,
- IntExpr(
- 1, derivedTypeSpec && !MayRequireFinalization(*derivedTypeSpec)));
+ IntExpr(KindsEnum::Kind1,
+ derivedTypeSpec && !MayRequireFinalization(*derivedTypeSpec)));
// Similarly, a flag to enable optimized runtime assignment.
AddValue(dtValues, derivedTypeSchema_, "nodefinedassignment"s,
- IntExpr(
- 1, derivedTypeSpec && !MayHaveDefinedAssignment(*derivedTypeSpec)));
+ IntExpr(KindsEnum::Kind1,
+ derivedTypeSpec && !MayHaveDefinedAssignment(*derivedTypeSpec)));
}
dtObject.get<ObjectEntityDetails>().set_init(MaybeExpr{
StructureExpr(Structure(derivedTypeSchema_, std::move(dtValues)))});
@@ -716,7 +717,7 @@ SomeExpr RuntimeTableBuilder::GetEnumValue(const char *name) const {
const Symbol &symbol{GetSchemaSymbol(name)};
auto value{evaluate::ToInt64(symbol.get<ObjectEntityDetails>().init())};
CHECK(value.has_value());
- return IntExpr(1, *value);
+ return IntExpr(KindsEnum::Kind1, *value);
}
Symbol &RuntimeTableBuilder::CreateObject(
@@ -741,12 +742,14 @@ SomeExpr RuntimeTableBuilder::SaveNameAsPointerTarget(
CHECK(name.front() != '.' || context_.IsTempName(name));
ObjectEntityDetails object;
auto len{static_cast<common::ConstantSubscript>(name.size())};
- if (const auto *spec{scope.FindType(DeclTypeSpec{CharacterTypeSpec{
- ParamValue{len, common::TypeParamAttr::Len}, MakeKindExpr(1)}})}) {
+ if (const auto *spec{scope.FindType(DeclTypeSpec{
+ CharacterTypeSpec{ParamValue{len, common::TypeParamAttr::Len},
+ MakeKindExpr(KindsEnum::Kind1)}})}) {
object.set_type(*spec);
} else {
- object.set_type(scope.MakeCharacterType(
- ParamValue{len, common::TypeParamAttr::Len}, MakeKindExpr(1)));
+ object.set_type(
+ scope.MakeCharacterType(ParamValue{len, common::TypeParamAttr::Len},
+ MakeKindExpr(KindsEnum::Kind1)));
}
using evaluate::Ascii, evaluate::AsciiKind, evaluate::MakeConstantExpr;
using AsciiExpr = evaluate::Expr<Ascii>;
@@ -783,14 +786,16 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
AddValue(values, componentSchema_, "name"s,
SaveNameAsPointerTarget(scope, symbol.name().ToString()));
AddValue(values, componentSchema_, "category"s,
- IntExpr(1, static_cast<int>(dyType.category())));
+ IntExpr(KindsEnum::Kind1, static_cast<int>(dyType.category())));
if (dyType.IsUnlimitedPolymorphic() ||
dyType.category() == TypeCategory::Derived) {
- AddValue(values, componentSchema_, "kind"s, IntExpr(1, 0));
+ AddValue(values, componentSchema_, "kind"s, IntExpr(KindsEnum::Kind1, 0));
} else {
- AddValue(values, componentSchema_, "kind"s, IntExpr(1, dyType.kind()));
+ AddValue(values, componentSchema_, "kind"s,
+ IntExpr(KindsEnum::Kind1, static_cast<std::int64_t>(dyType.kind())));
}
- AddValue(values, componentSchema_, "offset"s, IntExpr(8, symbol.offset()));
+ AddValue(values, componentSchema_, "offset"s,
+ IntExpr(KindsEnum::Kind8, symbol.offset()));
// CHARACTER length
auto len{typeAndShape->LEN()};
if (const semantics::DerivedTypeSpec *
@@ -864,7 +869,7 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
SomeExpr{evaluate::NullPointer{}});
}
// Shape information
- AddValue(values, componentSchema_, "rank"s, IntExpr(1, rank));
+ AddValue(values, componentSchema_, "rank"s, IntExpr(KindsEnum::Kind1, rank));
if (rank > 0 && !IsAllocatable(symbol) && !IsPointer(symbol)) {
std::vector<evaluate::StructureConstructor> bounds;
evaluate::NamedEntity entity{symbol};
@@ -929,7 +934,8 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
evaluate::StructureConstructorValues values;
AddValue(values, procPtrSchema_, "name"s,
SaveNameAsPointerTarget(scope, symbol.name().ToString()));
- AddValue(values, procPtrSchema_, "offset"s, IntExpr(8, symbol.offset()));
+ AddValue(values, procPtrSchema_, "offset"s,
+ IntExpr(KindsEnum::Kind8, symbol.offset()));
if (auto init{proc.init()}; init && *init) {
AddValue(values, procPtrSchema_, "initialization"s,
SomeExpr{evaluate::ProcedureDesignator{**init}});
@@ -1204,7 +1210,7 @@ void RuntimeTableBuilder::DescribeSpecialProc(
} else {
which = scalarFinalEnum_;
if (int rank{typeAndShape.Rank()}; rank > 0) {
- which = IntExpr(1, ToInt64(which).value() + rank);
+ which = IntExpr(KindsEnum::Kind1, ToInt64(which).value() + rank);
if (dummyData.IsPassedByDescriptor(proc->IsBindC())) {
argThatMightBeDescriptor = 1;
}
@@ -1247,7 +1253,8 @@ void RuntimeTableBuilder::DescribeSpecialProc(
which = writeUnformattedEnum_;
break;
}
- if (context_.defaultKinds().GetDefaultKind(TypeCategory::Integer) == 8) {
+ if (context_.defaultKinds().GetDefaultKind(TypeCategory::Integer) ==
+ KindsEnum::Kind8) {
specialCaseFlag = true; // UNIT= & IOSTAT= INTEGER(8)
}
}
@@ -1266,7 +1273,7 @@ void RuntimeTableBuilder::DescribeSpecialProc(
AddValue(
values, specialSchema_, "which"s, SomeExpr{std::move(which.value())});
AddValue(values, specialSchema_, "isargdescriptorset"s,
- IntExpr(1, isArgDescriptorSet));
+ IntExpr(KindsEnum::Kind1, isArgDescriptorSet));
int bindingIndex{0};
if (bindings) {
int j{0};
@@ -1279,9 +1286,10 @@ void RuntimeTableBuilder::DescribeSpecialProc(
}
}
CHECK(bindingIndex <= 255);
- AddValue(values, specialSchema_, "istypebound"s, IntExpr(1, bindingIndex));
+ AddValue(values, specialSchema_, "istypebound"s,
+ IntExpr(KindsEnum::Kind1, bindingIndex));
AddValue(values, specialSchema_, "specialcaseflag"s,
- IntExpr(1, specialCaseFlag));
+ IntExpr(KindsEnum::Kind1, specialCaseFlag));
AddValue(values, specialSchema_, procCompName,
SomeExpr{evaluate::ProcedureDesignator{specific}});
// index might already be present in the case of an override
@@ -1431,7 +1439,7 @@ CollectNonTbpDefinedIoGenericInterfaces(
flags |= IsDtvArgPolymorphic;
}
if (scope.context().GetDefaultKind(TypeCategory::Integer) ==
- 8) {
+ KindsEnum::Kind8) {
flags |= DefinedIoInteger8;
}
for (auto [iter, end]{result.equal_range(dtDesc)}; iter != end;
diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index 1ccbf79750be2..439403c688251 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -397,19 +397,19 @@ SemanticsContext::SemanticsContext(
SemanticsContext::~SemanticsContext() {}
-int SemanticsContext::GetDefaultKind(TypeCategory category) const {
+KindsEnum SemanticsContext::GetDefaultKind(TypeCategory category) const {
return defaultKinds_.GetDefaultKind(category);
}
const DeclTypeSpec &SemanticsContext::MakeNumericType(
- TypeCategory category, int kind) {
- if (kind == 0) {
+ TypeCategory category, KindsEnum kind) {
+ if (kind == KindsEnum::NoKind) {
kind = GetDefaultKind(category);
}
return globalScope_.MakeNumericType(category, MakeKindExpr(kind));
}
-const DeclTypeSpec &SemanticsContext::MakeLogicalType(int kind) {
- if (kind == 0) {
+const DeclTypeSpec &SemanticsContext::MakeLogicalType(KindsEnum kind) {
+ if (kind == KindsEnum::NoKind) {
kind = GetDefaultKind(TypeCategory::Logical);
}
return globalScope_.MakeLogicalType(MakeKindExpr(kind));
diff --git a/flang/lib/Semantics/type.cpp b/flang/lib/Semantics/type.cpp
index d8bafc2d26aa6..8e062dc7ba877 100644
--- a/flang/lib/Semantics/type.cpp
+++ b/flang/lib/Semantics/type.cpp
@@ -23,8 +23,6 @@
namespace Fortran::semantics {
-KindExpr MakeKindExpr(int v) { return evaluate::MakeSubscriptIntExpr(v); }
-
DerivedTypeSpec::DerivedTypeSpec(SourceName name, const Symbol &typeSymbol)
: name_{name}, originalTypeSymbol_{typeSymbol},
typeSymbol_{typeSymbol.GetUltimate()} {
@@ -116,7 +114,7 @@ void DerivedTypeSpec::EvaluateParameters(SemanticsContext &context) {
auto &messages{foldingContext.messages()};
for (const Symbol &symbol : OrderParameterDeclarations(typeSymbol_)) {
SourceName name{symbol.name()};
- int parameterKind{evaluate::TypeParamInquiry::ResultKind};
+ KindsEnum parameterKind{evaluate::TypeParamInquiry::ResultKind};
// Compute the integer kind value of the type parameter,
// which may depend on the values of earlier ones.
if (const auto *typeSpec{symbol.GetType()}) {
@@ -125,8 +123,9 @@ void DerivedTypeSpec::EvaluateParameters(SemanticsContext &context) {
auto restorer{foldingContext.WithPDTInstance(*this)};
auto folded{Fold(foldingContext, KindExpr{intrinType->kind()})};
if (auto k{evaluate::ToInt64(folded)}; k &&
- common::IsValidKindOfIntrinsicType(TypeCategory::Integer, *k)) {
- parameterKind = static_cast<int>(*k);
+ common::IsValidKindOfIntrinsicType(
+ TypeCategory::Integer, static_cast<KindsEnum>(*k))) {
+ parameterKind = static_cast<KindsEnum>(*k);
} else {
messages.Say(
"Type of type parameter '%s' (%s) is not a valid kind of INTEGER"_err_en_US,
@@ -672,11 +671,11 @@ const DeclTypeSpec &InstantiateHelper::InstantiateIntrinsicType(
CHECK(kindExpr.has_value());
}
KindExpr folded{Fold(std::move(*kindExpr))};
- int kind{context().GetDefaultKind(intrinsic.category())};
+ KindsEnum kind{context().GetDefaultKind(intrinsic.category())};
if (auto value{evaluate::ToInt64(folded)}) {
if (foldingContext().targetCharacteristics().IsTypeEnabled(
- intrinsic.category(), *value)) {
- kind = *value;
+ intrinsic.category(), static_cast<KindsEnum>(*value))) {
+ kind = static_cast<KindsEnum>(*value);
} else {
foldingContext().messages().Say(symbolName,
"KIND parameter value (%jd) of intrinsic type %s did not resolve to a supported value"_err_en_US,
diff --git a/flang/lib/Support/default-kinds.cpp b/flang/lib/Support/default-kinds.cpp
index b763f8ec19418..4d7b1afd138b3 100644
--- a/flang/lib/Support/default-kinds.cpp
+++ b/flang/lib/Support/default-kinds.cpp
@@ -14,54 +14,55 @@ namespace Fortran::common {
IntrinsicTypeDefaultKinds::IntrinsicTypeDefaultKinds() {}
IntrinsicTypeDefaultKinds &IntrinsicTypeDefaultKinds::set_defaultIntegerKind(
- int k) {
+ KindsEnum k) {
defaultIntegerKind_ = k;
return *this;
}
IntrinsicTypeDefaultKinds &IntrinsicTypeDefaultKinds::set_subscriptIntegerKind(
- int k) {
+ KindsEnum k) {
subscriptIntegerKind_ = k;
return *this;
}
IntrinsicTypeDefaultKinds &IntrinsicTypeDefaultKinds::set_sizeIntegerKind(
- int k) {
+ KindsEnum k) {
sizeIntegerKind_ = k;
return *this;
}
IntrinsicTypeDefaultKinds &IntrinsicTypeDefaultKinds::set_defaultRealKind(
- int k) {
+ KindsEnum k) {
defaultRealKind_ = k;
return *this;
}
IntrinsicTypeDefaultKinds &IntrinsicTypeDefaultKinds::set_doublePrecisionKind(
- int k) {
+ KindsEnum k) {
doublePrecisionKind_ = k;
return *this;
}
IntrinsicTypeDefaultKinds &IntrinsicTypeDefaultKinds::set_quadPrecisionKind(
- int k) {
+ KindsEnum k) {
quadPrecisionKind_ = k;
return *this;
}
IntrinsicTypeDefaultKinds &IntrinsicTypeDefaultKinds::set_defaultCharacterKind(
- int k) {
+ KindsEnum k) {
defaultCharacterKind_ = k;
return *this;
}
IntrinsicTypeDefaultKinds &IntrinsicTypeDefaultKinds::set_defaultLogicalKind(
- int k) {
+ KindsEnum k) {
defaultLogicalKind_ = k;
return *this;
}
-int IntrinsicTypeDefaultKinds::GetDefaultKind(TypeCategory category) const {
+KindsEnum IntrinsicTypeDefaultKinds::GetDefaultKind(
+ TypeCategory category) const {
switch (category) {
case TypeCategory::Integer:
case TypeCategory::Unsigned:
@@ -75,7 +76,7 @@ int IntrinsicTypeDefaultKinds::GetDefaultKind(TypeCategory category) const {
return defaultLogicalKind_;
default:
CRASH_NO_CASE;
- return 0;
+ return KindsEnum::NoKind;
}
}
} // namespace Fortran::common
diff --git a/flang/tools/f18-parse-demo/f18-parse-demo.cpp b/flang/tools/f18-parse-demo/f18-parse-demo.cpp
index 07280da15d7d9..7a68932fddbdb 100644
--- a/flang/tools/f18-parse-demo/f18-parse-demo.cpp
+++ b/flang/tools/f18-parse-demo/f18-parse-demo.cpp
@@ -406,10 +406,10 @@ int main(int argc, char *const argv[]) {
options.predefinitions.emplace_back(
arg.substr(2), std::optional<std::string>{});
} else if (arg == "-r8" || arg == "-fdefault-real-8") {
- defaultKinds.set_defaultRealKind(8);
+ defaultKinds.set_defaultRealKind(Fortran::common::KindsEnum::Kind8);
} else if (arg == "-i8" || arg == "-fdefault-integer-8") {
- defaultKinds.set_defaultIntegerKind(8);
- defaultKinds.set_defaultLogicalKind(8);
+ defaultKinds.set_defaultIntegerKind(Fortran::common::KindsEnum::Kind8);
+ defaultKinds.set_defaultLogicalKind(Fortran::common::KindsEnum::Kind8);
} else if (arg == "-help" || arg == "--help" || arg == "-?") {
llvm::errs()
<< "f18-parse-demo options:\n"
diff --git a/flang/unittests/Evaluate/CharacterValueTest.cpp b/flang/unittests/Evaluate/CharacterValueTest.cpp
index 803a3e106a80a..111ebafd519f2 100644
--- a/flang/unittests/Evaluate/CharacterValueTest.cpp
+++ b/flang/unittests/Evaluate/CharacterValueTest.cpp
@@ -37,11 +37,11 @@ struct KindName {
template <typename T> class CharacterValueTypedKind : public testing::Test {};
TYPED_TEST_SUITE(CharacterValueTypedKind, CharacterTypedKinds, KindName);
-class CharacterValueKind : public testing::TestWithParam<int> {};
+class CharacterValueKind : public testing::TestWithParam<KindsEnum> {};
INSTANTIATE_TEST_SUITE_P(CharacterValueKind, CharacterValueKind,
testing::ValuesIn(CharacterKinds),
- [](const testing::TestParamInfo<int> &info) {
- return "CHARACTER(" + std::to_string(info.param) + ")";
+ [](const testing::TestParamInfo<KindsEnum> &info) {
+ return "CHARACTER(" + std::to_string(static_cast<int>(info.param)) + ")";
});
//===----------------------------------------------------------------------===//
@@ -63,7 +63,7 @@ static testing::AssertionResult CharsEqual(const char *expectedExpr,
EXPECT_PRED_FORMAT2(CharsEqual, expected, value)
/// Writes one character of the value's own character type at "dst".
-static void PutChar(int kind, void *dst, char32_t c) {
+static void PutChar(KindsEnum kind, void *dst, char32_t c) {
CharacterValue::withCharProto(kind, [=](auto proto) {
using CharT = std::decay_t<decltype(proto)>;
CharT raw{static_cast<CharT>(c)};
@@ -96,7 +96,7 @@ TEST(CharacterValue, Monostate) {
TYPED_TEST(CharacterValueTypedKind, ConstructFromStdBasicString) {
using CharT = typename TypeParam::CharT;
using StringT = typename TypeParam::StringT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
CharT buffer[] = {'a', 'b', 'c', '\0'};
CharacterValue v{kind, StringT{buffer}};
@@ -106,7 +106,7 @@ TYPED_TEST(CharacterValueTypedKind, ConstructFromStdBasicString) {
}
TEST_P(CharacterValueKind, Zero) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue zero{CharacterValue::Zero(kind)};
CharacterValue empty{kind, ""};
CharacterValue monostate;
@@ -121,7 +121,7 @@ TEST_P(CharacterValueKind, Zero) {
}
TEST_P(CharacterValueKind, FillConstructor) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v(kind, 3, U'x');
EXPECT_FALSE(v.IsMonostate());
@@ -137,18 +137,18 @@ TEST_P(CharacterValueKind, FillConstructor) {
}
TEST(CharacterValue, SubscriptWidensToChar32) {
- CharacterValue u{1, std::string{"\x80"}};
+ CharacterValue u{KindsEnum::Kind1, std::string{"\x80"}};
EXPECT_EQ(char32_t('\x80'), u[0]);
- CharacterValue w{2, std::u16string{u"\u0100"}};
+ CharacterValue w{KindsEnum::Kind2, std::u16string{u"\u0100"}};
EXPECT_EQ(char32_t{u'\u0100'}, w[0]);
- CharacterValue v{4, std::u32string{U"\U0001F600"}};
+ CharacterValue v{KindsEnum::Kind4, std::u32string{U"\U0001F600"}};
EXPECT_EQ(U'\U0001F600', v[0]);
}
TEST_P(CharacterValueKind, CopyAndMove) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abc"};
CharacterValue copyConstructed{v};
@@ -171,7 +171,7 @@ TEST_P(CharacterValueKind, CopyAndMove) {
}
TEST_P(CharacterValueKind, CharSize) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abcd"};
EXPECT_EQ(kind, v.kind());
@@ -179,7 +179,7 @@ TEST_P(CharacterValueKind, CharSize) {
}
TEST_P(CharacterValueKind, SizeAndLength) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "hello"};
EXPECT_FALSE(v.empty());
@@ -192,26 +192,28 @@ TEST_P(CharacterValueKind, SizeAndLength) {
//===----------------------------------------------------------------------===//
TEST_P(CharacterValueKind, AsStringConversions) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abc"};
// Only the conversion matching the stored character type is available.
- EXPECT_EQ(kind == 1, v.AsStringRef().has_value());
- EXPECT_EQ(kind == 1, v.AsStdString().has_value());
- EXPECT_EQ(kind == 2, v.AsU16String().has_value());
- EXPECT_EQ(kind == 4, v.AsU32String().has_value());
+ EXPECT_EQ(kind == KindsEnum::Kind1, v.AsStringRef().has_value());
+ EXPECT_EQ(kind == KindsEnum::Kind1, v.AsStdString().has_value());
+ EXPECT_EQ(kind == KindsEnum::Kind2, v.AsU16String().has_value());
+ EXPECT_EQ(kind == KindsEnum::Kind4, v.AsU32String().has_value());
switch (kind) {
- case 1:
+ case KindsEnum::Kind1:
EXPECT_EQ("abc", *v.AsStringRef());
EXPECT_EQ("abc", *v.AsStdString());
break;
- case 2:
+ case KindsEnum::Kind2:
EXPECT_EQ(std::u16string{u"abc"}, *v.AsU16String());
break;
- case 4:
+ case KindsEnum::Kind4:
EXPECT_EQ(std::u32string{U"abc"}, *v.AsU32String());
break;
+ default:
+ break;
}
EXPECT_EQ("abc", v.ToStdString());
}
@@ -219,7 +221,7 @@ TEST_P(CharacterValueKind, AsStringConversions) {
TYPED_TEST(CharacterValueTypedKind, ToBasicString) {
using CharT = typename TypeParam::CharT;
using StringT = typename TypeParam::StringT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
const CharT data[] = {'a', 'b', 'c', '\0'};
CharacterValue v1{kind, data};
@@ -227,7 +229,7 @@ TYPED_TEST(CharacterValueTypedKind, ToBasicString) {
}
TEST_P(CharacterValueKind, WithStdString) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abcde"};
// The callable sees the concrete std::basic_string<> for the stored kind.
@@ -238,11 +240,11 @@ TEST_P(CharacterValueKind, WithStdString) {
}
TEST_P(CharacterValueKind, ToAscii) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// conversion to possible kinds
CharacterValue v{kind, "abc"};
- for (int to : std::initializer_list<int> FORTRAN_CHARACTER_KINDS) {
+ for (KindsEnum to : CharacterKinds) {
CharacterValue converted{v.ToAscii(to)};
EXPECT_EQ(to, converted.kind());
EXPECT_CHARS_EQ("abc", converted);
@@ -250,7 +252,7 @@ TEST_P(CharacterValueKind, ToAscii) {
// Conversion between kinds is defined only for 7-bit ASCII; anything else
// yields an empty string.
- CharacterValue nonascii{4, std::u32string{U"a\u0100b"}};
+ CharacterValue nonascii{KindsEnum::Kind4, std::u32string{U"a\u0100b"}};
EXPECT_TRUE(nonascii.ToAscii(kind).empty());
EXPECT_EQ(kind, nonascii.ToAscii(kind).kind());
@@ -265,7 +267,7 @@ TEST_P(CharacterValueKind, ToAscii) {
//===----------------------------------------------------------------------===//
TEST_P(CharacterValueKind, Compare) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue abc{kind, "abc"};
CharacterValue abd{kind, "abd"};
@@ -292,7 +294,7 @@ TEST_P(CharacterValueKind, Compare) {
}
TEST_P(CharacterValueKind, RelationalOperators) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue abc{kind, "abc"};
CharacterValue abd{kind, "abd"};
@@ -326,7 +328,7 @@ TEST_P(CharacterValueKind, RelationalOperators) {
//===----------------------------------------------------------------------===//
TEST_P(CharacterValueKind, AssignFill) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abc"};
v.assign(kind, 2, 'z');
@@ -345,22 +347,22 @@ TEST_P(CharacterValueKind, AssignFromPointerAndLength) {
// char
v.assign("abcd", 3);
- EXPECT_EQ(1, v.kind());
+ EXPECT_EQ(KindsEnum::Kind1, v.kind());
EXPECT_CHARS_EQ("abc", v);
// char16_t
v.assign(u"abcd", 2);
- EXPECT_EQ(2, v.kind());
+ EXPECT_EQ(KindsEnum::Kind2, v.kind());
EXPECT_CHARS_EQ("ab", v);
// char32_t
v.assign(U"abcd", 4);
- EXPECT_EQ(4, v.kind());
+ EXPECT_EQ(KindsEnum::Kind4, v.kind());
EXPECT_CHARS_EQ("abcd", v);
}
TEST_P(CharacterValueKind, Erase) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abcdef"};
v.erase(3);
@@ -373,7 +375,7 @@ TEST_P(CharacterValueKind, Erase) {
}
TEST_P(CharacterValueKind, Append) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "ab"};
v.append(3, '!');
@@ -384,7 +386,7 @@ TEST_P(CharacterValueKind, Append) {
}
TEST_P(CharacterValueKind, Replace) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abcdef"};
CharacterValue xy{kind, "XY"};
@@ -398,7 +400,7 @@ TEST_P(CharacterValueKind, Replace) {
}
TEST_P(CharacterValueKind, Substr) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abcdef"};
EXPECT_CHARS_EQ("cdef", v.substr(2));
@@ -414,7 +416,7 @@ TEST_P(CharacterValueKind, Substr) {
}
TEST_P(CharacterValueKind, Reserve) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abc"};
// Reserving capacity does not change the value.
@@ -425,7 +427,7 @@ TEST_P(CharacterValueKind, Reserve) {
}
TEST_P(CharacterValueKind, Subscript) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abc"};
EXPECT_EQ(U'a', v[0]);
EXPECT_EQ(U'b', v[1]);
@@ -433,7 +435,7 @@ TEST_P(CharacterValueKind, Subscript) {
}
TEST_P(CharacterValueKind, Concatenation) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue ab{kind, "ab"};
CharacterValue cd{kind, "cd"};
CharacterValue empty = CharacterValue::Zero(kind);
@@ -447,7 +449,7 @@ TEST_P(CharacterValueKind, Concatenation) {
}
TEST_P(CharacterValueKind, AppendAssignString) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "ab"};
CharacterValue cd{kind, "cd"};
@@ -456,7 +458,7 @@ TEST_P(CharacterValueKind, AppendAssignString) {
}
TEST_P(CharacterValueKind, AppendAssignChar) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "ab"};
EXPECT_EQ(kind, v.kind());
@@ -473,7 +475,7 @@ TEST(CharacterValue, Npos) {
}
TEST_P(CharacterValueKind, Find) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue abcabc{kind, "abcabc"};
CharacterValue bc{kind, "bc"};
CharacterValue abc{kind, "abc"};
@@ -498,7 +500,7 @@ TEST_P(CharacterValueKind, Find) {
}
TEST_P(CharacterValueKind, RFind) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "abcabc"};
CharacterValue bc{kind, "bc"};
CharacterValue abc{kind, "abc"};
@@ -510,7 +512,7 @@ TEST_P(CharacterValueKind, RFind) {
}
TEST_P(CharacterValueKind, FindFirstOf) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "hello"};
CharacterValue le{kind, "le"};
CharacterValue h{kind, "he"};
@@ -524,7 +526,7 @@ TEST_P(CharacterValueKind, FindFirstOf) {
}
TEST_P(CharacterValueKind, FindLastOf) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "hello"};
CharacterValue le{kind, "le"};
CharacterValue o{kind, "o"};
@@ -536,7 +538,7 @@ TEST_P(CharacterValueKind, FindLastOf) {
}
TEST_P(CharacterValueKind, FindFirstNotOfCharacter) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue aab{kind, "aab"};
CharacterValue aaa{kind, "aaa"};
@@ -546,7 +548,7 @@ TEST_P(CharacterValueKind, FindFirstNotOfCharacter) {
}
TEST_P(CharacterValueKind, FindLastNotOfCharacter) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue abb{kind, "abb"};
CharacterValue bbb{kind, "bbb"};
@@ -556,7 +558,7 @@ TEST_P(CharacterValueKind, FindLastNotOfCharacter) {
}
TEST_P(CharacterValueKind, FindFirstNotOfSet) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "aabbc"};
CharacterValue ab{kind, "ab"};
CharacterValue abc{kind, "abc"};
@@ -573,7 +575,7 @@ TEST_P(CharacterValueKind, FindFirstNotOfSet) {
}
TEST_P(CharacterValueKind, FindLastNotOfSet) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue v{kind, "aabbc"};
CharacterValue abc{kind, "abc"};
CharacterValue bc{kind, "bc"};
@@ -594,13 +596,13 @@ TEST_P(CharacterValueKind, FindLastNotOfSet) {
//===----------------------------------------------------------------------===//
TEST_P(CharacterValueKind, Data) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
CharacterValue abc{kind, "abc"};
CharacterValue same{abc};
CharacterValue v{kind, "abc"};
const CharacterValue &constRef{v};
- ASSERT_EQ(v.bytesStored(), std::size_t(3 * kind));
+ ASSERT_EQ(v.bytesStored(), std::size_t(3) * static_cast<std::size_t>(kind));
ASSERT_EQ(same.bytesStored(), v.bytesStored());
EXPECT_EQ(v.data(), static_cast<void *>(v.charData()));
EXPECT_EQ(constRef.data(), static_cast<const void *>(constRef.charData()));
@@ -612,7 +614,7 @@ TEST_P(CharacterValueKind, Data) {
}
TYPED_TEST(CharacterValueTypedKind, At) {
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
CharacterValue v{kind, "abc"};
const CharacterValue &constRef{v};
@@ -629,7 +631,7 @@ TYPED_TEST(CharacterValueTypedKind, At) {
TYPED_TEST(CharacterValueTypedKind, StoreRawBytes) {
using CharT = typename TypeParam::CharT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
CharacterValue v{kind, "abc"};
CharT buffer[4]{};
@@ -671,7 +673,7 @@ TYPED_TEST(CharacterValueTypedKind, StoreRawBytes) {
TYPED_TEST(CharacterValueTypedKind, FromRawBytes) {
using CharT = typename TypeParam::CharT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
CharT data[] = {'a', 'b', 'c', '\0'};
CharacterValue reference{kind, std::basic_string<CharT>(data)};
@@ -689,7 +691,7 @@ TYPED_TEST(CharacterValueTypedKind, FromRawBytes) {
TYPED_TEST(CharacterValueTypedKind, Print) {
using CharT = typename TypeParam::CharT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int pos{CharacterKindPos<TypeParam>};
llvm::SmallString<128> buf;
diff --git a/flang/unittests/Evaluate/ComplexValueTest.cpp b/flang/unittests/Evaluate/ComplexValueTest.cpp
index 93a882f551d4a..e3b166c8dc143 100644
--- a/flang/unittests/Evaluate/ComplexValueTest.cpp
+++ b/flang/unittests/Evaluate/ComplexValueTest.cpp
@@ -18,17 +18,18 @@ using namespace Fortran::evaluate::value;
namespace {
-class ComplexValueKind : public testing::TestWithParam<int> {};
+class ComplexValueKind : public testing::TestWithParam<KindsEnum> {};
INSTANTIATE_TEST_SUITE_P(ComplexValueKind, ComplexValueKind,
- testing::ValuesIn(RealKinds), [](const testing::TestParamInfo<int> &info) {
- return "COMPLEX(" + std::to_string(info.param) + ")";
+ testing::ValuesIn(RealKinds),
+ [](const testing::TestParamInfo<KindsEnum> &info) {
+ return "COMPLEX(" + std::to_string(static_cast<int>(info.param)) + ")";
});
-RealValue Real(int kind, std::int64_t n) {
- return RealValue::FromInteger(kind, IntegerValue{8, n}).value;
+RealValue Real(KindsEnum kind, std::int64_t n) {
+ return RealValue::FromInteger(kind, IntegerValue{KindsEnum::Kind8, n}).value;
}
-ComplexValue Complex(int kind, std::int64_t re, std::int64_t im) {
+ComplexValue Complex(KindsEnum kind, std::int64_t re, std::int64_t im) {
return ComplexValue{Real(kind, re), Real(kind, im)};
}
@@ -45,14 +46,14 @@ testing::AssertionResult ComplexValuesEqual(const char *lhsExpr,
#define EXPECT_COMPLEX_EQ(lhs, rhs) \
EXPECT_PRED_FORMAT2(ComplexValuesEqual, lhs, rhs)
-std::string AsFortranString(const ComplexValue &z, int kind) {
+std::string AsFortranString(const ComplexValue &z, KindsEnum kind) {
std::string s;
llvm::raw_string_ostream os{s};
- z.AsFortran(os, kind);
+ z.AsFortran(os, static_cast<int>(kind));
return s;
}
-constexpr int KindPos(int kind) {
+constexpr int KindPos(KindsEnum kind) {
for (std::size_t i{0}; i < std::size(RealKinds); ++i) {
if (RealKinds[i] == kind) {
return static_cast<int>(i);
@@ -75,7 +76,7 @@ TEST(ComplexValue, DefaultConstructionIsMonostate) {
}
TEST_P(ComplexValueKind, ConstructFromParts) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
ComplexValue z{Real(kind, 1), Real(kind, 2)};
EXPECT_FALSE(z.IsMonostate());
EXPECT_EQ(kind, z.kind());
@@ -84,7 +85,7 @@ TEST_P(ComplexValueKind, ConstructFromParts) {
}
TEST_P(ComplexValueKind, ConstructFromRealPartOnly) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
ComplexValue z{Real(kind, 3)};
EXPECT_EQ(kind, z.kind());
EXPECT_TRUE(z.REAL() == Real(kind, 3));
@@ -94,15 +95,15 @@ TEST_P(ComplexValueKind, ConstructFromRealPartOnly) {
}
TEST_P(ComplexValueKind, ImaginaryPartIsConvertedToTheRealPartsKind) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// The imaginary operand is converted to the kind of the real operand.
- ComplexValue z{Real(kind, 1), Real(8, 2)};
+ ComplexValue z{Real(kind, 1), Real(KindsEnum::Kind8, 2)};
EXPECT_EQ(kind, z.kind());
EXPECT_TRUE(z.AIMAG() == Real(kind, 2));
}
TEST(ComplexValue, CopyAndMove) {
- ComplexValue z{Complex(4, 1, 2)};
+ ComplexValue z{Complex(KindsEnum::Kind4, 1, 2)};
ComplexValue copyConstructed{z};
EXPECT_COMPLEX_EQ(z, copyConstructed);
ComplexValue copyAssigned;
@@ -116,16 +117,16 @@ TEST(ComplexValue, CopyAndMove) {
}
TEST(ComplexValue, KindCheckingConstructors) {
- ComplexValue z{Complex(4, 1, 2)};
- EXPECT_EQ(4, ComplexValue(4, z).kind());
- EXPECT_COMPLEX_EQ(z, ComplexValue(4, z));
- ComplexValue y{Complex(8, 1, 2)};
- ComplexValue moved{8, std::move(y)};
- EXPECT_EQ(8, moved.kind());
+ ComplexValue z{Complex(KindsEnum::Kind4, 1, 2)};
+ EXPECT_EQ(KindsEnum::Kind4, ComplexValue(KindsEnum::Kind4, z).kind());
+ EXPECT_COMPLEX_EQ(z, ComplexValue(KindsEnum::Kind4, z));
+ ComplexValue y{Complex(KindsEnum::Kind8, 1, 2)};
+ ComplexValue moved{KindsEnum::Kind8, std::move(y)};
+ EXPECT_EQ(KindsEnum::Kind8, moved.kind());
}
TEST_P(ComplexValueKind, Zero) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
ComplexValue zero{ComplexValue::Zero(kind)};
EXPECT_FALSE(zero.IsMonostate());
EXPECT_EQ(kind, zero.kind());
@@ -135,13 +136,13 @@ TEST_P(ComplexValueKind, Zero) {
}
TEST(ComplexValue, BytesStored) {
- EXPECT_EQ(4u, ComplexValue::bytesStored(2));
- EXPECT_EQ(4u, ComplexValue::bytesStored(3));
- EXPECT_EQ(8u, ComplexValue::bytesStored(4));
- EXPECT_EQ(16u, ComplexValue::bytesStored(8));
- EXPECT_EQ(32u, ComplexValue::bytesStored(10));
- EXPECT_EQ(32u, ComplexValue::bytesStored(16));
- EXPECT_EQ(8u, Complex(4, 1, 2).bytesStored());
+ EXPECT_EQ(4u, ComplexValue::bytesStored(KindsEnum::Kind2));
+ EXPECT_EQ(4u, ComplexValue::bytesStored(KindsEnum::Kind3));
+ EXPECT_EQ(8u, ComplexValue::bytesStored(KindsEnum::Kind4));
+ EXPECT_EQ(16u, ComplexValue::bytesStored(KindsEnum::Kind8));
+ EXPECT_EQ(32u, ComplexValue::bytesStored(KindsEnum::Kind10));
+ EXPECT_EQ(32u, ComplexValue::bytesStored(KindsEnum::Kind16));
+ EXPECT_EQ(8u, Complex(KindsEnum::Kind4, 1, 2).bytesStored());
}
//===----------------------------------------------------------------------===//
@@ -149,25 +150,25 @@ TEST(ComplexValue, BytesStored) {
//===----------------------------------------------------------------------===//
TEST_P(ComplexValueKind, REAL) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_TRUE(Complex(kind, 1, 2).REAL() == Real(kind, 1));
EXPECT_EQ(kind, Complex(kind, 1, 2).REAL().kind());
}
TEST_P(ComplexValueKind, AIMAG) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_TRUE(Complex(kind, 1, 2).AIMAG() == Real(kind, 2));
EXPECT_EQ(kind, Complex(kind, 1, 2).AIMAG().kind());
}
TEST_P(ComplexValueKind, CONJG) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_COMPLEX_EQ(Complex(kind, 1, -2), Complex(kind, 1, 2).CONJG());
EXPECT_COMPLEX_EQ(Complex(kind, 1, 2), Complex(kind, 1, 2).CONJG().CONJG());
}
TEST_P(ComplexValueKind, Negate) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_COMPLEX_EQ(Complex(kind, -1, -2), Complex(kind, 1, 2).Negate());
// Negating a zero flips both sign bits.
ComplexValue negZero{ComplexValue::Zero(kind).Negate()};
@@ -181,7 +182,7 @@ TEST_P(ComplexValueKind, Negate) {
//===----------------------------------------------------------------------===//
TEST_P(ComplexValueKind, Equals) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// Equals() compares numerically, so +0.0 and -0.0 are equal ...
EXPECT_TRUE(
ComplexValue::Zero(kind).Equals(ComplexValue::Zero(kind).Negate()));
@@ -193,7 +194,7 @@ TEST_P(ComplexValueKind, Equals) {
}
TEST_P(ComplexValueKind, EqualityOperators) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// The operators compare bit patterns, so -0.0 differs from +0.0 ...
EXPECT_FALSE(ComplexValue::Zero(kind) == ComplexValue::Zero(kind).Negate());
EXPECT_TRUE(ComplexValue::Zero(kind) != ComplexValue::Zero(kind).Negate());
@@ -204,14 +205,14 @@ TEST_P(ComplexValueKind, EqualityOperators) {
}
TEST_P(ComplexValueKind, IsZero) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_TRUE(ComplexValue::Zero(kind).IsZero());
EXPECT_FALSE(Complex(kind, 1, 0).IsZero());
EXPECT_FALSE(Complex(kind, 0, 1).IsZero());
}
TEST_P(ComplexValueKind, IsInfinite) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue inf{Real(kind, 1).Divide(RealValue::Zero(kind)).value};
ASSERT_TRUE(inf.IsInfinite());
EXPECT_FALSE(ComplexValue::Zero(kind).IsInfinite());
@@ -221,7 +222,7 @@ TEST_P(ComplexValueKind, IsInfinite) {
}
TEST_P(ComplexValueKind, IsNotANumber) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue nan{RealValue::NotANumber(kind)};
EXPECT_FALSE(ComplexValue::Zero(kind).IsNotANumber());
EXPECT_TRUE(ComplexValue::NotANumber(kind).IsNotANumber());
@@ -231,14 +232,14 @@ TEST_P(ComplexValueKind, IsNotANumber) {
}
TEST_P(ComplexValueKind, IsSignalingNaN) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_FALSE(ComplexValue::Zero(kind).IsSignalingNaN());
// NotANumber() produces quiet NaNs.
EXPECT_FALSE(ComplexValue::NotANumber(kind).IsSignalingNaN());
}
TEST_P(ComplexValueKind, NotANumber) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
ComplexValue nan{ComplexValue::NotANumber(kind)};
EXPECT_EQ(kind, nan.kind());
EXPECT_TRUE(nan.REAL().IsNotANumber());
@@ -250,22 +251,23 @@ TEST_P(ComplexValueKind, NotANumber) {
//===----------------------------------------------------------------------===//
TEST_P(ComplexValueKind, FromInteger) {
- const int kind{GetParam()};
- auto z{ComplexValue::FromInteger(kind, IntegerValue{8, 3})};
+ const KindsEnum kind{GetParam()};
+ auto z{ComplexValue::FromInteger(kind, IntegerValue{KindsEnum::Kind8, 3})};
EXPECT_TRUE(z.flags.empty());
EXPECT_EQ(kind, z.value.kind());
EXPECT_COMPLEX_EQ(Complex(kind, 3, 0), z.value);
- auto negative{ComplexValue::FromInteger(kind, IntegerValue{8, -3})};
+ auto negative{
+ ComplexValue::FromInteger(kind, IntegerValue{KindsEnum::Kind8, -3})};
EXPECT_COMPLEX_EQ(Complex(kind, -3, 0), negative.value);
// Reading the same bits as unsigned gives a large positive real part.
auto asUnsigned{ComplexValue::FromInteger(
- kind, IntegerValue{8, -1}, /*isUnsigned=*/true)};
+ kind, IntegerValue{KindsEnum::Kind8, -1}, /*isUnsigned=*/true)};
EXPECT_FALSE(asUnsigned.value.REAL().IsNegative());
EXPECT_TRUE(asUnsigned.value.AIMAG().IsZero());
}
TEST_P(ComplexValueKind, Add) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto sum{Complex(kind, 1, 2).Add(Complex(kind, 3, 4))};
EXPECT_TRUE(sum.flags.empty());
EXPECT_COMPLEX_EQ(Complex(kind, 4, 6), sum.value);
@@ -277,14 +279,14 @@ TEST_P(ComplexValueKind, Add) {
}
TEST_P(ComplexValueKind, Subtract) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto diff{Complex(kind, 1, 2).Subtract(Complex(kind, 3, 4))};
EXPECT_TRUE(diff.flags.empty());
EXPECT_COMPLEX_EQ(Complex(kind, -2, -2), diff.value);
}
TEST_P(ComplexValueKind, Multiply) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// (1+2i)*(3+4i) = (3-8) + (4+6)i
auto product{Complex(kind, 1, 2).Multiply(Complex(kind, 3, 4))};
EXPECT_TRUE(product.flags.empty());
@@ -295,7 +297,7 @@ TEST_P(ComplexValueKind, Multiply) {
}
TEST_P(ComplexValueKind, Divide) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// (-5+10i)/(3+4i) = 1+2i
auto quotient{Complex(kind, -5, 10).Divide(Complex(kind, 3, 4))};
EXPECT_COMPLEX_EQ(Complex(kind, 1, 2), quotient.value);
@@ -313,7 +315,7 @@ TEST_P(ComplexValueKind, Divide) {
}
TEST_P(ComplexValueKind, ABS) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto abs{Complex(kind, 3, 4).ABS()};
EXPECT_TRUE(abs.value == Real(kind, 5));
EXPECT_EQ(kind, abs.value.kind());
@@ -322,7 +324,7 @@ TEST_P(ComplexValueKind, ABS) {
}
TEST_P(ComplexValueKind, KahanSummation) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
ComplexValue correction{ComplexValue::Zero(kind)};
auto sum{Complex(kind, 1, 2).KahanSummation(Complex(kind, 3, 4), correction)};
EXPECT_COMPLEX_EQ(Complex(kind, 4, 6), sum.value);
@@ -337,7 +339,7 @@ TEST_P(ComplexValueKind, KahanSummation) {
}
TEST_P(ComplexValueKind, FlushSubnormalToZero) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue subnormal{RealValue{kind, IntegerValue{kind, 1}}};
ASSERT_FALSE(subnormal.IsZero());
ComplexValue z{subnormal, subnormal};
@@ -353,12 +355,14 @@ TEST_P(ComplexValueKind, FlushSubnormalToZero) {
//===----------------------------------------------------------------------===//
TEST(ComplexValue, DumpHexadecimal) {
- EXPECT_EQ("(0.0,0.0)", ComplexValue::Zero(4).DumpHexadecimal());
- EXPECT_EQ("(0x1.0p0,-0x1.0p1)", Complex(4, 1, -2).DumpHexadecimal());
+ EXPECT_EQ(
+ "(0.0,0.0)", ComplexValue::Zero(KindsEnum::Kind4).DumpHexadecimal());
+ EXPECT_EQ(
+ "(0x1.0p0,-0x1.0p1)", Complex(KindsEnum::Kind4, 1, -2).DumpHexadecimal());
}
TEST_P(ComplexValueKind, AsFortran) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
std::string s{AsFortranString(Complex(kind, 1, 2), kind)};
// The components are emitted as a parenthesized, comma-separated pair.
EXPECT_EQ('(', s.front());
@@ -367,7 +371,7 @@ TEST_P(ComplexValueKind, AsFortran) {
}
TEST_P(ComplexValueKind, RawBytesRoundTrip) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
ComplexValue original{Complex(kind, 1, -2)};
char buffer[32]{};
ASSERT_EQ(ComplexValue::bytesStored(kind), original.bytesStored());
@@ -384,7 +388,7 @@ TEST_P(ComplexValueKind, RawBytesRoundTrip) {
}
TEST_P(ComplexValueKind, Print) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
const int pos{KindPos(kind)};
llvm::SmallString<128> buf;
diff --git a/flang/unittests/Evaluate/IntegerValueTest.cpp b/flang/unittests/Evaluate/IntegerValueTest.cpp
index 59b063dfa1686..e267132207344 100644
--- a/flang/unittests/Evaluate/IntegerValueTest.cpp
+++ b/flang/unittests/Evaluate/IntegerValueTest.cpp
@@ -50,11 +50,11 @@ struct KindName {
template <typename T> class IntegerValueTypedKind : public testing::Test {};
TYPED_TEST_SUITE(IntegerValueTypedKind, IntegerTypedKinds, KindName);
-class IntegerValueKind : public testing::TestWithParam<int> {};
+class IntegerValueKind : public testing::TestWithParam<KindsEnum> {};
INSTANTIATE_TEST_SUITE_P(IntegerValueKind, IntegerValueKind,
testing::ValuesIn(IntegerKinds),
- [](const testing::TestParamInfo<int> &info) {
- return "INTEGER(" + std::to_string(info.param) + ")";
+ [](const testing::TestParamInfo<KindsEnum> &info) {
+ return "INTEGER(" + std::to_string(static_cast<int>(info.param)) + ")";
});
//===----------------------------------------------------------------------===//
@@ -78,7 +78,7 @@ TEST(IntegerValue, Monostate) {
TYPED_TEST(IntegerValueTypedKind, ConstructFromIntegral) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue positive{kind, 42};
EXPECT_EQ(42, positive.ToInt64());
@@ -102,7 +102,7 @@ TYPED_TEST(IntegerValueTypedKind, ConstructFromIntegral) {
}
TEST_P(IntegerValueKind, CopyAndMove) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
const IntegerValue x{IntegerValue::HUGE(kind)};
IntegerValue copyConstructed{x};
@@ -127,7 +127,7 @@ TEST_P(IntegerValueKind, CopyAndMove) {
TYPED_TEST(IntegerValueTypedKind, KindCheckingConstructors) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue x{kind, 7};
IntegerValue copied{kind, x};
@@ -143,7 +143,7 @@ TYPED_TEST(IntegerValueTypedKind, KindCheckingConstructors) {
TYPED_TEST(IntegerValueTypedKind, Zero) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(kind, zero.kind());
@@ -153,50 +153,51 @@ TYPED_TEST(IntegerValueTypedKind, Zero) {
}
TEST(IntegerValue, Bits) {
- EXPECT_EQ(8, IntegerValue::bits(1));
- EXPECT_EQ(16, IntegerValue::bits(2));
- EXPECT_EQ(16, IntegerValue::bits(3));
- EXPECT_EQ(32, IntegerValue::bits(4));
- EXPECT_EQ(64, IntegerValue::bits(8));
- EXPECT_EQ(128, IntegerValue::bits(10)); // 80 significant bits, 128 stored
- EXPECT_EQ(128, IntegerValue::bits(16));
-
- IntegerValue v{4, 0};
+ EXPECT_EQ(8, IntegerValue::bits(KindsEnum::Kind1));
+ EXPECT_EQ(16, IntegerValue::bits(KindsEnum::Kind2));
+ EXPECT_EQ(16, IntegerValue::bits(KindsEnum::Kind3));
+ EXPECT_EQ(32, IntegerValue::bits(KindsEnum::Kind4));
+ EXPECT_EQ(64, IntegerValue::bits(KindsEnum::Kind8));
+ EXPECT_EQ(128,
+ IntegerValue::bits(KindsEnum::Kind10)); // 80 significant bits, 128 stored
+ EXPECT_EQ(128, IntegerValue::bits(KindsEnum::Kind16));
+
+ IntegerValue v{KindsEnum::Kind4, 0};
EXPECT_EQ(32, v.bits());
}
TEST(IntegerValue, BytesStored) {
- EXPECT_EQ(1u, IntegerValue::bytesStored(1));
- EXPECT_EQ(2u, IntegerValue::bytesStored(2));
- EXPECT_EQ(2u, IntegerValue::bytesStored(3));
- EXPECT_EQ(4u, IntegerValue::bytesStored(4));
- EXPECT_EQ(8u, IntegerValue::bytesStored(8));
- EXPECT_EQ(16u, IntegerValue::bytesStored(10));
- EXPECT_EQ(16u, IntegerValue::bytesStored(16));
-
- IntegerValue v{4, 0};
+ EXPECT_EQ(1u, IntegerValue::bytesStored(KindsEnum::Kind1));
+ EXPECT_EQ(2u, IntegerValue::bytesStored(KindsEnum::Kind2));
+ EXPECT_EQ(2u, IntegerValue::bytesStored(KindsEnum::Kind3));
+ EXPECT_EQ(4u, IntegerValue::bytesStored(KindsEnum::Kind4));
+ EXPECT_EQ(8u, IntegerValue::bytesStored(KindsEnum::Kind8));
+ EXPECT_EQ(16u, IntegerValue::bytesStored(KindsEnum::Kind10));
+ EXPECT_EQ(16u, IntegerValue::bytesStored(KindsEnum::Kind16));
+
+ IntegerValue v{KindsEnum::Kind4, 0};
EXPECT_EQ(4u, v.bytesStored());
}
TYPED_TEST(IntegerValueTypedKind, DIGITS) {
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
EXPECT_EQ(TypeParam::bits - 1, IntegerValue::DIGITS(kind));
}
TEST(IntegerValue, RANGE) {
- EXPECT_EQ(2, IntegerValue::RANGE(1));
- EXPECT_EQ(4, IntegerValue::RANGE(2));
- EXPECT_EQ(9, IntegerValue::RANGE(4));
- EXPECT_EQ(18, IntegerValue::RANGE(8));
- EXPECT_EQ(38, IntegerValue::RANGE(16));
+ EXPECT_EQ(2, IntegerValue::RANGE(KindsEnum::Kind1));
+ EXPECT_EQ(4, IntegerValue::RANGE(KindsEnum::Kind2));
+ EXPECT_EQ(9, IntegerValue::RANGE(KindsEnum::Kind4));
+ EXPECT_EQ(18, IntegerValue::RANGE(KindsEnum::Kind8));
+ EXPECT_EQ(38, IntegerValue::RANGE(KindsEnum::Kind16));
}
TEST(IntegerValue, UnsignedRANGE) {
- EXPECT_EQ(2, IntegerValue::UnsignedRANGE(1));
- EXPECT_EQ(4, IntegerValue::UnsignedRANGE(2));
- EXPECT_EQ(9, IntegerValue::UnsignedRANGE(4));
- EXPECT_EQ(19, IntegerValue::UnsignedRANGE(8));
- EXPECT_EQ(38, IntegerValue::UnsignedRANGE(16));
+ EXPECT_EQ(2, IntegerValue::UnsignedRANGE(KindsEnum::Kind1));
+ EXPECT_EQ(4, IntegerValue::UnsignedRANGE(KindsEnum::Kind2));
+ EXPECT_EQ(9, IntegerValue::UnsignedRANGE(KindsEnum::Kind4));
+ EXPECT_EQ(19, IntegerValue::UnsignedRANGE(KindsEnum::Kind8));
+ EXPECT_EQ(38, IntegerValue::UnsignedRANGE(KindsEnum::Kind16));
}
//===----------------------------------------------------------------------===//
@@ -205,9 +206,9 @@ TEST(IntegerValue, UnsignedRANGE) {
TYPED_TEST(IntegerValueTypedKind, UnsignedDecimal) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ("0", zero.UnsignedDecimal());
IntegerValue one{kind, 1};
@@ -250,9 +251,9 @@ TYPED_TEST(IntegerValueTypedKind, UnsignedDecimal) {
TYPED_TEST(IntegerValueTypedKind, SignedDecimal) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ("0", zero.SignedDecimal());
IntegerValue one{kind, 1};
@@ -297,9 +298,9 @@ TYPED_TEST(IntegerValueTypedKind, SignedDecimal) {
TYPED_TEST(IntegerValueTypedKind, Hexadecimal) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ("0", zero.Hexadecimal());
IntegerValue one{kind, 1};
@@ -342,7 +343,7 @@ TYPED_TEST(IntegerValueTypedKind, Hexadecimal) {
TYPED_TEST(IntegerValueTypedKind, Read) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
{
// Leading blanks are skipped and trailing text is left for the caller.
@@ -404,7 +405,7 @@ TYPED_TEST(IntegerValueTypedKind, Read) {
TYPED_TEST(IntegerValueTypedKind, MASKL) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
static constexpr UnsignedT nobits{0};
static constexpr UnsignedT allbits{UnsignedT(~UnsignedT(0))};
@@ -442,7 +443,7 @@ TYPED_TEST(IntegerValueTypedKind, MASKL) {
TYPED_TEST(IntegerValueTypedKind, MASKR) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
static constexpr UnsignedT nobits{0};
static constexpr UnsignedT allbits{UnsignedT(~UnsignedT(0))};
@@ -473,7 +474,7 @@ TYPED_TEST(IntegerValueTypedKind, MASKR) {
TYPED_TEST(IntegerValueTypedKind, HUGE) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue huge{IntegerValue::HUGE(kind)};
EXPECT_EQ(kind, huge.kind());
@@ -482,7 +483,7 @@ TYPED_TEST(IntegerValueTypedKind, HUGE) {
TYPED_TEST(IntegerValueTypedKind, Least) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue least{IntegerValue::Least(kind)};
EXPECT_EQ(kind, least.kind());
@@ -496,9 +497,9 @@ TYPED_TEST(IntegerValueTypedKind, Least) {
TYPED_TEST(IntegerValueTypedKind, IsZero) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_TRUE(zero.IsZero());
IntegerValue one{kind, 1};
@@ -532,9 +533,9 @@ TYPED_TEST(IntegerValueTypedKind, IsZero) {
TYPED_TEST(IntegerValueTypedKind, IsNegative) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_FALSE(zero.IsNegative());
IntegerValue one{kind, 1};
@@ -568,9 +569,9 @@ TYPED_TEST(IntegerValueTypedKind, IsNegative) {
TYPED_TEST(IntegerValueTypedKind, CompareToZeroSigned) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(Ordering::Equal, zero.CompareToZeroSigned());
IntegerValue one{kind, 1};
@@ -604,10 +605,10 @@ TYPED_TEST(IntegerValueTypedKind, CompareToZeroSigned) {
TYPED_TEST(IntegerValueTypedKind, LEADZ) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(bits, zero.LEADZ());
IntegerValue one{kind, 1};
@@ -632,7 +633,7 @@ TYPED_TEST(IntegerValueTypedKind, LEADZ) {
EXPECT_EQ(0, sminv.LEADZ());
IntegerValue patternv{kind, 0x7FFFFFFF7FFF7F7Full};
- EXPECT_EQ((kind == 16) ? 65 : 1, patternv.LEADZ());
+ EXPECT_EQ((kind == KindsEnum::Kind16) ? 65 : 1, patternv.LEADZ());
IntegerValue invpatternv{kind, ~UnsignedT(0x7FFFFFFF7FFF7F7Full)};
EXPECT_EQ(0, invpatternv.LEADZ());
@@ -641,10 +642,10 @@ TYPED_TEST(IntegerValueTypedKind, LEADZ) {
TYPED_TEST(IntegerValueTypedKind, POPCNT) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(0, zero.POPCNT());
IntegerValue one{kind, 1};
@@ -670,19 +671,21 @@ TYPED_TEST(IntegerValueTypedKind, POPCNT) {
IntegerValue patternv{kind, 0x7FFFFFFF7FFF7F7Full};
const int kindPos{IntKindPos<TypeParam>};
- EXPECT_EQ((kind == 16) ? 60 : bits - kindPos - 1, patternv.POPCNT());
+ EXPECT_EQ(
+ (kind == KindsEnum::Kind16) ? 60 : bits - kindPos - 1, patternv.POPCNT());
IntegerValue invpatternv{kind, ~UnsignedT(0x7FFFFFFF7FFF7F7Full)};
- EXPECT_EQ((kind == 16) ? 68 : 1 + kindPos, invpatternv.POPCNT());
+ EXPECT_EQ(
+ (kind == KindsEnum::Kind16) ? 68 : 1 + kindPos, invpatternv.POPCNT());
}
TYPED_TEST(IntegerValueTypedKind, POPPAR) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_FALSE(zero.POPPAR());
IntegerValue one{kind, 1};
@@ -716,10 +719,10 @@ TYPED_TEST(IntegerValueTypedKind, POPPAR) {
TYPED_TEST(IntegerValueTypedKind, TRAILZ) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
- IntegerValue zero{IntegerValue::Zero(TypeParam::kind)};
+ IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(bits, zero.TRAILZ());
IntegerValue one{kind, 1};
@@ -751,7 +754,7 @@ TYPED_TEST(IntegerValueTypedKind, TRAILZ) {
}
TYPED_TEST(IntegerValueTypedKind, BTEST) {
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
IntegerValue zero{IntegerValue::Zero(kind)};
@@ -770,7 +773,7 @@ TYPED_TEST(IntegerValueTypedKind, BTEST) {
TYPED_TEST(IntegerValueTypedKind, CompareUnsigned) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(Ordering::Equal, zero.CompareUnsigned(zero));
@@ -796,7 +799,7 @@ TYPED_TEST(IntegerValueTypedKind, CompareUnsigned) {
TYPED_TEST(IntegerValueTypedKind, CompareSigned) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(Ordering::Equal, zero.CompareSigned(zero));
@@ -820,7 +823,7 @@ TYPED_TEST(IntegerValueTypedKind, CompareSigned) {
TYPED_TEST(IntegerValueTypedKind, BitwiseComparisons) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
IntegerValue one{kind, 1};
@@ -851,7 +854,7 @@ TYPED_TEST(IntegerValueTypedKind, BitwiseComparisons) {
TYPED_TEST(IntegerValueTypedKind, RelationalOperators) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_FALSE(zero < zero);
@@ -898,7 +901,7 @@ TYPED_TEST(IntegerValueTypedKind, RelationalOperators) {
TYPED_TEST(IntegerValueTypedKind, ToUInt64) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(0u, zero.ToUInt64());
@@ -946,7 +949,7 @@ TYPED_TEST(IntegerValueTypedKind, ToUInt64) {
TYPED_TEST(IntegerValueTypedKind, ToInt64) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(0, zero.ToInt64());
@@ -988,7 +991,7 @@ TYPED_TEST(IntegerValueTypedKind, ToInt64) {
TYPED_TEST(IntegerValueTypedKind, ToUInt) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
// Small values fit in every host width, regardless of kind.
IntegerValue zero{IntegerValue::Zero(kind)};
@@ -1031,7 +1034,7 @@ TYPED_TEST(IntegerValueTypedKind, ToUInt) {
// Least truncates to zero in any host width narrower than the kind.
IntegerValue sminv{kind, std::numeric_limits<SignedT>::min()};
- EXPECT_EQ(kind == 1 ? 0x80u : 0, sminv.ToUInt<uint8_t>());
+ EXPECT_EQ(kind == KindsEnum::Kind1 ? 0x80u : 0, sminv.ToUInt<uint8_t>());
EXPECT_EQ(uint128_t{UnsignedT(std::numeric_limits<SignedT>::min())},
sminv.ToUInt<uint128_t>());
@@ -1055,7 +1058,7 @@ TYPED_TEST(IntegerValueTypedKind, ToUInt) {
TYPED_TEST(IntegerValueTypedKind, ToSInt) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
// Small values fit in every host width, regardless of kind.
IntegerValue zero{IntegerValue::Zero(kind)};
@@ -1104,7 +1107,7 @@ TYPED_TEST(IntegerValueTypedKind, ToSInt) {
// kind; a narrower width truncates it away, along with the sign. Widening
// to the widest kind's own width (16) always sign-extends the true value.
IntegerValue sminv{kind, std::numeric_limits<SignedT>::min()};
- EXPECT_EQ(kind == 1 ? -128 : 0, sminv.ToSInt<int8_t>());
+ EXPECT_EQ(kind == KindsEnum::Kind1 ? -128 : 0, sminv.ToSInt<int8_t>());
EXPECT_EQ(
int8_t(std::numeric_limits<SignedT>::min()), sminv.ToSInt<int8_t>());
EXPECT_EQ(
@@ -1140,7 +1143,7 @@ TYPED_TEST(IntegerValueTypedKind, ToSInt) {
TYPED_TEST(IntegerValueTypedKind, NOT) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
EXPECT_EQ(UnsignedT(~UnsignedT{0}), zero.NOT().ToUInt<UnsignedT>());
@@ -1168,7 +1171,7 @@ TYPED_TEST(IntegerValueTypedKind, NOT) {
TYPED_TEST(IntegerValueTypedKind, IAND) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue theanswer{kind, 42};
EXPECT_EQ(theanswer, theanswer.IAND(theanswer));
@@ -1188,7 +1191,7 @@ TYPED_TEST(IntegerValueTypedKind, IAND) {
TYPED_TEST(IntegerValueTypedKind, IOR) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue theanswer{kind, 42};
EXPECT_EQ(theanswer, theanswer.IOR(theanswer));
@@ -1208,7 +1211,7 @@ TYPED_TEST(IntegerValueTypedKind, IOR) {
TYPED_TEST(IntegerValueTypedKind, IEOR) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
IntegerValue theanswer{kind, 42};
@@ -1225,7 +1228,7 @@ TYPED_TEST(IntegerValueTypedKind, IEOR) {
TYPED_TEST(IntegerValueTypedKind, MERGE_BITS) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue negone{kind, -1};
IntegerValue zero{IntegerValue::Zero(kind)};
@@ -1240,7 +1243,7 @@ TYPED_TEST(IntegerValueTypedKind, MERGE_BITS) {
TYPED_TEST(IntegerValueTypedKind, MAX) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
IntegerValue one{kind, 1};
@@ -1259,7 +1262,7 @@ TYPED_TEST(IntegerValueTypedKind, MAX) {
TYPED_TEST(IntegerValueTypedKind, MIN) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
IntegerValue one{kind, 1};
@@ -1279,7 +1282,7 @@ TYPED_TEST(IntegerValueTypedKind, MIN) {
TYPED_TEST(IntegerValueTypedKind, IBCLR) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
IntegerValue theanswer{kind, 0b101010};
@@ -1299,7 +1302,7 @@ TYPED_TEST(IntegerValueTypedKind, IBCLR) {
TYPED_TEST(IntegerValueTypedKind, IBSET) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
IntegerValue theanswer{kind, 42}; // 0b101010
@@ -1318,7 +1321,7 @@ TYPED_TEST(IntegerValueTypedKind, IBSET) {
}
TYPED_TEST(IntegerValueTypedKind, IBITS) {
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
// 0x...ef: low byte is 0b11101111.
@@ -1340,7 +1343,7 @@ TYPED_TEST(IntegerValueTypedKind, IBITS) {
TYPED_TEST(IntegerValueTypedKind, ISHFT) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
// A positive count shifts left; a negative count shifts right.
@@ -1366,7 +1369,7 @@ TYPED_TEST(IntegerValueTypedKind, ISHFT) {
TYPED_TEST(IntegerValueTypedKind, SHIFTL) {
using UnsignedT = typename TypeParam::UnsignedT;
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
IntegerValue one{kind, 1};
@@ -1385,7 +1388,7 @@ TYPED_TEST(IntegerValueTypedKind, SHIFTL) {
TYPED_TEST(IntegerValueTypedKind, SHIFTR) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
IntegerValue negone{kind, -1};
@@ -1404,7 +1407,7 @@ TYPED_TEST(IntegerValueTypedKind, SHIFTR) {
TYPED_TEST(IntegerValueTypedKind, SHIFTA) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
IntegerValue negone{kind, -1};
@@ -1423,7 +1426,7 @@ TYPED_TEST(IntegerValueTypedKind, SHIFTA) {
TYPED_TEST(IntegerValueTypedKind, ISHFTC) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
// Rotating a uniform bit pattern leaves it unchanged.
@@ -1451,7 +1454,7 @@ TYPED_TEST(IntegerValueTypedKind, ISHFTC) {
TYPED_TEST(IntegerValueTypedKind, DSHIFTL) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
const UnsignedT i{UnsignedT(0x0123456789abcdefull)};
const UnsignedT j{UnsignedT(~i)};
@@ -1470,7 +1473,7 @@ TYPED_TEST(IntegerValueTypedKind, DSHIFTL) {
TYPED_TEST(IntegerValueTypedKind, DSHIFTR) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
const UnsignedT i{UnsignedT(0x0123456789abcdefull)};
const UnsignedT j{UnsignedT(~i)};
@@ -1494,7 +1497,7 @@ TYPED_TEST(IntegerValueTypedKind, DSHIFTR) {
TYPED_TEST(IntegerValueTypedKind, Negate) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
auto negZero{zero.Negate()};
@@ -1530,7 +1533,7 @@ TYPED_TEST(IntegerValueTypedKind, Negate) {
TYPED_TEST(IntegerValueTypedKind, ABS) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
auto absZero{zero.ABS()};
@@ -1568,7 +1571,7 @@ TYPED_TEST(IntegerValueTypedKind, ABS) {
TYPED_TEST(IntegerValueTypedKind, AddUnsigned) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
auto zeroPlusZero{zero.AddUnsigned(zero)};
@@ -1605,7 +1608,7 @@ TYPED_TEST(IntegerValueTypedKind, AddUnsigned) {
TYPED_TEST(IntegerValueTypedKind, AddSigned) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
auto zeroPlusZero{zero.AddSigned(zero)};
@@ -1639,7 +1642,7 @@ TYPED_TEST(IntegerValueTypedKind, AddSigned) {
TYPED_TEST(IntegerValueTypedKind, SubtractSigned) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
auto zeroMinusZero{zero.SubtractSigned(zero)};
@@ -1672,7 +1675,7 @@ TYPED_TEST(IntegerValueTypedKind, SubtractSigned) {
TYPED_TEST(IntegerValueTypedKind, DIM) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue one{kind, 1};
IntegerValue theanswer{kind, 42};
@@ -1705,7 +1708,7 @@ TYPED_TEST(IntegerValueTypedKind, DIM) {
TYPED_TEST(IntegerValueTypedKind, SIGN) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue one{kind, 1};
IntegerValue negone{kind, -1};
@@ -1740,7 +1743,7 @@ TYPED_TEST(IntegerValueTypedKind, SIGN) {
TYPED_TEST(IntegerValueTypedKind, MultiplyUnsigned) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int bits{TypeParam::bits};
IntegerValue zero{IntegerValue::Zero(kind)};
@@ -1779,7 +1782,7 @@ TYPED_TEST(IntegerValueTypedKind, MultiplyUnsigned) {
TYPED_TEST(IntegerValueTypedKind, MultiplySigned) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue zero{IntegerValue::Zero(kind)};
IntegerValue theanswer{kind, 42};
@@ -1812,7 +1815,7 @@ TYPED_TEST(IntegerValueTypedKind, MultiplySigned) {
TYPED_TEST(IntegerValueTypedKind, DivideUnsigned) {
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue patternv{kind, 0x0123456789abcdefull};
IntegerValue zero{IntegerValue::Zero(kind)};
@@ -1846,7 +1849,7 @@ TYPED_TEST(IntegerValueTypedKind, DivideUnsigned) {
TYPED_TEST(IntegerValueTypedKind, DivideSigned) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
// A nonzero remainder has the sign of the dividend: this is MOD, not MODULO.
struct {
@@ -1892,7 +1895,7 @@ TYPED_TEST(IntegerValueTypedKind, DivideSigned) {
TYPED_TEST(IntegerValueTypedKind, MODULO) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
// The result has the sign of the divisor.
struct {
int64_t x, y, modulo;
@@ -1929,7 +1932,7 @@ TYPED_TEST(IntegerValueTypedKind, MODULO) {
}
TYPED_TEST(IntegerValueTypedKind, Power) {
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
IntegerValue three{kind, 3};
IntegerValue two{kind, 2};
auto square{three.Power(two)};
@@ -1977,7 +1980,7 @@ TYPED_TEST(IntegerValueTypedKind, Power) {
TYPED_TEST(IntegerValueTypedKind, RawBytesRoundTrip) {
using SignedT = typename TypeParam::SignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
ASSERT_EQ(
IntegerValue::bytesStored(kind), IntegerValue::Zero(kind).bytesStored());
@@ -2045,19 +2048,19 @@ TYPED_TEST(IntegerValueTypedKind, RawBytesRoundTrip) {
//===----------------------------------------------------------------------===//
class IntegerValueKindPair
- : public testing::TestWithParam<std::tuple<int, int>> {};
+ : public testing::TestWithParam<std::tuple<KindsEnum, KindsEnum>> {};
INSTANTIATE_TEST_SUITE_P(AllKindPairs, IntegerValueKindPair,
testing::Combine(
- testing::ValuesIn(std::initializer_list<int> FORTRAN_INTEGER_KINDS),
- testing::ValuesIn(std::initializer_list<int> FORTRAN_INTEGER_KINDS)),
- [](const testing::TestParamInfo<std::tuple<int, int>> &info) {
- return "KIND" + std::to_string(std::get<0>(info.param)) + "AndKIND" +
- std::to_string(std::get<1>(info.param));
+ testing::ValuesIn(IntegerKinds), testing::ValuesIn(IntegerKinds)),
+ [](const testing::TestParamInfo<std::tuple<KindsEnum, KindsEnum>> &info) {
+ return "KIND" +
+ std::to_string(static_cast<int>(std::get<0>(info.param))) +
+ "AndKIND" + std::to_string(static_cast<int>(std::get<1>(info.param)));
});
TEST_P(IntegerValueKindPair, ConvertUnsigned) {
- const int from{std::get<0>(GetParam())}, to{std::get<1>(GetParam())};
+ const KindsEnum from{std::get<0>(GetParam())}, to{std::get<1>(GetParam())};
const int fromBits{IntegerValue::bits(from)}, toBits{IntegerValue::bits(to)};
const int common{std::min(fromBits, toBits)};
@@ -2076,7 +2079,7 @@ TEST_P(IntegerValueKindPair, ConvertUnsigned) {
}
TEST_P(IntegerValueKindPair, ConvertSigned) {
- const int from{std::get<0>(GetParam())}, to{std::get<1>(GetParam())};
+ const KindsEnum from{std::get<0>(GetParam())}, to{std::get<1>(GetParam())};
const int fromBits{IntegerValue::bits(from)}, toBits{IntegerValue::bits(to)};
// All ones stays all ones: it sign-extends and truncates to itself.
auto ones{IntegerValue::ConvertSigned(IntegerValue{from, -1}, toBits)};
@@ -2095,8 +2098,8 @@ TEST_P(IntegerValueKindPair, ConvertSigned) {
}
TEST_P(IntegerValueKindPair, MixedKindOperandsAreCoerced) {
- const int receiver{std::get<0>(GetParam())};
- const int other{std::get<1>(GetParam())};
+ const KindsEnum receiver{std::get<0>(GetParam())};
+ const KindsEnum other{std::get<1>(GetParam())};
IntegerValue x{receiver, 0x5a};
IntegerValue allOnes{other, -1};
// The result takes the receiver's kind; the argument is converted to it,
@@ -2111,7 +2114,7 @@ TEST_P(IntegerValueKindPair, MixedKindOperandsAreCoerced) {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-TEST(IntegerValue, Dump) { IntegerValue(4, -1).dump(); }
+TEST(IntegerValue, Dump) { IntegerValue(KindsEnum::Kind4, -1).dump(); }
#endif
// Not an IntegerValue method, but the ordering that its comparisons return;
@@ -2131,7 +2134,7 @@ TEST(Ordering, Reverse) {
// dyadic operations, every pair of values) of a narrow kind.
//===----------------------------------------------------------------------===//
-void ExhaustiveUnary(int kind) {
+void ExhaustiveUnary(KindsEnum kind) {
const int bits{IntegerValue::bits(kind)};
ASSERT_LE(bits, 16); // the reference arithmetic below assumes a narrow kind
const uint64_t maxUnsigned{(uint64_t{1} << bits) - 1};
@@ -2231,12 +2234,12 @@ void ExhaustiveUnary(int kind) {
}
}
-TEST(IntegerValue, ExhaustiveUnaryKind1) { ExhaustiveUnary(1); }
+TEST(IntegerValue, ExhaustiveUnaryKind1) { ExhaustiveUnary(KindsEnum::Kind1); }
-TEST(IntegerValue, ExhaustiveUnaryKind2) { ExhaustiveUnary(2); }
+TEST(IntegerValue, ExhaustiveUnaryKind2) { ExhaustiveUnary(KindsEnum::Kind2); }
TEST(IntegerValue, ExhaustiveDyadicKind1) {
- constexpr int kind{1};
+ constexpr KindsEnum kind{KindsEnum::Kind1};
constexpr int bits{8};
constexpr uint64_t maxUnsigned{0xff};
constexpr int64_t maxPositiveSigned{0x7f};
@@ -2331,7 +2334,7 @@ TEST(IntegerValue, ExhaustiveDyadicKind1) {
}
TYPED_TEST(IntegerValueTypedKind, Print) {
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
constexpr int pos{IntKindPos<TypeParam>};
llvm::SmallString<128> buf;
diff --git a/flang/unittests/Evaluate/LogicalValueTest.cpp b/flang/unittests/Evaluate/LogicalValueTest.cpp
index bb0e9d9575f56..811906a83a6c9 100644
--- a/flang/unittests/Evaluate/LogicalValueTest.cpp
+++ b/flang/unittests/Evaluate/LogicalValueTest.cpp
@@ -19,14 +19,14 @@ using namespace Fortran::evaluate::value;
namespace {
-class LogicalValueKind : public testing::TestWithParam<int> {};
+class LogicalValueKind : public testing::TestWithParam<KindsEnum> {};
INSTANTIATE_TEST_SUITE_P(LogicalValueKind, LogicalValueKind,
testing::ValuesIn(LogicalKinds),
- [](const testing::TestParamInfo<int> &info) {
- return "LOGICAL(" + std::to_string(info.param) + ")";
+ [](const testing::TestParamInfo<KindsEnum> &info) {
+ return "LOGICAL(" + std::to_string(static_cast<int>(info.param)) + ")";
});
-constexpr int KindPos(int kind) {
+constexpr int KindPos(KindsEnum kind) {
for (std::size_t i{0}; i < std::size(LogicalKinds); ++i) {
if (LogicalKinds[i] == kind) {
return static_cast<int>(i);
@@ -46,7 +46,7 @@ TEST(LogicalValue, DefaultConstructionIsMonostate) {
}
TEST_P(LogicalValueKind, ConstructFromBool) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue truth{kind, true};
EXPECT_FALSE(truth.IsMonostate());
@@ -59,7 +59,7 @@ TEST_P(LogicalValueKind, ConstructFromBool) {
}
TEST_P(LogicalValueKind, ConstructFromWord) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue zero{kind, IntegerValue{kind, 0}};
EXPECT_FALSE(zero.IsTrue());
@@ -75,7 +75,7 @@ TEST_P(LogicalValueKind, ConstructFromWord) {
}
TEST_P(LogicalValueKind, CopyAndMove) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue x{kind, true};
LogicalValue copyConstructed{x};
@@ -95,7 +95,7 @@ TEST_P(LogicalValueKind, CopyAndMove) {
}
TEST_P(LogicalValueKind, KindCheckingConstructors) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue x{kind, true};
EXPECT_EQ(kind, LogicalValue(kind, x).kind());
@@ -108,7 +108,7 @@ TEST_P(LogicalValueKind, KindCheckingConstructors) {
}
TEST_P(LogicalValueKind, Zero) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue zero{LogicalValue::Zero(kind)};
EXPECT_FALSE(zero.IsMonostate());
@@ -118,23 +118,23 @@ TEST_P(LogicalValueKind, Zero) {
}
TEST(LogicalValue, Bits) {
- EXPECT_EQ(8, LogicalValue::bits(1));
- EXPECT_EQ(16, LogicalValue::bits(2));
- EXPECT_EQ(32, LogicalValue::bits(4));
- EXPECT_EQ(64, LogicalValue::bits(8));
- EXPECT_EQ(32, LogicalValue(4, true).bits());
+ EXPECT_EQ(8, LogicalValue::bits(KindsEnum::Kind1));
+ EXPECT_EQ(16, LogicalValue::bits(KindsEnum::Kind2));
+ EXPECT_EQ(32, LogicalValue::bits(KindsEnum::Kind4));
+ EXPECT_EQ(64, LogicalValue::bits(KindsEnum::Kind8));
+ EXPECT_EQ(32, LogicalValue(KindsEnum::Kind4, true).bits());
}
TEST(LogicalValue, BytesStored) {
- EXPECT_EQ(1u, LogicalValue::bytesStored(1));
- EXPECT_EQ(2u, LogicalValue::bytesStored(2));
- EXPECT_EQ(4u, LogicalValue::bytesStored(4));
- EXPECT_EQ(8u, LogicalValue::bytesStored(8));
- EXPECT_EQ(4u, LogicalValue(4, true).bytesStored());
+ EXPECT_EQ(1u, LogicalValue::bytesStored(KindsEnum::Kind1));
+ EXPECT_EQ(2u, LogicalValue::bytesStored(KindsEnum::Kind2));
+ EXPECT_EQ(4u, LogicalValue::bytesStored(KindsEnum::Kind4));
+ EXPECT_EQ(8u, LogicalValue::bytesStored(KindsEnum::Kind8));
+ EXPECT_EQ(4u, LogicalValue(KindsEnum::Kind4, true).bytesStored());
}
TEST_P(LogicalValueKind, Word_) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// .TRUE. is represented canonically as 1 and .FALSE. as 0.
EXPECT_EQ(1, LogicalValue(kind, true).word().ToInt64());
@@ -145,7 +145,7 @@ TEST_P(LogicalValueKind, Word_) {
}
TEST_P(LogicalValueKind, IsCanonical) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_TRUE(LogicalValue(kind, true).IsCanonical());
EXPECT_TRUE(LogicalValue(kind, false).IsCanonical());
@@ -156,7 +156,7 @@ TEST_P(LogicalValueKind, IsCanonical) {
}
TEST_P(LogicalValueKind, IsTrue) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_FALSE(LogicalValue{}.IsTrue());
EXPECT_FALSE(LogicalValue(kind, false).IsTrue());
@@ -165,7 +165,7 @@ TEST_P(LogicalValueKind, IsTrue) {
}
TEST_P(LogicalValueKind, RelationalOperators) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue f{kind, false}, t{kind, true};
EXPECT_TRUE(f < t);
@@ -198,7 +198,7 @@ TEST_P(LogicalValueKind, RelationalOperators) {
}
TEST_P(LogicalValueKind, NOT) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_TRUE(LogicalValue(kind, false).NOT().IsTrue());
EXPECT_FALSE(LogicalValue(kind, true).NOT().IsTrue());
@@ -206,7 +206,7 @@ TEST_P(LogicalValueKind, NOT) {
}
TEST_P(LogicalValueKind, AND) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue f{kind, false}, t{kind, true};
EXPECT_FALSE(f.AND(f).IsTrue());
@@ -217,7 +217,7 @@ TEST_P(LogicalValueKind, AND) {
}
TEST_P(LogicalValueKind, OR) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue f{kind, false}, t{kind, true};
EXPECT_FALSE(f.OR(f).IsTrue());
@@ -228,7 +228,7 @@ TEST_P(LogicalValueKind, OR) {
}
TEST_P(LogicalValueKind, EQV) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue f{kind, false}, t{kind, true};
EXPECT_TRUE(f.EQV(f).IsTrue());
@@ -239,7 +239,7 @@ TEST_P(LogicalValueKind, EQV) {
}
TEST_P(LogicalValueKind, NEQV) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
LogicalValue f{kind, false}, t{kind, true};
EXPECT_FALSE(f.NEQV(f).IsTrue());
@@ -250,7 +250,7 @@ TEST_P(LogicalValueKind, NEQV) {
}
TEST_P(LogicalValueKind, RawBytesRoundTrip) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
for (bool truth : {false, true}) {
SCOPED_TRACE(testing::Message() << "truth=" << truth);
@@ -271,7 +271,7 @@ TEST_P(LogicalValueKind, RawBytesRoundTrip) {
}
TEST_P(LogicalValueKind, Print) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
const int pos{KindPos(kind)};
struct Case {
@@ -299,9 +299,9 @@ TEST_P(LogicalValueKind, Print) {
// Replicates the coverage of the legacy non-GTest test
// flang/unittests/Evaluate/logical.cpp.
TEST_P(LogicalValueKind, TruthTables) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
- EXPECT_EQ(8 * kind, LogicalValue::bits(kind));
+ EXPECT_EQ(8 * static_cast<int>(kind), LogicalValue::bits(kind));
EXPECT_FALSE(LogicalValue{}.IsTrue());
EXPECT_FALSE(LogicalValue(kind, false).IsTrue());
EXPECT_TRUE(LogicalValue(kind, true).IsTrue());
diff --git a/flang/unittests/Evaluate/RealValueTest.cpp b/flang/unittests/Evaluate/RealValueTest.cpp
index 69119522b5f86..f7a0a499d4870 100644
--- a/flang/unittests/Evaluate/RealValueTest.cpp
+++ b/flang/unittests/Evaluate/RealValueTest.cpp
@@ -44,17 +44,18 @@ using RealHostTypedKinds = testing::Types<TypeKind<TypeCategory::Real, 4>,
template <typename T> class RealValueHostTypedKind : public testing::Test {};
TYPED_TEST_SUITE(RealValueHostTypedKind, RealHostTypedKinds, KindName);
-class RealValueKind : public testing::TestWithParam<int> {};
+class RealValueKind : public testing::TestWithParam<KindsEnum> {};
INSTANTIATE_TEST_SUITE_P(RealValueKind, RealValueKind,
- testing::ValuesIn(RealKinds), [](const testing::TestParamInfo<int> &info) {
- return "REAL(" + std::to_string(info.param) + ")";
+ testing::ValuesIn(RealKinds),
+ [](const testing::TestParamInfo<KindsEnum> &info) {
+ return "REAL(" + std::to_string(static_cast<int>(info.param)) + ")";
});
//===----------------------------------------------------------------------===//
// Helpers
//===----------------------------------------------------------------------===//
-constexpr int KindPos(int kind) {
+constexpr int KindPos(KindsEnum kind) {
for (std::size_t i{0}; i < std::size(RealKinds); ++i) {
if (RealKinds[i] == kind) {
return static_cast<int>(i);
@@ -75,10 +76,10 @@ testing::AssertionResult RealValuesEqual(const char *lhsExpr,
#define EXPECT_REAL_EQ(lhs, rhs) EXPECT_PRED_FORMAT2(RealValuesEqual, lhs, rhs)
-std::string AsFortranString(const RealValue &x, int kind, bool minimal) {
+std::string AsFortranString(const RealValue &x, KindsEnum kind, bool minimal) {
std::string s;
llvm::raw_string_ostream os{s};
- x.AsFortran(os, kind, minimal);
+ x.AsFortran(os, static_cast<int>(kind), minimal);
return s;
}
@@ -145,7 +146,7 @@ TEST(RealValue, DefaultConstructionIsMonostate) {
}
TEST_P(RealValueKind, ConstructFromWord) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// The word is the raw bit pattern, not a numeric value.
RealValue zero{kind, IntegerValue::Zero(kind)};
EXPECT_EQ(kind, zero.kind());
@@ -157,7 +158,7 @@ TEST_P(RealValueKind, ConstructFromWord) {
}
TEST(RealValue, CopyAndMove) {
- RealValue x{4, 3.0};
+ RealValue x{KindsEnum::Kind4, 3.0};
RealValue copyConstructed{x};
EXPECT_REAL_EQ(x, copyConstructed);
RealValue copyAssigned;
@@ -171,16 +172,16 @@ TEST(RealValue, CopyAndMove) {
}
TEST(RealValue, KindCheckingConstructors) {
- RealValue x{4, 3.0};
- EXPECT_EQ(4, RealValue(4, x).kind());
- EXPECT_REAL_EQ(x, RealValue(4, x));
- RealValue y{8, 3.0};
- RealValue moved{8, std::move(y)};
- EXPECT_EQ(8, moved.kind());
+ RealValue x{KindsEnum::Kind4, 3.0};
+ EXPECT_EQ(KindsEnum::Kind4, RealValue(KindsEnum::Kind4, x).kind());
+ EXPECT_REAL_EQ(x, RealValue(KindsEnum::Kind4, x));
+ RealValue y{KindsEnum::Kind8, 3.0};
+ RealValue moved{KindsEnum::Kind8, std::move(y)};
+ EXPECT_EQ(KindsEnum::Kind8, moved.kind());
}
TEST_P(RealValueKind, Zero) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue zero{RealValue::Zero(kind)};
EXPECT_FALSE(zero.IsMonostate());
EXPECT_EQ(kind, zero.kind());
@@ -192,38 +193,40 @@ TEST_P(RealValueKind, Zero) {
}
TEST(RealValue, Bits) {
- EXPECT_EQ(16, RealValue::bits(2));
- EXPECT_EQ(16, RealValue::bits(3));
- EXPECT_EQ(32, RealValue::bits(4));
- EXPECT_EQ(64, RealValue::bits(8));
- EXPECT_EQ(128, RealValue::bits(10)); // 80 significant bits, 128 stored
- EXPECT_EQ(128, RealValue::bits(16));
- EXPECT_EQ(32, (RealValue{4, 1.0}.bits()));
+ EXPECT_EQ(16, RealValue::bits(KindsEnum::Kind2));
+ EXPECT_EQ(16, RealValue::bits(KindsEnum::Kind3));
+ EXPECT_EQ(32, RealValue::bits(KindsEnum::Kind4));
+ EXPECT_EQ(64, RealValue::bits(KindsEnum::Kind8));
+ EXPECT_EQ(128,
+ RealValue::bits(KindsEnum::Kind10)); // 80 significant bits, 128 stored
+ EXPECT_EQ(128, RealValue::bits(KindsEnum::Kind16));
+ EXPECT_EQ(32, (RealValue{KindsEnum::Kind4, 1.0}.bits()));
}
TEST(RealValue, BytesStored) {
- EXPECT_EQ(2u, RealValue::bytesStored(2));
- EXPECT_EQ(2u, RealValue::bytesStored(3));
- EXPECT_EQ(4u, RealValue::bytesStored(4));
- EXPECT_EQ(8u, RealValue::bytesStored(8));
- EXPECT_EQ(16u, RealValue::bytesStored(10));
- EXPECT_EQ(16u, RealValue::bytesStored(16));
- EXPECT_EQ(4u, (RealValue{4, 1.0}.bytesStored()));
+ EXPECT_EQ(2u, RealValue::bytesStored(KindsEnum::Kind2));
+ EXPECT_EQ(2u, RealValue::bytesStored(KindsEnum::Kind3));
+ EXPECT_EQ(4u, RealValue::bytesStored(KindsEnum::Kind4));
+ EXPECT_EQ(8u, RealValue::bytesStored(KindsEnum::Kind8));
+ EXPECT_EQ(16u, RealValue::bytesStored(KindsEnum::Kind10));
+ EXPECT_EQ(16u, RealValue::bytesStored(KindsEnum::Kind16));
+ EXPECT_EQ(4u, (RealValue{KindsEnum::Kind4, 1.0}.bytesStored()));
}
TEST(RealValue, KindProperties) {
struct {
- int kind, digits, precision, range, maxExponent, minExponent;
+ KindsEnum kind;
+ int digits, precision, range, maxExponent, minExponent;
} expected[]{
- {2, 11, 3, 4, 16, -13},
- {3, 8, 2, 37, 128, -125},
- {4, 24, 6, 37, 128, -125},
- {8, 53, 15, 307, 1024, -1021},
- {10, 64, 18, 4931, 16384, -16381},
- {16, 113, 33, 4931, 16384, -16381},
+ {KindsEnum::Kind2, 11, 3, 4, 16, -13},
+ {KindsEnum::Kind3, 8, 2, 37, 128, -125},
+ {KindsEnum::Kind4, 24, 6, 37, 128, -125},
+ {KindsEnum::Kind8, 53, 15, 307, 1024, -1021},
+ {KindsEnum::Kind10, 64, 18, 4931, 16384, -16381},
+ {KindsEnum::Kind16, 113, 33, 4931, 16384, -16381},
};
for (auto &e : expected) {
- SCOPED_TRACE(testing::Message() << "kind=" << e.kind);
+ SCOPED_TRACE(testing::Message() << "kind=" << static_cast<int>(e.kind));
EXPECT_EQ(e.digits, RealValue::DIGITS(e.kind));
EXPECT_EQ(e.precision, RealValue::PRECISION(e.kind));
EXPECT_EQ(e.range, RealValue::RANGE(e.kind));
@@ -237,7 +240,7 @@ TEST(RealValue, KindProperties) {
//===----------------------------------------------------------------------===//
TEST_P(RealValueKind, IsZero) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_TRUE(RealValue::Zero(kind).IsZero());
EXPECT_TRUE(RealValue::NegativeZero(kind).IsZero());
EXPECT_FALSE((RealValue{kind, 1.0}.IsZero()));
@@ -246,7 +249,7 @@ TEST_P(RealValueKind, IsZero) {
}
TEST_P(RealValueKind, IsNegative) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_FALSE(RealValue::Zero(kind).IsNegative());
EXPECT_TRUE(RealValue::NegativeZero(kind).IsNegative());
EXPECT_FALSE((RealValue{kind, 1.0}.IsNegative()));
@@ -257,7 +260,7 @@ TEST_P(RealValueKind, IsNegative) {
}
TEST_P(RealValueKind, IsNotANumber) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_FALSE(RealValue::Zero(kind).IsNotANumber());
EXPECT_FALSE(RealValue::Infinity(kind).IsNotANumber());
EXPECT_FALSE(RealValue::Infinity(kind, /*negative=*/true).IsNotANumber());
@@ -266,7 +269,7 @@ TEST_P(RealValueKind, IsNotANumber) {
}
TEST_P(RealValueKind, IsSignalingNaN) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_FALSE(RealValue::Zero(kind).IsSignalingNaN());
EXPECT_FALSE(RealValue::Infinity(kind).IsSignalingNaN());
EXPECT_TRUE(RealValue::SignalingNaN(kind).IsSignalingNaN());
@@ -275,7 +278,7 @@ TEST_P(RealValueKind, IsSignalingNaN) {
}
TEST_P(RealValueKind, IsInfinite) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_FALSE(RealValue::Zero(kind).IsInfinite());
EXPECT_FALSE(RealValue::HUGE(kind).IsInfinite());
EXPECT_TRUE(RealValue::Infinity(kind).IsInfinite());
@@ -284,7 +287,7 @@ TEST_P(RealValueKind, IsInfinite) {
}
TEST_P(RealValueKind, IsFinite) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_TRUE(RealValue::Zero(kind).IsFinite());
EXPECT_TRUE(RealValue::HUGE(kind).IsFinite());
EXPECT_TRUE(RealValue::TINY(kind).IsFinite());
@@ -294,7 +297,7 @@ TEST_P(RealValueKind, IsFinite) {
}
TEST_P(RealValueKind, IsNormal) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_TRUE(RealValue::Zero(kind).IsNormal()); // zero counts as normal here
EXPECT_TRUE(RealValue::TINY(kind).IsNormal());
EXPECT_TRUE(RealValue::HUGE(kind).IsNormal());
@@ -310,7 +313,7 @@ TEST_P(RealValueKind, IsNormal) {
//===----------------------------------------------------------------------===//
TEST_P(RealValueKind, ABS) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_REAL_EQ((RealValue{kind, 3.0}), (RealValue{kind, -3.0}.ABS()));
EXPECT_REAL_EQ((RealValue{kind, 3.0}), (RealValue{kind, 3.0}.ABS()));
EXPECT_TRUE(RealValue::NegativeZero(kind).ABS().RawBits().IsZero());
@@ -319,7 +322,7 @@ TEST_P(RealValueKind, ABS) {
}
TEST_P(RealValueKind, SetSign) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_REAL_EQ((RealValue{kind, -3.0}), (RealValue{kind, 3.0}.SetSign(true)));
EXPECT_REAL_EQ(
(RealValue{kind, 3.0}), (RealValue{kind, -3.0}.SetSign(false)));
@@ -329,7 +332,7 @@ TEST_P(RealValueKind, SetSign) {
}
TEST_P(RealValueKind, SIGN) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_REAL_EQ((RealValue{kind, -3.0}),
(RealValue{kind, 3.0}.SIGN(RealValue{kind, -1.0})));
EXPECT_REAL_EQ((RealValue{kind, 3.0}),
@@ -340,7 +343,7 @@ TEST_P(RealValueKind, SIGN) {
}
TEST_P(RealValueKind, Negate) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_REAL_EQ((RealValue{kind, -3.0}), (RealValue{kind, 3.0}.Negate()));
EXPECT_REAL_EQ((RealValue{kind, 3.0}), (RealValue{kind, -3.0}.Negate()));
EXPECT_REAL_EQ(RealValue::NegativeZero(kind), RealValue::Zero(kind).Negate());
@@ -354,7 +357,7 @@ TEST_P(RealValueKind, Negate) {
//===----------------------------------------------------------------------===//
TEST_P(RealValueKind, Compare) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue zero{RealValue::Zero(kind)};
RealValue minusZero{RealValue::NegativeZero(kind)};
RealValue one{kind, 1.0};
@@ -385,7 +388,7 @@ TEST_P(RealValueKind, Compare) {
}
TEST_P(RealValueKind, EqualityOperators) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// operator== compares bit patterns, unlike Compare().
EXPECT_TRUE((RealValue{kind, 1.0} == RealValue{kind, 1.0}));
EXPECT_FALSE((RealValue{kind, 1.0} == RealValue{kind, 2.0}));
@@ -399,7 +402,7 @@ TEST_P(RealValueKind, EqualityOperators) {
//===----------------------------------------------------------------------===//
TEST_P(RealValueKind, Add) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto sum{RealValue{kind, 1.0}.Add(RealValue{kind, 2.0})};
EXPECT_TRUE(sum.flags.empty());
EXPECT_REAL_EQ((RealValue{kind, 3.0}), sum.value);
@@ -418,7 +421,7 @@ TEST_P(RealValueKind, Add) {
}
TEST_P(RealValueKind, Subtract) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto diff{RealValue{kind, 3.0}.Subtract(RealValue{kind, 5.0})};
EXPECT_TRUE(diff.flags.empty());
EXPECT_REAL_EQ((RealValue{kind, -2.0}), diff.value);
@@ -428,7 +431,7 @@ TEST_P(RealValueKind, Subtract) {
}
TEST_P(RealValueKind, Multiply) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto product{RealValue{kind, 3.0}.Multiply(RealValue{kind, 5.0})};
EXPECT_TRUE(product.flags.empty());
EXPECT_REAL_EQ((RealValue{kind, 15.0}), product.value);
@@ -448,7 +451,7 @@ TEST_P(RealValueKind, Multiply) {
}
TEST_P(RealValueKind, Divide) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto quotient{RealValue{kind, 15.0}.Divide(RealValue{kind, 5.0})};
EXPECT_TRUE(quotient.flags.empty());
EXPECT_REAL_EQ((RealValue{kind, 3.0}), quotient.value);
@@ -470,7 +473,7 @@ TEST_P(RealValueKind, Divide) {
}
TEST_P(RealValueKind, SQRT) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto four{RealValue{kind, 4.0}.SQRT()};
EXPECT_TRUE(four.flags.empty());
EXPECT_REAL_EQ((RealValue{kind, 2.0}), four.value);
@@ -483,7 +486,7 @@ TEST_P(RealValueKind, SQRT) {
}
TEST_P(RealValueKind, NEAREST) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue one{kind, 1.0};
// The next value above 1.0 is 1.0+EPSILON.
@@ -502,7 +505,7 @@ TEST_P(RealValueKind, NEAREST) {
}
TEST_P(RealValueKind, HYPOT) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto hypot{RealValue{kind, 3.0}.HYPOT(RealValue{kind, 4.0})};
EXPECT_REAL_EQ((RealValue{kind, 5.0}), hypot.value);
@@ -513,7 +516,7 @@ TEST_P(RealValueKind, HYPOT) {
}
TEST_P(RealValueKind, DIM) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto positive{RealValue{kind, 7.0}.DIM(RealValue{kind, 5.0})};
EXPECT_REAL_EQ((RealValue{kind, 2.0}), positive.value);
@@ -527,7 +530,7 @@ TEST_P(RealValueKind, DIM) {
}
TEST_P(RealValueKind, MOD) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// The result has the sign of the dividend.
RealValue m1{RealValue{kind, 8.0}.MOD(RealValue{kind, 5.0}).value};
@@ -545,7 +548,7 @@ TEST_P(RealValueKind, MOD) {
}
TEST_P(RealValueKind, MODULO) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// The result has the sign of the divisor.
RealValue m1{RealValue{kind, 8.0}.MODULO(RealValue{kind, 5.0}).value};
@@ -559,7 +562,7 @@ TEST_P(RealValueKind, MODULO) {
}
TEST_P(RealValueKind, KahanSummation) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue correction{RealValue::Zero(kind)};
auto sum{
@@ -581,7 +584,7 @@ TEST_P(RealValueKind, KahanSummation) {
//===----------------------------------------------------------------------===//
TEST_P(RealValueKind, EPSILON) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue eps{RealValue::EPSILON(kind)};
EXPECT_EQ(kind, eps.kind());
@@ -596,7 +599,7 @@ TEST_P(RealValueKind, EPSILON) {
}
TEST_P(RealValueKind, HUGE) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue huge{RealValue::HUGE(kind)};
EXPECT_EQ(kind, huge.kind());
@@ -610,7 +613,7 @@ TEST_P(RealValueKind, HUGE) {
}
TEST_P(RealValueKind, TINY) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue tiny{RealValue::TINY(kind)};
EXPECT_EQ(kind, tiny.kind());
@@ -622,7 +625,7 @@ TEST_P(RealValueKind, TINY) {
}
TEST_P(RealValueKind, NotANumber) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue nan{RealValue::NotANumber(kind)};
EXPECT_EQ(kind, nan.kind());
@@ -632,7 +635,7 @@ TEST_P(RealValueKind, NotANumber) {
}
TEST_P(RealValueKind, Exponent) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// Exponent() is the raw, biased exponent field. The bias is recovered
// from the (unbiased) Fortran MAXEXPONENT and the raw exponent of
@@ -647,22 +650,23 @@ TEST_P(RealValueKind, Exponent) {
}
TEST_P(RealValueKind, EXPONENT) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// The Fortran EXPONENT() intrinsic returns the unbiased exponent, plus one.
EXPECT_EQ(1, (RealValue{kind, 1.0}.EXPONENT().ToInt64()));
EXPECT_EQ(2, (RealValue{kind, 2.0}.EXPONENT().ToInt64()));
EXPECT_EQ(3, (RealValue{kind, 4.0}.EXPONENT().ToInt64()));
EXPECT_EQ(0, RealValue::Zero(kind).EXPONENT().ToInt64());
- EXPECT_EQ(4, (RealValue{kind, 1.0}.EXPONENT().kind())); // INTEGER(4) result
+ EXPECT_EQ(KindsEnum::Kind4,
+ (RealValue{kind, 1.0}.EXPONENT().kind())); // INTEGER(4) result
}
TEST_P(RealValueKind, RRSPACING) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// RRSPACING(1.0) is 2**(DIGITS-1).
RealValue scaled{RealValue{kind, 1.0}
- .SCALE(IntegerValue{4, RealValue::DIGITS(kind) - 1})
+ .SCALE(IntegerValue{KindsEnum::Kind4, RealValue::DIGITS(kind) - 1})
.value};
EXPECT_REAL_EQ(scaled, (RealValue{kind, 1.0}.RRSPACING()));
EXPECT_FALSE((RealValue{kind, -1.0}.RRSPACING().IsNegative()));
@@ -670,7 +674,7 @@ TEST_P(RealValueKind, RRSPACING) {
}
TEST_P(RealValueKind, SPACING) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_REAL_EQ(RealValue::EPSILON(kind), (RealValue{kind, 1.0}.SPACING()));
// The spacing of a zero or subnormal value is defined to be TINY.
@@ -679,7 +683,7 @@ TEST_P(RealValueKind, SPACING) {
}
TEST_P(RealValueKind, SET_EXPONENT) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// SET_EXPONENT(X,I) is FRACTION(X)*2**I.
EXPECT_REAL_EQ(
@@ -691,7 +695,7 @@ TEST_P(RealValueKind, SET_EXPONENT) {
}
TEST_P(RealValueKind, FRACTION) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// FRACTION() normalizes into [0.5, 1.0).
EXPECT_REAL_EQ((RealValue{kind, 0.5}), (RealValue{kind, 1.0}.FRACTION()));
@@ -700,20 +704,22 @@ TEST_P(RealValueKind, FRACTION) {
}
TEST_P(RealValueKind, SCALE) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
- auto scaled{RealValue{kind, 3.0}.SCALE(IntegerValue{4, 4})};
+ auto scaled{RealValue{kind, 3.0}.SCALE(IntegerValue{KindsEnum::Kind4, 4})};
EXPECT_TRUE(scaled.flags.empty());
EXPECT_REAL_EQ((RealValue{kind, 48.0}), scaled.value);
- RealValue rescaled{RealValue{kind, 48.0}.SCALE(IntegerValue{4, -4}).value};
+ RealValue rescaled{
+ RealValue{kind, 48.0}.SCALE(IntegerValue{KindsEnum::Kind4, -4}).value};
EXPECT_REAL_EQ((RealValue{kind, 3.0}), rescaled);
// Scaling a zero ignores the factor.
- EXPECT_TRUE(
- RealValue::Zero(kind).SCALE(IntegerValue{4, 1000}).value.IsZero());
+ EXPECT_TRUE(RealValue::Zero(kind)
+ .SCALE(IntegerValue{KindsEnum::Kind4, 1000})
+ .value.IsZero());
}
TEST_P(RealValueKind, FlushSubnormalToZero) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue subnormal{kind, IntegerValue{kind, 1}};
ASSERT_FALSE(subnormal.IsZero());
@@ -730,27 +736,28 @@ TEST_P(RealValueKind, FlushSubnormalToZero) {
//===----------------------------------------------------------------------===//
TEST_P(RealValueKind, FromInteger) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
- auto exact{RealValue::FromInteger(kind, IntegerValue{8, 3})};
+ auto exact{RealValue::FromInteger(kind, IntegerValue{KindsEnum::Kind8, 3})};
EXPECT_TRUE(exact.flags.empty());
EXPECT_EQ(kind, exact.value.kind());
EXPECT_EQ(Relation::Equal, exact.value.Compare(RealValue{kind, 3.0}));
- EXPECT_TRUE(
- RealValue::FromInteger(kind, IntegerValue::Zero(8)).value.IsZero());
+ EXPECT_TRUE(RealValue::FromInteger(kind, IntegerValue::Zero(KindsEnum::Kind8))
+ .value.IsZero());
- auto negative{RealValue::FromInteger(kind, IntegerValue{8, -3})};
+ auto negative{
+ RealValue::FromInteger(kind, IntegerValue{KindsEnum::Kind8, -3})};
EXPECT_TRUE(negative.value.IsNegative());
// The same bit pattern read as unsigned is a large positive number.
- auto asUnsigned{
- RealValue::FromInteger(kind, IntegerValue{8, -1}, /*isUnsigned=*/true)};
+ auto asUnsigned{RealValue::FromInteger(
+ kind, IntegerValue{KindsEnum::Kind8, -1}, /*isUnsigned=*/true)};
EXPECT_FALSE(asUnsigned.value.IsNegative());
EXPECT_FALSE(asUnsigned.value.IsZero());
}
TEST_P(RealValueKind, ToWholeNumber) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// 3.5 is representable in every supported format.
RealValue x{kind, 3.5};
@@ -778,13 +785,13 @@ TEST_P(RealValueKind, ToWholeNumber) {
}
TEST_P(RealValueKind, ToInteger) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
auto exact{RealValue{kind, 42.0}.ToInteger()};
EXPECT_TRUE(exact.flags.empty());
EXPECT_EQ(42, exact.value.ToInt64());
- EXPECT_EQ(8, exact.value.kind()); // an INTEGER(8) by default
- EXPECT_EQ(4,
+ EXPECT_EQ(KindsEnum::Kind8, exact.value.kind()); // an INTEGER(8) by default
+ EXPECT_EQ(KindsEnum::Kind4,
(RealValue{kind, 42.0}.ToInteger(RoundingMode::ToZero, 32).value.kind()));
EXPECT_EQ(-42, (RealValue{kind, -42.0}.ToInteger().value.ToInt64()));
@@ -798,7 +805,7 @@ TEST_P(RealValueKind, ToInteger) {
// A NaN is invalid and yields HUGE.
auto nan{RealValue::NotANumber(kind).ToInteger()};
EXPECT_TRUE(nan.flags.test(RealFlag::InvalidArgument));
- EXPECT_TRUE(nan.value == IntegerValue::HUGE(8));
+ EXPECT_TRUE(nan.value == IntegerValue::HUGE(KindsEnum::Kind8));
// An infinity overflows.
EXPECT_TRUE(
RealValue::Infinity(kind).ToInteger().flags.test(RealFlag::Overflow));
@@ -809,11 +816,11 @@ TEST_P(RealValueKind, ToInteger) {
}
TEST_P(RealValueKind, Convert) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// Widening to REAL(16) and narrowing back is lossless.
- auto widened{RealValue::Convert(16, RealValue{kind, 3.0})};
- EXPECT_EQ(16, widened.value.kind());
+ auto widened{RealValue::Convert(KindsEnum::Kind16, RealValue{kind, 3.0})};
+ EXPECT_EQ(KindsEnum::Kind16, widened.value.kind());
auto restored{RealValue::Convert(kind, widened.value)};
EXPECT_REAL_EQ((RealValue{kind, 3.0}), restored.value);
// Converting to the same kind is the identity.
@@ -821,12 +828,13 @@ TEST_P(RealValueKind, Convert) {
(RealValue::Convert(kind, RealValue{kind, 3.0}).value));
// A NaN is invalid but stays a NaN.
- auto nan{RealValue::Convert(kind, RealValue::NotANumber(16))};
+ auto nan{RealValue::Convert(kind, RealValue::NotANumber(KindsEnum::Kind16))};
EXPECT_TRUE(nan.flags.test(RealFlag::InvalidArgument));
EXPECT_TRUE(nan.value.IsNotANumber());
// Overflow when the source magnitude exceeds the destination's range.
- if (kind != 16) {
- auto overflowed{RealValue::Convert(kind, RealValue::HUGE(16))};
+ if (kind != KindsEnum::Kind16) {
+ auto overflowed{
+ RealValue::Convert(kind, RealValue::HUGE(KindsEnum::Kind16))};
EXPECT_TRUE(overflowed.flags.test(RealFlag::Overflow));
EXPECT_TRUE(overflowed.value.IsInfinite());
}
@@ -837,12 +845,13 @@ TEST_P(RealValueKind, Convert) {
//===----------------------------------------------------------------------===//
TEST_P(RealValueKind, RawBits) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
EXPECT_TRUE(RealValue::Zero(kind).RawBits().IsZero());
// REAL(10) stores 128 bits, but only 80 of them are significant.
- const int significantBits{kind == 10 ? 80 : RealValue::bits(kind)};
+ const int significantBits{
+ kind == KindsEnum::Kind10 ? 80 : RealValue::bits(kind)};
RealValue allOnes{kind, IntegerValue::MASKR(kind, significantBits)};
EXPECT_EQ(significantBits, allOnes.RawBits().POPCNT());
EXPECT_EQ(1, RealValue::NegativeZero(kind).RawBits().POPCNT());
@@ -854,7 +863,7 @@ TEST_P(RealValueKind, RawBits) {
}
TEST_P(RealValueKind, RawBytesRoundTrip) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
RealValue original{kind, -3.0};
char buffer[16]{};
ASSERT_EQ(RealValue::bytesStored(kind), original.bytesStored());
@@ -894,24 +903,25 @@ TEST(RealValue, DumpHexadecimal) {
{0x00000001, "0x0.000002p-126"},
};
for (auto &e : table) {
- EXPECT_EQ(
- e.expected, (RealValue{4, IntegerValue{4, e.raw}}.DumpHexadecimal()))
+ EXPECT_EQ(e.expected,
+ (RealValue{KindsEnum::Kind4, IntegerValue{KindsEnum::Kind4, e.raw}}
+ .DumpHexadecimal()))
<< "raw=" << e.raw;
}
}
TEST_P(RealValueKind, AsFortran) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// NaNs and infinities are emitted as parenthesized expressions.
std::string nan{AsFortranString(RealValue::NotANumber(kind), kind, false)};
- EXPECT_EQ("(0._" + std::to_string(kind) + "/0.)", nan);
+ EXPECT_EQ("(0._" + std::to_string(static_cast<int>(kind)) + "/0.)", nan);
std::string inf{AsFortranString(RealValue::Infinity(kind), kind, false)};
- EXPECT_EQ("(1._" + std::to_string(kind) + "/0.)", inf);
+ EXPECT_EQ("(1._" + std::to_string(static_cast<int>(kind)) + "/0.)", inf);
std::string negInf{
AsFortranString(RealValue::Infinity(kind, true), kind, false)};
- EXPECT_EQ("(-1._" + std::to_string(kind) + "/0.)", negInf);
+ EXPECT_EQ("(-1._" + std::to_string(static_cast<int>(kind)) + "/0.)", negInf);
// A finite value reads back as itself.
RealValue x{kind, 0.375};
@@ -934,7 +944,7 @@ TEST_P(RealValueKind, AsFortran) {
}
TEST_P(RealValueKind, Read) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
const char *text{"1.0rest"};
const char *p{text};
auto one{RealValue::Read(kind, p)};
@@ -954,7 +964,7 @@ TEST_P(RealValueKind, Read) {
}
TEST_P(RealValueKind, RoundingModes) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
// 1 + EPSILON/2 is exactly halfway between 1 and the next value up, so each
// rounding mode picks a different result.
@@ -971,7 +981,7 @@ TEST_P(RealValueKind, RoundingModes) {
}
TEST_P(RealValueKind, Print) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
const int pos{KindPos(kind)};
llvm::SmallString<128> buf;
@@ -991,13 +1001,13 @@ TEST_P(RealValueKind, Print) {
// Mirrors basicTests() from the legacy test: converts every power of two that
// fits in an INTEGER(8) and converts it back.
TEST_P(RealValueKind, FromIntegerPowersOfTwo) {
- const int kind{GetParam()};
+ const KindsEnum kind{GetParam()};
const int bias{
RealValue::Infinity(kind).Exponent() - RealValue::MAXEXPONENT(kind)};
for (int j{0}; j < 63; ++j) {
SCOPED_TRACE(testing::Message() << "kind=" << kind << " 2**" << j);
const std::uint64_t x{std::uint64_t{1} << j};
- IntegerValue ix{8, x};
+ IntegerValue ix{KindsEnum::Kind8, x};
ASSERT_FALSE(ix.IsNegative());
ASSERT_EQ(x, ix.ToUInt64());
@@ -1055,7 +1065,7 @@ TEST_P(RealValueKind, FromIntegerPowersOfTwo) {
TYPED_TEST(RealValueHostTypedKind, CompareUnaryWithHost) {
using HostT = typename TypeParam::HostT;
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
union {
UnsignedT ui;
@@ -1087,7 +1097,7 @@ TYPED_TEST(RealValueHostTypedKind, CompareUnaryWithHost) {
}
// Every value is emitted as a Fortran constant that reads back exactly.
- const std::string kindSuffix{std::to_string(kind)};
+ const std::string kindSuffix{std::to_string(static_cast<int>(kind))};
std::string text{AsFortranString(x, kind, false)};
if (std::isnan(f)) {
EXPECT_EQ("(0._" + kindSuffix + "/0.)", text);
@@ -1110,7 +1120,7 @@ TYPED_TEST(RealValueHostTypedKind, CompareUnaryWithHost) {
TYPED_TEST(RealValueHostTypedKind, CompareDyadicWithHost) {
using HostT = typename TypeParam::HostT;
using UnsignedT = typename TypeParam::UnsignedT;
- constexpr int kind{TypeParam::kind};
+ constexpr KindsEnum kind{TypeParam::kindsEnum};
union {
UnsignedT ui;
diff --git a/flang/unittests/Evaluate/expression.cpp b/flang/unittests/Evaluate/expression.cpp
index 8d570f517bc1f..abc09ccc55c78 100644
--- a/flang/unittests/Evaluate/expression.cpp
+++ b/flang/unittests/Evaluate/expression.cpp
@@ -12,12 +12,13 @@
using namespace Fortran::evaluate;
static Expr<Type<TypeCategory::Integer>> MakeDefaultIntegerExpr(int32_t v) {
- return MakeConstantExpr<Type<TypeCategory::Integer>>(4, v);
+ return MakeConstantExpr<Type<TypeCategory::Integer>>(
+ Fortran::common::KindsEnum::Kind4, v);
}
int main() {
using DefaultIntegerExpr = Expr<Type<TypeCategory::Integer>>;
- TEST(DefaultIntegerExpr::Result{4}.AsFortran() == "INTEGER(4)");
+ TEST(DefaultIntegerExpr::Result{Kind4}.AsFortran() == "INTEGER(4)");
MATCH("666_4", MakeDefaultIntegerExpr(666).AsFortran());
MATCH("-1_4", (-MakeDefaultIntegerExpr(1)).AsFortran());
auto ex1{MakeDefaultIntegerExpr(2) +
diff --git a/flang/unittests/Evaluate/folding.cpp b/flang/unittests/Evaluate/folding.cpp
index 7837e32df6994..161e64b99a76c 100644
--- a/flang/unittests/Evaluate/folding.cpp
+++ b/flang/unittests/Evaluate/folding.cpp
@@ -9,6 +9,7 @@
#include "flang/Testing/testing.h"
#include <tuple>
+using namespace Fortran::common;
using namespace Fortran::evaluate;
// helper to call functions on all types from tuple
@@ -16,7 +17,7 @@ template <typename... T> struct RunOnTypes {};
template <typename Test, typename... T>
struct RunOnTypes<Test, std::tuple<T...>> {
template <typename U> static void RunOnKinds() {
- for (int kind : KindsByType<U::category>::kinds) {
+ for (KindsEnum kind : KindsByType<U::category>::kinds) {
Test::template Run<U>(kind);
}
}
@@ -26,7 +27,7 @@ struct RunOnTypes<Test, std::tuple<T...>> {
// test for fold.h GetScalarConstantValue function
struct TestGetScalarConstantValue {
- template <typename T> static void Run(int kind) {
+ template <typename T> static void Run(KindsEnum kind) {
Expr<T> exprFullyTyped{MakeZeroExpr<T>(kind)};
Expr<SomeKind<T::category>> exprSomeKind{exprFullyTyped};
Expr<SomeType> exprSomeType{exprSomeKind};
@@ -39,7 +40,7 @@ struct TestGetScalarConstantValue {
template <typename T>
Scalar<T> CallHostRt(
HostRuntimeWrapper func, FoldingContext &context, Scalar<T> x) {
- const int kind{x.kind()};
+ const KindsEnum kind{x.kind()};
return GetScalarConstantValue<T>(
func(context, {AsGenericExpr(Constant<T>{kind, x})}))
.value();
@@ -68,7 +69,8 @@ void TestHostRuntimeSubnormalFlushing() {
// Test subnormal argument flushing
if (auto callable{GetHostRuntimeWrapper("log", r4, {r4})}) {
// Biggest IEEE 32bits subnormal power of two
- const Scalar<FR4> x1{4, Scalar<FR4>::Word{4, 0x00400000}};
+ const Scalar<FR4> x1{
+ KindsEnum::Kind4, Scalar<FR4>::Word{KindsEnum::Kind4, 0x00400000}};
Scalar<FR4> y1Flushing{CallHostRt<FR4>(*callable, flushingContext, x1)};
Scalar<FR4> y1NoFlushing{
CallHostRt<FR4>(*callable, noFlushingContext, x1)};
diff --git a/flang/unittests/Evaluate/intrinsics.cpp b/flang/unittests/Evaluate/intrinsics.cpp
index 69c8aa4246950..f8fa90d4fba67 100644
--- a/flang/unittests/Evaluate/intrinsics.cpp
+++ b/flang/unittests/Evaluate/intrinsics.cpp
@@ -44,7 +44,7 @@ class CookedStrings {
};
template <typename A> auto Const(A &&x) -> Constant<TypeOf<A>> {
- const int kind{x.kind()};
+ const common::KindsEnum kind{x.kind()};
return Constant<TypeOf<A>>{kind, std::move(x)};
}
@@ -148,76 +148,80 @@ struct TestCall {
void TestIntrinsics() {
common::IntrinsicTypeDefaultKinds defaults;
- MATCH(4, defaults.GetDefaultKind(TypeCategory::Integer));
- MATCH(4, defaults.GetDefaultKind(TypeCategory::Real));
+ MATCH(4, static_cast<int>(defaults.GetDefaultKind(TypeCategory::Integer)));
+ MATCH(4, static_cast<int>(defaults.GetDefaultKind(TypeCategory::Real)));
IntrinsicProcTable table{IntrinsicProcTable::Configure(defaults)};
table.Dump(llvm::outs());
using Int1 = Type<TypeCategory::Integer>;
- Int1 int1{1};
+ Int1 int1{Kind1};
using Int4 = Type<TypeCategory::Integer>;
- Int4 int4{4};
+ Int4 int4{Kind4};
using Int8 = Type<TypeCategory::Integer>;
- Int8 int8{8};
+ Int8 int8{Kind8};
using Real4 = Type<TypeCategory::Real>;
- Real4 real4{4};
+ Real4 real4{Kind4};
using Real8 = Type<TypeCategory::Real>;
- Real8 real8{8};
+ Real8 real8{Kind8};
using Complex4 = Type<TypeCategory::Complex>;
- Complex4 complex4{4};
+ Complex4 complex4{Kind4};
using Complex8 = Type<TypeCategory::Complex>;
- Complex8 complex8{8};
+ Complex8 complex8{Kind8};
using Char = Type<TypeCategory::Character>;
using Log4 = Type<TypeCategory::Logical>;
TestCall{defaults, table, "bad"}
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // bad intrinsic name
TestCall{defaults, table, "abs"}
- .Push(Named("a", Const(Scalar<Int4>::Zero(4))))
+ .Push(Named("a", Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4))))
.DoCall(int4.GetType());
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall(int4.GetType());
TestCall{defaults, table, "abs"}
- .Push(Named("bad", Const(Scalar<Int4>::Zero(4))))
+ .Push(Named("bad", Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4))))
.DoCall(); // bad keyword
TestCall{defaults, table, "abs"}.DoCall(); // insufficient args
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Int4>::Zero(4)))
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // too many args
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Int4>::Zero(4)))
- .Push(Named("a", Const(Scalar<Int4>::Zero(4))))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
+ .Push(Named("a", Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4))))
.DoCall();
TestCall{defaults, table, "abs"}
- .Push(Named("a", Const(Scalar<Int4>::Zero(4))))
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Named("a", Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4))))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall();
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Int1>::Zero(1)))
+ .Push(Const(Scalar<Int1>::Zero(common::KindsEnum::Kind1)))
.DoCall(int1.GetType());
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall(int4.GetType());
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Int8>::Zero(8)))
+ .Push(Const(Scalar<Int8>::Zero(common::KindsEnum::Kind8)))
.DoCall(int8.GetType());
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Real4>::Zero(4)))
+ .Push(Const(Scalar<Real4>::Zero(common::KindsEnum::Kind4)))
.DoCall(real4.GetType());
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Real8>::Zero(8)))
+ .Push(Const(Scalar<Real8>::Zero(common::KindsEnum::Kind8)))
.DoCall(real8.GetType());
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Complex4>::Zero(4)))
+ .Push(Const(Scalar<Complex4>::Zero(common::KindsEnum::Kind4)))
.DoCall(real4.GetType());
TestCall{defaults, table, "abs"}
- .Push(Const(Scalar<Complex8>::Zero(8)))
+ .Push(Const(Scalar<Complex8>::Zero(common::KindsEnum::Kind8)))
.DoCall(real8.GetType());
- TestCall{defaults, table, "abs"}.Push(Const(Scalar<Char>::Zero(1))).DoCall();
- TestCall{defaults, table, "abs"}.Push(Const(Scalar<Log4>::Zero(4))).DoCall();
+ TestCall{defaults, table, "abs"}
+ .Push(Const(Scalar<Char>::Zero(common::KindsEnum::Kind1)))
+ .DoCall();
+ TestCall{defaults, table, "abs"}
+ .Push(Const(Scalar<Log4>::Zero(common::KindsEnum::Kind4)))
+ .DoCall();
// "Ext" in names for calls allowed as extensions
TestCall maxCallR{defaults, table, "max"}, maxCallI{defaults, table, "min"},
@@ -226,14 +230,14 @@ void TestIntrinsics() {
max0ExtCall{defaults, table, "max0"},
amin1ExtCall{defaults, table, "amin1"};
for (int j{0}; j < 10; ++j) {
- maxCallR.Push(Const(Scalar<Real4>::Zero(4)));
- maxCallI.Push(Const(Scalar<Int4>::Zero(4)));
- max0Call.Push(Const(Scalar<Int4>::Zero(4)));
- max0ExtCall.Push(Const(Scalar<Real4>::Zero(4)));
- max1Call.Push(Const(Scalar<Real4>::Zero(4)));
- amin0Call.Push(Const(Scalar<Int4>::Zero(4)));
- amin1ExtCall.Push(Const(Scalar<Int4>::Zero(4)));
- amin1Call.Push(Const(Scalar<Real4>::Zero(4)));
+ maxCallR.Push(Const(Scalar<Real4>::Zero(common::KindsEnum::Kind4)));
+ maxCallI.Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)));
+ max0Call.Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)));
+ max0ExtCall.Push(Const(Scalar<Real4>::Zero(common::KindsEnum::Kind4)));
+ max1Call.Push(Const(Scalar<Real4>::Zero(common::KindsEnum::Kind4)));
+ amin0Call.Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)));
+ amin1ExtCall.Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)));
+ amin1Call.Push(Const(Scalar<Real4>::Zero(common::KindsEnum::Kind4)));
}
maxCallR.DoCall(real4.GetType());
maxCallI.DoCall(int4.GetType());
@@ -245,67 +249,68 @@ void TestIntrinsics() {
amin1ExtCall.DoCall(real4.GetType());
TestCall{defaults, table, "conjg"}
- .Push(Const(Scalar<Complex4>::Zero(4)))
+ .Push(Const(Scalar<Complex4>::Zero(common::KindsEnum::Kind4)))
.DoCall(complex4.GetType());
TestCall{defaults, table, "conjg"}
- .Push(Const(Scalar<Complex8>::Zero(8)))
+ .Push(Const(Scalar<Complex8>::Zero(common::KindsEnum::Kind8)))
.DoCall(complex8.GetType());
TestCall{defaults, table, "dconjg"}
- .Push(Const(Scalar<Complex8>::Zero(8)))
+ .Push(Const(Scalar<Complex8>::Zero(common::KindsEnum::Kind8)))
.DoCall(complex8.GetType());
TestCall{defaults, table, "float"}
- .Push(Const(Scalar<Real4>::Zero(4)))
+ .Push(Const(Scalar<Real4>::Zero(common::KindsEnum::Kind4)))
.DoCall();
TestCall{defaults, table, "float"}
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall(real4.GetType());
TestCall{defaults, table, "idint"}
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall();
TestCall{defaults, table, "idint"}
- .Push(Const(Scalar<Real8>::Zero(8)))
+ .Push(Const(Scalar<Real8>::Zero(common::KindsEnum::Kind8)))
.DoCall(int4.GetType());
// Allowed as extensions
TestCall{defaults, table, "float"}
- .Push(Const(Scalar<Int8>::Zero(8)))
+ .Push(Const(Scalar<Int8>::Zero(common::KindsEnum::Kind8)))
.DoCall(real4.GetType());
TestCall{defaults, table, "idint"}
- .Push(Const(Scalar<Real4>::Zero(4)))
+ .Push(Const(Scalar<Real4>::Zero(common::KindsEnum::Kind4)))
.DoCall(int4.GetType());
TestCall{defaults, table, "num_images"}.DoCall(int4.GetType());
TestCall{defaults, table, "num_images"}
- .Push(Const(Scalar<Int1>::Zero(1)))
+ .Push(Const(Scalar<Int1>::Zero(common::KindsEnum::Kind1)))
.DoCall(int4.GetType());
TestCall{defaults, table, "num_images"}
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall(int4.GetType());
TestCall{defaults, table, "num_images"}
- .Push(Const(Scalar<Int8>::Zero(8)))
+ .Push(Const(Scalar<Int8>::Zero(common::KindsEnum::Kind8)))
.DoCall(int4.GetType());
TestCall{defaults, table, "num_images"}
- .Push(Named("team_number", Const(Scalar<Int4>::Zero(4))))
+ .Push(Named(
+ "team_number", Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4))))
.DoCall(int4.GetType());
TestCall{defaults, table, "num_images"}
- .Push(Const(Scalar<Int4>::Zero(4)))
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // too many args
TestCall{defaults, table, "num_images"}
- .Push(Named("bad", Const(Scalar<Int4>::Zero(4))))
+ .Push(Named("bad", Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4))))
.DoCall(); // bad keyword
TestCall{defaults, table, "num_images"}
- .Push(Const(Scalar<Char>::Zero(1)))
+ .Push(Const(Scalar<Char>::Zero(common::KindsEnum::Kind1)))
.DoCall(); // bad type
TestCall{defaults, table, "num_images"}
- .Push(Const(Scalar<Log4>::Zero(4)))
+ .Push(Const(Scalar<Log4>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // bad type
TestCall{defaults, table, "num_images"}
- .Push(Const(Scalar<Complex8>::Zero(8)))
+ .Push(Const(Scalar<Complex8>::Zero(common::KindsEnum::Kind8)))
.DoCall(); // bad type
TestCall{defaults, table, "num_images"}
- .Push(Const(Scalar<Real4>::Zero(4)))
+ .Push(Const(Scalar<Real4>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // bad type
// This test temporarily removed because it requires access to
@@ -314,26 +319,26 @@ void TestIntrinsics() {
// TestCall{defaults, table, "team_number"}.DoCall(int4.GetType());
TestCall{defaults, table, "team_number"}
- .Push(Const(Scalar<Int4>::Zero(4)))
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // too many args
TestCall{defaults, table, "team_number"}
- .Push(Named("bad", Const(Scalar<Int4>::Zero(4))))
+ .Push(Named("bad", Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4))))
.DoCall(); // bad keyword
TestCall{defaults, table, "team_number"}
- .Push(Const(Scalar<Int4>::Zero(4)))
+ .Push(Const(Scalar<Int4>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // bad type
TestCall{defaults, table, "team_number"}
- .Push(Const(Scalar<Char>::Zero(1)))
+ .Push(Const(Scalar<Char>::Zero(common::KindsEnum::Kind1)))
.DoCall(); // bad type
TestCall{defaults, table, "team_number"}
- .Push(Const(Scalar<Log4>::Zero(4)))
+ .Push(Const(Scalar<Log4>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // bad type
TestCall{defaults, table, "team_number"}
- .Push(Const(Scalar<Complex8>::Zero(4)))
+ .Push(Const(Scalar<Complex8>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // bad type
TestCall{defaults, table, "team_number"}
- .Push(Const(Scalar<Real4>::Zero(4)))
+ .Push(Const(Scalar<Real4>::Zero(common::KindsEnum::Kind4)))
.DoCall(); // bad type
// TODO: test other intrinsics
diff --git a/flang/unittests/Evaluate/logical.cpp b/flang/unittests/Evaluate/logical.cpp
index c8bf850d6c08e..a58082a9db70f 100644
--- a/flang/unittests/Evaluate/logical.cpp
+++ b/flang/unittests/Evaluate/logical.cpp
@@ -2,13 +2,13 @@
#include "flang/Testing/testing.h"
#include <cstdio>
-static void testKind(int kind) {
+static void testKind(Fortran::common::KindsEnum kind) {
using Type = Fortran::evaluate::Type<Fortran::common::TypeCategory::Logical>;
TEST(Fortran::evaluate::IsSpecificIntrinsicType<Type>);
TEST(Type::category == Fortran::common::TypeCategory::Logical);
TEST(Type{kind}.kind() == kind);
using Value = Fortran::evaluate::Scalar<Type>;
- MATCH(8 * kind, Value::Zero(kind).bits());
+ MATCH(8 * static_cast<int>(kind), Value::Zero(kind).bits());
TEST(!Value{}.IsTrue());
TEST(!Value(kind, false).IsTrue());
TEST(Value(kind, true).IsTrue());
@@ -33,9 +33,10 @@ static void testKind(int kind) {
}
int main() {
- testKind(1);
- testKind(2);
- testKind(4);
- testKind(8);
+ using Fortran::common::KindsEnum;
+ testKind(KindsEnum::Kind1);
+ testKind(KindsEnum::Kind2);
+ testKind(KindsEnum::Kind4);
+ testKind(KindsEnum::Kind8);
return testing::Complete();
}
More information about the llvm-branch-commits
mailing list