9#ifndef FORTRAN_EVALUATE_TYPE_H_
10#define FORTRAN_EVALUATE_TYPE_H_
21#include "formatting.h"
25#include "flang/Common/idioms.h"
26#include "flang/Common/real.h"
27#include "flang/Common/template.h"
28#include "flang/Common/type-kinds.h"
29#include "flang/Support/Fortran-features.h"
30#include "flang/Support/Fortran.h"
36namespace Fortran::semantics {
45bool IsDescriptor(
const Symbol &);
46bool IsPassedViaDescriptor(
const Symbol &);
51using common::TypeCategory;
56template <TypeCategory CATEGORY,
int KIND = 0>
class Type;
75 constexpr DynamicType(TypeCategory cat,
int k) : category_{cat}, kind_{k} {
76 CHECK(common::IsValidKindOfIntrinsicType(category_, kind_));
81 constexpr DynamicType(
int k, std::int64_t len)
82 : category_{TypeCategory::Character}, kind_{k}, knownLength_{
84 CHECK(common::IsValidKindOfIntrinsicType(category_, kind_));
86 explicit constexpr DynamicType(
88 : category_{TypeCategory::Derived}, derived_{&dt} {
93 CONSTEXPR_CONSTRUCTORS_AND_ASSIGNMENTS(DynamicType)
99 static constexpr DynamicType TypelessIntrinsicArgument() {
101 result.category_ = TypeCategory::Integer;
102 result.kind_ = TypelessKind;
106 static constexpr DynamicType UnlimitedPolymorphic() {
108 result.category_ = TypeCategory::Derived;
109 result.kind_ = ClassKind;
110 result.derived_ =
nullptr;
114 static constexpr DynamicType AssumedType() {
116 result.category_ = TypeCategory::Derived;
117 result.kind_ = AssumedTypeKind;
118 result.derived_ =
nullptr;
123 bool operator==(
const DynamicType &)
const;
124 bool operator!=(
const DynamicType &that)
const {
return !(*
this == that); }
126 constexpr TypeCategory category()
const {
return category_; }
127 constexpr int kind()
const {
132 return charLengthParamValue_;
134 constexpr std::optional<std::int64_t> knownLength()
const {
135#if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE == 7
136 if (knownLength_ < 0) {
142 std::optional<Expr<SubscriptInteger>> GetCharLength()
const;
145 std::optional<Expr<SubscriptInteger>> MeasureSizeInBytes(
FoldingContext &,
147 std::optional<std::int64_t> charLength = std::nullopt)
const;
149 std::string AsFortran()
const;
150 std::string AsFortran(std::string &&charLenExpr)
const;
151 DynamicType ResultTypeForMultiply(
const DynamicType &)
const;
153 bool IsAssumedLengthCharacter()
const;
154 bool IsNonConstantLengthCharacter()
const;
155 bool IsTypelessIntrinsicArgument()
const;
156 constexpr bool IsAssumedType()
const {
157 return kind_ == AssumedTypeKind;
159 constexpr bool IsPolymorphic()
const {
160 return kind_ == ClassKind || IsAssumedType();
162 constexpr bool IsUnlimitedPolymorphic()
const {
163 return IsPolymorphic() && !derived_;
165 bool IsLengthlessIntrinsicType()
const;
167 return DEREF(derived_);
170 bool RequiresDescriptor()
const;
171 bool HasDeferredTypeParameter()
const;
172 bool HasDeferredOrAssumedTypeParameter()
const;
179 bool IsTkCompatibleWith(
const DynamicType &)
const;
180 bool IsTkCompatibleWith(
const DynamicType &, common::IgnoreTKRSet)
const;
184 bool IsTkLenCompatibleWith(
const DynamicType &)
const;
187 std::optional<bool> ExtendsTypeOf(
const DynamicType &)
const;
189 std::optional<bool> SameTypeAs(
const DynamicType &)
const;
193 bool IsEquivalentTo(
const DynamicType &)
const;
200 template <
typename A>
static std::optional<DynamicType> From(
const A &x) {
203 template <
typename A>
static std::optional<DynamicType> From(
const A *p) {
210 template <
typename A>
211 static std::optional<DynamicType> From(
const std::optional<A> &x) {
223 DynamicType DropNonConstantCharacterLength()
const;
231 AssumedTypeKind = -3,
234 constexpr DynamicType() {}
236 TypeCategory category_{TypeCategory::Derived};
239#if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE == 7
241 std::int64_t knownLength_{-1};
243 std::optional<std::int64_t> knownLength_;
251 const std::optional<DynamicType> &);
256 const std::optional<DynamicType> &);
260template <TypeCategory CATEGORY,
int KIND = 0>
struct TypeBase {
261 static constexpr TypeCategory category{CATEGORY};
262 static constexpr int kind{KIND};
263 constexpr bool operator==(
const TypeBase &)
const {
return true; }
264 static constexpr DynamicType GetType() {
return {category, kind}; }
265 static std::string AsFortran() {
return GetType().AsFortran(); }
269class Type<TypeCategory::Integer, KIND>
270 :
public TypeBase<TypeCategory::Integer, KIND> {
276class Type<TypeCategory::Unsigned, KIND>
277 :
public TypeBase<TypeCategory::Unsigned, KIND> {
279 using Scalar = value::Integer<8 * KIND>;
287 constexpr bool isFromInexactLiteralConversion()
const {
288 return isFromInexactLiteralConversion_;
290 void set_isFromInexactLiteralConversion(
bool yes =
true) {
291 isFromInexactLiteralConversion_ = yes;
295 bool isFromInexactLiteralConversion_{
false};
299class Type<TypeCategory::Real, KIND>
300 :
public TypeBase<TypeCategory::Real, KIND>,
303 static constexpr int precision{common::PrecisionOfRealKind(KIND)};
304 static constexpr int bits{common::BitsForBinaryPrecision(precision)};
306 value::Real<std::conditional_t<precision == 64,
307 value::X87IntegerContainer, value::Integer<bits>>,
313class Type<TypeCategory::Complex, KIND>
314 :
public TypeBase<TypeCategory::Complex, KIND>,
317 using Part = Type<TypeCategory::Real, KIND>;
318 using Scalar = value::Complex<typename Part::Scalar>;
322class Type<TypeCategory::Character, 1>
323 :
public TypeBase<TypeCategory::Character, 1> {
325 using Scalar = std::string;
329class Type<TypeCategory::Character, 2>
330 :
public TypeBase<TypeCategory::Character, 2> {
332 using Scalar = std::u16string;
336class Type<TypeCategory::Character, 4>
337 :
public TypeBase<TypeCategory::Character, 4> {
339 using Scalar = std::u32string;
343class Type<TypeCategory::Logical, KIND>
344 :
public TypeBase<TypeCategory::Logical, KIND> {
352template <TypeCategory CATEGORY,
typename T>
353using SameKind = Type<CATEGORY, std::decay_t<T>::kind>;
357using IndirectSubscriptIntegerExpr =
358 common::CopyableIndirection<Expr<SubscriptInteger>>;
363template <TypeCategory CATEGORY,
int KIND>
364using CategoryKindTuple =
365 std::conditional_t<common::IsValidKindOfIntrinsicType(CATEGORY, KIND),
366 std::tuple<Type<CATEGORY, KIND>>, std::tuple<>>;
368template <TypeCategory CATEGORY,
int... KINDS>
369using CategoryTypesHelper =
370 common::CombineTuples<CategoryKindTuple<CATEGORY, KINDS>...>;
372template <TypeCategory CATEGORY>
373using CategoryTypes = CategoryTypesHelper<CATEGORY, 1, 2, 3, 4, 8, 10, 16, 32>;
375using IntegerTypes = CategoryTypes<TypeCategory::Integer>;
376using RealTypes = CategoryTypes<TypeCategory::Real>;
377using ComplexTypes = CategoryTypes<TypeCategory::Complex>;
378using CharacterTypes = CategoryTypes<TypeCategory::Character>;
379using LogicalTypes = CategoryTypes<TypeCategory::Logical>;
380using UnsignedTypes = CategoryTypes<TypeCategory::Unsigned>;
382using FloatingTypes = common::CombineTuples<RealTypes, ComplexTypes>;
384 common::CombineTuples<IntegerTypes, FloatingTypes, UnsignedTypes>;
385using RelationalTypes = common::CombineTuples<IntegerTypes, RealTypes,
386 CharacterTypes, UnsignedTypes>;
387using AllIntrinsicTypes =
388 common::CombineTuples<NumericTypes, CharacterTypes, LogicalTypes>;
389using LengthlessIntrinsicTypes =
390 common::CombineTuples<NumericTypes, LogicalTypes>;
394constexpr bool IsSpecificIntrinsicType{common::HasMember<T, AllIntrinsicTypes>};
400constexpr bool IsLengthlessIntrinsicType{
401 common::HasMember<T, LengthlessIntrinsicTypes>};
405 static constexpr TypeCategory category{CATEGORY};
406 constexpr bool operator==(
const SomeKind &)
const {
return true; }
407 static std::string AsFortran() {
408 return "Some"s + std::string{common::EnumToString(category)};
412using NumericCategoryTypes =
415using AllIntrinsicCategoryTypes =
423 static std::string AsFortran() {
return "SomeType"s; }
429template <>
class SomeKind<TypeCategory::Derived> {
431 static constexpr TypeCategory category{TypeCategory::Derived};
432 using Scalar = StructureConstructor;
434 constexpr SomeKind() {}
435 constexpr explicit SomeKind(
const semantics::DerivedTypeSpec &dts)
436 : derivedTypeSpec_{&dts} {}
437 constexpr explicit SomeKind(
const DynamicType &dt)
438 : SomeKind(dt.GetDerivedTypeSpec()) {}
439 CONSTEXPR_CONSTRUCTORS_AND_ASSIGNMENTS(SomeKind)
441 bool IsUnlimitedPolymorphic()
const {
return !derivedTypeSpec_; }
442 constexpr DynamicType GetType()
const {
443 if (!derivedTypeSpec_) {
444 return DynamicType::UnlimitedPolymorphic();
446 return DynamicType{*derivedTypeSpec_};
449 const semantics::DerivedTypeSpec &derivedTypeSpec()
const {
450 CHECK(derivedTypeSpec_);
451 return *derivedTypeSpec_;
453 bool operator==(
const SomeKind &)
const;
454 std::string AsFortran()
const;
457 const semantics::DerivedTypeSpec *derivedTypeSpec_{
nullptr};
467using SomeCategory = std::tuple<SomeInteger, SomeReal, SomeComplex,
468 SomeCharacter, SomeLogical, SomeUnsigned, SomeDerived>;
471 common::CombineTuples<AllIntrinsicTypes, std::tuple<SomeDerived>>;
473template <
typename T>
using Scalar =
typename std::decay_t<T>::Scalar;
480 static constexpr bool value() {
481 return std::is_same_v<std::decay_t<CONST>,
482 std::decay_t<typename T::Scalar>>;
485 static constexpr int index{
486 common::SearchMembers<Predicate, AllIntrinsicTypes>};
487 using type = std::conditional_t<index >= 0,
488 std::tuple_element_t<index, AllIntrinsicTypes>,
void>;
491template <
typename CONST>
using TypeOf =
typename TypeOfHelper<CONST>::type;
493int SelectedCharKind(
const std::string &,
int defaultKind);
500std::optional<DynamicType> ComparisonType(
501 const DynamicType &,
const DynamicType &);
504std::optional<bool> IsInteroperableIntrinsicType(
const DynamicType &,
506 bool checkCharLength =
true);
507bool IsCUDAIntrinsicType(
const DynamicType &);
511bool AreSameDerivedType(
513bool AreSameDerivedTypeIgnoringTypeParameters(
517bool AreSameDerivedTypeIgnoringLengthParameters(
519bool AreSameDerivedTypeIgnoringSequence(
523#define EXPAND_FOR_EACH_INTEGER_KIND(M, P, S) \
524 M(P, S, 1) M(P, S, 2) M(P, S, 4) M(P, S, 8) M(P, S, 16)
525#define EXPAND_FOR_EACH_REAL_KIND(M, P, S) \
526 M(P, S, 2) M(P, S, 3) M(P, S, 4) M(P, S, 8) M(P, S, 10) M(P, S, 16)
527#define EXPAND_FOR_EACH_COMPLEX_KIND(M, P, S) EXPAND_FOR_EACH_REAL_KIND(M, P, S)
528#define EXPAND_FOR_EACH_CHARACTER_KIND(M, P, S) M(P, S, 1) M(P, S, 2) M(P, S, 4)
529#define EXPAND_FOR_EACH_LOGICAL_KIND(M, P, S) \
530 M(P, S, 1) M(P, S, 2) M(P, S, 4) M(P, S, 8)
531#define EXPAND_FOR_EACH_UNSIGNED_KIND EXPAND_FOR_EACH_INTEGER_KIND
533#define FOR_EACH_INTEGER_KIND_HELP(PREFIX, SUFFIX, K) \
534 PREFIX<Type<TypeCategory::Integer, K>> SUFFIX;
535#define FOR_EACH_REAL_KIND_HELP(PREFIX, SUFFIX, K) \
536 PREFIX<Type<TypeCategory::Real, K>> SUFFIX;
537#define FOR_EACH_COMPLEX_KIND_HELP(PREFIX, SUFFIX, K) \
538 PREFIX<Type<TypeCategory::Complex, K>> SUFFIX;
539#define FOR_EACH_CHARACTER_KIND_HELP(PREFIX, SUFFIX, K) \
540 PREFIX<Type<TypeCategory::Character, K>> SUFFIX;
541#define FOR_EACH_LOGICAL_KIND_HELP(PREFIX, SUFFIX, K) \
542 PREFIX<Type<TypeCategory::Logical, K>> SUFFIX;
543#define FOR_EACH_UNSIGNED_KIND_HELP(PREFIX, SUFFIX, K) \
544 PREFIX<Type<TypeCategory::Unsigned, K>> SUFFIX;
546#define FOR_EACH_INTEGER_KIND(PREFIX, SUFFIX) \
547 EXPAND_FOR_EACH_INTEGER_KIND(FOR_EACH_INTEGER_KIND_HELP, PREFIX, SUFFIX)
548#define FOR_EACH_REAL_KIND(PREFIX, SUFFIX) \
549 EXPAND_FOR_EACH_REAL_KIND(FOR_EACH_REAL_KIND_HELP, PREFIX, SUFFIX)
550#define FOR_EACH_COMPLEX_KIND(PREFIX, SUFFIX) \
551 EXPAND_FOR_EACH_COMPLEX_KIND(FOR_EACH_COMPLEX_KIND_HELP, PREFIX, SUFFIX)
552#define FOR_EACH_CHARACTER_KIND(PREFIX, SUFFIX) \
553 EXPAND_FOR_EACH_CHARACTER_KIND(FOR_EACH_CHARACTER_KIND_HELP, PREFIX, SUFFIX)
554#define FOR_EACH_LOGICAL_KIND(PREFIX, SUFFIX) \
555 EXPAND_FOR_EACH_LOGICAL_KIND(FOR_EACH_LOGICAL_KIND_HELP, PREFIX, SUFFIX)
556#define FOR_EACH_UNSIGNED_KIND(PREFIX, SUFFIX) \
557 EXPAND_FOR_EACH_UNSIGNED_KIND(FOR_EACH_UNSIGNED_KIND_HELP, PREFIX, SUFFIX)
559#define FOR_EACH_LENGTHLESS_INTRINSIC_KIND(PREFIX, SUFFIX) \
560 FOR_EACH_INTEGER_KIND(PREFIX, SUFFIX) \
561 FOR_EACH_REAL_KIND(PREFIX, SUFFIX) \
562 FOR_EACH_COMPLEX_KIND(PREFIX, SUFFIX) \
563 FOR_EACH_LOGICAL_KIND(PREFIX, SUFFIX) \
564 FOR_EACH_UNSIGNED_KIND(PREFIX, SUFFIX)
565#define FOR_EACH_INTRINSIC_KIND(PREFIX, SUFFIX) \
566 FOR_EACH_LENGTHLESS_INTRINSIC_KIND(PREFIX, SUFFIX) \
567 FOR_EACH_CHARACTER_KIND(PREFIX, SUFFIX)
568#define FOR_EACH_SPECIFIC_TYPE(PREFIX, SUFFIX) \
569 FOR_EACH_INTRINSIC_KIND(PREFIX, SUFFIX) \
570 PREFIX<SomeDerived> SUFFIX;
572#define FOR_EACH_CATEGORY_TYPE(PREFIX, SUFFIX) \
573 PREFIX<SomeInteger> SUFFIX; \
574 PREFIX<SomeReal> SUFFIX; \
575 PREFIX<SomeComplex> SUFFIX; \
576 PREFIX<SomeCharacter> SUFFIX; \
577 PREFIX<SomeLogical> SUFFIX; \
578 PREFIX<SomeUnsigned> SUFFIX; \
579 PREFIX<SomeDerived> SUFFIX; \
580 PREFIX<SomeType> SUFFIX;
581#define FOR_EACH_TYPE_AND_KIND(PREFIX, SUFFIX) \
582 FOR_EACH_INTRINSIC_KIND(PREFIX, SUFFIX) \
583 FOR_EACH_CATEGORY_TYPE(PREFIX, SUFFIX)
Definition Fortran-features.h:101
Definition expression.h:784